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 |