JDK-8360679 : Shenandoah: AOT saved adapter calls into broken GC barrier stub
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 25
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: aarch64
  • Submitted: 2025-06-26
  • Updated: 2025-08-02
  • Resolved: 2025-07-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 25 JDK 26
25Fixed 26 b09Fixed
Related Reports
Causes :  
Relates :  
Description
The following three cases fail with -XX:+UseShenandoahGC on AArch64:

test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java
test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java
test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java

Note-1: a fastdebug JDK is tested
Note-2: only the "aot" variant of these three cases failed. That is, "static" and "dynamic" can pass.
Note-3: I checked x86_64 as well and the tests passed on x86_64.

The test command I used:

case-1:
make test JTREG="VM_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC" TEST=test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesAsCollectorTest.java

case-2:
make test JTREG="VM_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC" TEST=test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesPermuteArgumentsTest.java

case-3:
make test JTREG="VM_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC" TEST=test/hotspot/jtreg/runtime/cds/appcds/methodHandles/MethodHandlesSpreadArgumentsTest.java

Here shows the snippet of error log for MethodHandlesAsCollectorTest.java:

STDERR:
STARTED    MethodHandlesAsCollectorTest::test 'test'
java.lang.RuntimeException: Hotspot crashed
	at jdk.test.lib.cds.CDSTestUtils.executeAndLog(CDSTestUtils.java:703)
	at jdk.test.lib.cds.CDSAppTester.executeAndCheck(CDSAppTester.java:212)
	at jdk.test.lib.cds.CDSAppTester.productionRun(CDSAppTester.java:427)
	at jdk.test.lib.cds.CDSAppTester.productionRun(CDSAppTester.java:392)
	at jdk.test.lib.cds.CDSAppTester.runAOTWorkflow(CDSAppTester.java:500)
	at jdk.test.lib.cds.CDSAppTester.run(CDSAppTester.java:448)
	at JDKMethodHandlesTestRunner.test(JDKMethodHandlesTestRunner.java:101)
	at MethodHandlesAsCollectorTest.test(MethodHandlesAsCollectorTest.java:79)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
FAILED     MethodHandlesAsCollectorTest::test 'test' [9430ms]
JavaTest Message: JUnit Platform Failure(s): 1

[ JUnit Containers: found 4, started 4, succeeded 4, failed 0, aborted 0, skipped 0]
[ JUnit Tests: found 1, started 1, succeeded 0, failed 1, aborted 0, skipped 0]

java.lang.Exception: JUnit test failure
	at com.sun.javatest.regtest.agent.JUnitRunner.runWithJUnitPlatform(JUnitRunner.java:179)
	at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:110)
	at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:76)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at com.sun.javatest.regtest.agent.MainWrapper$MainTask.run(MainWrapper.java:138)
	at java.base/java.lang.Thread.run(Thread.java:1474)

JavaTest Message: Test threw exception: java.lang.Exception: JUnit test failure
JavaTest Message: shutting down test

Comments
Fix request approved for JDK 25 Affects Shenandoah GC only.
24-07-2025

A pull request was submitted for review. Branch: jdk25 URL: https://git.openjdk.org/jdk/pull/26464 Date: 2025-07-24 15:59:37 +0000
24-07-2025

Changeset: 84776309 Branch: master Author: Aleksey Shipilev <shade@openjdk.org> Date: 2025-07-24 15:53:29 +0000 URL: https://git.openjdk.org/jdk/commit/8477630970b61e3178abd7ac812ed97e181e2684
24-07-2025

Fix Request (25) I would like to integrate this fix in JDK 25 under RDP2 rules. The bug is a recent regression in JDK 25. It is well-understood, easily reproducible, and the fix is simple. The issue is AOT-, Shenandoah-, AArch64- specific, which also limits the exposure in the unlikely case it turns out to be wrong. The change is tested by relevant CDS and Shenandoah tests in both mainline and JDK 25 stabilization branch. Therefore, I reason the risk for it is small for JDK 25.
24-07-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/26449 Date: 2025-07-23 18:43:59 +0000
23-07-2025

Oh, I think I see. Adapter resolves CLD via jweak resolve, see BarrierSetAssembler::c2i_entry_barrier. The jweak resolution path goes into GC barriers. For Shenandoah, we end up calling into a specific load reference barrier (LRB). For assembler, it is implemented as the call to appropriate runtime stub. Saved adapter captures the runtime stub address at the time of AOT dump. But we are missing a relocation for that address! Of course we end up calling weird address. This minimal fix seems to solve it: diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index a2b3f44c68b..e99f915c68c 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -292,7 +292,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, } else { assert(is_phantom, "only remaining strength"); assert(!is_narrow, "phantom access cannot be narrow"); - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom)); + __ lea(lr, RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom))); } __ blr(lr); __ mov(rscratch1, r0); We have argued back in Leyden that we are safe to call phantom barriers from adapters. It looks we "only" need to fix this one path. I would try to do this with for JDK 25 RDP2. x86_64 does not fail this way, because Shenandoah x86_64 BarrierSetAssembler calls through VM leaf, which sets up relocation. Shenandoah AArch64 BarrierSetAssembler should really do the same, leaving that to larger fix, JDK-8363974.
23-07-2025

Some debugging bread-crumbs: # # SIGSEGV (0xb) at pc=0x0000ffffa5688650, pid=33803, tid=33806 # # JRE version: OpenJDK Runtime Environment (26.0) (fastdebug build 26-internal-adhoc.shipilev.shipilev-jdk) # Java VM: OpenJDK 64-Bit Server VM (fastdebug 26-internal-adhoc.shipilev.shipilev-jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, shenandoah gc, linux-aarch64) # Problematic frame: # v ~AdapterBlob 0x0000ffffa39b7464 Adapter blob calls out to load_reference_barrier_phantom, and likely crashes somewhere there. ;; load_reference_barrier_phantom ;; 0xFFFFA5688650 0x0000ffffa39b7458: mov x30, #0x8650 // #34384 0x0000ffffa39b745c: movk x30, #0xa568, lsl #16 0x0000ffffa39b7460: movk x30, #0xffff, lsl #32 0x0000ffffa39b7464: blr x30 So we are trying to call the load_reference_barrier_phantom barrier at 0xFFFFA5688650, and getting SEGV, because that memory is not even mapped. WEIRD.
23-07-2025

Seeing the following crashes on current mainline. ----- Current thread (0x0000ffffa0021060): JavaThread "main" [_thread_in_Java, id=39453, stack(0x0000ffffa66f4000,0x0000ffffa68f2000) (2040K)] Stack: [0x0000ffffa66f4000,0x0000ffffa68f2000], sp=0x0000ffffa68ef820, free space=2030k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) v ~AdapterBlob 0x0000ffff8f9d39a8 siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000ffffad5035b0 ---- Current thread (0x0000ffff780bae10): JavaThread "main" [_thread_in_Java, id=43329, stack(0x0000ffff7fea7000,0x0000ffff800a5000) (2040K)] Stack: [0x0000ffff7fea7000,0x0000ffff800a5000], sp=0x0000ffff800a29a0, free space=2030k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x8a1320] ciKlass::prototype_header_offset()+0xfc (debug.hpp:66) siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000790 ---- The stack is not unwound further. This is extremely odd.
23-07-2025