changeset 23380:d7e25fa8bc3e

Truffle: compilation queue should weakly reference call targets
author Andreas Woess <andreas.woess@oracle.com>
date Thu, 04 Feb 2016 14:14:16 +0100
parents b6c33361df1e
children e36199b8cdb5
files graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/CompilationStatisticsListener.java
diffstat 3 files changed, 39 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- 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<OptimizedCallTarget, Future<?>> 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<OptimizedCallTarget> 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<OptimizedCallTarget> 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;
--- 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;
+    }
 }
--- 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);