# HG changeset patch # User Andreas Woess # Date 1454591656 -3600 # Node ID d7e25fa8bc3eeb6f445a4d0b7e598f0118c72f09 # Parent b6c33361df1e26d944feee8a4f68bee663ce7e19 Truffle: compilation queue should weakly reference call targets diff -r b6c33361df1e -r d7e25fa8bc3e graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Thu Feb 04 13:25:31 2016 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Thu Feb 04 14:14:16 2016 +0100 @@ -26,20 +26,20 @@ import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleCompileOnly; import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleEnableInfopoints; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CancellationException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Supplier; -import java.util.stream.Collectors; import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.code.stack.InspectedFrame; @@ -86,7 +86,6 @@ public abstract class GraalTruffleRuntime implements TruffleRuntime { protected abstract static class BackgroundCompileQueue implements CompilerThreadFactory.DebugConfigAccess { - private final ConcurrentMap> compilations; private final ExecutorService compileQueue; protected BackgroundCompileQueue() { @@ -104,7 +103,6 @@ } selectedProcessors = Math.max(1, selectedProcessors); compileQueue = Executors.newFixedThreadPool(selectedProcessors, factory); - compilations = new ConcurrentHashMap<>(); } } @@ -372,13 +370,17 @@ public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) { BackgroundCompileQueue l = getCompileQueue(); + final WeakReference weakCallTarget = new WeakReference<>(optimizedCallTarget); Future future = l.compileQueue.submit(new Runnable() { @Override public void run() { - doCompile(optimizedCallTarget); + OptimizedCallTarget callTarget = weakCallTarget.get(); + if (callTarget != null) { + doCompile(callTarget); + } } }); - l.compilations.put(optimizedCallTarget, future); + optimizedCallTarget.setCompilationTask(future); getCompilationNotify().notifyCompilationQueued(optimizedCallTarget); if (!mayBeAsynchronous) { @@ -397,10 +399,9 @@ } public boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason) { - BackgroundCompileQueue l = getCompileQueue(); - Future codeTask = l.compilations.get(optimizedCallTarget); + Future codeTask = optimizedCallTarget.getCompilationTask(); if (codeTask != null && isCompiling(optimizedCallTarget)) { - l.compilations.remove(optimizedCallTarget); + optimizedCallTarget.setCompilationTask(null); boolean result = codeTask.cancel(true); if (result) { optimizedCallTarget.notifyCompilationFinished(false); @@ -412,7 +413,7 @@ } public void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException { - Future codeTask = getCompileQueue().compilations.get(optimizedCallTarget); + Future codeTask = optimizedCallTarget.getCompilationTask(); if (codeTask != null && isCompiling(optimizedCallTarget)) { try { codeTask.get(timeout, TimeUnit.MILLISECONDS); @@ -422,15 +423,25 @@ } } + @Deprecated public Collection getQueuedCallTargets() { - return getCompileQueue().compilations.keySet().stream().filter(e -> !getCompileQueue().compilations.get(e).isDone()).collect(Collectors.toList()); + return Collections.emptyList(); + } + + public int getCompilationQueueSize() { + ExecutorService executor = getCompileQueue().compileQueue; + if (executor instanceof ThreadPoolExecutor) { + return ((ThreadPoolExecutor) executor).getQueue().size(); + } else { + return 0; + } } public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) { - Future codeTask = getCompileQueue().compilations.get(optimizedCallTarget); + Future codeTask = optimizedCallTarget.getCompilationTask(); if (codeTask != null) { if (codeTask.isCancelled() || codeTask.isDone()) { - getCompileQueue().compilations.remove(optimizedCallTarget); + optimizedCallTarget.setCompilationTask(null); return false; } return true; diff -r b6c33361df1e -r d7e25fa8bc3e 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 Feb 04 13:25:31 2016 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Feb 04 14:14:16 2016 +0100 @@ -40,6 +40,7 @@ import java.util.List; import java.util.Map; import java.util.Spliterators; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -99,7 +100,6 @@ private TruffleInlining inlining; private int cachedNonTrivialNodeCount = -1; - private boolean compiling; private int cloneIndex; /** @@ -109,6 +109,8 @@ */ private final CyclicAssumption nodeRewritingAssumption; + private volatile Future compilationTask; + public final RootNode getRootNode() { return rootNode; } @@ -135,7 +137,7 @@ } public final boolean isCompiling() { - return compiling; + return getCompilationTask() != null; } private static RootNode cloneRootNode(RootNode root) { @@ -385,7 +387,6 @@ public final void compile() { if (!isCompiling()) { - compiling = true; ensureCloned(); runtime.compile(this, TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue()); } @@ -423,7 +424,7 @@ if (successful && inlining != null) { dequeueInlinedCallSites(inlining); } - compiling = false; + setCompilationTask(null); } private void dequeueInlinedCallSites(TruffleInlining parentDecision) { @@ -623,4 +624,12 @@ public final int hashCode() { return System.identityHashCode(this); } + + Future getCompilationTask() { + return compilationTask; + } + + void setCompilationTask(Future compilationTask) { + this.compilationTask = compilationTask; + } } diff -r b6c33361df1e -r d7e25fa8bc3e graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/CompilationStatisticsListener.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/CompilationStatisticsListener.java Thu Feb 04 13:25:31 2016 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/CompilationStatisticsListener.java Thu Feb 04 14:14:16 2016 +0100 @@ -236,7 +236,7 @@ printStatistic(rt, "Compilation Accuracy", 1.0 - invalidations / (double) compilations); printStatistic(rt, "Queue Accuracy", 1.0 - dequeues / (double) queues); printStatistic(rt, "Compilation Utilization", compilationTime.getSum() / (double) (endTime - firstCompilation)); - printStatistic(rt, "Remaining Compilation Queue", rt.getQueuedCallTargets().size()); + printStatistic(rt, "Remaining Compilation Queue", rt.getCompilationQueueSize()); printStatistic(rt, "Times defered until compilation", deferCompilations); printStatisticTime(rt, "Time to queue", timeToQueue);