# HG changeset patch # User Peter Hofer # Date 1312199125 -7200 # Node ID 8cd198d7cbc164e55664181d8ceae0adba2aa78d # Parent be4ca325525a02339d7ad318f40210c6d382971e When a method that has been compiled before is considered for inlining, use its compiled (native) code size for size checks. This avoids inlining compiled methods that already contain many other inlined methods, reducing generated code size and usually execution time as well. Also, add GraalMetrics bookkeeping for inlining. diff -r be4ca325525a -r 8cd198d7cbc1 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalMetrics.java Mon Aug 01 13:45:25 2011 +0200 @@ -41,6 +41,10 @@ public static int InlinedFinalizerChecks; public static int InlineForcedMethods; public static int InlineForbiddenMethods; + public static int InlineConsidered; + public static int InlinePerformed; + public static int InlineUncompiledConsidered; + public static int InlineUncompiledPerformed; public static int BlocksDeleted; public static int BytecodesCompiled; public static int CodeBytesEmitted; diff -r be4ca325525a -r 8cd198d7cbc1 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 Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Mon Aug 01 13:45:25 2011 +0200 @@ -46,9 +46,12 @@ public static int MaximumInstructionCount = 3000; public static float MaximumInlineRatio = 0.90f; public static int MaximumInlineSize = 35; + public static int MaximumInlineCompSize = 350; public static int MaximumFreqInlineSize = 200; + public static int MaximumFreqInlineCompSize = 1500; public static int FreqInlineRatio = 20; public static int MaximumTrivialSize = 6; + public static int MaximumTrivialCompSize = 120; public static int MaximumInlineLevel = 9; public static int MaximumRecursiveInlineLevel = 2; public static int MaximumDesiredSize = 8000; diff -r be4ca325525a -r 8cd198d7cbc1 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 Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Mon Aug 01 13:45:25 2011 +0200 @@ -83,6 +83,13 @@ newInvokes = new ArrayDeque(); for (Invoke invoke : queue) { if (!invoke.isDeleted()) { + if (GraalOptions.Meter) { + GraalMetrics.InlineConsidered++; + if (!invoke.target.hasCompiledCode()) { + GraalMetrics.InlineUncompiledConsidered++; + } + } + RiMethod code = inlineInvoke(invoke, iterations, ratio); if (code != null) { if (graph.getNodeCount() > GraalOptions.MaximumInstructionCount) { @@ -97,6 +104,12 @@ methodCount.put(code, methodCount.get(code) + 1); } } + if (GraalOptions.Meter) { + GraalMetrics.InlinePerformed++; + if (!invoke.target.hasCompiledCode()) { + GraalMetrics.InlineUncompiledPerformed++; + } + } } } } @@ -303,6 +316,7 @@ private boolean checkSizeConditions(RiMethod caller, int iterations, RiMethod method, Invoke invoke, RiTypeProfile profile, float adjustedRatio) { int maximumSize = GraalOptions.MaximumTrivialSize; + int maximumCompiledSize = GraalOptions.MaximumTrivialCompSize; double ratio = 0; if (profile != null && profile.count > 0) { RiMethod parent = invoke.stateAfter().method(); @@ -313,16 +327,27 @@ } if (ratio >= GraalOptions.FreqInlineRatio) { maximumSize = GraalOptions.MaximumFreqInlineSize; + maximumCompiledSize = GraalOptions.MaximumFreqInlineCompSize; } else if (ratio >= 1 * (1 - adjustedRatio)) { maximumSize = GraalOptions.MaximumInlineSize; + maximumCompiledSize = GraalOptions.MaximumInlineCompSize; } } if (hints != null && hints.contains(invoke)) { maximumSize = GraalOptions.MaximumFreqInlineSize; + maximumCompiledSize = GraalOptions.MaximumFreqInlineCompSize; } - if (method.codeSize() > maximumSize || iterations >= GraalOptions.MaximumInlineLevel || (method == compilation.method && iterations > GraalOptions.MaximumRecursiveInlineLevel)) { + boolean oversize; + int compiledSize = method.compiledCodeSize(); + if (compiledSize < 0) { + oversize = (method.codeSize() > maximumSize); + } else { + oversize = (compiledSize > maximumCompiledSize); + } + if (oversize || iterations >= GraalOptions.MaximumInlineLevel || (method == compilation.method && iterations > GraalOptions.MaximumRecursiveInlineLevel)) { if (GraalOptions.TraceInlining) { - TTY.println("not inlining %s because of code size (size: %d, max size: %d, ratio %5.3f, %s) or inling level", methodName(method, invoke), method.codeSize(), maximumSize, ratio, profile); + TTY.println("not inlining %s because of size (bytecode: %d, bytecode max: %d, compiled: %d, compiled max: %d, ratio %5.3f, %s) or inlining level", + methodName(method, invoke), method.codeSize(), maximumSize, compiledSize, maximumCompiledSize, ratio, profile); } if (GraalOptions.Extend) { boolean newResult = overrideInliningDecision(iterations, caller, invoke.bci, method, false); diff -r be4ca325525a -r 8cd198d7cbc1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Mon Aug 01 13:45:25 2011 +0200 @@ -170,9 +170,7 @@ } public boolean hasCompiledCode() { - // TODO: needs a VMEntries to go cache the result of that method. - // This isn't used by GRAAL for now, so this is enough.throwoutCount - return false; + return compiler.getVMEntries().RiMethod_hasCompiledCode(this); } @Override @@ -210,6 +208,11 @@ return compiler.getVMEntries().RiMethod_switchProbability(this, bci); } + @Override + public int compiledCodeSize() { + return compiler.getVMEntries().RiMethod_compiledCodeSize(this); + } + public void dumpProfile() { TTY.println("profile info for %s", this); TTY.println("canBeStaticallyBound: " + canBeStaticallyBound()); diff -r be4ca325525a -r 8cd198d7cbc1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodUnresolved.java Mon Aug 01 13:45:25 2011 +0200 @@ -181,4 +181,9 @@ public double[] switchProbability(int bci) { return null; } + + @Override + public int compiledCodeSize() { + return -1; + } } diff -r be4ca325525a -r 8cd198d7cbc1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntries.java Mon Aug 01 13:45:25 2011 +0200 @@ -101,5 +101,9 @@ RiField[] RiType_fields(HotSpotTypeResolved klass); + boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); + + int RiMethod_compiledCodeSize(HotSpotMethodResolved method); + // Checkstyle: resume } diff -r be4ca325525a -r 8cd198d7cbc1 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java Wed Jul 27 17:32:44 2011 -0700 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/VMEntriesNative.java Mon Aug 01 13:45:25 2011 +0200 @@ -147,5 +147,11 @@ @Override public native RiField[] RiType_fields(HotSpotTypeResolved klass); + @Override + public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); + + @Override + public native int RiMethod_compiledCodeSize(HotSpotMethodResolved method); + // Checkstyle: resume } diff -r be4ca325525a -r 8cd198d7cbc1 src/share/vm/graal/graalVMEntries.cpp --- a/src/share/vm/graal/graalVMEntries.cpp Wed Jul 27 17:32:44 2011 -0700 +++ b/src/share/vm/graal/graalVMEntries.cpp Mon Aug 01 13:45:25 2011 +0200 @@ -183,7 +183,7 @@ return method->invocation_count(); } -// public native int RiMethod_throwoutCount(long vmId); +// public native int RiMethod_exceptionProbability(long vmId, int bci); JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_2exceptionProbability(JNIEnv *, jobject, jobject hotspot_method, jint bci) { TRACE_graal_3("VMEntries::RiMethod_exceptionProbability"); ciMethod* cimethod; @@ -337,6 +337,23 @@ } } +// public native boolean RiMethod_hasCompiledCode(HotSpotMethodResolved method); +JNIEXPORT jboolean JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasCompiledCode(JNIEnv *, jobject, jobject hotspot_method) { + TRACE_graal_3("VMEntries::RiMethod_hasCompiledCode"); + methodOop method = getMethodFromHotSpotMethod(hotspot_method); + return method->has_compiled_code(); +} + +// public native boolean RiMethod_compiledCodeSize(HotSpotMethodResolved method); +JNIEXPORT jint JNICALL Java_com_oracle_graal_runtime_VMEntries_RiMethod_1compiledCodeSize(JNIEnv *, jobject, jobject hotspot_method) { + TRACE_graal_3("VMEntries::RiMethod_compiledCodeSize"); + nmethod* code = getMethodFromHotSpotMethod(hotspot_method)->code(); + if (code != NULL) { + return code->insts_end() - code->verified_entry_point(); + } + return -1; +} + // public RiType RiSignature_lookupType(String returnType, HotSpotTypeResolved accessingClass); JNIEXPORT jobject JNICALL Java_com_oracle_graal_runtime_VMEntries_RiSignature_1lookupType(JNIEnv *env, jobject, jstring jname, jobject accessingClass) { TRACE_graal_3("VMEntries::RiSignature_lookupType"); @@ -901,6 +918,8 @@ {CC"RiMethod_switchProbability", CC"("RESOLVED_METHOD"I)[D", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_2switchProbability)}, {CC"RiMethod_invocationCount", CC"("RESOLVED_METHOD")I", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1invocationCount)}, {CC"RiMethod_exceptionProbability", CC"("RESOLVED_METHOD"I)I", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_2exceptionProbability)}, + {CC"RiMethod_hasCompiledCode", CC"("RESOLVED_METHOD")Z", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1hasCompiledCode)}, + {CC"RiMethod_compiledCodeSize", CC"("RESOLVED_METHOD")I", FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiMethod_1compiledCodeSize)}, {CC"RiSignature_lookupType", CC"("STRING RESOLVED_TYPE")"TYPE, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiSignature_1lookupType)}, {CC"RiConstantPool_lookupConstant", CC"("PROXY"I)"OBJECT, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupConstant)}, {CC"RiConstantPool_lookupMethod", CC"("PROXY"IB)"METHOD, FN_PTR(Java_com_oracle_graal_runtime_VMEntries_RiConstantPool_1lookupMethod)},