RFR: 8351997: AArch64: Interpreter volatile reference stores with G1 are not sequentially consistent

Aleksey Shipilev shade at openjdk.org
Wed May 28 10:51:51 UTC 2025


On Wed, 28 May 2025 08:49:17 GMT, Erik Österlund <eosterlund at openjdk.org> wrote:

> The optimized fast_aputfield bytecode on AArch64 stores the field flags in r3, and performs the leading and trailing fencing depending on its volatile bit being set or not. However, r3 is also the last temp register passed in to the barrier set for reference stores, and G1 clobbers it in a way that may clear the volatile bit. Then the trailing fence won't get executed, and sequential consistency is broken.
> 
> My fix puts the flags in r5 instead, which is the register that was used by normal aputfield bytecodes. This way, barriers don't clobber the volatile bits.
> 
> This bug has been observed to mess up a classic Dekker duality in the java.util.concurrent.Exchanger class, leading to a hang in the test/jdk/java/util/concurrent/Exchanger/ExchangeLoops.java test that exercises it. Using G1 and -Xint a reproducer hangs 30/100 times in mach5. With the fix, the same reproducer hangs 0/100 times.

Ouch. I think this is fine without further refactoring, especially since I see it should be backported into JDK 21 as well.

I was wondering why haven't we caught this in jcstress. jcstress runs in int/C1/C2 modes specifically to catch issues like these. I believe this slipped through because all of our seqcst tests, Dekker included, operate on primitives. So we never actually explore what happens with reference load/stores, and as this bug shows, there are _interesting_ interactions with GC barriers. I'll see how to amend jcstress to cover this...

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

Marked as reviewed by shade (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/25483#pullrequestreview-2874530955


More information about the hotspot-dev mailing list