JDK-8308023 - Exponential classfile blowup with nested try/finally
Remi Forax
forax at univ-mlv.fr
Thu Jul 27 20:16:49 UTC 2023
> From: "Archie Cobbs" <archie.cobbs at gmail.com>
> To: "compiler-dev" <compiler-dev at openjdk.java.net>
> Sent: Thursday, July 27, 2023 8:33:41 PM
> Subject: JDK-8308023 - Exponential classfile blowup with nested try/finally
> This issue caught my eye: [ https://bugs.openjdk.org/browse/JDK-8308023 |
> JDK-8308023 ] - Javac generates exponentially large class file with nested try
> catch statements
> In a nutshell, since JSR/RET is no longer allowed/used, we now compile try { X }
> finally { Y } into this:
> X
> Y
> goto L2
> L1: Store exception in local e1
> Y
> Load exception from local e1
> Throw exception
> L2: ...
> The L1 label is the target for the exception range surrounding X .
> Note that the finally block Y is duplicated.
> This means that if we hare N nested finally's:
> try {
> X0
> } finally {
> try {
> X1
> } finally {
> try {
> X2
> } finally {
> .... try {
> XN
> } finally {
> // done
> ... }
> }
> }
> }
> }
> then each block Xi will be replicated 2^i times in the classfile.
> Question: Can we solve this problem simply by avoiding the duplication of
> finally blocks?
> 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: ...
> There are three new instructions, so in trivial cases this would make the
> classfile larger. But in the highly nested cases it would change the classfile
> growth from exponential to linear.
> Thoughts? What am I missing?
It's a well known issue since the introduction of the split-verifier, the alternative is exponential verification time.
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.
The official workaround if there are a lot on enclosed try/finally blocks is to use several methods.
> -Archie
regards,
Rémi
> --
> Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230727/28418249/attachment.htm>
More information about the compiler-dev
mailing list