# HG changeset patch # User Christian Humer # Date 1415265606 -3600 # Node ID 1f3ab088d9585fca9464f08c42368b8bf976aadf # Parent ab4284c5b5b008793b89183a82ee6879fe85646f Truffle: implemented defer compilation. diff -r ab4284c5b5b0 -r 1f3ab088d958 CHANGELOG.md --- a/CHANGELOG.md Wed Nov 05 19:29:11 2014 +0100 +++ b/CHANGELOG.md Thu Nov 06 10:20:06 2014 +0100 @@ -15,6 +15,7 @@ * Renamed DirectCallNode#split to DirectCallNode#cloneCallTarget * Renamed DirectCallNode#isSplit to DirectCallNode#isCallTargetCloned * Added PrimitiveValueProfile. +* Added -G:TruffleTimeThreshold=5000 option to defer compilation for call targets * ... ## Version 0.5 diff -r ab4284c5b5b0 -r 1f3ab088d958 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Nov 05 19:29:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Thu Nov 06 10:20:06 2014 +0100 @@ -116,12 +116,13 @@ private RootCallTarget createCallTargetImpl(OptimizedCallTarget source, RootNode rootNode) { CompilationPolicy compilationPolicy; if (acceptForCompilation(rootNode)) { - compilationPolicy = new CounterBasedCompilationPolicy(); + compilationPolicy = new CounterAndTimeBasedCompilationPolicy(); } else { compilationPolicy = new InterpreterOnlyCompilationPolicy(); } OptimizedCallTarget target = new OptimizedCallTarget(source, rootNode, this, compilationPolicy, new HotSpotSpeculationLog()); callTargets.put(target, null); + return target; } diff -r ab4284c5b5b0 -r 1f3ab088d958 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 Wed Nov 05 19:29:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationProfile.java Thu Nov 06 10:20:06 2014 +0100 @@ -28,16 +28,21 @@ public class CompilationProfile { + private static final int TIMESTAMP_THRESHOLD = Math.max(TruffleCompilationThreshold.getValue() / 2, 1); + /** * Number of times an installed code for this tree was invalidated. */ private int invalidationCount; + private int deferedCount; private int interpreterCallCount; private int interpreterCallAndLoopCount; private int compilationCallThreshold; private int compilationCallAndLoopThreshold; + private long timestamp; + public CompilationProfile() { this.compilationCallThreshold = TruffleMinInvokeThreshold.getValue(); this.compilationCallAndLoopThreshold = TruffleCompilationThreshold.getValue(); @@ -54,8 +59,8 @@ String callsThreshold = String.format("%7d/%5d", getInterpreterCallCount(), getCompilationCallThreshold()); String loopsThreshold = String.format("%7d/%5d", getInterpreterCallAndLoopCount(), getCompilationCallAndLoopThreshold()); String invalidations = String.format("%5d", invalidationCount); - properties.put("C/T", callsThreshold); - properties.put("L/T", loopsThreshold); + properties.put("Calls/Thres", callsThreshold); + properties.put("CallsAndLoop/Thres", loopsThreshold); properties.put("Inval#", invalidations); return properties; } @@ -72,6 +77,10 @@ return interpreterCallCount; } + public int getDeferedCount() { + return deferedCount; + } + public int getCompilationCallAndLoopThreshold() { return compilationCallAndLoopThreshold; } @@ -101,6 +110,11 @@ public void reportInterpreterCall() { interpreterCallCount++; interpreterCallAndLoopCount++; + + int callsMissing = compilationCallAndLoopThreshold - interpreterCallAndLoopCount; + if (callsMissing == TIMESTAMP_THRESHOLD) { + timestamp = System.nanoTime(); + } } public void reportDirectCall() { @@ -115,8 +129,19 @@ } + public void deferCompilation() { + ensureProfiling(0, TIMESTAMP_THRESHOLD + 1); + timestamp = 0; + deferedCount++; + } + void reportLoopCount(int count) { interpreterCallAndLoopCount += count; + + int callsMissing = compilationCallAndLoopThreshold - interpreterCallAndLoopCount; + if (callsMissing <= TIMESTAMP_THRESHOLD && callsMissing + count > TIMESTAMP_THRESHOLD) { + timestamp = System.nanoTime(); + } } void reportNodeReplaced() { @@ -125,4 +150,7 @@ ensureProfiling(1, replaceBackoff); } + public long getTimestamp() { + return timestamp; + } } diff -r ab4284c5b5b0 -r 1f3ab088d958 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterAndTimeBasedCompilationPolicy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CounterAndTimeBasedCompilationPolicy.java Thu Nov 06 10:20:06 2014 +0100 @@ -0,0 +1,49 @@ +/* + * 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 CounterAndTimeBasedCompilationPolicy extends CounterBasedCompilationPolicy { + + private static final long threshold = TruffleTimeThreshold.getValue() * 1_000_000L; + + @Override + public boolean shouldCompile(CompilationProfile profile) { + if (super.shouldCompile(profile)) { + long time = profile.getTimestamp(); + if (time == 0) { + throw new AssertionError(); + } + long timeElapsed = System.nanoTime() - time; + if (timeElapsed > threshold) { + profile.deferCompilation(); + return false; + } + return true; + } else { + return false; + } + } + +} diff -r ab4284c5b5b0 -r 1f3ab088d958 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 Wed Nov 05 19:29:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Nov 06 10:20:06 2014 +0100 @@ -54,6 +54,7 @@ protected final CompilationPolicy compilationPolicy; private final OptimizedCallTarget sourceCallTarget; private final AtomicInteger callSitesKnown = new AtomicInteger(0); + @CompilationFinal private Class[] profiledArgumentTypes; @CompilationFinal private Assumption profiledArgumentTypesAssumption; @CompilationFinal private Class profiledReturnType; @@ -238,7 +239,7 @@ // We are called and we are still in Truffle interpreter mode. interpreterCall(); } else { - // We come here from compiled code (i.e., we have been inlined). + // We come here from compiled code } return callRoot(args); diff -r ab4284c5b5b0 -r 1f3ab088d958 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 Wed Nov 05 19:29:11 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Thu Nov 06 10:20:06 2014 +0100 @@ -45,6 +45,8 @@ public static final OptionValue TruffleCompileOnly = new OptionValue<>(null); @Option(help = "Compile call target when call count exceeds this threshold") public static final OptionValue TruffleCompilationThreshold = new OptionValue<>(1000); + @Option(help = "Defines the maximum timespan in milliseconds that is required for a call target to be queued for compilation.") + public static final OptionValue TruffleTimeThreshold = new OptionValue<>(5000); @Option(help = "Minimum number of calls before a call target is compiled") public static final OptionValue TruffleMinInvokeThreshold = new OptionValue<>(3); @Option(help = "Delay compilation after an invalidation to allow for reprofiling")