# HG changeset patch # User twisti # Date 1388002469 28800 # Node ID fe03864a2c7281c66800c87b13855cfc6e89e393 # Parent 37f0c86f58d4b3756a25731751a1bf1b5cb434a6 replaced CompilerToVM.getUniqueImplementor with getKlassImplementor and moved the logic into Java diff -r 37f0c86f58d4 -r fe03864a2c72 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- 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. diff -r 37f0c86f58d4 -r fe03864a2c72 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- 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); diff -r 37f0c86f58d4 -r fe03864a2c72 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- 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(); diff -r 37f0c86f58d4 -r fe03864a2c72 src/share/vm/graal/graalCompilerToVM.cpp --- 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)},