JDK-8308023 - Exponential classfile blowup with nested try/finally

forax at univ-mlv.fr forax at univ-mlv.fr
Thu Jul 27 22:22:15 UTC 2023


> From: "Archie Cobbs" <archie.cobbs at gmail.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "compiler-dev" <compiler-dev at openjdk.java.net>
> Sent: Thursday, July 27, 2023 10:26:14 PM
> Subject: Re: JDK-8308023 - Exponential classfile blowup with nested try/finally

> Thanks for your comments.

> Bear with me while I play devil's advocate...

> On Thu, Jul 27, 2023 at 3:16 PM Remi Forax < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>>> What if we compiled try { X } finally { Y } into this:

>>> X
>>> Store null in local e1 // new instruction
>>> goto L2
>>> L1: Store exception in local e1
>>> L2: Y
>>> Load exception from local e1
>>> If null, goto L3 // new instruction
>>> Load exception from local e1 // new instruction
>>> Throw exception
>>> L3: ...

>> It's a well known issue since the introduction of the split-verifier, the
>> alternative is exponential verification time.

> Wait - are you saying the split-verifier has exponential verification time in
> certain cases?

> If so, how is that not just a stupid verifier bug? Not to mention an easy way to
> DOS Java's widely heralded code portability.

There are two verifiers, the old one that does not use StackMapTable attributes has an exponential verification time if JSR/RET are used. 
The new one, the split-verifier, is linear but requires StackMapTable attributes and to duplicated finally blocks. 

see [ https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.10.2 | https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.10.2 ] 

>> If you try to generate the code above most JITs will refuse to optimize the
>> code, sharing the nominal path and the exception path is a big no no.

> And this is whose fault... ?

> Isn't it a JIT's job to be aware of any such effects (if they exist on some
> particular hardware) and deal with them??

It has nothing to do with a peculiar hardware, a JIT is an optimizing bytecode to assembly compiler, like any optimizing compiler, not all bytecode shapes are equal. 

The crux of this issue is this question, Why do want a VM engineer to spend time on a bytecode shape that no sane bytecode generators will ever generate ? 
And do not forget that there are several existing Java VMs, so each VM will have to dedicate engineering time to do that optimization. 

>> The official workaround if there are a lot on enclosed try/finally blocks is to
>> use several methods.

> Workaround for whom?

> If for the programmer, then so what? The existence of a workaround doesn't mean
> a bug shouldn't still be fixed.

> If for the compiler, then when is the "official" workaround going to be actually
> implemented?

For the developer. 

> Thanks,
> -Archie

Rémi 

> --
> Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230728/c0c473d7/attachment.htm>


More information about the compiler-dev mailing list