changeset 17404:b725292b8a11

Truffle: updated TruffleCallTargetProfiling
author Christian Humer <christian.humer@gmail.com>
date Thu, 09 Oct 2014 17:25:59 +0200
parents 79ac83ff7a99
children 04d6bb76cfb3
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterBasedCompilationPolicy.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInlining.java
diffstat 5 files changed, 81 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- 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<String, Object> getDebugProperties() {
         Map<String, Object> 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() {
--- 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) {
--- 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();
             }
--- 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<OptimizedCallTarget, Integer> 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<OptimizedCallTarget> sortedCallTargets = new ArrayList<>(callTargets.keySet());
-        Collections.sort(sortedCallTargets, new Comparator<OptimizedCallTarget>() {
+    private static int sumCalls(List<OptimizedCallTarget> targets, Function<TraceCompilationProfile, Integer> 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<OptimizedCallTarget, List<OptimizedCallTarget>> 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<OptimizedCallTarget> 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<OptimizedCallTarget> 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);
-    }
-
 }
--- 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<OptimizedCallTarget> 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;