ConstantDynamic in unvisited catch causes 74X slowdown

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Jan 25 20:51:52 UTC 2022


> From: "eirbjo" <eirbjo at gmail.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "hotspot compiler" <hotspot-compiler-dev at openjdk.java.net>
> Sent: Tuesday, January 25, 2022 9:26:09 PM
> Subject: Re: ConstantDynamic in unvisited catch causes 74X slowdown

> Remi,

> The catch block is actually only reachable via exception, otherwise the method
> returns as normally. There is no GOTO.

> If I also LDC the same ConstantDynamic in the main part of the method (outside
> the catch block), then indeed the method gets compiled.

> I don't actually want try/finally semantics here, since the instrumentation
> logic on the catch branch should be different than when the method exits
> normally. So the semantics here is more try/catch/rethrow.

ok, got it, yes, there is something fishy here, the JIT should not bailout by install a code that will bail to the interpreter if the condy is reached. 

> Thanks,
> Eirik.

regards, 
Rémi 

> On Tue, Jan 25, 2022 at 9:00 PM Remi Forax < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>> Hi,
>> if i'm not wrong in the code you generate the catch block can be reached either
>> by the normal case (no goto in the normal case) and if there is an exception,
>> usually JITs bail out when they detect this kind of patterns.

>> There is a simple way to generate efficient bytecodes, generate exactly the same
>> code as javac :)
>> In your case, you want to generate an equivalent of a try/finally, so the
>> invokedynamic/ldc constantdynamic should be generated twice, one in the normal
>> case and one in the exceptional case with a goto after the normal case to jump
>> over the exception block.

>> regards,
>> Rémi

>> ----- Original Message -----
>> > From: "eirbjo" < [ mailto:eirbjo at gmail.com | eirbjo at gmail.com ] >
>>> To: "hotspot compiler" < [ mailto:hotspot-compiler-dev at openjdk.java.net |
>> > hotspot-compiler-dev at openjdk.java.net ] >
>> > Sent: Tuesday, January 25, 2022 8:19:27 PM
>> > Subject: ConstantDynamic in unvisited catch causes 74X slowdown

>> > Hi,

>> > I'm looking at a JMH benchmark which shows a 74X slowdown when a
>> > single invokeDynamic instruction is replaced by an equivalent
>> > ConstantDynamic LDC instruction.

>> > An interesting side note is that the LDC/invokeDynamic instructions live
>> > inside a catch block which wraps the method being run. So the
>> > LDC/invokeDynamic instructions are actually never executed when running the
>> > benchmark (because no exception was thrown/catched).

>> > I was expecting ConstantDynamic to be as fast as (or faster than)
>> > invokeDynamic, so this one is a bit of a puzzle. Does it make sense that
>> > simply having a ConstantDynamic instruction present in the code prevents
>> > some Hotspot optimizations from kicking in?

>> > I've made a Maven project [1] with a minimal reproducer [2] for the issue.
>> > (Minimal does not mean small, since there is a good amount of code for
>> > setting up the instrumentation and class loading magic)

>> > With Java 17.0.1 on my Intel Macbook pro, the JMH benchmark runs at ~350
>> > ops/s using ConstantDynamic, and around 27000 ops/s when switching to
>> > invokeDynamic.

>> > What is going on here?

>>> [1] [ https://github.com/eirbjo/constant-dynamic-cliff |
>> > https://github.com/eirbjo/constant-dynamic-cliff ]
>> > [2]
>>> [
>>> https://github.com/eirbjo/constant-dynamic-cliff/blob/main/src/test/java/com/eirbjo/cpc/ConstantDynamicCliff.java
>>> |
>>> https://github.com/eirbjo/constant-dynamic-cliff/blob/main/src/test/java/com/eirbjo/cpc/ConstantDynamicCliff.java
>> > ]

>> > Thanks,
>> > Eirik.


More information about the hotspot-compiler-dev mailing list