# HG changeset patch # User Christian Haeubl # Date 1329505372 28800 # Node ID 5a5c603f7e0fd24003072170edb5f7cc268ad68d # Parent 495a81cd6969c95e2a22fdf7737d6e529b97e884# Parent a1780986a4fee43f08949fbad01ba8fa03679a6e Merge diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedType.java Fri Feb 17 11:02:52 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 */ diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Fri Feb 17 11:02:52 2012 -0800 @@ -521,8 +521,10 @@ @Override public void visitCheckCast(CheckCastNode x) { - XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); - emitXir(snippet, x, state(), true); + if (x.emitCode()) { + XirSnippet snippet = xir.genCheckCast(site(x), toXirArgument(x.object()), toXirArgument(x.targetClassInstruction()), x.targetClass(), x.hints(), x.hintsExact()); + emitXir(snippet, x, state(), true); + } // The result of a checkcast is the unmodified object, so no need to allocate a new variable for it. setResult(x, operand(x.object())); } diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Fri Feb 17 11:02:52 2012 -0800 @@ -178,8 +178,7 @@ AnchorNode anchor = graph.add(new AnchorNode()); assert invoke.predecessor() != null; - ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(type.getEncoding(Representation.ObjectHub), runtime, graph)); - CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, type, receiver)); + CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, anchor, type, receiver); invoke.callTarget().replaceFirstInput(receiver, checkCast); graph.addBeforeFixed(invoke.node(), objectClass); @@ -326,18 +325,10 @@ 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)); + CheckCastNode checkCast = createAnchoredReceiver(graph, runtime, node, commonType, receiver); invokeForInlining.callTarget().replaceFirstInput(receiver, checkCast); RiResolvedMethod concrete = concretes.get(i); @@ -347,6 +338,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; @@ -653,6 +659,13 @@ } } + private static CheckCastNode createAnchoredReceiver(StructuredGraph graph, GraalRuntime runtime, FixedNode anchor, RiResolvedType commonType, ValueNode receiver) { + // to avoid that floating reads on receiver fields float above the type check + ConstantNode typeConst = graph.unique(ConstantNode.forCiConstant(commonType.getEncoding(Representation.ObjectHub), runtime, graph)); + CheckCastNode checkCast = graph.unique(new CheckCastNode(anchor, typeConst, commonType, receiver, false)); + return checkCast; + } + private static void convertTypeToBranchProbabilities(double[] typeProbabilities, double notRecordedTypeProbability) { // avoid branches with 0.0/1.0 probability double total = Math.max(1E-10, notRecordedTypeProbability); diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Fri Feb 17 11:02:52 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); diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Fri Feb 17 11:02:52 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 diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypePrimitive.java Fri Feb 17 11:02:52 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"); } diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Fri Feb 17 11:02:52 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; diff -r a1780986a4fe -r 5a5c603f7e0f graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 17 19:24:53 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/java/CheckCastNode.java Fri Feb 17 11:02:52 2012 -0800 @@ -38,11 +38,16 @@ public final class CheckCastNode extends TypeCheckNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType { @Input protected final FixedNode anchor; + @Data protected final boolean emitCode; public FixedNode anchor() { return anchor; } + public boolean emitCode() { + return emitCode; + } + /** * Creates a new CheckCast instruction. * @@ -54,9 +59,18 @@ this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false); } + public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, boolean emitCode) { + this(anchor, targetClassInstruction, targetClass, object, EMPTY_HINTS, false, emitCode); + } + public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact) { + this(anchor, targetClassInstruction, targetClass, object, hints, hintsExact, true); + } + + private CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiResolvedType[] hints, boolean hintsExact, boolean emitCode) { super(targetClassInstruction, targetClass, object, hints, hintsExact, targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass)); this.anchor = anchor; + this.emitCode = emitCode; } @Override diff -r a1780986a4fe -r 5a5c603f7e0f src/share/tools/ProjectCreator/BuildConfig.java --- a/src/share/tools/ProjectCreator/BuildConfig.java Fri Feb 17 19:24:53 2012 +0100 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Fri Feb 17 11:02:52 2012 -0800 @@ -74,7 +74,7 @@ outDir = outDir.substring(0, lastDirectorySeparator); } - outDir += Util.sep + build + Util.sep + "bin"; + outDir += Util.sep + build + Util.sep + "jre" + Util.sep + "bin"; if (flavour.equals("graal")) { outDir += Util.sep + "graal"; } else if (flavour.equals("compiler1")) { diff -r a1780986a4fe -r 5a5c603f7e0f src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Feb 17 19:24:53 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Fri Feb 17 11:02:52 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() {