# HG changeset patch # User Christian Haeubl # Date 1328668669 28800 # Node ID e6e14d25e60854dfdb61bb5608f8d0313cb45827 # Parent a0cca63cd366f0a107c168e8e4b375e235217625 added two inlining policies for comparison diff -r a0cca63cd366 -r e6e14d25e608 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiResolvedMethod.java Tue Feb 07 18:37:49 2012 -0800 @@ -49,6 +49,12 @@ int codeSize(); /** + * Gets the size of the compiled machine code. + * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists. + */ + int compiledCodeSize(); + + /** * Gets the symbol used to link this method if it is native, otherwise {@code null}. */ String jniSymbol(); diff -r a0cca63cd366 -r e6e14d25e608 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Tue Feb 07 18:37:49 2012 -0800 @@ -44,18 +44,23 @@ public static boolean CacheGraphs = ____; public static boolean InlineMonomorphicCalls = true; public static boolean InlinePolymorphicCalls = true; + public static boolean InlineMegamorphicCalls = true; public static int InliningPolicy = 0; - public static int MaximumInlineSize = 35; - public static int MaximumFreqInlineSize = 300; - public static float NestedInliningSizeRatio = 0.9f; - public static int FreqInlineRatio = 20; public static int MaximumTrivialSize = 6; - public static int MaximumInlineLevel = 30; + public static int MaximumInlineLevel = 9; public static int MaximumDesiredSize = 6000; + // WeightBasedInliningPolicy (0) public static boolean ParseBeforeInlining = ____; public static float InliningSizePenaltyExp = 20; public static float MaximumInlineWeight = 1.25f; public static float InliningSizePenalty = 1; + // StaticSizeBasedInliningPolicy (1), DynamicSizeBasedInliningPolicy (2), GreedySizeBasedInlining (3) + public static int MaximumInlineSize = 35; + public static float NestedInliningSizeRatio = 0.9f; + public static float BoostInliningForEscapeAnalysis = 2f; + public static float ProbabilityCapForInlining = 1f; + public static int MaximumGreedyInlineSize = 250; + public static int SmallCompiledCodeSize = 1500; // escape analysis settings public static boolean EscapeAnalysis = true; diff -r a0cca63cd366 -r e6e14d25e608 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Tue Feb 07 18:37:49 2012 -0800 @@ -191,7 +191,11 @@ if (GraalOptions.InliningPolicy == 0) { return new WeightBasedInliningPolicy(); } else if (GraalOptions.InliningPolicy == 1) { - return new SizeBasedInliningPolicy(); + return new StaticSizeBasedInliningPolicy(); + } else if (GraalOptions.InliningPolicy == 2) { + return new DynamicSizeBasedInliningPolicy(); + } else if (GraalOptions.InliningPolicy == 3) { + return new GreedySizeBasedInliningPolicy(); } else { Util.shouldNotReachHere(); return null; @@ -272,14 +276,14 @@ } } - private class SizeBasedInliningPolicy implements InliningPolicy { + private class StaticSizeBasedInliningPolicy implements InliningPolicy { @Override public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { + double codeSize = method.codeSize(); if (preferredInvoke) { - return method.codeSize() / 2; - } else { - return method.codeSize(); + codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; } + return codeSize; } @Override @@ -288,4 +292,51 @@ return info.weight <= maxSize; } } + + private class DynamicSizeBasedInliningPolicy implements InliningPolicy { + @Override + public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { + double codeSize = method.codeSize(); + if (preferredInvoke) { + codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; + } + return codeSize; + } + + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + assert GraalOptions.ProbabilityAnalysis; + if (info.compiledCodeSize() <= GraalOptions.SmallCompiledCodeSize) { + double inlineBoost = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); + double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumInlineSize; + maxSize = maxSize + maxSize * inlineBoost; + maxSize = Math.max(GraalOptions.MaximumTrivialSize, maxSize); + return info.weight <= maxSize; + } + return false; + } + } + + private class GreedySizeBasedInliningPolicy implements InliningPolicy { + @Override + public double computeWeight(RiResolvedMethod caller, RiResolvedMethod method, Invoke invoke, boolean preferredInvoke) { + double codeSize = method.codeSize(); + if (preferredInvoke) { + codeSize = codeSize / GraalOptions.BoostInliningForEscapeAnalysis; + } + return codeSize; + } + + @Override + public boolean isWorthInlining(StructuredGraph callerGraph, InlineInfo info) { + assert GraalOptions.ProbabilityAnalysis; + if (info.compiledCodeSize() <= GraalOptions.SmallCompiledCodeSize) { + double inlineRatio = Math.min(GraalOptions.ProbabilityCapForInlining, info.invoke.probability()); + double maxSize = Math.pow(GraalOptions.NestedInliningSizeRatio, info.level) * GraalOptions.MaximumGreedyInlineSize * inlineRatio; + maxSize = Math.max(maxSize, GraalOptions.MaximumInlineSize); + return info.weight <= maxSize; + } + return false; + } + } } diff -r a0cca63cd366 -r e6e14d25e608 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 Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Tue Feb 07 18:37:49 2012 -0800 @@ -82,6 +82,8 @@ this.level = level; } + public abstract int compiledCodeSize(); + @Override public int compareTo(InlineInfo o) { return (weight < o.weight) ? -1 : (weight > o.weight) ? 1 : 0; @@ -128,6 +130,11 @@ } @Override + public int compiledCodeSize() { + return concrete.compiledCodeSize(); + } + + @Override public String toString() { return "exact inlining " + CiUtil.format("%H.%n(%p):%r", concrete); } @@ -153,6 +160,11 @@ } @Override + public int compiledCodeSize() { + return concrete.compiledCodeSize(); + } + + @Override public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) { // receiver null check must be before the type check InliningUtil.receiverNullCheck(invoke); @@ -206,6 +218,15 @@ } @Override + public int compiledCodeSize() { + int result = 0; + for (RiResolvedMethod m: concretes) { + result += m.compiledCodeSize(); + } + return result; + } + + @Override public void inline(StructuredGraph graph, GraalRuntime runtime, InliningCallback callback) { int numberOfMethods = concretes.size(); boolean hasReturnValue = invoke.node().kind() != CiKind.Void; @@ -401,7 +422,7 @@ @Override public String toString() { - StringBuilder builder = new StringBuilder(String.format("type-checked inlining of %d methods with %d type checks: ", concretes.size(), types.length)); + StringBuilder builder = new StringBuilder(String.format("inlining %d methods with %d type checks: ", concretes.size(), types.length)); for (int i = 0; i < concretes.size(); i++) { builder.append(CiUtil.format(" %H.%n(%p):%r", concretes.get(i))); } @@ -530,7 +551,7 @@ return null; } } else { - if (GraalOptions.InlinePolymorphicCalls) { + if (GraalOptions.InlinePolymorphicCalls && notRecordedTypeProbability == 0 || GraalOptions.InlineMegamorphicCalls && notRecordedTypeProbability > 0) { // TODO (ch) inlining of multiple methods should work differently // 1. check which methods can be inlined // 2. for those methods, use weight and probability to compute which of them should be inlined diff -r a0cca63cd366 -r e6e14d25e608 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 Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVM.java Tue Feb 07 18:37:49 2012 -0800 @@ -99,6 +99,8 @@ boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); + int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method); + RiMethod getRiMethod(Method reflectionMethod); long getMaxCallTargetOffset(CiRuntimeCall rtcall); diff -r a0cca63cd366 -r e6e14d25e608 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 Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/bridge/CompilerToVMImpl.java Tue Feb 07 18:37:49 2012 -0800 @@ -145,6 +145,9 @@ public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); @Override + public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method); + + @Override public native long getMaxCallTargetOffset(CiRuntimeCall rtcall); @Override diff -r a0cca63cd366 -r e6e14d25e608 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Tue Feb 07 18:37:49 2012 -0800 @@ -178,6 +178,10 @@ return compiler.getVMEntries().RiMethod_hasCompiledCode(this); } + public int compiledCodeSize() { + return compiler.getVMEntries().RiMethod_getCompiledCodeSize(this); + } + @Override public RiResolvedType accessor() { return null; diff -r a0cca63cd366 -r e6e14d25e608 graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Tue Feb 07 12:09:11 2012 -0800 +++ b/graal/com.oracle.max.graal.hotspot/src/com/oracle/max/graal/hotspot/ri/HotSpotXirGenerator.java Tue Feb 07 18:37:49 2012 -0800 @@ -1185,7 +1185,7 @@ } asm.mov(checkHub, hub); - // if we get an exact match: continue + // if we get an exact match: continue. asm.jneq(falseSucc, objHub, checkHub); return asm.finishTemplate(objHub, "typeCheck"); diff -r a0cca63cd366 -r e6e14d25e608 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 07 12:09:11 2012 -0800 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Feb 07 18:37:49 2012 -0800 @@ -239,6 +239,13 @@ return getMethodFromHotSpotMethod(hotspot_method)->has_compiled_code(); } +// public native int RiMethod_getCompiledCodeSize(HotSpotMethodResolved method); +JNIEXPORT jint JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiMethod_1getCompiledCodeSize(JNIEnv *env, jobject, jobject hotspot_method) { + TRACE_graal_3("CompilerToVM::RiMethod_getCompiledCodeSize"); + nmethod* code = getMethodFromHotSpotMethod(hotspot_method)->code(); + return code == NULL ? 0 : code->insts_size(); +} + // public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); JNIEXPORT jobject JNICALL Java_com_oracle_max_graal_hotspot_bridge_CompilerToVMImpl_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass) { TRACE_graal_3("CompilerToVM::RiSignature_lookupType"); @@ -935,6 +942,7 @@ {CC"HotSpotMethodData_isMature", CC"("METHOD_DATA")Z", FN_PTR(HotSpotMethodData_1isMature)}, {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")"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)},