RFR: 8361892: AArch64: Incorrect matching rule leading to improper oop instruction encoding [v2]

Andrew Dinn adinn at openjdk.org
Mon Jul 14 09:17:39 UTC 2025


On Sun, 13 Jul 2025 08:40:45 GMT, Yadong Wang <yadongwang at openjdk.org> wrote:

>> The bug is that the predicate rule of immByteMapBase would cause a ConP Node for oop incorrect matching with byte_map_base when the placeholder jni handle address was just allocated to the address of byte_map_base.
>> 
>> 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 CardTable. It's possible because JNIHandleBlocks are allocated by malloc.
>> 
>>   // The assembler 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 = (CardValue*) rs.base();
>>   _byte_map_base = _byte_map - (uintptr_t(low_bound) >> _card_shift);
>> 
>> In aarch64 port, C2 will incorrectly match ConP for oop to ConP for byte_map_base by the immByteMapBase operand.
>> 
>> // 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);
>> %}
>> 
>> As below, a typical incorrect instructions generated by C2 for java.lang.ref.Finalizer.register(Ljava/lang/Object;)V (10 bytes) @ 0x0000ffff25caf0bc [0x0000ffff25caee80+0x23c], where 0xffff21730000 is the byte_map_base address mistakenly used as an object address:
>>    0xffff25caf08c:	ldaxr	x8, [x11]
>>    0xffff25caf090:	cmp	x10, x8
>>    0xffff25caf094:	b.ne	0xffff25caf0a0  // b.any
>>    0xffff25caf098:	stlxr	w8, x28, [x11]
>>    0xffff25caf09c:	cbnz	w8, 0xffff25caf08c
>>    0xffff25caf0a0:	orr	x11, xzr, #0x3
>>    0xffff25caf0a4:	str	x11, [x13]
>>    0xffff25caf0a8:	b.eq	0xffff25caef80  // b.none
>>    0xffff25caf0ac:	str	x14, [sp]
>>    0xffff25caf0b0:	add	x2, sp, #0x20
>>    0xffff25caf0b4:	adrp	x1, 0xffff21730000
>>    0xffff25caf0b8:	bl	0xffff256fffc0
>>    0xffff25caf0bc:	ldr	x14, [sp]
>>    0xffff25caf0c0:	b	0xffff25caef80
>>    0xffff25caf0c4:	add	x13, sp, #0x20
>>    0xffff25caf0c8:	adrp	x12, 0xffff21730000
>>    0xffff25caf0cc:	ldr	x10, [x13]
>>    0xffff25caf0d0:	cmp	x10, xzr
>>    0xffff25c...
>
> Yadong Wang has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8361892: AArch64: Incorrect matching rule leading to improper oop instruction encoding

The proposed solution is not simply going to work when the Leyden project introduces code save/restore. In the assembly phase for an AOT cache (i.e when compiling code to store in the cache) we need to recognize that an incoming address is the byte map base address and generate an lea with an external address relocation. So, the current code in premain relies on matching against immByteMapBase.

I believe we can retain the current approach if we make the immByteMapBase predicate test the operand type for a RawPtr rather than an OopPtr. That is actually the key distinction that separates the cases we are dealing with. I believe it would work for both immByteMapBase and immPollPage and is a much smaller change to the status quo.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/26249#issuecomment-3068574613


More information about the hotspot-compiler-dev mailing list