changeset 13478:fe03864a2c72

replaced CompilerToVM.getUniqueImplementor with getKlassImplementor and moved the logic into Java
author twisti
date Wed, 25 Dec 2013 12:14:29 -0800
parents 37f0c86f58d4
children 606959535fd4
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 4 files changed, 50 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Dec 23 21:21:06 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed Dec 25 12:14:29 2013 -0800
@@ -79,13 +79,12 @@
     long findUniqueConcreteMethod(long metaspaceMethod);
 
     /**
-     * Used to determine if an interface has exactly one implementor.
+     * Returns the implementor for the given interface class.
      * 
-     * @param interfaceType interface for which the implementor should be returned
-     * @return the unique implementor of the interface or null if the interface has 0 or more than 1
-     *         implementor
+     * @param metaspaceKlass the metaspace klass to get the implementor for
+     * @return the implementor as metaspace klass pointer or null if there is no implementor
      */
-    ResolvedJavaType getUniqueImplementor(HotSpotResolvedObjectType interfaceType);
+    long getKlassImplementor(long metaspaceKlass);
 
     /**
      * Initializes a {@link HotSpotResolvedJavaMethod} object from a metaspace Method object.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Dec 23 21:21:06 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed Dec 25 12:14:29 2013 -0800
@@ -59,7 +59,7 @@
     public native long findUniqueConcreteMethod(long metaspaceMethod);
 
     @Override
-    public native ResolvedJavaType getUniqueImplementor(HotSpotResolvedObjectType interfaceType);
+    public native long getKlassImplementor(long metaspaceKlass);
 
     @Override
     public native JavaType lookupType(String name, HotSpotResolvedObjectType accessingClass, boolean eagerResolve);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Dec 23 21:21:06 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Dec 25 12:14:29 2013 -0800
@@ -171,23 +171,60 @@
         if (isArray()) {
             return isFinal(getElementalType(this).getModifiers()) ? this : null;
         } else if (isInterface()) {
-            return runtime().getCompilerToVM().getUniqueImplementor(this);
+            final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(metaspaceKlass());
+
+            // No implementor.
+            if (implementorMetaspaceKlass == 0) {
+                return null;
+            }
+
+            HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) fromMetaspaceKlass(implementorMetaspaceKlass);
+
+            /*
+             * If the implementor field contains itself that indicates that the interface has more
+             * than one implementors (see: InstanceKlass::add_implementor). The isInterface check
+             * takes care of this fact since this class is an interface.
+             */
+            if (isAbstract(type.getModifiers()) || type.isInterface() || !type.isLeafClass()) {
+                return null;
+            }
+            return type;
         } else {
             HotSpotResolvedObjectType type = this;
             while (isAbstract(type.getModifiers())) {
-                long subklass = unsafeReadWord(type.metaspaceKlass() + config.subklassOffset);
+                long subklass = type.getSubklass();
                 if (subklass == 0 || unsafeReadWord(subklass + config.nextSiblingOffset) != 0) {
                     return null;
                 }
                 type = (HotSpotResolvedObjectType) fromMetaspaceKlass(subklass);
             }
-            if (isAbstract(type.getModifiers()) || type.isInterface() || unsafeReadWord(type.metaspaceKlass() + config.subklassOffset) != 0) {
+            if (isAbstract(type.getModifiers()) || type.isInterface() || !type.isLeafClass()) {
                 return null;
             }
             return type;
         }
     }
 
+    /**
+     * Returns if type {@code type} is a leaf class. This is the case if the
+     * {@code Klass::_subklass} field of the underlying class is zero.
+     * 
+     * @return true if the type is a leaf class
+     */
+    private boolean isLeafClass() {
+        return getSubklass() == 0;
+    }
+
+    /**
+     * Returns the {@code Klass::_subklass} field of the underlying metaspace klass for the given
+     * type {@code type}.
+     * 
+     * @return value of the subklass field as metaspace klass pointer
+     */
+    private long getSubklass() {
+        return unsafeReadWord(metaspaceKlass() + runtime().getConfig().subklassOffset);
+    }
+
     @Override
     public HotSpotResolvedObjectType getSuperclass() {
         Class javaSuperclass = javaClass.getSuperclass();
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Dec 23 21:21:06 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed Dec 25 12:14:29 2013 -0800
@@ -181,17 +181,9 @@
   return (jlong) (address) ucm;
 C2V_END
 
-C2V_VMENTRY(jobject, getUniqueImplementor, (JNIEnv *, jobject, jobject interface_type))
-  InstanceKlass* klass = (InstanceKlass*) java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(interface_type));
-  assert(klass->is_interface(), "must be");
-  if (klass->nof_implementors() == 1) {
-    InstanceKlass* implementor = (InstanceKlass*) klass->implementor();
-    if (!implementor->is_abstract() && !implementor->is_interface() && implementor->is_leaf_class()) {
-      Handle type = GraalCompiler::createHotSpotResolvedObjectType(implementor, CHECK_NULL);
-      return JNIHandles::make_local(THREAD, type());
-    }
-  }
-  return NULL;
+C2V_VMENTRY(jlong, getKlassImplementor, (JNIEnv *, jobject, jlong metaspace_klass))
+  InstanceKlass* klass = (InstanceKlass*) asKlass(metaspace_klass);
+  return (jlong) (address) klass->implementor();
 C2V_END
 
 C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
@@ -839,17 +831,9 @@
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
-#define RESOLVED_TYPE         "Lcom/oracle/graal/api/meta/ResolvedJavaType;"
 #define TYPE                  "Lcom/oracle/graal/api/meta/JavaType;"
 #define METHOD                "Lcom/oracle/graal/api/meta/JavaMethod;"
 #define FIELD                 "Lcom/oracle/graal/api/meta/JavaField;"
-#define SIGNATURE             "Lcom/oracle/graal/api/meta/Signature;"
-#define CONSTANT_POOL         "Lcom/oracle/graal/api/meta/ConstantPool;"
-#define CONSTANT              "Lcom/oracle/graal/api/meta/Constant;"
-#define KIND                  "Lcom/oracle/graal/api/meta/Kind;"
-#define RUNTIME_CALL          "Lcom/oracle/graal/api/code/RuntimeCall;"
-#define REFLECT_METHOD        "Ljava/lang/reflect/Method;"
-#define REFLECT_CONSTRUCTOR   "Ljava/lang/reflect/Constructor;"
 #define STRING                "Ljava/lang/String;"
 #define OBJECT                "Ljava/lang/Object;"
 #define CLASS                 "Ljava/lang/Class;"
@@ -859,8 +843,8 @@
 #define HS_RESOLVED_FIELD     "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaField;"
 #define HS_COMPILED_CODE      "Lcom/oracle/graal/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG             "Lcom/oracle/graal/hotspot/HotSpotVMConfig;"
-#define HS_METHOD             "Lcom/oracle/graal/hotspot/meta/HotSpotMethod;"
 #define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
+#define METASPACE_KLASS       "J"
 #define METASPACE_METHOD      "J"
 #define METASPACE_CONSTANT_POOL "J"
 
@@ -869,7 +853,7 @@
   {CC"exceptionTableStart",           CC"("METASPACE_METHOD")J",                                        FN_PTR(exceptionTableStart)},
   {CC"hasBalancedMonitors",           CC"("METASPACE_METHOD")Z",                                        FN_PTR(hasBalancedMonitors)},
   {CC"findUniqueConcreteMethod",      CC"("METASPACE_METHOD")"METASPACE_METHOD,                         FN_PTR(findUniqueConcreteMethod)},
-  {CC"getUniqueImplementor",          CC"("HS_RESOLVED_TYPE")"RESOLVED_TYPE,                            FN_PTR(getUniqueImplementor)},
+  {CC"getKlassImplementor",           CC"("METASPACE_KLASS")"METASPACE_KLASS,                           FN_PTR(getKlassImplementor)},
   {CC"getStackTraceElement",          CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                     FN_PTR(getStackTraceElement)},
   {CC"initializeMethod",              CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V",                     FN_PTR(initializeMethod)},
   {CC"doNotInlineOrCompile",          CC"("METASPACE_METHOD")V",                                        FN_PTR(doNotInlineOrCompile)},