changeset 23012:a8bab192d632

Move Truffle compile queue to VM-independent baseclass
author Christian Wimmer <christian.wimmer@oracle.com>
date Tue, 17 Nov 2015 16:31:30 -0800
parents 40024a40f63c
children 79266e707964 31f1578ea3ab
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java
diffstat 5 files changed, 133 insertions(+), 114 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java	Fri Nov 13 10:39:44 2015 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java	Tue Nov 17 16:31:30 2015 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.compiler;
 
 import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess;
+import com.oracle.graal.debug.DebugConfig;
 import com.oracle.graal.debug.DebugDumpHandler;
 import com.oracle.graal.debug.GraalDebugConfig;
 
@@ -44,7 +45,7 @@
 
     @Override
     public void run() {
-        GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig();
+        DebugConfig debugConfig = debugConfigAccess.getDebugConfig();
         setContextClassLoader(getClass().getClassLoader());
         try {
             super.run();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java	Fri Nov 13 10:39:44 2015 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java	Tue Nov 17 16:31:30 2015 -0800
@@ -24,7 +24,7 @@
 
 import java.util.concurrent.ThreadFactory;
 
-import com.oracle.graal.debug.GraalDebugConfig;
+import com.oracle.graal.debug.DebugConfig;
 
 /**
  * Facility for creating {@linkplain CompilerThread compiler threads}.
@@ -39,7 +39,7 @@
          * Get a thread-local debug configuration for the current thread. This will be null if
          * debugging is disabled.
          */
-        GraalDebugConfig getDebugConfig();
+        DebugConfig getDebugConfig();
     }
 
     protected final String threadNamePrefix;
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Fri Nov 13 10:39:44 2015 -0800
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Tue Nov 17 16:31:30 2015 -0800
@@ -27,7 +27,6 @@
 import static com.oracle.graal.hotspot.meta.HotSpotSuitesProvider.withSimpleDebugInfo;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TraceTruffleStackTraceLimit;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TraceTruffleTransferToInterpreter;
-import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleCompilationExceptionsAreThrown;
 import static com.oracle.graal.truffle.hotspot.UnsafeAccess.UNSAFE;
 import static jdk.vm.ci.code.CodeUtil.getCallingConvention;
 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
@@ -35,21 +34,12 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.IdentityHashMap;
 import java.util.ListIterator;
 import java.util.Map;
 import java.util.WeakHashMap;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-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.CallingConvention;
 import jdk.vm.ci.code.CallingConvention.Type;
 import jdk.vm.ci.code.CodeCacheProvider;
@@ -68,7 +58,6 @@
 import jdk.vm.ci.service.Services;
 
 import com.oracle.graal.api.runtime.GraalRuntime;
-import com.oracle.graal.compiler.CompilerThreadFactory;
 import com.oracle.graal.compiler.target.Backend;
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.Debug.Scope;
@@ -102,7 +91,6 @@
 import com.oracle.graal.truffle.OptimizedCallTarget;
 import com.oracle.graal.truffle.TruffleCallBoundary;
 import com.oracle.graal.truffle.TruffleCompiler;
-import com.oracle.graal.truffle.TruffleCompilerOptions;
 import com.oracle.graal.truffle.TruffleTreeDumpHandler;
 import com.oracle.graal.truffle.hotspot.nfi.HotSpotNativeFunctionInterface;
 import com.oracle.graal.truffle.hotspot.nfi.RawNativeCallNodeFactory;
@@ -118,38 +106,22 @@
 
     private final Map<RootCallTarget, Void> callTargets = Collections.synchronizedMap(new WeakHashMap<RootCallTarget, Void>());
 
-    static class Lazy {
-        private Map<OptimizedCallTarget, Future<?>> compilations = Collections.synchronizedMap(new IdentityHashMap<>());
-        private final ExecutorService compileQueue;
+    static class Lazy extends BackgroundCompileQueue {
         private StackIntrospection stackIntrospection;
 
         public Lazy(HotSpotTruffleRuntime runtime) {
             runtime.installDefaultListeners();
+        }
 
-            // Create compilation queue.
-            CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() {
-                public GraalDebugConfig getDebugConfig() {
-                    if (Debug.isEnabled()) {
-                        GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
-                        debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
-                        return debugConfig;
-                    } else {
-                        return null;
-                    }
-                }
-            });
-            int selectedProcessors = TruffleCompilerOptions.TruffleCompilerThreads.getValue();
-            if (selectedProcessors == 0) {
-                // No manual selection made, check how many processors are available.
-                int availableProcessors = Runtime.getRuntime().availableProcessors();
-                if (availableProcessors >= 12) {
-                    selectedProcessors = 4;
-                } else if (availableProcessors >= 4) {
-                    selectedProcessors = 2;
-                }
+        @Override
+        public GraalDebugConfig getDebugConfig() {
+            if (Debug.isEnabled()) {
+                GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out());
+                debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler());
+                return debugConfig;
+            } else {
+                return null;
             }
-            selectedProcessors = Math.max(1, selectedProcessors);
-            compileQueue = Executors.newFixedThreadPool(selectedProcessors, factory);
         }
     }
 
@@ -303,34 +275,16 @@
     }
 
     @Override
+    protected BackgroundCompileQueue getCompileQueue() {
+        return lazy();
+    }
+
+    @Override
     public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) {
         /* Ensure compiler is created. */
         getTruffleCompiler();
 
-        Runnable r = new Runnable() {
-            @Override
-            public void run() {
-                doCompile(optimizedCallTarget);
-            }
-        };
-        Lazy l = lazy();
-        Future<?> future = l.compileQueue.submit(r);
-        l.compilations.put(optimizedCallTarget, future);
-        getCompilationNotify().notifyCompilationQueued(optimizedCallTarget);
-
-        if (!mayBeAsynchronous) {
-            try {
-                future.get();
-            } catch (ExecutionException e) {
-                if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException && !((BailoutException) e.getCause()).isPermanent())) {
-                    throw new RuntimeException(e.getCause());
-                } else {
-                    // silently ignored
-                }
-            } catch (InterruptedException | CancellationException e) {
-                // silently ignored
-            }
-        }
+        super.compile(optimizedCallTarget, mayBeAsynchronous);
     }
 
     @Override
@@ -340,48 +294,7 @@
             return false;
         }
 
-        Lazy l = lazy();
-        Future<?> codeTask = l.compilations.get(optimizedCallTarget);
-        if (codeTask != null && isCompiling(optimizedCallTarget)) {
-            l.compilations.remove(optimizedCallTarget);
-            boolean result = codeTask.cancel(true);
-            if (result) {
-                optimizedCallTarget.notifyCompilationFinished(false);
-                getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason);
-            }
-            return result;
-        }
-        return false;
-    }
-
-    @Override
-    public void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException {
-        Future<?> codeTask = lazy().compilations.get(optimizedCallTarget);
-        if (codeTask != null && isCompiling(optimizedCallTarget)) {
-            try {
-                codeTask.get(timeout, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                // ignore interrupted
-            }
-        }
-    }
-
-    @Override
-    public Collection<OptimizedCallTarget> getQueuedCallTargets() {
-        return lazy().compilations.keySet().stream().filter(e -> !lazy().compilations.get(e).isDone()).collect(Collectors.toList());
-    }
-
-    @Override
-    public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) {
-        Future<?> codeTask = lazy().compilations.get(optimizedCallTarget);
-        if (codeTask != null) {
-            if (codeTask.isCancelled() || codeTask.isDone()) {
-                lazy().compilations.remove(optimizedCallTarget);
-                return false;
-            }
-            return true;
-        }
-        return false;
+        return super.cancelInstalledTask(optimizedCallTarget, source, reason);
     }
 
     private static CodeCacheProvider getCodeCache() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Nov 13 10:39:44 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Tue Nov 17 16:31:30 2015 -0800
@@ -22,16 +22,26 @@
  */
 package com.oracle.graal.truffle;
 
+import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleCompilationExceptionsAreThrown;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleCompileOnly;
 import static com.oracle.graal.truffle.TruffleCompilerOptions.TruffleEnableInfopoints;
 
 import java.util.ArrayList;
 import java.util.Collection;
 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.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.CompilationResult;
 import jdk.vm.ci.code.stack.InspectedFrame;
 import jdk.vm.ci.code.stack.InspectedFrameVisitor;
@@ -42,6 +52,7 @@
 import jdk.vm.ci.service.Services;
 
 import com.oracle.graal.api.runtime.GraalRuntime;
+import com.oracle.graal.compiler.CompilerThreadFactory;
 import com.oracle.graal.debug.Debug;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.TTY;
@@ -74,6 +85,29 @@
 
 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() {
+            CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", this);
+
+            int selectedProcessors = TruffleCompilerOptions.TruffleCompilerThreads.getValue();
+            if (selectedProcessors == 0) {
+                // No manual selection made, check how many processors are available.
+                int availableProcessors = Runtime.getRuntime().availableProcessors();
+                if (availableProcessors >= 12) {
+                    selectedProcessors = 4;
+                } else if (availableProcessors >= 4) {
+                    selectedProcessors = 2;
+                }
+            }
+            selectedProcessors = Math.max(1, selectedProcessors);
+            compileQueue = Executors.newFixedThreadPool(selectedProcessors, factory);
+            compilations = new ConcurrentHashMap<>();
+        }
+    }
+
     private ArrayList<String> includes;
     private ArrayList<String> excludes;
 
@@ -306,10 +340,6 @@
         getCompilationNotify().notifyShutdown(this);
     }
 
-    public abstract Collection<OptimizedCallTarget> getQueuedCallTargets();
-
-    public abstract void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous);
-
     @SuppressWarnings("try")
     protected void doCompile(OptimizedCallTarget optimizedCallTarget) {
         boolean success = true;
@@ -323,11 +353,76 @@
         }
     }
 
-    public abstract boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason);
+    protected abstract BackgroundCompileQueue getCompileQueue();
+
+    public void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous) {
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                doCompile(optimizedCallTarget);
+            }
+        };
+        BackgroundCompileQueue l = getCompileQueue();
+        Future<?> future = l.compileQueue.submit(r);
+        l.compilations.put(optimizedCallTarget, future);
+        getCompilationNotify().notifyCompilationQueued(optimizedCallTarget);
+
+        if (!mayBeAsynchronous) {
+            try {
+                future.get();
+            } catch (ExecutionException e) {
+                if (TruffleCompilationExceptionsAreThrown.getValue() && !(e.getCause() instanceof BailoutException && !((BailoutException) e.getCause()).isPermanent())) {
+                    throw new RuntimeException(e.getCause());
+                } else {
+                    // silently ignored
+                }
+            } catch (InterruptedException | CancellationException e) {
+                // silently ignored
+            }
+        }
+    }
 
-    public abstract void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException;
+    public boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason) {
+        BackgroundCompileQueue l = getCompileQueue();
+        Future<?> codeTask = l.compilations.get(optimizedCallTarget);
+        if (codeTask != null && isCompiling(optimizedCallTarget)) {
+            l.compilations.remove(optimizedCallTarget);
+            boolean result = codeTask.cancel(true);
+            if (result) {
+                optimizedCallTarget.notifyCompilationFinished(false);
+                getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason);
+            }
+            return result;
+        }
+        return false;
+    }
 
-    public abstract boolean isCompiling(OptimizedCallTarget optimizedCallTarget);
+    public void waitForCompilation(OptimizedCallTarget optimizedCallTarget, long timeout) throws ExecutionException, TimeoutException {
+        Future<?> codeTask = getCompileQueue().compilations.get(optimizedCallTarget);
+        if (codeTask != null && isCompiling(optimizedCallTarget)) {
+            try {
+                codeTask.get(timeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // ignore interrupted
+            }
+        }
+    }
+
+    public Collection<OptimizedCallTarget> getQueuedCallTargets() {
+        return getCompileQueue().compilations.keySet().stream().filter(e -> !getCompileQueue().compilations.get(e).isDone()).collect(Collectors.toList());
+    }
+
+    public boolean isCompiling(OptimizedCallTarget optimizedCallTarget) {
+        Future<?> codeTask = getCompileQueue().compilations.get(optimizedCallTarget);
+        if (codeTask != null) {
+            if (codeTask.isCancelled() || codeTask.isDone()) {
+                getCompileQueue().compilations.remove(optimizedCallTarget);
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
 
     public abstract void invalidateInstalledCode(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Nov 13 10:39:44 2015 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Tue Nov 17 16:31:30 2015 -0800
@@ -607,4 +607,14 @@
             return true;
         }
     }
+
+    @Override
+    public final boolean equals(Object obj) {
+        return obj == this;
+    }
+
+    @Override
+    public final int hashCode() {
+        return System.identityHashCode(this);
+    }
 }