< prev index next >

src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp

Print this page

 646   // This is convenient but results a ST-before-CAS penalty.  The following CAS suffers
 647   // additional latency as we have another ST in the store buffer that must drain.
 648 
 649   // avoid ST-before-CAS
 650   // register juggle because we need tmpReg for cmpxchgptr below
 651   movptr(scrReg, boxReg);
 652   movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
 653 
 654   // Optimistic form: consider XORL tmpReg,tmpReg
 655   movptr(tmpReg, NULL_WORD);
 656 
 657   // Appears unlocked - try to swing _owner from null to non-null.
 658   // Ideally, I'd manifest "Self" with get_thread and then attempt
 659   // to CAS the register containing Self into m->Owner.
 660   // But we don't have enough registers, so instead we can either try to CAS
 661   // rsp or the address of the box (in scr) into &m->owner.  If the CAS succeeds
 662   // we later store "Self" into m->Owner.  Transiently storing a stack address
 663   // (rsp or the address of the box) into  m->owner is harmless.
 664   // Invariant: tmpReg == 0.  tmpReg is EAX which is the implicit cmpxchg comparand.
 665   lock();
 666   cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
 667   movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
 668   // If we weren't able to swing _owner from null to the BasicLock
 669   // then take the slow path.
 670   jccb  (Assembler::notZero, NO_COUNT);
 671   // update _owner from BasicLock to thread
 672   get_thread (scrReg);                    // beware: clobbers ICCs
 673   movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
 674   xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
 675 
 676   // If the CAS fails we can either retry or pass control to the slow path.
 677   // We use the latter tactic.
 678   // Pass the CAS result in the icc.ZFlag into DONE_LABEL
 679   // If the CAS was successful ...
 680   //   Self has acquired the lock
 681   //   Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
 682   // Intentional fall-through into DONE_LABEL ...
 683 #else // _LP64
 684   // It's inflated and we use scrReg for ObjectMonitor* in this section.
 685   movq(scrReg, tmpReg);
 686   xorq(tmpReg, tmpReg);
 687   lock();
 688   cmpxchgptr(thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
 689   // Unconditionally set box->_displaced_header = markWord::unused_mark().
 690   // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
 691   movptr(Address(boxReg, 0), checked_cast<int32_t>(markWord::unused_mark().value()));
 692   // Propagate ICC.ZF from CAS above into DONE_LABEL.
 693   jccb(Assembler::equal, COUNT);          // CAS above succeeded; propagate ZF = 1 (success)
 694 

 646   // This is convenient but results a ST-before-CAS penalty.  The following CAS suffers
 647   // additional latency as we have another ST in the store buffer that must drain.
 648 
 649   // avoid ST-before-CAS
 650   // register juggle because we need tmpReg for cmpxchgptr below
 651   movptr(scrReg, boxReg);
 652   movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
 653 
 654   // Optimistic form: consider XORL tmpReg,tmpReg
 655   movptr(tmpReg, NULL_WORD);
 656 
 657   // Appears unlocked - try to swing _owner from null to non-null.
 658   // Ideally, I'd manifest "Self" with get_thread and then attempt
 659   // to CAS the register containing Self into m->Owner.
 660   // But we don't have enough registers, so instead we can either try to CAS
 661   // rsp or the address of the box (in scr) into &m->owner.  If the CAS succeeds
 662   // we later store "Self" into m->Owner.  Transiently storing a stack address
 663   // (rsp or the address of the box) into  m->owner is harmless.
 664   // Invariant: tmpReg == 0.  tmpReg is EAX which is the implicit cmpxchg comparand.
 665   lock();
 666   cmpxchgptr(thread, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
 667   movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3







 668 
 669   // If the CAS fails we can either retry or pass control to the slow path.
 670   // We use the latter tactic.
 671   // Pass the CAS result in the icc.ZFlag into DONE_LABEL
 672   // If the CAS was successful ...
 673   //   Self has acquired the lock
 674   //   Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
 675   // Intentional fall-through into DONE_LABEL ...
 676 #else // _LP64
 677   // It's inflated and we use scrReg for ObjectMonitor* in this section.
 678   movq(scrReg, tmpReg);
 679   xorq(tmpReg, tmpReg);
 680   lock();
 681   cmpxchgptr(thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
 682   // Unconditionally set box->_displaced_header = markWord::unused_mark().
 683   // Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
 684   movptr(Address(boxReg, 0), checked_cast<int32_t>(markWord::unused_mark().value()));
 685   // Propagate ICC.ZF from CAS above into DONE_LABEL.
 686   jccb(Assembler::equal, COUNT);          // CAS above succeeded; propagate ZF = 1 (success)
 687 
< prev index next >