JDK-8319700 : [AArch64] C2 compilation fails with "Field too big for insn"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 21,22
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: aarch64
  • Submitted: 2023-11-08
  • Updated: 2024-01-26
  • Resolved: 2023-11-23
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 21 JDK 22
21.0.2Fixed 22 b26Fixed
Related Reports
Relates :  
Relates :  
Description
Test name(s): applications/runthese/RunThese8H.java 
Product(s) tested: JDK 21.0.2 b04 (issue seen in 21.0.1 also)
OS/architecture: Linux-aarch64 
Reproducible: Highly Intermittent
VM flag: -XX:+UseZGC -XX:+ZGenerational

Excerpts from Log: 

#  guarantee(chk == -1 || chk == 0) failed: Field too big for insn at 0x0000ffff8c4d0eb4
#
# JRE version: Java(TM) SE Runtime Environment (21.0.2+4) (fastdebug build 21.0.2+4-LTS-43)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 21.0.2+4-LTS-43, mixed mode, sharing, tiered, compressed class ptrs, z gc, linux-aarch64)
# Problematic frame:
# V  [libjvm.so+0x11b56a8]  Instruction_aarch64::spatch(unsigned char*, int, int, long) [clone .part.0]+0x38
#


Current thread (0x0000ffff9c2fb4f0):  JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=2550844, stack(0x0000fffb23c03000,0x0000fffb23e01000) (2040K)]


Current CompileTask:
C2:28479996 4899959       4       com.sun.tck.lib.tgf.TransformingIterator::shift (62 bytes)

Stack: [0x0000fffb23c03000,0x0000fffb23e01000],  sp=0x0000fffb23dfc6f0,  free space=2021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x11b56a8]  Instruction_aarch64::spatch(unsigned char*, int, int, long) [clone .part.0]+0x38  (assembler_aarch64.hpp:231)
V  [libjvm.so+0x11b6cac]  MacroAssembler::pd_patch_instruction_size(unsigned char*, unsigned char*)+0x46c  (macroAssembler_aarch64.cpp:235)
V  [libjvm.so+0x5d8418]  Label::patch_instructions(MacroAssembler*)+0xf8  (macroAssembler_aarch64.hpp:631)
V  [libjvm.so+0x17c7f10]  ZLoadBarrierStubC2Aarch64::emit_code(MacroAssembler&)+0x9c  (macroAssembler_aarch64.hpp:150)
V  [libjvm.so+0x17d01fc]  ZBarrierSetC2::emit_stubs(CodeBuffer&) const+0xd8  (zBarrierSetC2.cpp:341)
V  [libjvm.so+0x1385cbc]  PhaseOutput::fill_buffer(CodeBuffer*, unsigned int*)+0x1c0c  (output.cpp:1755)
V  [libjvm.so+0x9083b8]  Compile::Code_Gen()+0x3c8  (compile.cpp:2971)
V  [libjvm.so+0x90c870]  Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x15b0  (compile.cpp:875)
V  [libjvm.so+0x762a58]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x328  (c2compiler.cpp:118)
V  [libjvm.so+0x918904]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x974  (compileBroker.cpp:2265)
V  [libjvm.so+0x919424]  CompileBroker::compiler_thread_loop()+0x590  (compileBroker.cpp:1944)
V  [libjvm.so+0xdabbf0]  JavaThread::thread_main_inner()+0xd0  (javaThread.cpp:719)
V  [libjvm.so+0x16050a4]  Thread::call_run()+0xb0  (thread.cpp:217)
V  [libjvm.so+0x1360718]  thread_native_entry(Thread*)+0x138  (os_linux.cpp:783)
C  [libpthread.so.0+0x7928]  start_thread+0x188
Comments
I don't think JDK-8320682 is related because it happens during C1 compilation and with G1. This fix is ZGC specific.
24-11-2023

This fix appears insufficient as we still see the crash in tier 6
24-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u/pull/398 Date: 2023-11-23 12:46:47 +0000
23-11-2023

[jdk21u-fix-request] Approval Request from Axel Boldt-Christmas Bugs needs fixing in 21 as well.
23-11-2023

Changeset: 3787ff8d Author: Axel Boldt-Christmas <aboldtch@openjdk.org> Date: 2023-11-23 12:41:51 +0000 URL: https://git.openjdk.org/jdk/commit/3787ff8d1d8dbcaaebb9616c5bc543e2fe21a90c
23-11-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16780 Date: 2023-11-22 10:44:12 +0000
22-11-2023

I see lots of what looks like junk trampolines: 0x0000ffffa5283638: b 0xffffa5283644 0x0000ffffa528363c: b 0xffffa5283644 0x0000ffffa5283640: b 0xffffa5283644 0x0000ffffa5283644: mov x1, x0 0x0000ffffa5283648: b 0xffffa5278f04 0x0000ffffa528364c: b 0xffffa5283658 0x0000ffffa5283650: b 0xffffa5283658 0x0000ffffa5283654: b 0xffffa5283658 0x0000ffffa5283658: mov x1, x0 0x0000ffffa528365c: b 0xffffa5278f04 0x0000ffffa5283660: b 0xffffa5283700 0x0000ffffa5283664: b 0xffffa5283700 0x0000ffffa5283668: b 0xffffa5283700 0x0000ffffa528366c: b 0xffffa5283700 : : : 0x0000ffffa52836f8: b 0xffffa5283700 0x0000ffffa52836fc: b 0xffffa5283700 0x0000ffffa5283700: mov x1, x0 0x0000ffffa5283704: b 0xffffa5278f04 0x0000ffffa5283708: b 0xffffa52837a8 There aren't any branchs to these trampolines though - there are 100s of bytes which I suspect is what might be throwing off the calculations.
13-11-2023

ZLoadBarrierStubC2Aarch64 would generate code directly if it does not interfere with emission of the next trampoline: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp#L1356 I guess, maybe some sutbs do not follow this rule. E.g., https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad#L64 This generates ZLoadBarrierStubC2, but not ZLoadBarrierStubC2AArch64. Therefore, following trampoline may be interfered.
13-11-2023

I had a quick look and it seems that we are patching a tbnz but the value we want to patch in is too large: 0xffffe02172b4: cmp w12, w11 0xffffe02172b8: b.ne 0xffffe021cbe4 // b.any 0xffffe02172bc: ldr x11, [x29, #16] 0xffffe02172c0: tbnz w11, #0, 0xffffe02172c0 <----- The value is 8247. The tbnz is from the load barrier: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad#L76 The assumption that the stub->entry() label is within 32K does not hold: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp#L213 The patching happens here in ZLoadBarrierStubC2Aarch64::emit_code: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp#L1352 AbstractAssembler::bind -> MacroAssembler::pd_patch_instruction -> ... -> Patcher::testAndBranch -> Instruction_aarch64::spatch(insn_addr, 18, 5, offset) msb = 18 lsb = 5 nbits = 14 Looks correct according to https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions/TBNZ--Test-bit-and-Branch-if-Nonzero- It says: "Is the program label to be conditionally branched to. Its offset from the address of this instruction, in the range +/-32KB, is encoded as "imm14" times 4." The maximum value of signed imm14 is (1 << 13) - 1 = 8191 But for val = 8247, chk = val >> (nbits - 1) = 8247 >> (14 - 1) = 1 Patch::testAndBranch already divided the offset by 4, so the original offset was 8247<<2 = 32988 which is greater than 32k: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp#L284 This should have been detected by aarch64_test_and_branch_reachable: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp#L1281 The computation in ZLoadBarrierStubC2Aarch64::ZLoadBarrierStubC2Aarch64 must be wrong but I can't see how yet: https://github.com/openjdk/jdk/blob/d20034b09c99026e7dc2213f7d88ebdc85e5b1e7/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp#L1293
10-11-2023

ILW = Patching of tbnz fails because destination is too far away, intermittent on AArch64 with Generational ZGC, use different GC or disable compilation of affected method = HMM = P2
10-11-2023

I've found this problem to be quite reproducible with the JTREG testcase: jdk/jdk/incubator/vector/VectorMaxConversionTests.java#ZGenerational Enabling "-esa -ea" made it much more reproducible.
09-11-2023

ILW = C2 assertion on AArch64, observed only with reported test, Not sure = HLM = P3
08-11-2023

ILW = Guarantee failure during C2 compilation, with stress test and generational ZGC, disable generational ZGC = HLM = P3
08-11-2023