Skip to content

Commit b345181

Browse files
committed
[GR-70132] JVMCI: Add ResolvedJavaType#getEnclosingMethod
PullRequest: labsjdk-ce/223
2 parents d9c8ead + 81f5065 commit b345181

File tree

8 files changed

+104
-0
lines changed

8 files changed

+104
-0
lines changed

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJDKReflection.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import java.lang.annotation.Annotation;
2929
import java.lang.reflect.Array;
30+
import java.lang.reflect.Constructor;
3031
import java.lang.reflect.Executable;
3132
import java.lang.reflect.Field;
3233
import java.lang.reflect.Method;
@@ -103,6 +104,17 @@ HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder
103104
return (HotSpotResolvedObjectType) runtime().fromClass(javaMirror.getEnclosingClass());
104105
}
105106

107+
@Override
108+
HotSpotResolvedJavaMethod getEnclosingMethod(HotSpotResolvedObjectTypeImpl holder) {
109+
Class<?> javaMirror = getMirror(holder);
110+
Method enclosingMethod = javaMirror.getEnclosingMethod();
111+
Executable enclosingExecutable = enclosingMethod != null ? enclosingMethod : javaMirror.getEnclosingConstructor();
112+
if (enclosingExecutable == null) {
113+
return null;
114+
}
115+
return compilerToVM().asResolvedJavaMethod(enclosingExecutable);
116+
}
117+
106118
@Override
107119
boolean equals(HotSpotObjectConstantImpl a, HotSpotObjectConstantImpl b) {
108120
return resolveObject(a) == resolveObject(b) && a.isCompressed() == b.isCompressed();

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ abstract class HotSpotJVMCIReflection {
5050

5151
abstract HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder);
5252

53+
abstract HotSpotResolvedJavaMethod getEnclosingMethod(HotSpotResolvedObjectTypeImpl holder);
54+
5355
abstract boolean equals(HotSpotObjectConstantImpl hotSpotResolvedJavaType, HotSpotObjectConstantImpl that);
5456

5557
abstract ResolvedJavaMethod.Parameter[] getParameters(HotSpotResolvedJavaMethodImpl javaMethod);

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public HotSpotResolvedObjectType getArrayClass() {
6161
return arrayOfType;
6262
}
6363

64+
@Override
65+
public abstract HotSpotResolvedJavaMethod getEnclosingMethod();
66+
6467
/**
6568
* Checks whether this type is currently being initialized. If a type is being initialized it
6669
* implies that it was {@link #isLinked() linked} and that the static initializer is currently

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,11 @@ public HotSpotResolvedObjectType getEnclosingType() {
11501150
return runtime().reflection.getEnclosingClass(this);
11511151
}
11521152

1153+
@Override
1154+
public HotSpotResolvedJavaMethod getEnclosingMethod() {
1155+
return runtime().reflection.getEnclosingMethod(this);
1156+
}
1157+
11531158
@Override
11541159
public ResolvedJavaMethod[] getDeclaredConstructors() {
11551160
link();

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ public ResolvedJavaType getEnclosingType() {
317317
return null;
318318
}
319319

320+
@Override
321+
public HotSpotResolvedJavaMethod getEnclosingMethod() {
322+
return null;
323+
}
324+
320325
@Override
321326
public ResolvedJavaMethod[] getDeclaredConstructors() {
322327
return new ResolvedJavaMethod[0];

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ HotSpotResolvedObjectType getEnclosingClass(HotSpotResolvedObjectTypeImpl holder
7171
throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.getEnclosingClass()");
7272
}
7373

74+
@Override
75+
HotSpotResolvedJavaMethod getEnclosingMethod(HotSpotResolvedObjectTypeImpl holder) {
76+
throw new HotSpotJVMCIUnsupportedOperationError("requires a call Class.getEnclosingMethod()");
77+
}
78+
7479
@Override
7580
boolean equals(HotSpotObjectConstantImpl x, HotSpotObjectConstantImpl y) {
7681
if (x == y) {

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,26 @@ default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, Reso
414414
*/
415415
ResolvedJavaType getEnclosingType();
416416

417+
/**
418+
* Returns a {@link ResolvedJavaMethod} representing the immediately enclosing
419+
* method or constructor of the underlying type, if this type represents a local
420+
* or anonymous class within a method. Returns {@code null} otherwise.
421+
*
422+
* In particular, this method returns {@code null} if the underlying
423+
* type is a local or anonymous class immediately enclosed by a class or
424+
* interface declaration, instance initializer or static initializer.
425+
*
426+
* Note that in contrast to {@link Class#getEnclosingMethod()}, this returns
427+
* both, methods and constructors.
428+
*
429+
* @return the immediately enclosing method or constructor of the underlying
430+
* class, if this type is a local or anonymous class, otherwise {@code null}.
431+
*
432+
* @see Class#getEnclosingMethod()
433+
* @see Class#getEnclosingConstructor()
434+
*/
435+
ResolvedJavaMethod getEnclosingMethod();
436+
417437
/**
418438
* Returns an array reflecting all the constructors declared by this type. This method is
419439
* similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. Calling

test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import java.lang.invoke.MethodHandles.Lookup;
6767
import java.lang.reflect.AccessibleObject;
6868
import java.lang.reflect.Constructor;
69+
import java.lang.reflect.Executable;
6970
import java.lang.reflect.Field;
7071
import java.lang.reflect.Method;
7172
import java.lang.reflect.Modifier;
@@ -799,6 +800,57 @@ private void assertGetPermittedSubclasses(Class<?> clazz) {
799800
}
800801
}
801802

803+
@Test
804+
public void getEnclosingMethodTest() {
805+
// no anonymous class -> expected null
806+
Object obj0 = new Object();
807+
testEnclosingMethod(obj0.getClass(), false);
808+
809+
// anonymous class -> not null
810+
Object obj1 = new Object() {};
811+
testEnclosingMethod(obj1.getClass(), true);
812+
813+
// local class -> not null
814+
class Foo {};
815+
testEnclosingMethod(Foo.class, true);
816+
817+
class Bar {
818+
final Object obj0;
819+
final Object obj1;
820+
final Object obj2;
821+
822+
Bar() {
823+
// no anonymous class -> expected null
824+
obj0 = new Object();
825+
826+
// anonymous class -> not null
827+
obj1 = new Object() {};
828+
829+
// local class -> not null
830+
class Foo {};
831+
obj2 = new Foo();
832+
}
833+
}
834+
Bar bar = new Bar();
835+
testEnclosingMethod(bar.obj0.getClass(), false);
836+
testEnclosingMethod(bar.obj1.getClass(), true);
837+
testEnclosingMethod(bar.obj2.getClass(), true);
838+
}
839+
840+
private static void testEnclosingMethod(Class<?> clazz, boolean isEnclosed) {
841+
ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
842+
Method enclosingMethod = clazz.getEnclosingMethod();
843+
Executable expected = enclosingMethod != null ? enclosingMethod : clazz.getEnclosingConstructor();
844+
ResolvedJavaMethod actual = type.getEnclosingMethod();
845+
if (expected == null) {
846+
assertFalse(isEnclosed);
847+
assertNull(actual);
848+
} else {
849+
assertTrue(isEnclosed);
850+
assertEquals(metaAccess.lookupJavaMethod(expected), actual);
851+
}
852+
}
853+
802854
static final Map<Class<?>, VTable> vtables = new HashMap<>();
803855

804856
static class VTable {

0 commit comments

Comments
 (0)