# HG changeset patch # User Christian Wimmer # Date 1447806690 28800 # Node ID a8bab192d632a655d2ef91e58c2019571e032ce8 # Parent 40024a40f63ca9009327067d2e20284e8f2a61af Move Truffle compile queue to VM-independent baseclass diff -r 40024a40f63c -r a8bab192d632 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java --- 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(); diff -r 40024a40f63c -r a8bab192d632 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java --- 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; diff -r 40024a40f63c -r a8bab192d632 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 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 callTargets = Collections.synchronizedMap(new WeakHashMap()); - static class Lazy { - private Map> 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 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() { diff -r 40024a40f63c -r a8bab192d632 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 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> 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 includes; private ArrayList excludes; @@ -306,10 +340,6 @@ getCompilationNotify().notifyShutdown(this); } - public abstract Collection 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 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); diff -r 40024a40f63c -r a8bab192d632 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 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); + } }