RFR: 8341854: Incorrect clearing of ZF in fast_unlock_lightweight on x86

Daniel D. Daugherty dcubed at openjdk.org
Wed Oct 9 16:08:58 UTC 2024


On Wed, 9 Oct 2024 13:11:58 GMT, Fredrik Bredberg <fbredberg at openjdk.org> wrote:

> This bug was created in [JDK-8320318](https://bugs.openjdk.org/browse/JDK-8320318).
> 
> `C2_MacroAssembler::fast_unlock_lightweight()` on x86 issues a `testl(monitor, monitor);` instruction for the sole purpose of clearing the zero-flag, which should force us to go into the slow path.
> 
> However, this instruction incorrectly only checks the lower 32-bits, which results in setting the zero-flag if the ObjectMonitor has all-zeros in the lower 32-bits. For some reason this seems to be quite common on macosx-x64, where we tend to get an ObjectMonitor address that is 0x0000600000000000.
> 
> The reason we wanted to go into the slow path was that we've observed that there is a thread queued on either the EntryList or cxq, and there is no successor. However since we failed to clear the zero-flag, we will go into the fast path and no one will wake up the stranded thread. Thus the system will hang and any test system will timeout.
> 
> Tested ok in tier1-3 on all x64 related platforms. Also ran the vm.lang.LockUnlock.testContendedLock test.

Thumbs up. I think this is a trivial fix since the new instruction:
`orl(t, 1)` is one of the well known ways to set ZF to 0. It's just
the opposite of the well known way to set ZF to 1 used on L835
below: `xorl(t, t)`.

-------------

Marked as reviewed by dcubed (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/21422#pullrequestreview-2357597296


More information about the hotspot-compiler-dev mailing list