JDK-8308023 - Exponential classfile blowup with nested try/finally
Archie Cobbs
archie.cobbs at gmail.com
Sun Jul 30 21:24:13 UTC 2023
On Fri, Jul 28, 2023 at 3:17 AM Jan Lahoda <jan.lahoda at oracle.com> wrote:
> I believe a few of us were looking at this some time ago.
>
I played around with this some more and now realize there is a bigger (and
more subtle) obstacle with this idea or any other similar variant that
attempts to "reuse" the same finally block bytecode for both normal and
exceptional execution paths.
Suppose you have code like this:
public int method() {
int x;
try {
x = 7;
} finally {
doWhatever();
}
return x;
}
If the finally block is only emitted once, then there must be two possible
exit paths out of it - one where it rethrows some caught exception, and the
other where it falls through to the return statement.
My idea was to store the caught exception (in the former case) or a null
placeholder (in the latter case) in a local variable as a way of telling
the finally block which exit path to take:
public int method();
descriptor: ()I
Code:
0: bipush 7
2: istore_1
3: aconst_null
4: astore_2
5: aload_0
6: invokevirtual #14 // Method doWhatever:()V
9: aload_2
10: ifnull 15
13: aload_2
14: athrow
15: iload_1
16: ireturn
Exception table:
from to target type
0 4 4 any
The problem is that there's no way to prove to the verifier that in the
second case, the local variable corresponding to 'x' (Local#1) is always
definitely assigned, even though of course we know that it always will be
in that case. So you get a 'Bad local variable type' verifier error.
This could be worked-around by initializing, prior to entering the try
block, the locals that get (a) assigned for the first time within the try
block and (b) referenced in the finally block. Not very elegant though.
In summary, JSR/RET is gone now, and the verifier also makes it difficult
to synthesize "subroutines". This makes the compiler's job a lot harder
wrt. finally blocks.
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230730/98f1817c/attachment.htm>
More information about the compiler-dev
mailing list