RFR: 8252505: C1/C2 compiler support for blackholes

Aleksey Shipilev shade at openjdk.java.net
Fri Nov 20 12:31:29 UTC 2020


JMH uses the [`Blackhole::consume`](https://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-core/src/main/java/org/openjdk/jmh/infra/Blackhole.java#l153) methods to avoid dead-code elimination of the code that produces benchmark values. It now relies on producing opaque side-effects and breaking inlining. While it was proved useful for many years, it unfortunately comes with several major drawbacks:
 
  1. Call costs dominate nanobenchmarks. On TR 3970X, the call cost is several nanoseconds.
  2. The work spent in Blackhole.consume dominates nanobenchmarks too. It takes about a nanosecond on TR 3970X.
  3. Argument preparation for call makes different argument types behave differently. This is prominent on architectures where calling conventions for passing e.g. floating-point arguments require elaborate dance.

Supporting this directly in compilers would improve nanobenchmark fidelity.

Instead of introducing public APIs or special-casing JMH methods in JVM, we can hook a new command to compiler control, and let JMH sign up its Blackhole methods for it with `-XX:CompileCommand=blackhole,org.openjdk.jmh.infra.Blackhole::consume`. This is being prototyped as [CODETOOLS-7902762](https://bugs.openjdk.java.net/browse/CODETOOLS-7902762). It makes Blackholes behave [substantially better](http://cr.openjdk.java.net/~shade/8252505/bh-old-vs-new.png).

Current prototype is for initial approach review and early testing. I am open for suggestions how to make it simpler; not that I haven't tried, but it is likely there is something I am overlooking here.

C1 code is platform-independent, and it adds the new node which is then lowered to nothing.

C2 code is more complicated. I tried to introduce new node and hook arguments there, but failed. There seems to be no way to model the effects we are after: consume the value, but have no observable side effects. Roland suggested we instead put the boolean flag onto `CallJavaNode`, and then match it to nothing in `.ad`. This drags the blackhole through C2 as if it has call-like side effects, and then emits nothing. On the downside, it requires fiddling with arch-specific code in every .ad.

-------------

Commit messages:
 - 8252505: C1/C2 compiler support for blackholes

Changes: https://git.openjdk.java.net/jdk/pull/1203/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1203&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8252505
  Stats: 1428 lines in 38 files changed: 1425 ins; 0 del; 3 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1203.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1203/head:pull/1203

PR: https://git.openjdk.java.net/jdk/pull/1203


More information about the hotspot-compiler-dev mailing list