[aarch64-port-dev ] AArch64: Incorrect matching rule leading to improper oop instruction encoding
wangyadong (E)
yadonn.wang at huawei.com
Sun Jul 6 11:46:30 UTC 2025
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=<optimized out>, context=<optimized out>)
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=<optimized out>, info=0xffff270f6d80, uc=<optimized out>)
at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:4839
#6 <signal handler called>
#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=<optimized out>) at /usr1/jenkins/BiShengJDK/open_source/openjdk/openjdk/hotspot/src/share/vm/oops/oop.inline.hpp:186
#10 ServiceUtil::visible_oop (o=<optimized out>) 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=<synthetic pointer>)
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=<optimized out>, __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=<optimized out>, __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: <https://mail.openjdk.org/pipermail/aarch64-port-dev/attachments/20250706/7760a466/attachment-0001.htm>
More information about the aarch64-port-dev
mailing list