8182310: [AOT][JVMCI] Get host class of VM anonymous class
Summary: Add missing JVMCI functionality
Reviewed-by: dlong, kvn
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Fri Jun 16 12:18:46 2017 -0700
@@ -644,4 +644,9 @@
* {@link Long}
*/
native Object getFlagValue(String name);
+
+ /**
+ * Gets the host class for {@code type}.
+ */
+ native HotSpotResolvedObjectTypeImpl getHostClass(HotSpotResolvedObjectTypeImpl type);
}
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Fri Jun 16 12:18:46 2017 -0700
@@ -412,6 +412,14 @@
}
@Override
+ public ResolvedJavaType getHostClass() {
+ if (isArray()) {
+ return null;
+ }
+ return compilerToVM().getHostClass(this);
+ }
+
+ @Override
public boolean isJavaLangObject() {
return javaClass.equals(Object.class);
}
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Fri Jun 16 12:18:46 2017 -0700
@@ -154,6 +154,11 @@
}
@Override
+ public ResolvedJavaType getHostClass() {
+ return null;
+ }
+
+ @Override
public JavaKind getJavaKind() {
return kind;
}
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Fri Jun 16 12:18:46 2017 -0700
@@ -105,6 +105,13 @@
boolean isAssignableFrom(ResolvedJavaType other);
/**
+ * Returns the {@link ResolvedJavaType} object representing the host class of this VM anonymous
+ * class (as opposed to the unrelated concept specified by {@link Class#isAnonymousClass()}) or
+ * {@code null} if this object does not represent a VM anonymous class.
+ */
+ ResolvedJavaType getHostClass();
+
+ /**
* Returns true if this type is exactly the type {@link java.lang.Object}.
*/
default boolean isJavaLangObject() {
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Fri Jun 16 12:18:46 2017 -0700
@@ -1687,6 +1687,13 @@
}
C2V_END
+C2V_VMENTRY(jobject, getHostClass, (JNIEnv*, jobject, jobject jvmci_type))
+ InstanceKlass* k = InstanceKlass::cast(CompilerToVM::asKlass(jvmci_type));
+ InstanceKlass* host = k->host_klass();
+ oop result = CompilerToVM::get_jvmci_type(host, CHECK_NULL);
+ return JNIHandles::make_local(THREAD, result);
+C2V_END
+
C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv*, jobject, jobject bytecode_frame_handle))
if (bytecode_frame_handle == NULL) {
THROW_0(vmSymbols::java_lang_NullPointerException());
@@ -1817,6 +1824,7 @@
{CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
{CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
{CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
+ {CC "getHostClass", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getHostClass)},
{CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
{CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)},
{CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)},
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Thu Jun 15 17:43:56 2017 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Fri Jun 16 12:18:46 2017 -0700
@@ -54,6 +54,7 @@
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
+import java.util.function.Supplier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -143,6 +144,27 @@
}
@Test
+ public void getHostClassTest() {
+ for (Class<?> c : classes) {
+ ResolvedJavaType type = metaAccess.lookupJavaType(c);
+ ResolvedJavaType host = type.getHostClass();
+ assertNull(host);
+ }
+
+ class LocalClass {}
+ Cloneable clone = new Cloneable() {};
+ assertNull(metaAccess.lookupJavaType(LocalClass.class).getHostClass());
+ assertNull(metaAccess.lookupJavaType(clone.getClass()).getHostClass());
+
+ Supplier<Runnable> lambda = () -> () -> System.out.println("run");
+ ResolvedJavaType lambdaType = metaAccess.lookupJavaType(lambda.getClass());
+ ResolvedJavaType nestedLambdaType = metaAccess.lookupJavaType(lambda.get().getClass());
+ assertNotNull(lambdaType.getHostClass());
+ assertNotNull(nestedLambdaType.getHostClass());
+ assertEquals(lambdaType.getHostClass(), nestedLambdaType.getHostClass());
+ }
+
+ @Test
public void getModifiersTest() {
for (Class<?> c : classes) {
ResolvedJavaType type = metaAccess.lookupJavaType(c);