< prev index next >

src/cpu/sparc/vm/macroAssembler_sparc.cpp

Print this page
rev 10742 : Make fields used in lock-free algorithms volatile


 738     tst(L0);
 739     restore();
 740     breakpoint_trap(notZero, Assembler::ptr_cc);
 741     // }
 742 # endif
 743 
 744   st_ptr(oop_result, vm_result_addr);
 745 }
 746 
 747 
 748 void MacroAssembler::ic_call(address entry, bool emit_delay, jint method_index) {
 749   RelocationHolder rspec = virtual_call_Relocation::spec(pc(), method_index);
 750   patchable_set((intptr_t)Universe::non_oop_word(), G5_inline_cache_reg);
 751   relocate(rspec);
 752   call(entry, relocInfo::none);
 753   if (emit_delay) {
 754     delayed()->nop();
 755   }
 756 }
 757 
 758 void MacroAssembler::card_table_write(jbyte* byte_map_base,
 759                                       Register tmp, Register obj) {
 760 #ifdef _LP64
 761   srlx(obj, CardTableModRefBS::card_shift, obj);
 762 #else
 763   srl(obj, CardTableModRefBS::card_shift, obj);
 764 #endif
 765   assert(tmp != obj, "need separate temp reg");
 766   set((address) byte_map_base, tmp);
 767   stb(G0, tmp, obj);
 768 }
 769 
 770 
 771 void MacroAssembler::internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) {
 772   address save_pc;
 773   int shiftcnt;
 774 #ifdef _LP64
 775 # ifdef CHECK_DELAY
 776   assert_not_delayed((char*) "cannot put two instructions in delay slot");
 777 # endif
 778   v9_dep();


3793     generate_satb_log_enqueue_if_necessary(true); // with frame
3794 
3795     call(satb_log_enqueue_with_frame);
3796     delayed()->mov(pre_val, O0);
3797   } else {
3798     generate_satb_log_enqueue_if_necessary(false); // frameless
3799 
3800     save_frame(0);
3801     call(satb_log_enqueue_frameless);
3802     delayed()->mov(pre_val->after_save(), O0);
3803     restore();
3804   }
3805 
3806   bind(filtered);
3807 }
3808 
3809 static address dirty_card_log_enqueue = 0;
3810 static u_char* dirty_card_log_enqueue_end = 0;
3811 
3812 // This gets to assume that o0 contains the object address.
3813 static void generate_dirty_card_log_enqueue(jbyte* byte_map_base) {
3814   BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
3815   CodeBuffer buf(bb);
3816   MacroAssembler masm(&buf);
3817 #define __ masm.
3818   address start = __ pc();
3819 
3820   Label not_already_dirty, restart, refill, young_card;
3821 
3822 #ifdef _LP64
3823   __ srlx(O0, CardTableModRefBS::card_shift, O0);
3824 #else
3825   __ srl(O0, CardTableModRefBS::card_shift, O0);
3826 #endif
3827   AddressLiteral addrlit(byte_map_base);
3828   __ set(addrlit, O1); // O1 := <card table base>
3829   __ ldub(O0, O1, O2); // O2 := [O0 + O1]
3830 
3831   __ cmp_and_br_short(O2, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
3832 
3833   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
3834   __ ldub(O0, O1, O2); // O2 := [O0 + O1]
3835 
3836   assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
3837   __ cmp_and_br_short(O2, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
3838 
3839   __ bind(young_card);
3840   // We didn't take the branch, so we're already dirty: return.
3841   // Use return-from-leaf
3842   __ retl();
3843   __ delayed()->nop();
3844 
3845   // Not dirty.
3846   __ bind(not_already_dirty);
3847 


3888   // Since the call will overwrite O7, we save and restore that, as well.
3889   __ mov(O7, L4);
3890 
3891   __ call_VM_leaf(L7_thread_cache, handle_zero, G2_thread);
3892   __ mov(L3, G1_scratch);
3893   __ mov(L5, G3_scratch);
3894   __ mov(L6, O3);
3895   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3896   __ delayed()->mov(L4, O7);
3897 
3898   dirty_card_log_enqueue = start;
3899   dirty_card_log_enqueue_end = __ pc();
3900   // XXX Should have a guarantee here about not going off the end!
3901   // Does it already do so?  Do an experiment...
3902 
3903 #undef __
3904 
3905 }
3906 
3907 static inline void
3908 generate_dirty_card_log_enqueue_if_necessary(jbyte* byte_map_base) {
3909   if (dirty_card_log_enqueue == 0) {
3910     generate_dirty_card_log_enqueue(byte_map_base);
3911     assert(dirty_card_log_enqueue != 0, "postcondition.");
3912   }
3913 }
3914 
3915 
3916 void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3917 
3918   Label filtered;
3919   MacroAssembler* post_filter_masm = this;
3920 
3921   if (new_val == G0) return;
3922 
3923   G1SATBCardTableLoggingModRefBS* bs =
3924     barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
3925 
3926   if (G1RSBarrierRegionFilter) {
3927     xor3(store_addr, new_val, tmp);
3928 #ifdef _LP64


5100   ba(L_cleanup_check);
5101   delayed()->nop();
5102 
5103   // Table look-up method for the remaining few bytes
5104   bind(L_cleanup_loop);
5105   ldub(buf, 0, O4);
5106   inc(buf);
5107   dec(len);
5108   xor3(O4, crc, O4);
5109   and3(O4, 0xFF, O4);
5110   sllx(O4, 2, O4);
5111   lduw(table, O4, O4);
5112   srlx(crc, 8, crc);
5113   xor3(O4, crc, crc);
5114   bind(L_cleanup_check);
5115   nop();
5116   cmp_and_br_short(len, 0, Assembler::greaterUnsigned, Assembler::pt, L_cleanup_loop);
5117 
5118   not1(crc);
5119 }
5120 


 738     tst(L0);
 739     restore();
 740     breakpoint_trap(notZero, Assembler::ptr_cc);
 741     // }
 742 # endif
 743 
 744   st_ptr(oop_result, vm_result_addr);
 745 }
 746 
 747 
 748 void MacroAssembler::ic_call(address entry, bool emit_delay, jint method_index) {
 749   RelocationHolder rspec = virtual_call_Relocation::spec(pc(), method_index);
 750   patchable_set((intptr_t)Universe::non_oop_word(), G5_inline_cache_reg);
 751   relocate(rspec);
 752   call(entry, relocInfo::none);
 753   if (emit_delay) {
 754     delayed()->nop();
 755   }
 756 }
 757 
 758 void MacroAssembler::card_table_write(volatile jbyte* byte_map_base,
 759                                       Register tmp, Register obj) {
 760 #ifdef _LP64
 761   srlx(obj, CardTableModRefBS::card_shift, obj);
 762 #else
 763   srl(obj, CardTableModRefBS::card_shift, obj);
 764 #endif
 765   assert(tmp != obj, "need separate temp reg");
 766   set((address) byte_map_base, tmp);
 767   stb(G0, tmp, obj);
 768 }
 769 
 770 
 771 void MacroAssembler::internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable) {
 772   address save_pc;
 773   int shiftcnt;
 774 #ifdef _LP64
 775 # ifdef CHECK_DELAY
 776   assert_not_delayed((char*) "cannot put two instructions in delay slot");
 777 # endif
 778   v9_dep();


3793     generate_satb_log_enqueue_if_necessary(true); // with frame
3794 
3795     call(satb_log_enqueue_with_frame);
3796     delayed()->mov(pre_val, O0);
3797   } else {
3798     generate_satb_log_enqueue_if_necessary(false); // frameless
3799 
3800     save_frame(0);
3801     call(satb_log_enqueue_frameless);
3802     delayed()->mov(pre_val->after_save(), O0);
3803     restore();
3804   }
3805 
3806   bind(filtered);
3807 }
3808 
3809 static address dirty_card_log_enqueue = 0;
3810 static u_char* dirty_card_log_enqueue_end = 0;
3811 
3812 // This gets to assume that o0 contains the object address.
3813 static void generate_dirty_card_log_enqueue(volatile jbyte* byte_map_base) {
3814   BufferBlob* bb = BufferBlob::create("dirty_card_enqueue", EnqueueCodeSize*2);
3815   CodeBuffer buf(bb);
3816   MacroAssembler masm(&buf);
3817 #define __ masm.
3818   address start = __ pc();
3819 
3820   Label not_already_dirty, restart, refill, young_card;
3821 
3822 #ifdef _LP64
3823   __ srlx(O0, CardTableModRefBS::card_shift, O0);
3824 #else
3825   __ srl(O0, CardTableModRefBS::card_shift, O0);
3826 #endif
3827   AddressLiteral addrlit((address)byte_map_base);
3828   __ set(addrlit, O1); // O1 := <card table base>
3829   __ ldub(O0, O1, O2); // O2 := [O0 + O1]
3830 
3831   __ cmp_and_br_short(O2, G1SATBCardTableModRefBS::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
3832 
3833   __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
3834   __ ldub(O0, O1, O2); // O2 := [O0 + O1]
3835 
3836   assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
3837   __ cmp_and_br_short(O2, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
3838 
3839   __ bind(young_card);
3840   // We didn't take the branch, so we're already dirty: return.
3841   // Use return-from-leaf
3842   __ retl();
3843   __ delayed()->nop();
3844 
3845   // Not dirty.
3846   __ bind(not_already_dirty);
3847 


3888   // Since the call will overwrite O7, we save and restore that, as well.
3889   __ mov(O7, L4);
3890 
3891   __ call_VM_leaf(L7_thread_cache, handle_zero, G2_thread);
3892   __ mov(L3, G1_scratch);
3893   __ mov(L5, G3_scratch);
3894   __ mov(L6, O3);
3895   __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
3896   __ delayed()->mov(L4, O7);
3897 
3898   dirty_card_log_enqueue = start;
3899   dirty_card_log_enqueue_end = __ pc();
3900   // XXX Should have a guarantee here about not going off the end!
3901   // Does it already do so?  Do an experiment...
3902 
3903 #undef __
3904 
3905 }
3906 
3907 static inline void
3908 generate_dirty_card_log_enqueue_if_necessary(volatile jbyte* byte_map_base) {
3909   if (dirty_card_log_enqueue == 0) {
3910     generate_dirty_card_log_enqueue(byte_map_base);
3911     assert(dirty_card_log_enqueue != 0, "postcondition.");
3912   }
3913 }
3914 
3915 
3916 void MacroAssembler::g1_write_barrier_post(Register store_addr, Register new_val, Register tmp) {
3917 
3918   Label filtered;
3919   MacroAssembler* post_filter_masm = this;
3920 
3921   if (new_val == G0) return;
3922 
3923   G1SATBCardTableLoggingModRefBS* bs =
3924     barrier_set_cast<G1SATBCardTableLoggingModRefBS>(Universe::heap()->barrier_set());
3925 
3926   if (G1RSBarrierRegionFilter) {
3927     xor3(store_addr, new_val, tmp);
3928 #ifdef _LP64


5100   ba(L_cleanup_check);
5101   delayed()->nop();
5102 
5103   // Table look-up method for the remaining few bytes
5104   bind(L_cleanup_loop);
5105   ldub(buf, 0, O4);
5106   inc(buf);
5107   dec(len);
5108   xor3(O4, crc, O4);
5109   and3(O4, 0xFF, O4);
5110   sllx(O4, 2, O4);
5111   lduw(table, O4, O4);
5112   srlx(crc, 8, crc);
5113   xor3(O4, crc, crc);
5114   bind(L_cleanup_check);
5115   nop();
5116   cmp_and_br_short(len, 0, Assembler::greaterUnsigned, Assembler::pt, L_cleanup_loop);
5117 
5118   not1(crc);
5119 }

< prev index next >