8182310: [AOT][JVMCI] Get host class of VM anonymous class
authordnsimon
Fri, 16 Jun 2017 12:18:46 -0700
changeset 45626 c4ea64135530
parent 45625 3cadf59aa678
child 45627 d7ddaa250ae1
8182310: [AOT][JVMCI] Get host class of VM anonymous class Summary: Add missing JVMCI functionality Reviewed-by: dlong, kvn
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java
hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp
hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java
--- 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);