Having this code (complete test case attached):
private final AtomicReference<Object> obj = new AtomicReference<Object>();
public void run() {
for (int c = 0; c < 10000; c++) {
obj.getAndSet(CURRENT);
}
}
Compiling and disassembling with the latest hotspot-comp/Linux x86_64 will yield this hot loop body:
; get field obj + null check
0x00007fe8a5102e02: mov (%rcx),%r11d
0x00007fe8a5102e05: test %r11d,%r11d
0x00007fe8a5102e08: je 0x00007fe8a5102ed7
; load and unpack AtomicReference obj, ***killed by the next LEA***
0x00007fe8a5102e0e: lea (%r12,%r11,8),%r10
; load the AtomicReference.value field offset into %r10
0x00007fe8a5102e12: lea 0xc(%r12,%r11,8),%r10
; load CURRENT
0x00007fe8a5102e17: mov $0xf5a0b9a6,%r8d
; CAS!
0x00007fe8a5102e1d: xchg %r8d,(%r10)
; cardmark against AtomicReference.value!
0x00007fe8a5102e20: shr $0x9,%r10
0x00007fe8a5102e24: mov %r12b,(%rbx,%r10,1)
; loop control + back branch
0x00007fe8a5102e28: inc %r9d
0x00007fe8a5102e2b: cmp $0x1,%r9d
0x00007fe8a5102e2f: jl 0x00007fe8a5102e02
Note that we kill %r10 with the second lea.
N.B.: We also effectively do the card mark against the %r10, which contains the *field* address, not the containing object address. This seems to be the good behavior for precise card marks?
private final AtomicReference<Object> obj = new AtomicReference<Object>();
public void run() {
for (int c = 0; c < 10000; c++) {
obj.getAndSet(CURRENT);
}
}
Compiling and disassembling with the latest hotspot-comp/Linux x86_64 will yield this hot loop body:
; get field obj + null check
0x00007fe8a5102e02: mov (%rcx),%r11d
0x00007fe8a5102e05: test %r11d,%r11d
0x00007fe8a5102e08: je 0x00007fe8a5102ed7
; load and unpack AtomicReference obj, ***killed by the next LEA***
0x00007fe8a5102e0e: lea (%r12,%r11,8),%r10
; load the AtomicReference.value field offset into %r10
0x00007fe8a5102e12: lea 0xc(%r12,%r11,8),%r10
; load CURRENT
0x00007fe8a5102e17: mov $0xf5a0b9a6,%r8d
; CAS!
0x00007fe8a5102e1d: xchg %r8d,(%r10)
; cardmark against AtomicReference.value!
0x00007fe8a5102e20: shr $0x9,%r10
0x00007fe8a5102e24: mov %r12b,(%rbx,%r10,1)
; loop control + back branch
0x00007fe8a5102e28: inc %r9d
0x00007fe8a5102e2b: cmp $0x1,%r9d
0x00007fe8a5102e2f: jl 0x00007fe8a5102e02
Note that we kill %r10 with the second lea.
N.B.: We also effectively do the card mark against the %r10, which contains the *field* address, not the containing object address. This seems to be the good behavior for precise card marks?
- relates to
-
JDK-8354930 IGV: dump C2 graph before and after live range stretching
-
- Open
-
-
JDK-8339262 C2: useless compressed oops decode instruction in compiled code
-
- Open
-