Mercurial > hg > graal-compiler
changeset 12592:42c8f76a98bf
Move Truffle compilations to background compilation thread.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Thu, 17 Oct 2013 15:55:18 +0200 |
parents | 33fe56e68abd |
children | 561217cf2ac5 |
files | graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java |
diffstat | 5 files changed, 91 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 17 14:28:37 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 17 15:55:18 2013 +0200 @@ -26,6 +26,7 @@ import java.io.*; import java.util.*; +import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; @@ -54,6 +55,7 @@ } private InstalledCode installedCode; + private Future<InstalledCode> installedCodeTask; private final TruffleCompiler compiler; private final CompilationPolicy compilationPolicy; private boolean disableCompilation; @@ -105,6 +107,13 @@ OUT.printf("[truffle] invalidated %-48s |Inv# %d |Replace# %d\n", rootNode, invalidationCount, nodeReplaceCount); } } + + Future<InstalledCode> task = this.installedCodeTask; + if (task != null) { + task.cancel(true); + this.installedCodeTask = null; + compilationPolicy.compilationInvalidated(); + } } private Object interpreterCall(PackedFrame caller, Arguments args) { @@ -113,19 +122,55 @@ if (disableCompilation || !compilationPolicy.compileOrInline()) { return executeHelper(caller, args); } else { - compileOrInline(); - return call(caller, args); + return compileOrInline(caller, args); } } - private void compileOrInline() { + private Object compileOrInline(PackedFrame caller, Arguments args) { + if (installedCodeTask != null) { + // There is already a compilation running. + if (installedCodeTask.isCancelled()) { + installedCodeTask = null; + } else { + if (installedCodeTask.isDone()) { + receiveInstalledCode(); + } + return executeHelper(caller, args); + } + } + if (TruffleFunctionInlining.getValue() && inline()) { compilationPolicy.inlined(MIN_INVOKES_AFTER_INLINING); + return call(caller, args); } else { compile(); + return executeHelper(caller, args); } } + private void receiveInstalledCode() { + try { + this.installedCode = installedCodeTask.get(); + if (TruffleCallTargetProfiling.getValue()) { + resetProfiling(); + } + } catch (InterruptedException | ExecutionException e) { + disableCompilation = true; + OUT.printf("[truffle] opt failed %-48s %s\n", rootNode, e.getMessage()); + if (e.getCause() instanceof BailoutException) { + // Bailout => move on. + } else { + if (TraceTruffleCompilationExceptions.getValue()) { + e.printStackTrace(OUT); + } + if (TruffleCompilationExceptionsAreFatal.getValue()) { + System.exit(-1); + } + } + } + installedCodeTask = null; + } + public boolean inline() { CompilerAsserts.neverPartOfCompilation(); return new InliningHelper(this).inline(); @@ -133,30 +178,9 @@ public void compile() { CompilerAsserts.neverPartOfCompilation(); - try { - installedCode = compiler.compile(this); - if (installedCode == null) { - throw new BailoutException(String.format("code installation failed")); - } else { - if (TruffleCallTargetProfiling.getValue()) { - resetProfiling(); - } - } - } catch (Throwable e) { - disableCompilation = true; - if (TraceTruffleCompilation.getValue()) { - if (e instanceof BailoutException) { - OUT.printf("[truffle] opt bailout %-48s %s\n", rootNode, e.getMessage()); - } else { - OUT.printf("[truffle] opt failed %-49s %s\n", rootNode, e.toString()); - if (TraceTruffleCompilationExceptions.getValue()) { - e.printStackTrace(OUT); - } - if (TruffleCompilationExceptionsAreFatal.getValue()) { - System.exit(-1); - } - } - } + this.installedCodeTask = compiler.compile(this); + if (!TruffleBackgroundCompilation.getValue()) { + receiveInstalledCode(); } }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Oct 17 14:28:37 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Oct 17 15:55:18 2013 +0200 @@ -132,6 +132,10 @@ // Make sure frame does not escape. expandTree(graph, assumptions); + if (Thread.interrupted()) { + return; + } + new VerifyFrameDoesNotEscapePhase().apply(graph, false); if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) { @@ -219,6 +223,10 @@ } } + if (Thread.interrupted()) { + return; + } + if (graph.getNodeCount() > TruffleCompilerOptions.TruffleGraphMaxNodes.getValue()) { throw new BailoutException("Truffle compilation is exceeding maximum node count: " + graph.getNodeCount()); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java Thu Oct 17 14:28:37 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java Thu Oct 17 15:55:18 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.truffle; +import java.util.concurrent.*; + import com.oracle.graal.api.code.*; /** @@ -30,5 +32,5 @@ */ public interface TruffleCompiler { - InstalledCode compile(OptimizedCallTarget node); + Future<InstalledCode> compile(OptimizedCallTarget node); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Oct 17 14:28:37 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Oct 17 15:55:18 2013 +0200 @@ -39,6 +39,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -65,6 +66,7 @@ private final ResolvedJavaType[] skippedExceptionTypes; private final HotSpotGraalRuntime runtime; private final TruffleCache truffleCache; + private final ThreadPoolExecutor compileQueue; private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{SlowPathException.class, UnexpectedResultException.class, ArithmeticException.class}; @@ -79,6 +81,9 @@ this.runtime = HotSpotGraalRuntime.runtime(); this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); + // Create compilation queue. + compileQueue = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), CompilerThread.FACTORY); + final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(); config.setSkippedExceptionTypes(skippedExceptionTypes); this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations); @@ -98,15 +103,22 @@ return skippedExceptionTypes; } - public InstalledCode compile(final OptimizedCallTarget compilable) { - Object[] debug = new Object[]{new DebugDumpScope("Truffle: " + compilable)}; - return Debug.scope("Truffle", debug, new Callable<InstalledCode>() { + public Future<InstalledCode> compile(final OptimizedCallTarget compilable) { + Future<InstalledCode> future = compileQueue.submit(new Callable<InstalledCode>() { @Override public InstalledCode call() throws Exception { - return compileMethodImpl(compilable); + Object[] debug = new Object[]{new DebugDumpScope("Truffle: " + compilable)}; + return Debug.scope("Truffle", debug, new Callable<InstalledCode>() { + + @Override + public InstalledCode call() throws Exception { + return compileMethodImpl(compilable); + } + }); } }); + return future; } public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime"); @@ -124,15 +136,23 @@ try (TimerCloseable a = PartialEvaluationTime.start()) { graph = partialEvaluator.createGraph(compilable, assumptions); } + if (Thread.interrupted()) { + return null; + } long timePartialEvaluationFinished = System.nanoTime(); int nodeCountPartialEval = graph.getNodeCount(); InstalledCode compiledMethod = compileMethodHelper(graph, config, assumptions); long timeCompilationFinished = System.nanoTime(); int nodeCountLowered = graph.getNodeCount(); - if (TraceTruffleCompilation.getValue() && compiledMethod != null) { + if (compiledMethod == null) { + throw new BailoutException("Could not install method, code cache is full!"); + } + + if (TraceTruffleCompilation.getValue()) { int nodeCountTruffle = NodeUtil.countNodes(compilable.getRootNode()); - OUT.printf("[truffle] optimized %-50s |Nodes %7d |Time %5.0f(%4.0f+%-4.0f)ms |Nodes %5d/%5d |CodeSize %d\n", compilable.getRootNode(), nodeCountTruffle, + System.out.println(compiledMethod.getCode()); + OUT.printf("[truffle] optimized %-50s %d |Nodes %7d |Time %5.0f(%4.0f+%-4.0f)ms |Nodes %5d/%5d |CodeSize %d\n", compilable.getRootNode(), compilable.hashCode(), nodeCountTruffle, (timeCompilationFinished - timeCompilationStarted) / 1e6, (timePartialEvaluationFinished - timeCompilationStarted) / 1e6, (timeCompilationFinished - timePartialEvaluationFinished) / 1e6, nodeCountPartialEval, nodeCountLowered, compiledMethod.getCode().length); }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Thu Oct 17 14:28:37 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Thu Oct 17 15:55:18 2013 +0200 @@ -71,6 +71,9 @@ public static final OptionValue<Boolean> TruffleUseTimeForCompilationDecision = new OptionValue<>(false); @Option(help = "") public static final OptionValue<Integer> TruffleCompilationDecisionTime = new OptionValue<>(100); + @Option(help = "") + public static final OptionValue<Boolean> TruffleBackgroundCompilation = new OptionValue<>(true); + // tracing @Option(help = "") public static final OptionValue<Boolean> TraceTruffleCompilation = new OptionValue<>(true);