2769 // and stores within the critical section from reordering (floating)
2770 // past the store that releases the lock. But TSO is a strong memory model
2771 // and that particular flavor of barrier is a noop, so we can safely elide it.
2772 // Note that we use 1-0 locking by default for the inflated case. We
2773 // close the resultant (and rare) race by having contended threads in
2774 // monitorenter periodically poll _owner.
2775
2776 // 1-0 form : avoids CAS and MEMBAR in the common case
2777 // Do not bother to ratify that m->Owner == Self.
2778 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), Rbox);
2779 orcc(Rbox, G0, G0);
2780 brx(Assembler::notZero, false, Assembler::pn, done);
2781 delayed()->
2782 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)), Rscratch);
2783 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)), Rbox);
2784 orcc(Rbox, Rscratch, G0);
2785 brx(Assembler::zero, false, Assembler::pt, done);
2786 delayed()->
2787 st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
2788
2789 if (os::is_MP()) { membar(StoreLoad); }
2790 // Check that _succ is (or remains) non-zero
2791 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
2792 andcc(Rscratch, Rscratch, G0);
2793 brx(Assembler::notZero, false, Assembler::pt, done);
2794 delayed()->andcc(G0, G0, G0);
2795 add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
2796 mov(G2_thread, Rscratch);
2797 cas_ptr(Rmark, G0, Rscratch);
2798 cmp(Rscratch, G0);
2799 // invert icc.zf and goto done
2800 // A slightly better v8+/v9 idiom would be the following:
2801 // movrnz Rscratch,1,Rscratch
2802 // ba done
2803 // xorcc Rscratch,1,G0
2804 // In v8+ mode the idiom would be valid IFF Rscratch was a G or O register
2805 brx(Assembler::notZero, false, Assembler::pt, done);
2806 delayed()->cmp(G0, G0);
2807 br(Assembler::always, false, Assembler::pt, done);
2808 delayed()->cmp(G0, 1);
2809
|
2769 // and stores within the critical section from reordering (floating)
2770 // past the store that releases the lock. But TSO is a strong memory model
2771 // and that particular flavor of barrier is a noop, so we can safely elide it.
2772 // Note that we use 1-0 locking by default for the inflated case. We
2773 // close the resultant (and rare) race by having contended threads in
2774 // monitorenter periodically poll _owner.
2775
2776 // 1-0 form : avoids CAS and MEMBAR in the common case
2777 // Do not bother to ratify that m->Owner == Self.
2778 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)), Rbox);
2779 orcc(Rbox, G0, G0);
2780 brx(Assembler::notZero, false, Assembler::pn, done);
2781 delayed()->
2782 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList)), Rscratch);
2783 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq)), Rbox);
2784 orcc(Rbox, Rscratch, G0);
2785 brx(Assembler::zero, false, Assembler::pt, done);
2786 delayed()->
2787 st_ptr(G0, Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
2788
2789 membar(StoreLoad);
2790 // Check that _succ is (or remains) non-zero
2791 ld_ptr(Address(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), Rscratch);
2792 andcc(Rscratch, Rscratch, G0);
2793 brx(Assembler::notZero, false, Assembler::pt, done);
2794 delayed()->andcc(G0, G0, G0);
2795 add(Rmark, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner), Rmark);
2796 mov(G2_thread, Rscratch);
2797 cas_ptr(Rmark, G0, Rscratch);
2798 cmp(Rscratch, G0);
2799 // invert icc.zf and goto done
2800 // A slightly better v8+/v9 idiom would be the following:
2801 // movrnz Rscratch,1,Rscratch
2802 // ba done
2803 // xorcc Rscratch,1,G0
2804 // In v8+ mode the idiom would be valid IFF Rscratch was a G or O register
2805 brx(Assembler::notZero, false, Assembler::pt, done);
2806 delayed()->cmp(G0, G0);
2807 br(Assembler::always, false, Assembler::pt, done);
2808 delayed()->cmp(G0, 1);
2809
|