JDK-8369043 : [lworld] -XX:AOTMode=create crashes with UseCompactObjectHeaders on aarch64
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: repo-valhalla
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • CPU: aarch64
  • Submitted: 2025-10-02
  • Updated: 2025-10-27
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.
Other
repo-valhallaUnresolved
Related Reports
Causes :  
Relates :  
Description
Low frequency intermittent crashes seen on aarch64 + linux/macos. We saw a total of 90 occurrences in Mach5 between Aug 14 and Oct 3.

Example: runtime/cds/appcds/aotCache/HelloAOTCache.java and runtime/cds/appcds/aotCode/AOTCodeCompressedOopsTest.java crash with -XX:+UseCompactObjectHeaders.

Command Line: -XX:MaxRAMPercentage=6.25 -Dtest.boot.jdk=/opt/mach5/mesos/work_dir/jib-master/install/jdk/24/36/bundles/linux-aarch64/jdk-24_linux-aarch64_bin.tar.gz/jdk-24 -Djava.io.tmpdir=/opt/mach5/mesos/work_dir/slaves/0103b69c-746c-4fb5-bf13-94918f380124-S10516/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/4e67a137-8f8c-4072-b215-325956e1bd2a/runs/e8e82f14-66b9-4c58-a28b-2cd89d41010d/testoutput/test-support/jtreg_open_test_hotspot_jtreg_tier1_runtime/tmp -XX:+UseCompactObjectHeaders -Xlog:class+load -Xlog:arguments,class+load=debug,aot=debug,aot+class=debug,cds=debug:file=HelloAOTCache.aot.log::filesize=0 -XX:AOTCacheOutput=HelloAOTCache.aot -XX:AOTConfiguration=HelloAOTCache.aot.config -XX:AOTMode=create 


# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/open/src/hotspot/share/code/vtableStubs.cpp:195), pid=2035017, tid=2035020
#  assert((masm->pc() + index_dependent_slop) <= s->code_end()) failed: itable #0: spare space for 32-bit offset: required = 4, available = 3
#
# JRE version: Java(TM) SE Runtime Environment (26.0+1) (fastdebug build 26-valhalla+1-59)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-valhalla+1-59, mixed mode, sharing, tiered, compressed oops, compact obj headers, g1 gc, linux-aarch64)
# Problematic frame:
# V  [libjvm.so+0x19fc928]  VtableStubs::bookkeeping(MacroAssembler*, outputStream*, VtableStub*, unsigned char*, unsigned char*, bool, int, int, int)+0x404

Stack: [0x0000ffff8d015000,0x0000ffff8d213000],  sp=0x0000ffff8d20c480,  free space=2013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x19fc928]  VtableStubs::bookkeeping(MacroAssembler*, outputStream*, VtableStub*, unsigned char*, unsigned char*, bool, int, int, int)+0x404  (vtableStubs.cpp:195)
V  [libjvm.so+0x19fde5c]  VtableStubs::create_itable_stub(int, bool)+0x578  (vtableStubs_aarch64.cpp:243)
V  [libjvm.so+0x19fba38]  VtableStubs::find_stub(bool, int, bool)+0x258  (vtableStubs.cpp:218)
V  [libjvm.so+0x9e4df0]  CompiledIC::set_to_megamorphic(CallInfo*, bool)+0x1e0  (vtableStubs.hpp:108)
V  [libjvm.so+0x174ef98]  SharedRuntime::handle_ic_miss_helper(bool&, bool&, JavaThread*)+0x38c  (sharedRuntime.cpp:1719)
V  [libjvm.so+0x174f3c4]  SharedRuntime::handle_wrong_method_ic_miss(JavaThread*)+0x160  (sharedRuntime.cpp:1497)
v  ~RuntimeStub::Shared Runtime ic_miss_blob 0x0000ffff77ce7810
J 159 c1 jdk.internal.classfile.impl.SplitConstantPool.internalAdd(Ljava/lang/classfile/constantpool/PoolEntry;I)Ljava/lang/classfile/constantpool/PoolEntry; java.base@26-valhalla (78 bytes) @ 0x0000ffff706feed4 [0x0000ffff706feb80+0x0000000000000354]
J 158 c1 jdk.internal.classfile.impl.SplitConstantPool.internalAdd(Ljava/lang/classfile/constantpool/PoolEntry;)Ljava/lang/classfile/constantpool/PoolEntry; java.base@26-valhalla (12 bytes) @ 0x0000ffff706fddb4 [0x0000ffff706fdcc0+0x00000000000000f4]
j  jdk.internal.classfile.impl.SplitConstantPool.utf8Entry(Ljava/lang/String;)Ljdk/internal/classfile/impl/AbstractPoolEntry$Utf8EntryImpl;+34 java.base@26-valhalla
j  jdk.internal.classfile.impl.SplitConstantPool.utf8Entry(Ljava/lang/String;)Ljava/lang/classfile/constantpool/Utf8Entry;+2 java.base@26-valhalla
j  java.lang.classfile.ClassBuilder.withMethod(Ljava/lang/String;Ljava/lang/constant/MethodTypeDesc;ILjava/util/function/Consumer;)Ljava/lang/classfile/ClassBuilder;+8 java.base@26-valhalla
j  java.lang.classfile.ClassBuilder.withMethodBody(Ljava/lang/String;Ljava/lang/constant/MethodTypeDesc;ILjava/util/function/Consumer;)Ljava/lang/classfile/ClassBuilder;+9 java.base@26-valhalla
j  java.lang.invoke.InnerClassLambdaMetafactory.generateConstructor(Ljava/lang/classfile/ClassBuilder;)V+17 java.base@26-valhalla
[...]

Only seen on Linux AArch64.
Comments
Also appears in: runtime/cds/appcds/aotCode/AOTCodeFlags.java
27-10-2025

Please check my comment for mdash history. This failure can happen intermittently to many different CDS tests, so problem listing individual tests will not get rid of it.
07-10-2025

runtime/cds/appcds/aotCode/AOTCodeFlags.java is failing with similar behavior
06-10-2025

FYI: we problemlisted HelloAOTCache.java on lworld.
06-10-2025

I am not sure what the cause might be, as all the "slopes" code seems convoluted. But this might make the crash go away VtableStub* VtableStubs::create_itable_stub(int itable_index, bool caller_is_c1) { // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing. - const int stub_code_length = code_size_limit(false); + const int stub_code_length = code_size_limit(false) + 4;
04-10-2025

The crash might be related to this valhalla-specific code: https://github.com/openjdk/valhalla/blame/db38c83fe407c7bb5623db3b5988f28198b860bc/src/hotspot/cpu/aarch64/vtableStubs_aarch64.cpp#L242C23-L242C23 ========================== VtableStub* VtableStubs::create_itable_stub(int itable_index, bool caller_is_c1) { [...] const int index_dependent_slop = (itable_index == 0) ? 4 : // code size change with transition from 8-bit to 32-bit constant (@index == 16). (itable_index < 16) ? 3 : 0; // index == 0 generates even shorter code. [...] slop_bytes += index_dependent_slop; // add'l slop for size variance due to large itable offsets bookkeeping(masm, tty, s, npe_addr, ame_addr, false, itable_index, slop_bytes, index_dependent_slop); ========================== Maybe it's possible for the first ever call of create_itable_stub() to get index_dependent_slop==3, which is used later by VtableStubs::check_and_set_size_limit() to update the VtableStubs::_itab_stub_size. The next time VtableStubs::create_itable_stub() is called, we come to here: const int stub_code_length = code_size_limit(false); which will return VtableStubs::_itab_stub_size. If now we get index_dependent_slop==4, this will trigger the assert "required = 4, available=3".
04-10-2025

Might be a leftover from JDK-8348972 ([~chagedorn], FYI).
03-10-2025