# HG changeset patch # User Christian Humer # Date 1447952470 -3600 # Node ID 73fa2bf51eaac03a759337fd38ed6542d68d477f # Parent 2c730119cb92373523c2212c8fa19fce69df2fa0 Make OSR policy a lot less agressive (100000 executions); OSR counter is reset per interpreter call. diff -r 2c730119cb92 -r 73fa2bf51eaa 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 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++; diff -r 2c730119cb92 -r 73fa2bf51eaa graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java --- 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; } } diff -r 2c730119cb92 -r 73fa2bf51eaa graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- 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 TruffleOSR = new OptionValue<>(true); @Option(help = "Number of loop iterations until on-stack-replacement compilation is triggered.", type = OptionType.Debug) - public static final OptionValue TruffleOSRCompilationThreshold = new OptionValue<>(10000); + public static final OptionValue TruffleOSRCompilationThreshold = new OptionValue<>(100000); @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug) public static final OptionValue TruffleSplittingMaxCalleeSize = new OptionValue<>(100);