On constructors and compiler blackholes
Andrew Haley
aph at redhat.com
Mon Apr 11 09:28:42 UTC 2022
In these benchmarks, on AArch64:
@Benchmark
public AtomicLong newAtomicLong() {
return new AtomicLong();
}
@Benchmark
public AtomicLong newInitAtomicLong() {
return new AtomicLong(9);
}
If we use compiler blackholes, the volatile AtomicLong field value is initialized
like this:
2.87% │ 0x0000ffff8ce3d40c: mov x15, #0x20000 // #131072
│ ; {metadata('java/util/concurrent/atomic/AtomicLong')}
0.20% │ 0x0000ffff8ce3d410: movk x15, #0x1390
0.16% │ 0x0000ffff8ce3d414: str x10, [x0]
12.42% │ 0x0000ffff8ce3d418: str w15, [x0, #8]
4.21% │ 0x0000ffff8ce3d41c: prfm pstl1keep, [x11, #192]
0.68% │ 0x0000ffff8ce3d420: str wzr, [x0, #12] ;*new {reexecute=0 rethrow=0 return_oop=0}
│ ; - org.openjdk.jmh.samples.MulHiTest::newInitAtomicLong at 0 (line 108)
│ ; - org.openjdk.jmh.samples.jmh_generated.MulHiTest_newInitAtomicLong_jmhTest::newInitAtomicLong_avgt_jmhStub at 17 (line 190)
0.03% │ 0x0000ffff8ce3d424: mov x10, #0x9 // #9
5.84% │ 0x0000ffff8ce3d428: str x10, [x0, #16] ;*invokestatic consumeCompiler {reexecute=0 rethrow=0 return_oop=0}
│ ; - org.openjdk.jmh.infra.Blackhole::consume at 7 (line 315)
│ ; - org.openjdk.jmh.samples.jmh_generated.MulHiTest_newInitAtomicLong_jmhTest::newInitAtomicLong_avgt_jmhStub at 20 (line 190)
but without compiler blackholes, like this:
│ 0x0000ffff74e3ce70: mov x13, #0x20000 // #131072
│ ; {metadata('java/util/concurrent/atomic/AtomicLong')}
│ 0x0000ffff74e3ce74: movk x13, #0x1390
0.69% │ 0x0000ffff74e3ce78: str x10, [x2]
│ 0x0000ffff74e3ce7c: str w13, [x2, #8]
│ 0x0000ffff74e3ce80: str wzr, [x2, #12]
│ 0x0000ffff74e3ce84: prfm pstl1keep, [x11, #192]
0.96% │ 0x0000ffff74e3ce88: str xzr, [x2, #16]
│ 0x0000ffff74e3ce8c: stp x12, x14, [sp, #16]
│ 0x0000ffff74e3ce90: dmb ishst ;*new {reexecute=0 rethrow=0 return_oop=0}
│ ; - org.openjdk.jmh.samples.MulHiTest::newInitAtomicLong at 0 (line 108)
│ ; - org.openjdk.jmh.samples.jmh_generated.MulHiTest_newInitAtomicLong_jmhTest::newInitAtomicLong_avgt_jmhStub at 17 (line 190)
│ 0x0000ffff74e3ce94: mov x11, #0x9 // #9
│ 0x0000ffff74e3ce98: add x10, x2, #0x10
│ 0x0000ffff74e3ce9c: stlr x11, [x10] ;*putfield value {reexecute=0 rethrow=0 return_oop=0}
│ ; - java.util.concurrent.atomic.AtomicLong::<init>@6 (line 88)
│ ; - org.openjdk.jmh.samples.MulHiTest::newInitAtomicLong at 7 (line 108)
│ ; - org.openjdk.jmh.samples.jmh_generated.MulHiTest_newInitAtomicLong_jmhTest::newInitAtomicLong_avgt_jmhStub at 17 (line 190)
The significant difference is that if we use compiler blackholes, C2 omits all of
the fences that would usually be necessary. I guess that C2 detects that the
newly-constructed AtomicLong is non-escaping.
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the jmh-dev
mailing list