Skip to content

Commit e36756b

Browse files
committed
8297727: Forcing LF interpretation lead to StackOverflowError in reflection code
Reviewed-by: jvernee
1 parent 24bc714 commit e36756b

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ private static LambdaForm preparedLambdaForm(MemberName m, boolean adaptToSpecia
214214
which = LF_INVSPECIAL_IFC;
215215
}
216216
LambdaForm lform = preparedLambdaForm(mtype, which);
217-
maybeCompile(lform, m);
218217
assert(lform.methodType().dropParameterTypes(0, 1)
219218
.equals(m.getInvocationType().basicType()))
220219
: Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
@@ -320,12 +319,6 @@ static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
320319
return null;
321320
}
322321

323-
private static void maybeCompile(LambdaForm lform, MemberName m) {
324-
if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
325-
// Help along bootstrapping...
326-
lform.compileToBytecode();
327-
}
328-
329322
/** Static wrapper for DirectMethodHandle.internalMemberName. */
330323
@ForceInline
331324
/*non-public*/
@@ -666,7 +659,6 @@ private static LambdaForm preparedFieldLambdaForm(MemberName m) {
666659
formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
667660
}
668661
LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
669-
maybeCompile(lform, m);
670662
assert(lform.methodType().dropParameterTypes(0, 1)
671663
.equals(m.getInvocationType().basicType()))
672664
: Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
@@ -843,6 +835,9 @@ static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, i
843835
}
844836
LambdaForm.associateWithDebugName(form, nameBuilder.toString());
845837
}
838+
839+
// NF_UNSAFE uses field form, avoid circular dependency in interpreter
840+
form.compileToBytecode();
846841
return form;
847842
}
848843

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.lang.invoke.MethodHandle;
25+
import java.lang.invoke.MethodHandles;
26+
27+
/*
28+
* @test
29+
* @bug 8297727
30+
* @summary MethodHandle field access fails with bytecode compilation disabled
31+
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames
32+
* -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=-1
33+
* ReflectionInInterpretTest
34+
*/
35+
public class ReflectionInInterpretTest {
36+
private static Integer f; // non-Object type is required to find a non-compiled form
37+
38+
public static void main(String... args) throws Throwable {
39+
MethodHandle mh = MethodHandles.lookup().findStaticGetter(ReflectionInInterpretTest.class, "f", Integer.class);
40+
var _ = (Integer) mh.invokeExact();
41+
}
42+
}

0 commit comments

Comments
 (0)