Suboptimal C2 code generation
Vitaly Davidovich
vitalyd at gmail.com
Thu Nov 19 23:06:34 UTC 2015
Actually, I would hope/expect that a null check is performed followed by a
type check for $C and if those pass constant 2 returned.
sent from my phone
On Nov 19, 2015 5:58 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:
> Hi guys,
>
> Consider the following code/setup (8u51 C2 compiler):
>
> private interface I
> {
> long value();
>
> long value2();
> }
>
> private static final class C implements I
> {
>
> @Override
> public long value() {
> return 1;
> }
>
> @Override
> public long value2() {
> return 1;
> }
> }
>
> private static final class Wrapper
> {
> private I _i;
>
> public long value() {
> return _i != null ? _i.value() : -1;
> }
>
> public long value2() {
> return _i != null ? _i.value2() : -1;
> }
> }
>
> // The below is in the outer class now
>
> private final Wrapper _w = new Wrapper();
>
> private long doIt() {
> return _w.value() + _w.value2();
> }
>
> Simple harness to get code generated:
>
> public void foo() {
> int s = 0;
> for (int i = 0; i < 15_000; ++i) {
> if (i % 1000 == 0) {
> _w._i = null;
> } else {
> _w._i = new C();
> }
> s += doIt();
> }
> System.out.println(s);
> }
>
> The idea here is to create a profile whereby vast majority of the time
> _w._i is not null. Here's the generated code for doIt(), which is the
> method I'm interested in:
>
> [Verified Entry Point]
> 0x00007ff5f82e0080: mov %eax,-0x14000(%rsp)
> 0x00007ff5f82e0087: push %rbp
> 0x00007ff5f82e0088: sub $0x20,%rsp ;*synchronization entry
>
> 0x00007ff5f82e008c: mov 0x18(%rsi),%r11d ;*getfield _w
>
> 0x00007ff5f82e0090: mov 0xc(%r12,%r11,8),%r11d ;*getfield _i
> ; implicit exception:
> dispatches to 0x00007ff5f82e0111
> 0x00007ff5f82e0095: mov $0x1,%eax
> 0x00007ff5f82e009a: test %r11d,%r11d
> 0x00007ff5f82e009d: je 0x00007ff5f82e00d4 ;*ifnull
>
> 0x00007ff5f82e009f: mov 0x8(%r12,%r11,8),%r8d
> 0x00007ff5f82e00a4: cmp $0xf8015a89,%r8d ; {metadata('$C')} //
> NOTE: I'm stripping away the nonessential fully qualified name
> 0x00007ff5f82e00ab: jne 0x00007ff5f82e00f9 ;*invokeinterface value
>
> 0x00007ff5f82e00ad: mov $0x1,%ebp ;*lreturn
>
> 0x00007ff5f82e00b2: test %r11d,%r11d
> 0x00007ff5f82e00b5: je 0x00007ff5f82e00dd ;*ifnull
>
> 0x00007ff5f82e00b7: mov 0x8(%r12,%r11,8),%r10d
> 0x00007ff5f82e00bc: cmp $0xf8015a89,%r10d ; {metadata('$C')}
> 0x00007ff5f82e00c3: jne 0x00007ff5f82e00e6 ;*lreturn
>
> 0x00007ff5f82e00c5: add %rbp,%rax ;*ladd
>
> 0x00007ff5f82e00c8: add $0x20,%rsp
> 0x00007ff5f82e00cc: pop %rbp
> 0x00007ff5f82e00cd: test %eax,0x5e11f2d(%rip) #
> 0x00007ff5fe0f2000
> ; {poll_return}
> 0x00007ff5f82e00d3: retq
>
> Does anyone know why (a) the null check is performed twice and (b) the
> type check for $C is performed twice? The simple getters were devirtualized
> and constants inlined, which is nice, but I'm wondering why there are
> redundant safety checks.
>
> Thanks
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20151119/39fc15db/attachment.html>
More information about the hotspot-compiler-dev
mailing list