# HG changeset patch # User Christian Humer # Date 1412868359 -7200 # Node ID b725292b8a11106e86c275cab1999d8a620db240 # Parent 79ac83ff7a99b18704759e742cc1ba7767b17df4 Truffle: updated TruffleCallTargetProfiling diff -r 79ac83ff7a99 -r b725292b8a11 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Thu Oct 09 17:25:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Thu Oct 09 17:25:59 2014 +0200 @@ -40,31 +40,30 @@ private long previousTimestamp; - private int callCount; - private int callAndLoopCount; + private int interpreterCallCount; + private int interpreterCallAndLoopCount; private int compilationCallThreshold; private int compilationCallAndLoopThreshold; - private final int originalInvokeCounter; private final int originalCompilationThreshold; public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter) { this.previousTimestamp = System.nanoTime(); this.compilationCallThreshold = initialInvokeCounter; this.compilationCallAndLoopThreshold = compilationThreshold; - this.originalInvokeCounter = initialInvokeCounter; this.originalCompilationThreshold = compilationThreshold; } @Override public String toString() { - return String.format("CompilationProfile(callCount=%d/%d, callAndLoopCount=%d/%d)", callCount, compilationCallThreshold, callAndLoopCount, compilationCallAndLoopThreshold); + return String.format("CompilationProfile(callCount=%d/%d, callAndLoopCount=%d/%d)", interpreterCallCount, compilationCallThreshold, interpreterCallAndLoopCount, + compilationCallAndLoopThreshold); } public Map getDebugProperties() { Map properties = new LinkedHashMap<>(); - String callsThreshold = String.format("%7d/%5d", getCallCount(), getCompilationCallThreshold()); - String loopsThreshold = String.format("%7d/%5d", getCallAndLoopCount(), getCompilationCallAndLoopThreshold()); + String callsThreshold = String.format("%7d/%5d", getInterpreterCallCount(), getCompilationCallThreshold()); + String loopsThreshold = String.format("%7d/%5d", getInterpreterCallAndLoopCount(), getCompilationCallAndLoopThreshold()); String invalidationReplace = String.format("%5d/%5d", invalidationCount, nodeReplaceCount); properties.put("C/T", callsThreshold); properties.put("L/T", loopsThreshold); @@ -72,13 +71,6 @@ return properties; } - public void reset() { - callCount = 0; - callAndLoopCount = 0; - compilationCallAndLoopThreshold = originalCompilationThreshold; - compilationCallThreshold = originalInvokeCounter; - } - public long getPreviousTimestamp() { return previousTimestamp; } @@ -91,12 +83,12 @@ return nodeReplaceCount; } - public int getCallAndLoopCount() { - return callAndLoopCount; + public int getInterpreterCallAndLoopCount() { + return interpreterCallAndLoopCount; } - public int getCallCount() { - return callCount; + public int getInterpreterCallCount() { + return interpreterCallCount; } public int getCompilationCallAndLoopThreshold() { @@ -108,12 +100,12 @@ } void ensureProfiling(int calls, int callsAndLoop) { - int increaseCallAndLoopThreshold = callsAndLoop - (this.compilationCallAndLoopThreshold - this.callAndLoopCount); + int increaseCallAndLoopThreshold = callsAndLoop - (this.compilationCallAndLoopThreshold - this.interpreterCallAndLoopCount); if (increaseCallAndLoopThreshold > 0) { this.compilationCallAndLoopThreshold += increaseCallAndLoopThreshold; } - int increaseCallsThreshold = calls - (this.compilationCallThreshold - this.callCount); + int increaseCallsThreshold = calls - (this.compilationCallThreshold - this.interpreterCallCount); if (increaseCallsThreshold > 0) { this.compilationCallThreshold += increaseCallsThreshold; } @@ -131,24 +123,24 @@ } public void reportInterpreterCall() { - callCount++; - callAndLoopCount++; + interpreterCallCount++; + interpreterCallAndLoopCount++; } - void reportInlinedCall() { - callCount++; - callAndLoopCount++; - compilationCallThreshold++; - compilationCallAndLoopThreshold++; + public void reportDirectCall() { + } - void reportInterpreterCalls(int calls) { - this.callCount += calls; - this.callAndLoopCount += calls; + public void reportIndirectCall() { + + } + + public void reportInlinedCall() { + } void reportLoopCount(int count) { - callAndLoopCount += count; + interpreterCallAndLoopCount += count; } void reportNodeReplaced() { diff -r 79ac83ff7a99 -r b725292b8a11 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java Thu Oct 09 17:25:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java Thu Oct 09 17:25:59 2014 +0200 @@ -27,7 +27,7 @@ private boolean compilationFailed; public boolean shouldCompile(CompilationProfile profile) { - return !compilationFailed && profile.getCallCount() >= profile.getCompilationCallThreshold() && profile.getCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold(); + return !compilationFailed && profile.getInterpreterCallCount() >= profile.getCompilationCallThreshold() && profile.getInterpreterCallAndLoopCount() >= profile.getCompilationCallAndLoopThreshold(); } public void recordCompilationFailure(Throwable t) { diff -r 79ac83ff7a99 -r b725292b8a11 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 09 17:25:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 09 17:25:59 2014 +0200 @@ -49,7 +49,6 @@ protected final GraalTruffleRuntime runtime; private SpeculationLog speculationLog; - protected int callCount; protected boolean inliningPerformed; protected final CompilationProfile compilationProfile; protected final CompilationPolicy compilationPolicy; @@ -81,9 +80,10 @@ this.rootNode.adoptChildren(); this.rootNode.setCallTarget(this); this.compilationPolicy = compilationPolicy; - this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter); if (TruffleCallTargetProfiling.getValue()) { - registerCallTarget(this); + this.compilationProfile = new TraceCompilationProfile(compilationThreshold, invokeCounter); + } else { + this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter); } } @@ -121,6 +121,7 @@ @Override public Object call(Object... args) { + compilationProfile.reportIndirectCall(); if (profiledArgumentTypesAssumption != null && profiledArgumentTypesAssumption.isValid()) { CompilerDirectives.transferToInterpreterAndInvalidate(); profiledArgumentTypesAssumption.invalidate(); @@ -130,6 +131,7 @@ } public final Object callDirect(Object... args) { + compilationProfile.reportDirectCall(); profileArguments(args); Object result = doInvoke(args); Class klass = profiledReturnType; @@ -140,9 +142,7 @@ } public final Object callInlined(Object... arguments) { - if (CompilerDirectives.inInterpreter()) { - compilationProfile.reportInlinedCall(); - } + compilationProfile.reportInlinedCall(); VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), arguments); return callProxy(frame); } @@ -285,9 +285,6 @@ this.runtime.reinstallStubs(); } else { compilationProfile.reportInterpreterCall(); - if (TruffleCallTargetProfiling.getValue()) { - callCount++; - } if (compilationPolicy.shouldCompile(compilationProfile)) { compile(); } diff -r 79ac83ff7a99 -r b725292b8a11 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Thu Oct 09 17:25:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Thu Oct 09 17:25:59 2014 +0200 @@ -26,20 +26,20 @@ import java.io.*; import java.util.*; +import java.util.function.*; +import java.util.stream.*; import com.oracle.graal.debug.*; import com.oracle.graal.truffle.TruffleInlining.CallTreeNodeVisitor; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; public final class OptimizedCallTargetLog { protected static final PrintStream OUT = TTY.out().out(); - private static Map callTargets; static { if (TruffleCallTargetProfiling.getValue()) { - callTargets = new WeakHashMap<>(); - Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -250,42 +250,59 @@ OUT.println(sb.toString()); } - private static void printProfiling() { - List sortedCallTargets = new ArrayList<>(callTargets.keySet()); - Collections.sort(sortedCallTargets, new Comparator() { + private static int sumCalls(List targets, Function function) { + return targets.stream().collect(Collectors.summingInt(target -> function.apply((TraceCompilationProfile) target.getCompilationProfile()))); + } - @Override - public int compare(OptimizedCallTarget o1, OptimizedCallTarget o2) { - return o2.callCount - o1.callCount; + private static void printProfiling() { + Map> groupedTargets = Truffle.getRuntime().getCallTargets().stream()// + .map(target -> (OptimizedCallTarget) target)// + .collect(Collectors.groupingBy(target -> { + if (target.getSplitSource() != null) { + return target.getSplitSource(); } - }); + return target; + })); - int totalCallCount = 0; - int totalInlinedCallSiteCount = 0; - int totalNodeCount = 0; + List uniqueSortedTargets = groupedTargets.keySet().stream()// + .sorted((target1, target2) -> sumCalls(groupedTargets.get(target2), p -> p.getTotalCallCount()) - sumCalls(groupedTargets.get(target1), p -> p.getTotalCallCount()))// + .collect(Collectors.toList()); + + int totalDirectCallCount = 0; + int totalInlinedCallCount = 0; + int totalIndirectCallCount = 0; + int totalTotalCallCount = 0; + int totalInterpretedCallCount = 0; int totalInvalidationCount = 0; OUT.println(); - OUT.printf("%-50s | %-10s | %s / %s | %s | %s\n", "Call Target", "Call Count", "Calls Sites Inlined", "Not Inlined", "Node Count", "Inv"); - for (OptimizedCallTarget callTarget : sortedCallTargets) { - if (callTarget.callCount == 0) { - continue; + OUT.printf(" %-50s | %-15s || %-15s | %-15s || %-15s | %-15s | %-15s || %3s \n", "Call Target", "Total Calls", "Interp. Calls", "Opt. Calls", "Direct Calls", "Inlined Calls", + "Indirect Calls", "Invalidations"); + for (OptimizedCallTarget uniqueCallTarget : uniqueSortedTargets) { + List allCallTargets = groupedTargets.get(uniqueCallTarget); + int directCallCount = sumCalls(allCallTargets, p -> p.getDirectCallCount()); + int indirectCallCount = sumCalls(allCallTargets, p -> p.getIndirectCallCount()); + int inlinedCallCount = sumCalls(allCallTargets, p -> p.getInlinedCallCount()); + int interpreterCallCount = sumCalls(allCallTargets, p -> p.getInterpreterCallCount()); + int totalCallCount = sumCalls(allCallTargets, p -> p.getTotalCallCount()); + int invalidationCount = allCallTargets.stream().collect(Collectors.summingInt(target -> target.getCompilationProfile().getInvalidationCount())); + + totalDirectCallCount += directCallCount; + totalInlinedCallCount += inlinedCallCount; + totalIndirectCallCount += indirectCallCount; + totalInvalidationCount += invalidationCount; + totalInterpretedCallCount += interpreterCallCount; + totalTotalCallCount += totalCallCount; + + if (totalCallCount > 0) { + OUT.printf(" %-50s | %15d || %15d | %15d || %15d | %15d | %15d || %3d\n", uniqueCallTarget, totalCallCount, interpreterCallCount, totalCallCount - interpreterCallCount, + directCallCount, inlinedCallCount, indirectCallCount, invalidationCount); } - int nodeCount = OptimizedCallUtils.countNonTrivialNodes(callTarget, true); - String comment = callTarget.isValid() ? "" : " int"; - OUT.printf("%-50s | %10d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, nodeCount, nodeCount, callTarget.getCompilationProfile().getInvalidationCount(), comment); + } - totalCallCount += callTarget.callCount; - totalInlinedCallSiteCount += nodeCount; - totalNodeCount += nodeCount; - totalInvalidationCount += callTarget.getCompilationProfile().getInvalidationCount(); - } - OUT.printf("%-50s | %10d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNodeCount, totalInvalidationCount); + OUT.printf(" %-50s | %15d || %15d | %15d || %15d | %15d | %15d || %3d\n", "Total", totalTotalCallCount, totalInterpretedCallCount, totalTotalCallCount - totalInterpretedCallCount, + totalDirectCallCount, totalInlinedCallCount, totalIndirectCallCount, totalInvalidationCount); + } - - public static void registerCallTarget(OptimizedCallTarget callTarget) { - callTargets.put(callTarget, 0); - } - } diff -r 79ac83ff7a99 -r b725292b8a11 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Thu Oct 09 17:25:59 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java Thu Oct 09 17:25:59 2014 +0200 @@ -94,7 +94,7 @@ } private static double calculateFrequency(OptimizedCallTarget target, OptimizedDirectCallNode ocn) { - return (double) Math.max(1, ocn.getCallCount()) / (double) Math.max(1, target.getCompilationProfile().getCallCount()); + return (double) Math.max(1, ocn.getCallCount()) / (double) Math.max(1, target.getCompilationProfile().getInterpreterCallCount()); } private static boolean isRecursiveStack(List stack) { @@ -291,8 +291,8 @@ if (iterable.hasNext()) { return iterable; } else { - iteratorStack.remove(--tos); - inliningDecisionStack.remove(--tos); + iteratorStack.remove(tos); + inliningDecisionStack.remove(tos--); } } return null;