hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
changeset 31782 b23b74f8ae8d
parent 31592 43f48e165466
child 31849 92ca49fa9fa7
equal deleted inserted replaced
31781:6bc2497120a9 31782:b23b74f8ae8d
  1779          lock();
  1779          lock();
  1780        }
  1780        }
  1781        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  1781        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  1782     } else
  1782     } else
  1783     if ((EmitSync & 128) == 0) {                      // avoid ST-before-CAS
  1783     if ((EmitSync & 128) == 0) {                      // avoid ST-before-CAS
       
  1784        // register juggle because we need tmpReg for cmpxchgptr below
  1784        movptr(scrReg, boxReg);
  1785        movptr(scrReg, boxReg);
  1785        movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
  1786        movptr(boxReg, tmpReg);                   // consider: LEA box, [tmp-2]
  1786 
  1787 
  1787        // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
  1788        // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes
  1788        if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
  1789        if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) {
  1812        if (os::is_MP()) {
  1813        if (os::is_MP()) {
  1813          lock();
  1814          lock();
  1814        }
  1815        }
  1815        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  1816        cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  1816        movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
  1817        movptr(Address(scrReg, 0), 3);          // box->_displaced_header = 3
       
  1818        // If we weren't able to swing _owner from NULL to the BasicLock
       
  1819        // then take the slow path.
  1817        jccb  (Assembler::notZero, DONE_LABEL);
  1820        jccb  (Assembler::notZero, DONE_LABEL);
       
  1821        // update _owner from BasicLock to thread
  1818        get_thread (scrReg);                    // beware: clobbers ICCs
  1822        get_thread (scrReg);                    // beware: clobbers ICCs
  1819        movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
  1823        movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg);
  1820        xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
  1824        xorptr(boxReg, boxReg);                 // set icc.ZFlag = 1 to indicate success
  1821 
  1825 
  1822        // If the CAS fails we can either retry or pass control to the slow-path.
  1826        // If the CAS fails we can either retry or pass control to the slow-path.
  2081        jccb  (Assembler::notZero, LSuccess);
  2085        jccb  (Assembler::notZero, LSuccess);
  2082 
  2086 
  2083        xorptr(boxReg, boxReg);                  // box is really EAX
  2087        xorptr(boxReg, boxReg);                  // box is really EAX
  2084        if (os::is_MP()) { lock(); }
  2088        if (os::is_MP()) { lock(); }
  2085        cmpxchgptr(rsp, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  2089        cmpxchgptr(rsp, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
       
  2090        // There's no successor so we tried to regrab the lock with the
       
  2091        // placeholder value. If that didn't work, then another thread
       
  2092        // grabbed the lock so we're done (and exit was a success).
  2086        jccb  (Assembler::notEqual, LSuccess);
  2093        jccb  (Assembler::notEqual, LSuccess);
  2087        // Since we're low on registers we installed rsp as a placeholding in _owner.
  2094        // Since we're low on registers we installed rsp as a placeholding in _owner.
  2088        // Now install Self over rsp.  This is safe as we're transitioning from
  2095        // Now install Self over rsp.  This is safe as we're transitioning from
  2089        // non-null to non=null
  2096        // non-null to non=null
  2090        get_thread (boxReg);
  2097        get_thread (boxReg);
  2188       // box is really RAX -- the following CMPXCHG depends on that binding
  2195       // box is really RAX -- the following CMPXCHG depends on that binding
  2189       // cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
  2196       // cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
  2190       movptr(boxReg, (int32_t)NULL_WORD);
  2197       movptr(boxReg, (int32_t)NULL_WORD);
  2191       if (os::is_MP()) { lock(); }
  2198       if (os::is_MP()) { lock(); }
  2192       cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
  2199       cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
       
  2200       // There's no successor so we tried to regrab the lock.
       
  2201       // If that didn't work, then another thread grabbed the
       
  2202       // lock so we're done (and exit was a success).
  2193       jccb  (Assembler::notEqual, LSuccess);
  2203       jccb  (Assembler::notEqual, LSuccess);
  2194       // Intentional fall-through into slow-path
  2204       // Intentional fall-through into slow-path
  2195 
  2205 
  2196       bind  (LGoSlowPath);
  2206       bind  (LGoSlowPath);
  2197       orl   (boxReg, 1);                      // set ICC.ZF=0 to indicate failure
  2207       orl   (boxReg, 1);                      // set ICC.ZF=0 to indicate failure