changeset 4635:f35c183f33ce

fixed checkcast when inlining more than one method
author Christian Haeubl <christian.haeubl@oracle.com>
date Fri, 17 Feb 2012 10:34:34 -0800
parents 0f899c0b7e86
children 495a81cd6969
files graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 7 files changed, 91 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java	Fri Feb 17 10:34:34 2012 -0800
@@ -122,6 +122,13 @@
     RiResolvedType superType();
 
     /**
+     * Walks the class hierarchy upwards and returns the least common type that is a super type of both
+     * the current and the given type.
+     * @return the least common type that is a super type of both the current and the given type, or null if primitive types are involved.
+     */
+    RiResolvedType leastCommonAncestor(RiResolvedType otherType);
+
+    /**
      * Attempts to get the unique concrete subtype of this type.
      * @return the exact type of this type, if it exists; {@code null} otherwise
      */
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java	Fri Feb 17 10:34:34 2012 -0800
@@ -326,18 +326,11 @@
             for (int i = 0; i < calleeEntryNodes.length; i++) {
                 BeginNode node = calleeEntryNodes[i];
                 Invoke invokeForInlining = (Invoke) node.next();
-                int typeIdx = -1;
-                for (int j = 0; j < typesToConcretes.length; j++) {
-                    if (typesToConcretes[j] == i) {
-                        typeIdx = j;
-                        break;
-                    }
-                }
-                assert typeIdx >= 0;
+                RiResolvedType commonType = getLeastCommonType(i);
 
                 ValueNode receiver = invokeForInlining.callTarget().receiver();
-                ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(types[typeIdx].getEncoding(Representation.ObjectHub), runtime, graph));
-                CheckCastNode checkCast = graph.unique(new CheckCastNode(node, typeConst, types[typeIdx], receiver));
+                ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph));
+                CheckCastNode checkCast = graph.unique(new CheckCastNode(node, typeConst, commonType, receiver));
                 invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast);
 
                 RiResolvedMethod concrete = concretes.get(i);
@@ -347,6 +340,21 @@
             }
         }
 
+        private RiResolvedType getLeastCommonType(int concreteMethodIndex) {
+            RiResolvedType commonType = null;
+            for (int i = 0; i < typesToConcretes.length; i++) {
+                if (typesToConcretes[i] == concreteMethodIndex) {
+                    if (commonType == null) {
+                        commonType = types[i];
+                    } else {
+                        commonType = commonType.leastCommonAncestor(types[i]);
+                    }
+                }
+            }
+            assert commonType != null;
+            return commonType;
+        }
+
         private void inlineSingleMethod(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) {
             assert concretes.size() == 1 && types.length > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java	Fri Feb 17 10:34:34 2012 -0800
@@ -73,6 +73,8 @@
 
     boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
 
+    RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+
     RiType getPrimitiveArrayType(CiKind kind);
 
     RiType RiType_arrayOf(HotSpotTypeResolved klass);
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java	Fri Feb 17 10:34:34 2012 -0800
@@ -93,6 +93,9 @@
     public native boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
 
     @Override
+    public native RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+
+    @Override
     public native RiType getPrimitiveArrayType(CiKind kind);
 
     @Override
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java	Fri Feb 17 10:34:34 2012 -0800
@@ -75,6 +75,11 @@
     }
 
     @Override
+    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
+        return null;
+    }
+
+    @Override
     public CiConstant getEncoding(Representation r) {
         throw GraalInternalError.unimplemented("HotSpotTypePrimitive.getEncoding");
     }
--- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Fri Feb 17 10:30:39 2012 -0800
+++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java	Fri Feb 17 10:34:34 2012 -0800
@@ -98,6 +98,15 @@
     }
 
     @Override
+    public RiResolvedType leastCommonAncestor(RiResolvedType otherType) {
+        if (otherType instanceof HotSpotTypePrimitive) {
+            return null;
+        } else {
+            return (RiResolvedType) compiler.getVMEntries().RiType_leastCommonAncestor(this, (HotSpotTypeResolved) otherType);
+        }
+    }
+
+    @Override
     public RiResolvedType exactType() {
         if (Modifier.isFinal(accessFlags)) {
             return this;
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Fri Feb 17 10:30:39 2012 -0800
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Fri Feb 17 10:34:34 2012 -0800
@@ -542,6 +542,8 @@
 // public boolean RiType_isSubtypeOf(HotSpotTypeResolved klass, RiType other);
 JNIEXPORT jboolean JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_2isSubtypeOf(JNIEnv *, jobject, jobject klass, jobject jother) {
   TRACE_graal_3("CompilerToVM::RiType_isSubtypeOf");
+  VM_ENTRY_MARK;
+  
   oop other = JNIHandles::resolve(jother);
   assert(other->is_a(HotSpotTypeResolved::klass()), "resolved hotspot type expected");
   assert(JNIHandles::resolve(klass) != NULL, "");
@@ -557,6 +559,18 @@
   }
 }
 
+// public RiType RiType_leastCommonAncestor(HotSpotTypeResolved thisType, HotSpotTypeResolved otherType);
+JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_2leastCommonAncestor(JNIEnv *, jobject, jobject this_type, jobject other_type) {
+  TRACE_graal_3("CompilerToVM::RiType_leastCommonAncestor");
+  VM_ENTRY_MARK;
+
+  Klass* this_klass  = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(this_type))->klass_part();
+  Klass* other_klass = java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(other_type))->klass_part();
+  Klass* lca         = this_klass->LCA(other_klass);
+
+  return JNIHandles::make_local(GraalCompiler::get_RiType(lca, THREAD)());
+}
+
 // public RiType RiType_componentType(HotSpotResolvedType klass);
 JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiType_1componentType(JNIEnv *, jobject, jobject klass) {
   TRACE_graal_3("CompilerToVM::RiType_componentType");
@@ -937,38 +951,39 @@
 #define CLASS           "Ljava/lang/Class;"
 
 JNINativeMethod CompilerToVM_methods[] = {
-  {CC"RiMethod_code",                     CC"("RESOLVED_METHOD")[B",                  FN_PTR(RiMethod_1code)},
-  {CC"RiMethod_signature",                CC"("RESOLVED_METHOD")"STRING,              FN_PTR(RiMethod_1signature)},
-  {CC"RiMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,  FN_PTR(RiMethod_1exceptionHandlers)},
-  {CC"RiMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                   FN_PTR(RiMethod_1hasBalancedMonitors)},
-  {CC"RiMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,              FN_PTR(RiMethod_1uniqueConcreteMethod)},
-  {CC"getRiMethod",                       CC"("REFLECT_METHOD")"METHOD,               FN_PTR(getRiMethod)},
-  {CC"RiMethod_methodData",               CC"("RESOLVED_METHOD")"METHOD_DATA,         FN_PTR(RiMethod_1methodData)},
-  {CC"RiMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                   FN_PTR(RiMethod_1invocationCount)},
-  {CC"RiMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                   FN_PTR(RiMethod_1hasCompiledCode)},
-  {CC"RiMethod_getCompiledCodeSize",      CC"("RESOLVED_METHOD")I",                   FN_PTR(RiMethod_1getCompiledCodeSize)},
-  {CC"RiSignature_lookupType",            CC"("STRING RESOLVED_TYPE"Z)"TYPE,          FN_PTR(RiSignature_1lookupType)},
-  {CC"RiConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,               FN_PTR(RiConstantPool_1lookupConstant)},
-  {CC"RiConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,              FN_PTR(RiConstantPool_1lookupMethod)},
-  {CC"RiConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                 FN_PTR(RiConstantPool_1lookupType)},
-  {CC"RiConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                   FN_PTR(RiConstantPool_1loadReferencedType)},
-  {CC"RiConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,               FN_PTR(RiConstantPool_1lookupField)},
-  {CC"RiType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,  FN_PTR(RiType_3resolveMethodImpl)},
-  {CC"RiType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                FN_PTR(RiType_2isSubtypeOf)},
-  {CC"RiType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1componentType)},
-  {CC"RiType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1uniqueConcreteSubtype)},
-  {CC"RiType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1superType)},
-  {CC"RiType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                  FN_PTR(RiType_1arrayOf)},
-  {CC"RiType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,       FN_PTR(RiType_1fields)},
-  {CC"RiType_isInitialized",              CC"("RESOLVED_TYPE")Z",                     FN_PTR(RiType_1isInitialized)},
-  {CC"getPrimitiveArrayType",             CC"("CI_KIND")"TYPE,                        FN_PTR(getPrimitiveArrayType)},
-  {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                   FN_PTR(getMaxCallTargetOffset)},
-  {CC"getType",                           CC"("CLASS")"TYPE,                          FN_PTR(getType)},
-  {CC"getConfiguration",                  CC"()"CONFIG,                               FN_PTR(getConfiguration)},
-  {CC"installMethod",                     CC"("TARGET_METHOD"Z)"HS_COMP_METHOD,       FN_PTR(installMethod)},
-  {CC"installStub",                       CC"("TARGET_METHOD")"PROXY,                 FN_PTR(installStub)},
-  {CC"disassembleNative",                 CC"([BJ)"STRING,                            FN_PTR(disassembleNative)},
-  {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,              FN_PTR(disassembleJava)},
+  {CC"RiMethod_code",                     CC"("RESOLVED_METHOD")[B",                            FN_PTR(RiMethod_1code)},
+  {CC"RiMethod_signature",                CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(RiMethod_1signature)},
+  {CC"RiMethod_exceptionHandlers",        CC"("RESOLVED_METHOD")"EXCEPTION_HANDLERS,            FN_PTR(RiMethod_1exceptionHandlers)},
+  {CC"RiMethod_hasBalancedMonitors",      CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasBalancedMonitors)},
+  {CC"RiMethod_uniqueConcreteMethod",     CC"("RESOLVED_METHOD")"METHOD,                        FN_PTR(RiMethod_1uniqueConcreteMethod)},
+  {CC"getRiMethod",                       CC"("REFLECT_METHOD")"METHOD,                         FN_PTR(getRiMethod)},
+  {CC"RiMethod_methodData",               CC"("RESOLVED_METHOD")"METHOD_DATA,                   FN_PTR(RiMethod_1methodData)},
+  {CC"RiMethod_invocationCount",          CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1invocationCount)},
+  {CC"RiMethod_hasCompiledCode",          CC"("RESOLVED_METHOD")Z",                             FN_PTR(RiMethod_1hasCompiledCode)},
+  {CC"RiMethod_getCompiledCodeSize",      CC"("RESOLVED_METHOD")I",                             FN_PTR(RiMethod_1getCompiledCodeSize)},
+  {CC"RiSignature_lookupType",            CC"("STRING RESOLVED_TYPE"Z)"TYPE,                    FN_PTR(RiSignature_1lookupType)},
+  {CC"RiConstantPool_lookupConstant",     CC"("RESOLVED_TYPE"I)"OBJECT,                         FN_PTR(RiConstantPool_1lookupConstant)},
+  {CC"RiConstantPool_lookupMethod",       CC"("RESOLVED_TYPE"IB)"METHOD,                        FN_PTR(RiConstantPool_1lookupMethod)},
+  {CC"RiConstantPool_lookupType",         CC"("RESOLVED_TYPE"I)"TYPE,                           FN_PTR(RiConstantPool_1lookupType)},
+  {CC"RiConstantPool_loadReferencedType", CC"("RESOLVED_TYPE"IB)V",                             FN_PTR(RiConstantPool_1loadReferencedType)},
+  {CC"RiConstantPool_lookupField",        CC"("RESOLVED_TYPE"IB)"FIELD,                         FN_PTR(RiConstantPool_1lookupField)},
+  {CC"RiType_resolveMethodImpl",          CC"("RESOLVED_TYPE STRING STRING")"METHOD,            FN_PTR(RiType_3resolveMethodImpl)},
+  {CC"RiType_isSubtypeOf",                CC"("RESOLVED_TYPE TYPE")Z",                          FN_PTR(RiType_2isSubtypeOf)},
+  {CC"RiType_leastCommonAncestor",        CC"("RESOLVED_TYPE RESOLVED_TYPE")"TYPE,              FN_PTR(RiType_2leastCommonAncestor)},
+  {CC"RiType_componentType",              CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1componentType)},
+  {CC"RiType_uniqueConcreteSubtype",      CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1uniqueConcreteSubtype)},
+  {CC"RiType_superType",                  CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1superType)},
+  {CC"RiType_arrayOf",                    CC"("RESOLVED_TYPE")"TYPE,                            FN_PTR(RiType_1arrayOf)},
+  {CC"RiType_fields",                     CC"("RESOLVED_TYPE")["RESOLVED_FIELD,                 FN_PTR(RiType_1fields)},
+  {CC"RiType_isInitialized",              CC"("RESOLVED_TYPE")Z",                               FN_PTR(RiType_1isInitialized)},
+  {CC"getPrimitiveArrayType",             CC"("CI_KIND")"TYPE,                                  FN_PTR(getPrimitiveArrayType)},
+  {CC"getMaxCallTargetOffset",            CC"("CI_RUNTIME_CALL")J",                             FN_PTR(getMaxCallTargetOffset)},
+  {CC"getType",                           CC"("CLASS")"TYPE,                                    FN_PTR(getType)},
+  {CC"getConfiguration",                  CC"()"CONFIG,                                         FN_PTR(getConfiguration)},
+  {CC"installMethod",                     CC"("TARGET_METHOD"Z)"HS_COMP_METHOD,                 FN_PTR(installMethod)},
+  {CC"installStub",                       CC"("TARGET_METHOD")"PROXY,                           FN_PTR(installStub)},
+  {CC"disassembleNative",                 CC"([BJ)"STRING,                                      FN_PTR(disassembleNative)},
+  {CC"disassembleJava",                   CC"("RESOLVED_METHOD")"STRING,                        FN_PTR(disassembleJava)},
 };
 
 int CompilerToVM_methods_count() {