# HG changeset patch # User Christian Humer # Date 1383837666 -3600 # Node ID d2d0c44662bb8b5da961d559264d280a14fd50be # Parent 85bab2227295dc92446134dc616ec3357871062b Truffle: refactored CompilationProfile to separate the profile and the policy in separate classes. diff -r 85bab2227295 -r d2d0c44662bb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java Thu Nov 07 15:10:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java Thu Nov 07 16:21:06 2013 +0100 @@ -22,96 +22,8 @@ */ package com.oracle.graal.truffle; -import static com.oracle.graal.truffle.TruffleCompilerOptions.*; - -public class CompilationPolicy { - - private int invokeCounter; - private int originalInvokeCounter; - private int loopAndInvokeCounter; - private long prevTimestamp; - - private final int compilationThreshold; - private final String name; - - public CompilationPolicy(final int compilationThreshold, final int initialInvokeCounter, final String name) { - this.invokeCounter = initialInvokeCounter; - this.loopAndInvokeCounter = compilationThreshold; - this.originalInvokeCounter = compilationThreshold; - this.prevTimestamp = System.nanoTime(); - - this.compilationThreshold = compilationThreshold; - this.name = name; - } - - public String getName() { - return this.name; - } - - public int getInvokeCounter() { - return invokeCounter; - } - - public int getOriginalInvokeCounter() { - return originalInvokeCounter; - } - - public int getLoopAndInvokeCounter() { - return loopAndInvokeCounter; - } - - public void reportCompilationInvalidated() { - int invalidationReprofileCount = TruffleInvalidationReprofileCount.getValue(); - invokeCounter = invalidationReprofileCount; - if (TruffleFunctionInlining.getValue()) { - originalInvokeCounter += invalidationReprofileCount; - } - } +public interface CompilationPolicy { - public void reportInterpreterCall() { - invokeCounter--; - loopAndInvokeCounter--; - } - - public void reportCallInlined(int minInvokesAfterInlining) { - invokeCounter = minInvokesAfterInlining; - int inliningReprofileCount = TruffleInliningReprofileCount.getValue(); - loopAndInvokeCounter = inliningReprofileCount; - originalInvokeCounter = inliningReprofileCount; - } - - public void reportLoopCount(int count) { - loopAndInvokeCounter = Math.max(0, loopAndInvokeCounter - count); - } - - public void notifyNodeReplaced() { - // delay compilation until tree is deemed stable enough - int replaceBackoff = TruffleReplaceReprofileCount.getValue(); - if (loopAndInvokeCounter < replaceBackoff) { - loopAndInvokeCounter = replaceBackoff; - } - } + boolean shouldCompile(CompilationProfile profile); - public boolean shouldCompileOrInline() { - if (invokeCounter <= 0 && loopAndInvokeCounter <= 0) { - if (TruffleUseTimeForCompilationDecision.getValue()) { - long timestamp = System.nanoTime(); - long timespan = (timestamp - prevTimestamp); - if (timespan < (TruffleCompilationDecisionTime.getValue())) { - return true; - } - this.loopAndInvokeCounter = compilationThreshold; - this.originalInvokeCounter = compilationThreshold; - this.prevTimestamp = timestamp; - if (TruffleCompilationDecisionTimePrintFail.getValue()) { - // Checkstyle: stop - System.out.println(name + ": timespan " + (timespan / 1000000) + " ms larger than threshold"); - // Checkstyle: resume - } - } else { - return true; - } - } - return false; - } } diff -r 85bab2227295 -r d2d0c44662bb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Thu Nov 07 16:21:06 2013 +0100 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle; + +import static com.oracle.graal.truffle.TruffleCompilerOptions.*; + +public class CompilationProfile { + + private static final int MIN_INVOKES_AFTER_INLINING = 2; + + private int invokeCounter; + private int originalInvokeCounter; + private int loopAndInvokeCounter; + /** + * Number of times an installed code for this tree was invalidated. + */ + private int invalidationCount; + + /** + * Number of times a node was replaced in this tree. + */ + private int nodeReplaceCount; + + private long previousTimestamp; + + private final int compilationThreshold; + private final String name; + + public CompilationProfile(final int compilationThreshold, final int initialInvokeCounter, final String name) { + this.invokeCounter = initialInvokeCounter; + this.loopAndInvokeCounter = compilationThreshold; + this.originalInvokeCounter = compilationThreshold; + this.previousTimestamp = System.nanoTime(); + + this.compilationThreshold = compilationThreshold; + this.name = name; + } + + public long getPreviousTimestamp() { + return previousTimestamp; + } + + public String getName() { + return this.name; + } + + public int getInvalidationCount() { + return invalidationCount; + } + + public int getNodeReplaceCount() { + return nodeReplaceCount; + } + + public int getInvokeCounter() { + return invokeCounter; + } + + public int getOriginalInvokeCounter() { + return originalInvokeCounter; + } + + public int getLoopAndInvokeCounter() { + return loopAndInvokeCounter; + } + + void reportTiminingFailed(long timestamp) { + this.loopAndInvokeCounter = compilationThreshold; + this.originalInvokeCounter = compilationThreshold; + this.previousTimestamp = timestamp; + } + + void reportInvalidated() { + invalidationCount++; + int invalidationReprofileCount = TruffleInvalidationReprofileCount.getValue(); + invokeCounter = invalidationReprofileCount; + if (TruffleFunctionInlining.getValue()) { + originalInvokeCounter += invalidationReprofileCount; + } + } + + void reportInterpreterCall() { + invokeCounter--; + loopAndInvokeCounter--; + } + + void reportInliningPerformed() { + invokeCounter = MIN_INVOKES_AFTER_INLINING; + int inliningReprofileCount = TruffleInliningReprofileCount.getValue(); + loopAndInvokeCounter = inliningReprofileCount; + originalInvokeCounter = inliningReprofileCount; + } + + void reportLoopCount(int count) { + loopAndInvokeCounter = Math.max(0, loopAndInvokeCounter - count); + } + + void reportNodeReplaced() { + nodeReplaceCount++; + // delay compilation until tree is deemed stable enough + int replaceBackoff = TruffleReplaceReprofileCount.getValue(); + if (loopAndInvokeCounter < replaceBackoff) { + loopAndInvokeCounter = replaceBackoff; + } + } + +} diff -r 85bab2227295 -r d2d0c44662bb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultCompilationPolicy.java Thu Nov 07 16:21:06 2013 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle; + +public class DefaultCompilationPolicy implements CompilationPolicy { + + public boolean shouldCompile(CompilationProfile profile) { + return profile.getInvokeCounter() <= 0 && profile.getLoopAndInvokeCounter() <= 0; + } + +} diff -r 85bab2227295 -r d2d0c44662bb 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 Nov 07 15:10:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Nov 07 16:21:06 2013 +0100 @@ -41,45 +41,41 @@ public final class OptimizedCallTarget extends DefaultCallTarget implements FrameFactory, LoopCountReceiver, ReplaceObserver { private static final PrintStream OUT = TTY.out().out(); - private static final int MIN_INVOKES_AFTER_INLINING = 2; + + private InstalledCode installedCode; + private Future installedCodeTask; + private final TruffleCompiler compiler; + private final CompilationProfile compilationProfile; + private final CompilationPolicy compilationPolicy; + private final TruffleInlining inlining; + private boolean disableCompilation; + private int callCount; protected OptimizedCallTarget(RootNode rootNode, FrameDescriptor descriptor, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) { super(rootNode, descriptor); this.compiler = compiler; - this.compilationPolicy = new CompilationPolicy(compilationThreshold, invokeCounter, rootNode.toString()); + this.compilationProfile = new CompilationProfile(compilationThreshold, invokeCounter, rootNode.toString()); this.inlining = new TruffleInliningImpl(); this.rootNode.setCallTarget(this); + if (TruffleUseTimeForCompilationDecision.getValue()) { + compilationPolicy = new TimedCompilationPolicy(); + } else { + compilationPolicy = new DefaultCompilationPolicy(); + } + if (TruffleCallTargetProfiling.getValue()) { registerCallTarget(this); } } - private InstalledCode installedCode; - private Future installedCodeTask; - private final TruffleCompiler compiler; - private final CompilationPolicy compilationPolicy; - private final TruffleInlining inlining; - private boolean disableCompilation; - private int callCount; - - /** - * Number of times an installed code for this tree was invalidated. - */ - private int invalidationCount; - - /** - * Number of times a node was replaced in this tree. - */ - private int nodeReplaceCount; - @Override public Object call(PackedFrame caller, Arguments args) { return callHelper(caller, args); } - CompilationPolicy getCompilationPolicy() { - return compilationPolicy; + public CompilationProfile getCompilationProfile() { + return compilationProfile; } private Object callHelper(PackedFrame caller, Arguments args) { @@ -115,10 +111,10 @@ if (m != null) { CompilerAsserts.neverPartOfCompilation(); installedCode = null; - invalidationCount++; - compilationPolicy.reportCompilationInvalidated(); + compilationProfile.reportInvalidated(); if (TraceTruffleCompilation.getValue()) { - OUT.printf("[truffle] invalidated %-48s |Inv# %d |Replace# %d\n", rootNode, invalidationCount, nodeReplaceCount); + OUT.printf("[truffle] invalidated %-48s |Inv# %d |Replace# %d\n", rootNode, compilationProfile.getInvalidationCount(), + compilationProfile.getNodeReplaceCount()); } } @@ -126,14 +122,14 @@ if (task != null) { task.cancel(true); this.installedCodeTask = null; - compilationPolicy.reportCompilationInvalidated(); + compilationProfile.reportInvalidated(); } } private Object interpreterCall(PackedFrame caller, Arguments args) { CompilerAsserts.neverPartOfCompilation(); - compilationPolicy.reportInterpreterCall(); - if (disableCompilation || !compilationPolicy.shouldCompileOrInline()) { + compilationProfile.reportInterpreterCall(); + if (disableCompilation || !compilationPolicy.shouldCompile(compilationProfile)) { return executeHelper(caller, args); } else { return compileOrInline(caller, args); @@ -154,7 +150,7 @@ } if (TruffleFunctionInlining.getValue() && inline()) { - compilationPolicy.reportCallInlined(MIN_INVOKES_AFTER_INLINING); + compilationProfile.reportInliningPerformed(); return call(caller, args); } else { compile(); @@ -214,14 +210,13 @@ @Override public void reportLoopCount(int count) { - compilationPolicy.reportLoopCount(count); + compilationProfile.reportLoopCount(count); } @Override public void nodeReplaced() { - nodeReplaceCount++; + compilationProfile.reportNodeReplaced(); invalidate(); - compilationPolicy.notifyNodeReplaced(); } private static void resetProfiling() { @@ -259,13 +254,13 @@ String comment = callTarget.installedCode == null ? " int" : ""; comment += callTarget.disableCompilation ? " fail" : ""; OUT.printf("%-50s | %10d | %15d | %15d | %10d | %3d%s\n", callTarget.getRootNode(), callTarget.callCount, inlinedCallSiteCount, notInlinedCallSiteCount, nodeCount, - callTarget.invalidationCount, comment); + callTarget.getCompilationProfile().getInvalidationCount(), comment); totalCallCount += callTarget.callCount; totalInlinedCallSiteCount += inlinedCallSiteCount; totalNotInlinedCallSiteCount += notInlinedCallSiteCount; totalNodeCount += nodeCount; - totalInvalidationCount += callTarget.invalidationCount; + totalInvalidationCount += callTarget.getCompilationProfile().getInvalidationCount(); } OUT.printf("%-50s | %10d | %15d | %15d | %10d | %3d\n", "Total", totalCallCount, totalInlinedCallSiteCount, totalNotInlinedCallSiteCount, totalNodeCount, totalInvalidationCount); } diff -r 85bab2227295 -r d2d0c44662bb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TimedCompilationPolicy.java Thu Nov 07 16:21:06 2013 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle; + +import static com.oracle.graal.truffle.TruffleCompilerOptions.*; + +public class TimedCompilationPolicy extends DefaultCompilationPolicy { + + @Override + public boolean shouldCompile(CompilationProfile profile) { + if (super.shouldCompile(profile)) { + long timestamp = System.nanoTime(); + long prevTimestamp = profile.getPreviousTimestamp(); + long timespan = (timestamp - prevTimestamp); + if (timespan < (TruffleCompilationDecisionTime.getValue())) { + return true; + } + // TODO shouldCompile should not modify the compilation profile + // maybe introduce another method? + profile.reportTiminingFailed(timestamp); + if (TruffleCompilationDecisionTimePrintFail.getValue()) { + // Checkstyle: stop + System.out.println(profile.getName() + ": timespan " + (timespan / 1000000) + " ms larger than threshold"); + // Checkstyle: resume + } + } + return false; + } + +} diff -r 85bab2227295 -r d2d0c44662bb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Thu Nov 07 15:10:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleInliningImpl.java Thu Nov 07 16:21:06 2013 +0100 @@ -105,7 +105,7 @@ public InliningPolicy(OptimizedCallTarget caller) { this.callerNodeCount = NodeUtil.countNodes(caller.getRootNode()); - this.callerInvocationCount = caller.getCompilationPolicy().getOriginalInvokeCounter(); + this.callerInvocationCount = caller.getCompilationProfile().getOriginalInvokeCounter(); } public boolean continueInlining() {