From yadonn.wang at huawei.com Sun Jul 6 11:46:30 2025 From: yadonn.wang at huawei.com (wangyadong (E)) Date: Sun, 6 Jul 2025 11:46:30 +0000 Subject: [aarch64-port-dev ] AArch64: Incorrect matching rule leading to improper oop instruction encoding Message-ID: Hi, guys, We have found a suspected C2 bug of Aarch64 port, randomly crashed in the arm64 server, and existed since day one from the initial commit and on all Java 8+ versions. C2 uses JNI handles as placeholders to encoding constant oops, and one of some handle maybe locate at the address of byte_map_base, which is not memory reserved by CardTableModRefBS byte_map. // The assember store_check code will do an unsigned shift of the oop, // then add it to byte_map_base, i.e. // // _byte_map = byte_map_base + (uintptr_t(low_bound) >> card_shift) _byte_map = (jbyte*) heap_rs.base(); byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); C2 will incorrectly match ConP of oop to ConP of byte_map_base in aarch64.ad. // Card Table Byte Map Base operand immByteMapBase() %{ // Get base of card map predicate((jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); match(ConP); op_cost(0); format %{ %} interface(CONST_INTER); %} // Load Byte Map Base Constant instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) %{ match(Set dst con); ins_cost(INSN_COST); format %{ "adr $dst, $con\t# Byte Map Base" %} ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); ins_pipe(ialu_imm); %} A typical backtrace as below: #0 0x0000ffff280866e0 in raise () from /lib64/libc.so.6 #1 0x0000ffff28087a8c in abort () from /lib64/libc.so.6 #2 0x0000ffff27af1e7c in os::abort (dump_core=true, siginfo=, context=) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:1601 #3 0x0000ffff27cd48a0 in VMError::report_and_die (this=this at entry=0xffff270f6c58) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/utilities/vmError.cpp:1159 #4 0x0000ffff27aff4dc in JVM_handle_linux_signal (sig=11, info=info at entry=0xffff270f6d80, ucVoid=0xffff270f6e00, abort_if_unrecognized=abort_if_unrecognized at entry=1) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp:410 #5 0x0000ffff27aee3b0 in signalHandler (sig=, info=0xffff270f6d80, uc=) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:4839 #6 #7 Klass::layout_helper (this=0x8b56b87d8) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/oops/klass.hpp:577 #8 Klass::oop_is_instance (this=0x8b56b87d8) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/oops/klass.hpp:577 #9 oopDesc::is_instance (this=) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/oops/oop.inline.hpp:186 #10 ServiceUtil::visible_oop (o=) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/services/serviceUtil.hpp:47 #11 JavaThreadBlockedOnMonitorEnterState::JavaThreadBlockedOnMonitorEnterState (obj_m=0xffff180114d8, java_thread=0xffff20029000, this=) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/services/threadService.hpp:552 #12 ObjectMonitor::enter (this=0xffff180114d8, __the_thread__=__the_thread__ at entry=0xffff20029000) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp:390 #13 0x0000ffff27c271dc in ObjectSynchronizer::slow_enter (__the_thread__=0xffff20029000, lock=0xffff270f8130, obj=...) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/runtime/handles.hpp:79 #14 ObjectSynchronizer::fast_enter (obj=..., lock=lock at entry=0xffff270f8130, attempt_rebias=attempt_rebias at entry=true, __the_thread__=__the_thread__ at entry=0xffff20029000) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp:183 #15 0x0000ffff27bb10b0 in SharedRuntime::complete_monitor_locking_C (_obj=0xffff21730000, lock=0xffff270f8130, thread=0xffff20029000) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp:1879 #16 0x0000ffff256ffff8 in ?? () #17 0x0000ffff277a0414 in InstanceKlass::register_finalizer (i=, __the_thread__=0xfffeebc09d20) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/utilities/growableArray.hpp:261 #18 0x0000ffff277a0414 in InstanceKlass::register_finalizer (i=, __the_thread__=0xffff20029000) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/utilities/growableArray.hpp:261 #19 0x0000ffff270f8390 in ?? () #20 0x00000007ad622658 in ?? () Passing byte_map_base instead of oop to complete_monitor_locking_C: #15 0x0000ffff27bb10b0 in SharedRuntime::complete_monitor_locking_C (_obj=0xffff21730000, lock=0xffff270f8130, thread=0xffff20029000) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp:1879 Called by complete_monitor_lock_Java: 0xffff256fffc0: nop 0xffff256fffc4: sub sp, sp, #0x10 0xffff256fffc8: stp x29, x30, [sp] 0xffff256fffcc: mov x9, sp 0xffff256fffd0: str x9, [x28, #592] 0xffff256fffd4: mov x0, x1 0xffff256fffd8: mov x1, x2 0xffff256fffdc: mov x2, x28 0xffff256fffe0: adr x9, 0xffff256ffff8 0xffff256fffe4: mov x8, #0xff0 // #4080 0xffff256fffe8: movk x8, #0x27bb, lsl #16 0xffff256fffec: movk x8, #0xffff, lsl #32 0xffff256ffff0: stp xzr, x9, [sp, #-16]! 0xffff256ffff4: blr x8 0xffff256ffff8: add sp, sp, #0x10 0xffff256ffffc: str xzr, [x28, #592] 0xffff25700000: str xzr, [x28, #600] 0xffff25700004: ldr x10, [x28, #8] 0xffff25700008: cbnz x10, 0xffff25700018 0xffff2570000c: ldp x29, x30, [sp] 0xffff25700010: add sp, sp, #0x10 0xffff25700014: ret 0xffff25700018: adrp x10, 0xffff25580000 0xffff2570001c: add x10, x10, #0x340 0xffff25700020: mov x12, xzr 0xffff25700024: ldp x29, x30, [sp] 0xffff25700028: add sp, sp, #0x10 0xffff2570002c: br x10 Called by J 1821 C2 java.lang.ref.Finalizer.register(Ljava/lang/Object;)V (10 bytes) @ 0x0000ffff25caf0bc [0x0000ffff25caee80+0x23c] 0xffff25caf0b4: adrp x1, 0xffff21730000 0xffff25caf0b8: bl 0xffff256fffc0 Which encoding byte_map_base instead of the specific oop and passing it to complete_monitor_lock_Java. So the entire story is that the predicate rule of immByteMapBase caused an incorrect ConP match when a corresponding JNIHandleBlock with an oop was allocated to the address of byte_map_base by malloc. I have a simple fix that just remove the specialized match rule for immByteMapBase below, and crashes disappeared. diff --git a/hotspot/src/cpu/aarch64/vm/aarch64.ad b/hotspot/src/cpu/aarch64/vm/aarch64.ad index d73d5d457..5305467c1 100644 --- a/hotspot/src/cpu/aarch64/vm/aarch64.ad +++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad @@ -3054,11 +3054,6 @@ encode %{ assert(off == 0, "assumed offset == 0"); %} - enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{ - MacroAssembler _masm(&cbuf); - __ load_byte_map_base($dst$$Register); - %} - enc_class aarch64_enc_mov_n(iRegN dst, immN src) %{ MacroAssembler _masm(&cbuf); Register dst_reg = as_Register($dst$$reg); @@ -4311,19 +4306,6 @@ operand immPollPage() interface(CONST_INTER); %} -// Card Table Byte Map Base -operand immByteMapBase() -%{ - // Get base of card map - predicate((jbyte*)n->get_ptr() == - ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); - match(ConP); - - op_cost(0); - format %{ %} - interface(CONST_INTER); -%} - // Pointer Immediate Minus One // this is used when we want to write the current PC to the thread anchor operand immP_M1() @@ -6772,20 +6754,6 @@ instruct loadConPollPage(iRegPNoSp dst, immPollPage con) ins_pipe(ialu_imm); %} -// Load Byte Map Base Constant - -instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con) -%{ - match(Set dst con); - - ins_cost(INSN_COST); - format %{ "adr $dst, $con\t# Byte Map Base" %} - - ins_encode(aarch64_enc_mov_byte_map_base(dst, con)); - - ins_pipe(ialu_imm); -%} - // Load Narrow Pointer Constant instruct loadConN(iRegNNoSp dst, immN con) Does anyone have any suggestions on this? Yadong -------------- next part -------------- An HTML attachment was scrubbed... URL: