Currently, g1 pre-write barrier checks orig is null pointer.
// G1 pre write barrier slowpath
JRT_LEAF(void, G1BarrierSetRuntime::write_ref_field_pre_entry(oopDesc* orig, JavaThread *thread))
if (orig == NULL) {
assert(false, "should be optimized out");
return;
}
...
In my understanding, orig can't be NULL here. if it's NULL, this call should be removed by JIT compilers. Actually, Shenandoah pre-write barrier uses a assert(orig != NULL, "should be optimized out") instead of a branch.
now compilers have to generate code to do compare and branch for it, even though it's non-taken. eg. 698f30: cbz on armv8.
0000000000698f30 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread>:
698f30: b4000060 cbz x0, 698f3c <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0xc>
698f34: 39410022 ldrb w2, [x1, #64]
698f38: 35000042 cbnz w2, 698f40 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0x10>
698f3c: d65f03c0 ret
...
eg. gcc generates 2 instructions (707ef1:test and 707ef7:je) for x86_64.
0000000000707ef0 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread>:
707ef0: 55 push %rbp
707ef1: 48 85 ff test %rdi,%rdi
707ef4: 48 89 e5 mov %rsp,%rbp
707ef7: 74 06 je 707eff <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0xf>
707ef9: 80 7e 40 00 cmpb $0x0,0x40(%rsi)
707efd: 75 09 jne 707f08 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0x18>
707eff: 5d pop %rbp
707f00: c3 retq
// G1 pre write barrier slowpath
JRT_LEAF(void, G1BarrierSetRuntime::write_ref_field_pre_entry(oopDesc* orig, JavaThread *thread))
if (orig == NULL) {
assert(false, "should be optimized out");
return;
}
...
In my understanding, orig can't be NULL here. if it's NULL, this call should be removed by JIT compilers. Actually, Shenandoah pre-write barrier uses a assert(orig != NULL, "should be optimized out") instead of a branch.
now compilers have to generate code to do compare and branch for it, even though it's non-taken. eg. 698f30: cbz on armv8.
0000000000698f30 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread>:
698f30: b4000060 cbz x0, 698f3c <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0xc>
698f34: 39410022 ldrb w2, [x1, #64]
698f38: 35000042 cbnz w2, 698f40 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0x10>
698f3c: d65f03c0 ret
...
eg. gcc generates 2 instructions (707ef1:test and 707ef7:je) for x86_64.
0000000000707ef0 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread>:
707ef0: 55 push %rbp
707ef1: 48 85 ff test %rdi,%rdi
707ef4: 48 89 e5 mov %rsp,%rbp
707ef7: 74 06 je 707eff <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0xf>
707ef9: 80 7e 40 00 cmpb $0x0,0x40(%rsi)
707efd: 75 09 jne 707f08 <_ZN19G1BarrierSetRuntime25write_ref_field_pre_entryEP7oopDescP10JavaThread+0x18>
707eff: 5d pop %rbp
707f00: c3 retq