Get some random crash issue on aarch64, it crash in template interpreter. The symptom is: in checkcast, klass being checked is not valid klass address. The root cause is on aarch64 it miss load acquire when trying to read tag in constant pool before reference resolved class.
Code for checkcast
0x7f8409a5a0: add x8, x3, #0x4
0x7f8409a5a4: ldrb w1, [x8,x19] // load tag
0x7f8409a5a8: cmp x1, #0x7 __ cmp(r1, JVM_CONSTANT_Class);
0x7f8409a62c: mov x3, x0
0x7f8409a630: add x0, x2, x19, uxtx #3
0x7f8409a634: ldr x0, [x0,#80]
0x7f8409a638: ldr w19, [x3,#8] // load resolved class
0x7f8409a63c: eor x19, x19, #0x800000000 // x19 hold klass being checked
Load resolved class might finish before load tag and read incorrect value. Fix is use load acquire when load tag.
These tags are updated with release store in ConstantPool::release_tag_at_put (which triggers OrderAccess::release_store), it need load with load acquire instruction.
After fix:
0x0000007f8009a6a4: add x8, x8, x19
0x0000007f8009a6a8: ldarb w1, [x8]
0x0000007f8009a6ac: cmp x1, #0x7
0x0000007f8009a6b0: b.eq 0x0000007f8009a730
….
0x0000007f8009a730: mov x3, x0
0x0000007f8009a734: add x0, x2, x19, uxtx #3
0x0000007f8009a738: ldr x0, [x0,#80]
0x0000007f8009a73c: ldr w19, [x3,#8]
0x0000007f8009a740: eor x19, x19, #0x800000000
Checking similar places in aarch64, other places needs similar fix:
1. Instanceof is similar with checkcast
2. “ldc”, similar with load resolved class in checkcast, need load acquire when loading tag in constant pool
3. “new” load tag for resovled class.
4. "new" Load and check class initialized status, status update is guarded with orderaccess::storestore, load needs acquire.
5. C1 runtime checks if class initialize status when generate code for fast_new_instance_init_check_id, similar with “new”.
Code for checkcast
0x7f8409a5a0: add x8, x3, #0x4
0x7f8409a5a4: ldrb w1, [x8,x19] // load tag
0x7f8409a5a8: cmp x1, #0x7 __ cmp(r1, JVM_CONSTANT_Class);
0x7f8409a62c: mov x3, x0
0x7f8409a630: add x0, x2, x19, uxtx #3
0x7f8409a634: ldr x0, [x0,#80]
0x7f8409a638: ldr w19, [x3,#8] // load resolved class
0x7f8409a63c: eor x19, x19, #0x800000000 // x19 hold klass being checked
Load resolved class might finish before load tag and read incorrect value. Fix is use load acquire when load tag.
These tags are updated with release store in ConstantPool::release_tag_at_put (which triggers OrderAccess::release_store), it need load with load acquire instruction.
After fix:
0x0000007f8009a6a4: add x8, x8, x19
0x0000007f8009a6a8: ldarb w1, [x8]
0x0000007f8009a6ac: cmp x1, #0x7
0x0000007f8009a6b0: b.eq 0x0000007f8009a730
….
0x0000007f8009a730: mov x3, x0
0x0000007f8009a734: add x0, x2, x19, uxtx #3
0x0000007f8009a738: ldr x0, [x0,#80]
0x0000007f8009a73c: ldr w19, [x3,#8]
0x0000007f8009a740: eor x19, x19, #0x800000000
Checking similar places in aarch64, other places needs similar fix:
1. Instanceof is similar with checkcast
2. “ldc”, similar with load resolved class in checkcast, need load acquire when loading tag in constant pool
3. “new” load tag for resovled class.
4. "new" Load and check class initialized status, status update is guarded with orderaccess::storestore, load needs acquire.
5. C1 runtime checks if class initialize status when generate code for fast_new_instance_init_check_id, similar with “new”.