# HG changeset patch # User Lukas Stadler # Date 1353082870 -3600 # Node ID 98d691bc23da8073574dc0739ed8164c3bd4c54e # Parent b62581e29024f5442d01ceaa564af01c2dc4552c make osr compilations asynchronous diff -r b62581e29024 -r 98d691bc23da graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Nov 15 17:18:16 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri Nov 16 17:21:10 2012 +0100 @@ -42,15 +42,8 @@ } }; - public static final ThreadLocal withinCompilation = new ThreadLocal() { - @Override - protected Long initialValue() { - return 0L; - } - }; - - private volatile boolean cancelled; + private volatile boolean inProgress; private final HotSpotGraalRuntime graalRuntime; private final PhasePlan plan; @@ -59,13 +52,12 @@ private final int entryBCI; private final int id; private final int priority; - private final Runnable callback; - public static CompilationTask create(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority, Runnable callback) { - return new CompilationTask(graalRuntime, plan, optimisticOpts, method, entryBCI, id, priority, callback); + public static CompilationTask create(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority) { + return new CompilationTask(graalRuntime, plan, optimisticOpts, method, entryBCI, id, priority); } - private CompilationTask(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority, Runnable callback) { + private CompilationTask(HotSpotGraalRuntime graalRuntime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id, int priority) { this.graalRuntime = graalRuntime; this.plan = plan; this.method = method; @@ -73,14 +65,13 @@ this.entryBCI = entryBCI; this.id = id; this.priority = priority; - this.callback = callback; } - public ResolvedJavaMethod method() { + public ResolvedJavaMethod getMethod() { return method; } - public int priority() { + public int getPriority() { return priority; } @@ -88,12 +79,21 @@ cancelled = true; } + public boolean isInProgress() { + return inProgress; + } + + public int getEntryBCI() { + return entryBCI; + } + public void run() { withinEnqueue.set(Boolean.FALSE); try { if (cancelled) { return; } + inProgress = true; if (GraalOptions.DynamicCompilePriority) { int threadPriority = priority < GraalOptions.SlowQueueCutoff ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY; if (Thread.currentThread().getPriority() != threadPriority) { @@ -105,12 +105,12 @@ method.setCurrentTask(null); } } finally { + inProgress = false; withinEnqueue.set(Boolean.TRUE); } } public void runCompilation() { - withinCompilation.set(withinCompilation.get() + 1); CompilationStatistics stats = CompilationStatistics.create(method); try { final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed(); @@ -156,10 +156,6 @@ } } stats.finish(method); - if (callback != null) { - callback.run(); - } - withinCompilation.set(withinCompilation.get() - 1); } private void installMethod(final CompilationResult tm) { diff -r b62581e29024 -r 98d691bc23da graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Nov 15 17:18:16 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri Nov 16 17:21:10 2012 +0100 @@ -65,6 +65,8 @@ private ThreadPoolExecutor slowCompileQueue; private AtomicInteger compileTaskIds = new AtomicInteger(); + private volatile boolean bootstrapRunning; + private PrintStream log = System.out; public VMToCompilerImpl(HotSpotGraalRuntime compiler) { @@ -170,6 +172,7 @@ TTY.flush(); long startTime = System.currentTimeMillis(); + bootstrapRunning = true; boolean firstRun = true; do { // Initialize compile queue with a selected set of methods. @@ -213,6 +216,7 @@ } } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap); CompilationStatistics.clear("bootstrap"); + bootstrapRunning = false; TTY.println(" in %d ms", System.currentTimeMillis() - startTime); if (graalRuntime.getCache() != null) { @@ -349,6 +353,12 @@ @Override public boolean compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, boolean blocking, int priority) throws Throwable { + boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; + if (osrCompilation && bootstrapRunning) { + // no OSR compilations during bootstrap - the compiler is just too slow at this point, and we know that there are no endless loops + return true; + } + if (CompilationTask.withinEnqueue.get()) { // This is required to avoid deadlocking a compiler thread. The issue is that a // java.util.concurrent.BlockingQueue is used to implement the compilation worker @@ -361,18 +371,27 @@ try { CompilationTask current = method.currentTask(); if (!blocking && current != null) { - if (GraalOptions.PriorityCompileQueue) { - // normally compilation tasks will only be re-queued when they get a priority boost, so cancel the old task and add a new one - current.cancel(); + if (current.isInProgress()) { + if (current.getEntryBCI() == entryBCI) { + // a compilation with the correct bci is already in progress, so just return true + return true; + } } else { - // without a prioritizing compile queue it makes no sense to re-queue the compilation task - return true; + if (GraalOptions.PriorityCompileQueue) { + // normally compilation tasks will only be re-queued when they get a priority boost, so cancel the old task and add a new one + current.cancel(); + } else { + // without a prioritizing compile queue it makes no sense to re-queue the compilation task + return true; + } } } final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method); int id = compileTaskIds.incrementAndGet(); - CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts, false), optimisticOpts, method, StructuredGraph.INVOCATION_ENTRY_BCI, id, priority, null); + // osr compilations need to be finished quickly, so they get max priority + int queuePriority = osrCompilation ? -1 : priority; + CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id, queuePriority); if (blocking) { task.runCompilation(); } else { @@ -388,21 +407,6 @@ return false; } } - if (entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI && CompilationTask.withinCompilation.get() == 0) { - final OptimisticOptimizations osrOptimisticOpts = new OptimisticOptimizations(method); - int osrId = compileTaskIds.incrementAndGet(); - Debug.log("OSR compilation %s@%d", method, entryBCI); - final CountDownLatch latch = new CountDownLatch(1); - Runnable callback = new Runnable() { - @Override - public void run() { - latch.countDown(); - } - }; - CompilationTask osrTask = CompilationTask.create(graalRuntime, createPhasePlan(osrOptimisticOpts, true), osrOptimisticOpts, method, entryBCI, osrId, Integer.MAX_VALUE, callback); - compileQueue.execute(osrTask); - latch.await(); - } return true; } finally { CompilationTask.withinEnqueue.set(Boolean.FALSE);