changeset 23032:73fa2bf51eaa

Make OSR policy a lot less agressive (100000 executions); OSR counter is reset per interpreter call.
author Christian Humer <christian.humer@oracle.com>
date Thu, 19 Nov 2015 18:01:10 +0100
parents 2c730119cb92
children 9751654cd23f 075e134c16ff
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java
diffstat 3 files changed, 62 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Thu Nov 19 18:01:10 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java	Thu Nov 19 18:01:10 2015 +0100
@@ -26,11 +26,13 @@
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleInvalidationReprofileCount;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleMinInvokeThreshold;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleReplaceReprofileCount;
+import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleOSRCompilationThreshold;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
 
 public class CompilationProfile {
+    private static final int RESET_OSR_VALUE = Integer.MAX_VALUE - TruffleOSRCompilationThreshold.getValue();
 
     /**
      * Number of times an installed code for this tree was invalidated.
@@ -43,11 +45,14 @@
     private int compilationCallThreshold;
     private int compilationCallAndLoopThreshold;
 
+    private int osrThreshold;
+
     private long timestamp;
 
     public CompilationProfile() {
         compilationCallThreshold = TruffleMinInvokeThreshold.getValue();
         compilationCallAndLoopThreshold = TruffleCompilationThreshold.getValue();
+        osrThreshold = RESET_OSR_VALUE;
     }
 
     @Override
@@ -109,7 +114,16 @@
         ensureProfiling(reprofile, reprofile);
     }
 
+    final void reportOSRCompiledLoop() {
+        osrThreshold = RESET_OSR_VALUE;
+    }
+
+    final void reportOSR() throws ArithmeticException {
+        osrThreshold = Math.incrementExact(osrThreshold);
+    }
+
     public void reportInterpreterCall() {
+        osrThreshold = RESET_OSR_VALUE;
         interpreterCallCount++;
         interpreterCallAndLoopCount++;
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java	Thu Nov 19 18:01:10 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java	Thu Nov 19 18:01:10 2015 +0100
@@ -34,12 +34,14 @@
 
 public final class OptimizedOSRLoopNode extends LoopNode implements ReplaceObserver {
 
-    private int interpreterLoopCount;
+    private CompilationProfile cachedProfile;
     private int lastLoopCount;
     private OptimizedCallTarget compiledTarget;
 
     @Child private RepeatingNode repeatableNode;
 
+    private boolean disabled;
+
     private OptimizedOSRLoopNode(RepeatingNode repeatableNode) {
         this.repeatableNode = repeatableNode;
     }
@@ -48,7 +50,6 @@
     public Node copy() {
         OptimizedOSRLoopNode copy = (OptimizedOSRLoopNode) super.copy();
         copy.compiledTarget = null;
-        copy.interpreterLoopCount = 0;
         return copy;
     }
 
@@ -80,23 +81,40 @@
     }
 
     private boolean profilingLoop(VirtualFrame frame) {
-        int osrThreshold = TruffleCompilerOptions.TruffleOSRCompilationThreshold.getValue();
-        int overflowLoopCount = Integer.MAX_VALUE - osrThreshold + interpreterLoopCount;
+        CompilationProfile profile = getProfile(getCallTarget());
+        int loopCount = 0;
+        boolean localDisabled = this.disabled;
         try {
             while (repeatableNode.executeRepeating(frame)) {
-                try {
-                    overflowLoopCount = Math.incrementExact(overflowLoopCount);
-                } catch (ArithmeticException e) {
-                    compileLoop(frame);
-                    return false;
+                loopCount++;
+                if (!localDisabled) {
+                    try {
+                        profile.reportOSR();
+                    } catch (ArithmeticException e) {
+                        compileLoop(frame);
+                        return false;
+                    }
                 }
             }
         } finally {
-            reportLoopCount(overflowLoopCount - Integer.MAX_VALUE + osrThreshold - interpreterLoopCount);
+            reportLoopCount(loopCount);
         }
         return true;
     }
 
+    private CompilationProfile getProfile(OptimizedCallTarget target) {
+        CompilationProfile profile = this.cachedProfile;
+        if (profile == null) {
+            profile = target.getCompilationProfile();
+            this.cachedProfile = profile;
+        }
+        return profile;
+    }
+
+    private OptimizedCallTarget getCallTarget() {
+        return (OptimizedCallTarget) getRootNode().getCallTarget();
+    }
+
     private boolean compilingLoop(VirtualFrame frame) {
         int iterations = 0;
         try {
@@ -118,7 +136,6 @@
                     invalidate(this, "OSR compilation failed or cancelled");
                     return false;
                 }
-                iterations++;
             } while (repeatableNode.executeRepeating(frame));
         } finally {
             reportLoopCount(iterations);
@@ -136,31 +153,36 @@
                  */
                 if (compiledTarget == null) {
                     compiledTarget = compileImpl(frame);
-                    if (compiledTarget == null) {
-                        interpreterLoopCount = 0;
-                    }
                 }
             }
         });
     }
 
     private OptimizedCallTarget compileImpl(VirtualFrame frame) {
-        Node parent = getParent();
-        OptimizedCallTarget target = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(new OSRRootNode(this));
-        // to avoid a deopt on first call we provide some profiling information
-        target.profileReturnType(Boolean.TRUE);
-        target.profileReturnType(Boolean.FALSE);
-        target.profileArguments(new Object[]{frame});
-        // let the old parent re-adopt the children
-        parent.adoptChildren();
-        target.compile();
-        return target;
+        OptimizedCallTarget parentTarget = getCallTarget();
+        CompilationProfile profile = getProfile(parentTarget);
+        profile.reportOSRCompiledLoop();
+
+        if (parentTarget.isValid() || parentTarget.isCompiling()) {
+            disabled = true;
+            return null;
+        } else {
+            Node parent = getParent();
+            OptimizedCallTarget osrTarget = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(new OSRRootNode(this));
+            // to avoid a deopt on first call we provide some profiling information
+            osrTarget.profileReturnType(Boolean.TRUE);
+            osrTarget.profileReturnType(Boolean.FALSE);
+            osrTarget.profileArguments(new Object[]{frame});
+            // let the old parent re-adopt the children
+            parent.adoptChildren();
+            osrTarget.compile();
+            return osrTarget;
+        }
     }
 
     private void reportLoopCount(int reportIterations) {
         if (reportIterations != 0) {
             lastLoopCount = reportIterations;
-            interpreterLoopCount += reportIterations;
             getRootNode().reportLoopCount(reportIterations);
         }
     }
@@ -175,7 +197,6 @@
         if (target != null) {
             target.invalidate(source, reason);
             compiledTarget = null;
-            interpreterLoopCount = 0;
         }
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Nov 19 18:01:10 2015 +0100
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Thu Nov 19 18:01:10 2015 +0100
@@ -96,7 +96,7 @@
     public static final OptionValue<Boolean> TruffleOSR = new OptionValue<>(true);
 
     @Option(help = "Number of loop iterations until on-stack-replacement compilation is triggered.", type = OptionType.Debug)
-    public static final OptionValue<Integer> TruffleOSRCompilationThreshold = new OptionValue<>(10000);
+    public static final OptionValue<Integer> TruffleOSRCompilationThreshold = new OptionValue<>(100000);
 
     @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug)
     public static final OptionValue<Integer> TruffleSplittingMaxCalleeSize = new OptionValue<>(100);