changeset 15463:a20be10ad437

made Graal work with the HotSpot compiler queue and compiler threads, enabled by -XX:-UseGraalCompilationQueue
author Doug Simon <doug.simon@oracle.com>
date Fri, 02 May 2014 00:36:27 +0200
parents 05d3f069cff2
children 8df78fe6d84c 5ecbed00da23
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/compiler/compileBroker.cpp src/share/vm/compiler/compileBroker.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompiler.hpp src/share/vm/graal/graalGlobals.hpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/graal/graalVMToCompiler.cpp src/share/vm/graal/graalVMToCompiler.hpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/oops/method.cpp src/share/vm/prims/jni.cpp src/share/vm/runtime/javaCalls.cpp src/share/vm/runtime/thread.cpp src/share/vm/runtime/thread.hpp src/share/vm/runtime/vmStructs.cpp src/share/vm/utilities/exceptions.cpp
diffstat 27 files changed, 244 insertions(+), 142 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri May 02 00:36:27 2014 +0200
@@ -26,6 +26,7 @@
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.bridge.VMToCompilerImpl.*;
 import static com.oracle.graal.nodes.StructuredGraph.*;
 import static com.oracle.graal.phases.common.InliningUtil.*;
@@ -117,11 +118,23 @@
      */
     private final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean();
 
-    public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking) {
+    /**
+     * The address of the native CompileTask associated with this compilation. If 0L, then this
+     * compilation is being managed by a Graal compilation queue otherwise its managed by a native
+     * HotSpot compilation queue.
+     */
+    private final long ctask;
+
+    public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, long ctask, boolean blocking) {
         this.backend = backend;
         this.method = method;
         this.entryBCI = entryBCI;
-        this.id = method.allocateCompileId(entryBCI);
+        if (ctask == 0L) {
+            this.id = method.allocateCompileId(entryBCI);
+        } else {
+            this.id = unsafe.getInt(ctask + backend.getRuntime().getConfig().compileTaskCompileIdOffset);
+        }
+        this.ctask = ctask;
         this.blocking = blocking;
         this.taskId = uniqueTaskIds.incrementAndGet();
         this.status = new AtomicReference<>(CompilationStatus.Queued);
@@ -337,13 +350,17 @@
                 System.exit(-1);
             }
         } finally {
+            int processedBytes = (int) (InlinedBytecodes.getCurrentValue() - previousInlinedBytecodes);
+            if (ctask != 0L) {
+                unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, processedBytes);
+            }
             if ((config.ciTime || config.ciTimeEach || PrintCompRate.getValue() != 0) && installedCode != null) {
-                long processedBytes = InlinedBytecodes.getCurrentValue() - previousInlinedBytecodes;
+
                 long time = CompilationTime.getCurrentValue() - previousCompilationTime;
                 TimeUnit timeUnit = CompilationTime.getTimeUnit();
                 long timeUnitsPerSecond = timeUnit.convert(1, TimeUnit.SECONDS);
                 CompilerToVM c2vm = backend.getRuntime().getCompilerToVM();
-                c2vm.notifyCompilationStatistics(id, method, entryBCI != INVOCATION_ENTRY_BCI, (int) processedBytes, time, timeUnitsPerSecond, installedCode);
+                c2vm.notifyCompilationStatistics(id, method, entryBCI != INVOCATION_ENTRY_BCI, processedBytes, time, timeUnitsPerSecond, installedCode);
             }
 
             if (clearFromCompilationQueue) {
@@ -388,7 +405,7 @@
         final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache();
         InstalledCode installedCode = null;
         try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) {
-            installedCode = codeCache.installMethod(method, compResult);
+            installedCode = codeCache.installMethod(method, compResult, ctask);
         } catch (Throwable e) {
             throw Debug.handle(e);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Fri May 02 00:36:27 2014 +0200
@@ -317,7 +317,7 @@
     class CTWCompilationTask extends CompilationTask {
 
         CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method) {
-            super(backend, method, INVOCATION_ENTRY_BCI, false);
+            super(backend, method, INVOCATION_ENTRY_BCI, 0L, false);
         }
 
         /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Fri May 02 00:36:27 2014 +0200
@@ -34,11 +34,17 @@
     public final HotSpotResolvedJavaMethod method;
     public final int entryBCI;
     public final int id;
+    public final long ctask;
 
     public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+        this(target, method, compResult, 0L);
+    }
+
+    public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) {
         super(target, compResult);
         this.method = method;
         this.entryBCI = compResult.getEntryBCI();
         this.id = compResult.getId();
+        this.ctask = ctask;
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri May 02 00:36:27 2014 +0200
@@ -170,7 +170,7 @@
                 String name = annotation.name();
                 Flags.Flag entry = flags.get(name);
                 if (entry == null) {
-                    if (!isRequired(currentArch, annotation.archs())) {
+                    if (annotation.optional() || !isRequired(currentArch, annotation.archs())) {
                         continue;
                     }
                     throw new IllegalArgumentException("flag not found: " + name);
@@ -716,6 +716,7 @@
     @HotSpotVMFlag(name = "CIPrintCompilerName") @Stable public boolean printCompilerName;
     @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
     @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking;
+    @HotSpotVMFlag(name = "UseGraalCompilationQueue", optional = true) @Stable public boolean useGraalCompilationQueue;
     @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
     @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload;
     @HotSpotVMFlag(name = "TieredCompilation") @Stable public boolean tieredCompilation;
@@ -1067,6 +1068,9 @@
     @HotSpotVMConstant(name = "JVM_ACC_MONITOR_MATCH") @Stable public int jvmAccMonitorMatch;
     @HotSpotVMConstant(name = "JVM_ACC_HAS_MONITOR_BYTECODES") @Stable public int jvmAccHasMonitorBytecodes;
 
+    @HotSpotVMField(name = "CompileTask::_compile_id", type = "uint", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskCompileIdOffset;
+    @HotSpotVMField(name = "CompileTask::_num_inlined_bytecodes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskNumInlinedBytecodesOffset;
+
     /**
      * Value of Method::extra_stack_entries().
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java	Fri May 02 00:36:27 2014 +0200
@@ -36,4 +36,6 @@
      * required on all architectures.
      */
     String[] archs() default {};
+
+    boolean optional() default false;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 02 00:36:27 2014 +0200
@@ -33,8 +33,10 @@
     /**
      * Compiles a method to machine code. This method is called from the VM
      * (VMToCompiler::compileMethod).
+     *
+     * @param ctask the CompileTask pointer if this is a request from a HotSpot compiler thread
      */
-    void compileMethod(long metaspaceMethod, int entryBCI, boolean blocking);
+    void compileMethod(long metaspaceMethod, int entryBCI, long ctask, boolean blocking);
 
     void shutdownCompiler() throws Exception;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 02 00:36:27 2014 +0200
@@ -192,55 +192,57 @@
             }
         }
 
-        // Create compilation queue.
-        CompilerThreadFactory factory = new CompilerThreadFactory("GraalCompilerThread", new DebugConfigAccess() {
-            public GraalDebugConfig getDebugConfig() {
-                return Debug.isEnabled() ? DebugEnvironment.initialize(log) : null;
-            }
-        });
-        compileQueue = new Queue(factory);
+        if (runtime.getConfig().useGraalCompilationQueue) {
+
+            // Create compilation queue.
+            CompilerThreadFactory factory = new CompilerThreadFactory("GraalCompilerThread", new DebugConfigAccess() {
+                public GraalDebugConfig getDebugConfig() {
+                    return Debug.isEnabled() ? DebugEnvironment.initialize(log) : null;
+                }
+            });
+            compileQueue = new Queue(factory);
 
-        // Create queue status printing thread.
-        if (PrintQueue.getValue()) {
-            Thread t = new Thread() {
+            // Create queue status printing thread.
+            if (PrintQueue.getValue()) {
+                Thread t = new Thread() {
 
-                @Override
-                public void run() {
-                    while (true) {
-                        TTY.println(compileQueue.toString());
-                        try {
-                            Thread.sleep(1000);
-                        } catch (InterruptedException e) {
+                    @Override
+                    public void run() {
+                        while (true) {
+                            TTY.println(compileQueue.toString());
+                            try {
+                                Thread.sleep(1000);
+                            } catch (InterruptedException e) {
+                            }
                         }
                     }
-                }
-            };
-            t.setDaemon(true);
-            t.start();
-        }
-
-        if (PrintCompRate.getValue() != 0) {
-            if (runtime.getConfig().ciTime || runtime.getConfig().ciTimeEach) {
-                throw new GraalInternalError("PrintCompRate is incompatible with CITime and CITimeEach");
+                };
+                t.setDaemon(true);
+                t.start();
             }
-            Thread t = new Thread() {
+
+            if (PrintCompRate.getValue() != 0) {
+                if (runtime.getConfig().ciTime || runtime.getConfig().ciTimeEach) {
+                    throw new GraalInternalError("PrintCompRate is incompatible with CITime and CITimeEach");
+                }
+                Thread t = new Thread() {
 
-                @Override
-                public void run() {
-                    while (true) {
-                        runtime.getCompilerToVM().printCompilationStatistics(true, false);
-                        runtime.getCompilerToVM().resetCompilationStatistics();
-                        try {
-                            Thread.sleep(PrintCompRate.getValue());
-                        } catch (InterruptedException e) {
+                    @Override
+                    public void run() {
+                        while (true) {
+                            runtime.getCompilerToVM().printCompilationStatistics(true, false);
+                            runtime.getCompilerToVM().resetCompilationStatistics();
+                            try {
+                                Thread.sleep(PrintCompRate.getValue());
+                            } catch (InterruptedException e) {
+                            }
                         }
                     }
-                }
-            };
-            t.setDaemon(true);
-            t.start();
+                };
+                t.setDaemon(true);
+                t.start();
+            }
         }
-
         BenchmarkCounters.initialize(runtime.getCompilerToVM());
 
         compilerStartTime = System.nanoTime();
@@ -346,23 +348,24 @@
     private void enqueue(Method m) throws Throwable {
         JavaMethod javaMethod = runtime.getHostProviders().getMetaAccess().lookupJavaMethod(m);
         assert !((HotSpotResolvedJavaMethod) javaMethod).isAbstract() && !((HotSpotResolvedJavaMethod) javaMethod).isNative() : javaMethod;
-        compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false);
+        compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, 0L, false);
     }
 
     public void shutdownCompiler() throws Exception {
-        try (Enqueueing enqueueing = new Enqueueing()) {
-            // We have to use a privileged action here because shutting down the compiler might be
-            // called from user code which very likely contains unprivileged frames.
-            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
-                public Void run() throws Exception {
-                    if (compileQueue != null) {
-                        compileQueue.shutdown();
+        if (runtime.getConfig().useGraalCompilationQueue) {
+            try (Enqueueing enqueueing = new Enqueueing()) {
+                // We have to use a privileged action here because shutting down the compiler might
+                // be called from user code which very likely contains unprivileged frames.
+                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws Exception {
+                        if (compileQueue != null) {
+                            compileQueue.shutdown();
+                        }
+                        return null;
                     }
-                    return null;
-                }
-            });
+                });
+            }
         }
-
         printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
         phaseTransition("final");
 
@@ -537,22 +540,34 @@
     }
 
     @Override
-    public void compileMethod(long metaspaceMethod, final int entryBCI, final boolean blocking) {
+    public void compileMethod(long metaspaceMethod, final int entryBCI, long ctask, final boolean blocking) {
         final HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod);
-        // We have to use a privileged action here because compilations are enqueued from user code
-        // which very likely contains unprivileged frames.
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            public Void run() {
-                compileMethod(method, entryBCI, blocking);
-                return null;
-            }
-        });
+        if (ctask != 0L) {
+            // This is on a VM CompilerThread - no user frames exist
+            compileMethod(method, entryBCI, ctask, false);
+        } else {
+            // We have to use a privileged action here because compilations are
+            // enqueued from user code which very likely contains unprivileged frames.
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    compileMethod(method, entryBCI, 0L, blocking);
+                    return null;
+                }
+            });
+        }
     }
 
     /**
      * Compiles a method to machine code.
      */
-    void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, final boolean blocking) {
+    void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, long ctask, final boolean blocking) {
+        if (ctask != 0L) {
+            HotSpotBackend backend = runtime.getHostBackend();
+            CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, false);
+            task.runCompilation(false);
+            return;
+        }
+
         boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI;
         if (osrCompilation && bootstrapRunning) {
             // no OSR compilations during bootstrap - the compiler is just too slow at this point,
@@ -575,7 +590,7 @@
                 assert method.isQueuedForCompilation();
 
                 HotSpotBackend backend = runtime.getHostBackend();
-                CompilationTask task = new CompilationTask(backend, method, entryBCI, block);
+                CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, block);
 
                 try {
                     compileQueue.execute(task);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Fri May 02 00:17:40 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Fri May 02 00:36:27 2014 +0200
@@ -206,12 +206,12 @@
         return installedCode;
     }
 
-    public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+    public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) {
         if (compResult.getId() == -1) {
             compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true);
-        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult), installedCode, method.getSpeculationLog());
+        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult, ctask), installedCode, method.getSpeculationLog());
         return logOrDump(installedCode, compResult);
     }
 
@@ -236,7 +236,7 @@
     @Override
     public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        return installMethod(hotspotMethod, compResult);
+        return installMethod(hotspotMethod, compResult, 0L);
     }
 
     public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
--- a/src/share/vm/classfile/systemDictionary.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri May 02 00:36:27 2014 +0200
@@ -216,7 +216,7 @@
 // Forwards to resolve_instance_class_or_null
 
 Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) {
-  assert(!THREAD->is_Compiler_thread(),
+  assert(THREAD->can_call_java(),
          err_msg("can not load classes with compiler thread: class=%s, classloader=%s",
                  class_name->as_C_string(),
                  class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string()));
@@ -2347,7 +2347,7 @@
                                                           TRAPS) {
   methodHandle empty;
   assert(EnableInvokeDynamic, "");
-  assert(!THREAD->is_Compiler_thread(), "");
+  assert(THREAD->can_call_java() ,"");
   Handle method_type =
     SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
   if (false) {  // FIXME: Decide if the Java upcall should resolve signatures.
@@ -2400,7 +2400,7 @@
   if (spe != NULL && spe->method_type() != NULL) {
     assert(java_lang_invoke_MethodType::is_instance(spe->method_type()), "");
     return Handle(THREAD, spe->method_type());
-  } else if (THREAD->is_Compiler_thread()) {
+  } else if (!THREAD->can_call_java()) {
     warning("SystemDictionary::find_method_handle_type called from compiler thread");  // FIXME
     return Handle();  // do not attempt from within compiler, unless it was cached
   }
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri May 02 00:36:27 2014 +0200
@@ -367,7 +367,7 @@
   template(compileTheWorld_name,                  "compileTheWorld")                                                                  \
   template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
   template(compileMethod_name,                    "compileMethod")                                                                    \
-  template(compileMethod_signature,               "(JIZ)V")                                                                           \
+  template(compileMethod_signature,               "(JIJZ)V")                                                                          \
   template(setOption_name,                        "setOption")                                                                        \
   template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
   template(finalizeOptions_name,                  "finalizeOptions")                                                                  \
--- a/src/share/vm/compiler/compileBroker.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/compiler/compileBroker.cpp	Fri May 02 00:36:27 2014 +0200
@@ -804,7 +804,7 @@
 
 #if defined(COMPILERGRAAL)
   _compilers[1] = graal;
-  c2_count = 0;
+  c2_count = UseGraalCompilationQueue ? 0 : c2_count;
 #endif // COMPILERGRAAL
 
 #ifdef COMPILER2
@@ -1143,22 +1143,24 @@
     return;
   }
 
-#if defined(COMPILERGRAAL)
-  // In tiered mode we want to only handle highest tier compiles and
-  // in non-tiered mode the default level should be
-  // CompLevel_full_optimization which equals CompLevel_highest_tier.
-  assert(TieredCompilation || comp_level == CompLevel_full_optimization, "incorrect compile level");
-  assert(CompLevel_full_optimization == CompLevel_highest_tier, "incorrect level definition");
-  if (comp_level == CompLevel_full_optimization) {
-    if (!JavaThread::current()->is_graal_compiling()) {
-      bool blockingCompilation = is_compile_blocking(method, osr_bci);
-      GraalCompiler::instance()->compile_method(method, osr_bci, blockingCompilation);
-    } else {
-      // Can't enqueue this request because there would be no one to service it, so simply return.
+#ifdef COMPILERGRAAL
+  if (UseGraalCompilationQueue) {
+    // In tiered mode we want to only handle highest tier compiles and
+    // in non-tiered mode the default level should be
+    // CompLevel_full_optimization which equals CompLevel_highest_tier.
+    assert(TieredCompilation || comp_level == CompLevel_full_optimization, "incorrect compile level");
+    assert(CompLevel_full_optimization == CompLevel_highest_tier, "incorrect level definition");
+    if (comp_level == CompLevel_full_optimization) {
+      if (!JavaThread::current()->is_graal_compiling()) {
+        bool blockingCompilation = is_compile_blocking(method, osr_bci);
+        GraalCompiler::instance()->compile_method(method, osr_bci, NULL, blockingCompilation);
+      } else {
+        // Can't enqueue this request because there would be no one to service it, so simply return.
+      }
+      return;
     }
-    return;
+    assert(TieredCompilation, "should only reach here in tiered mode");
   }
-  assert(TieredCompilation, "should only reach here in tiered mode");
 #endif // COMPILERGRAAL
 
   // Outputs from the following MutexLocker block:
@@ -1881,6 +1883,35 @@
   tty->print(s.as_string());
 }
 
+void CompileBroker::post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env) {
+
+  if (success) {
+    task->mark_success();
+    if (ci_env != NULL) {
+      task->set_num_inlined_bytecodes(ci_env->num_inlined_bytecodes());
+    }
+    if (_compilation_log != NULL) {
+      nmethod* code = task->code();
+      if (code != NULL) {
+        _compilation_log->log_nmethod(thread, code);
+      }
+    }
+  }
+
+  // simulate crash during compilation
+  assert(task->compile_id() != CICrashAt, "just as planned");
+  if (event.should_commit()) {
+    event.set_method(task->method());
+    event.set_compileID(task->compile_id());
+    event.set_compileLevel(task->comp_level());
+    event.set_succeded(task->is_success());
+    event.set_isOsr(task->osr_bci() != CompileBroker::standard_entry_bci);
+    event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size());
+    event.set_inlinedBytes(task->num_inlined_bytecodes());
+    event.commit();
+  }
+}
+
 // ------------------------------------------------------------------
 // CompileBroker::invoke_compiler_on_method
 //
@@ -1929,6 +1960,21 @@
   push_jni_handle_block();
   Method* target_handle = task->method();
   int compilable = ciEnv::MethodCompilable;
+  AbstractCompiler *comp = compiler(task_level);
+
+#ifdef COMPILERGRAAL
+  if (comp != NULL && comp->is_graal()) {
+    assert(!UseGraalCompilationQueue, "should not reach here");
+    GraalCompiler* graal = (GraalCompiler*) comp;
+
+    TraceTime t1("compilation", &time);
+    EventCompilation event;
+
+    graal->compile_method(target_handle, osr_bci, task, false);
+
+    post_compile(thread, task, event, task->code() != NULL, NULL);
+  } else
+#endif // COMPILERGRAAL
   {
     int system_dictionary_modification_counter;
     {
@@ -1960,7 +2006,6 @@
     TraceTime t1("compilation", &time);
     EventCompilation event;
 
-    AbstractCompiler *comp = compiler(task_level);
     if (comp == NULL) {
       ci_env.record_method_not_compilable("no compiler", !TieredCompilation);
     } else {
@@ -1988,28 +2033,9 @@
             err_msg_res("COMPILE SKIPPED: %s",      ci_env.failure_reason());
         task->print_compilation(tty, msg);
       }
-    } else {
-      task->mark_success();
-      task->set_num_inlined_bytecodes(ci_env.num_inlined_bytecodes());
-      if (_compilation_log != NULL) {
-        nmethod* code = task->code();
-        if (code != NULL) {
-          _compilation_log->log_nmethod(thread, code);
-        }
-      }
     }
-    // simulate crash during compilation
-    assert(task->compile_id() != CICrashAt, "just as planned");
-    if (event.should_commit()) {
-      event.set_method(target->get_Method());
-      event.set_compileID(compile_id);
-      event.set_compileLevel(task->comp_level());
-      event.set_succeded(task->is_success());
-      event.set_isOsr(is_osr);
-      event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size());
-      event.set_inlinedBytes(task->num_inlined_bytecodes());
-      event.commit();
-    }
+
+    post_compile(thread, task, event, !ci_env.failing(), &ci_env);
   }
   pop_jni_handle_block();
 
--- a/src/share/vm/compiler/compileBroker.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/compiler/compileBroker.hpp	Fri May 02 00:36:27 2014 +0200
@@ -28,6 +28,7 @@
 #include "ci/compilerInterface.hpp"
 #include "compiler/abstractCompiler.hpp"
 #include "runtime/perfData.hpp"
+#include "trace/tracing.hpp"
 
 class nmethod;
 class nmethodLocker;
@@ -339,6 +340,7 @@
   static void wait_for_completion(CompileTask* task);
 
   static void invoke_compiler_on_method(CompileTask* task);
+  static void post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env);
   static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level);
   static void push_jni_handle_block();
   static void pop_jni_handle_block();
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 02 00:36:27 2014 +0200
@@ -422,12 +422,13 @@
     methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
     jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
     jint id = HotSpotCompiledNmethod::id(compiled_code);
+    CompileTask* task = (CompileTask*) (address) HotSpotCompiledNmethod::ctask(compiled_code);
     if (id == -1) {
       // Make sure a valid compile_id is associated with every compile
       id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
     }
     result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
-        GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, id, false, installed_code, speculation_log);
+        GraalCompiler::instance(), _debug_recorder, _dependencies, task, id, false, installed_code, speculation_log);
     cb = nm;
   }
 
--- a/src/share/vm/graal/graalCompiler.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Fri May 02 00:36:27 2014 +0200
@@ -44,7 +44,10 @@
 
 // Initialization
 void GraalCompiler::initialize() {
-  
+  if (!should_perform_init()) {
+    return;
+  }
+
   ThreadToNativeFromVM trans(JavaThread::current());
   JavaThread* THREAD = JavaThread::current();
   TRACE_graal_1("GraalCompiler::initialize");
@@ -100,7 +103,7 @@
     if (UseCompiler) {
       _external_deopt_i2c_entry = create_external_deopt_i2c();
 #ifdef COMPILERGRAAL
-      bool bootstrap = FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal;
+      bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
 #else
       bool bootstrap = false;
 #endif
@@ -172,7 +175,7 @@
   return buffer_blob;
 }
 
-void GraalCompiler::compile_method(methodHandle method, int entry_bci, jboolean blocking) {
+void GraalCompiler::compile_method(methodHandle method, int entry_bci, CompileTask* task, jboolean blocking) {
   GRAAL_EXCEPTION_CONTEXT
   if (!_initialized) {
     CompilationPolicy::policy()->delay_compilation(method());
@@ -182,7 +185,7 @@
   assert(_initialized, "must already be initialized");
   ResourceMark rm;
   thread->set_is_graal_compiling(true);
-  VMToCompiler::compileMethod(method(), entry_bci, blocking);
+  VMToCompiler::compileMethod(method(), entry_bci, (jlong) (address) task, blocking);
   thread->set_is_graal_compiling(false);
 }
 
--- a/src/share/vm/graal/graalCompiler.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Fri May 02 00:36:27 2014 +0200
@@ -60,7 +60,7 @@
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
-  void compile_method(methodHandle target, int entry_bci, jboolean blocking);
+  void compile_method(methodHandle target, int entry_bci, CompileTask* task, jboolean blocking);
 
   // Print compilation timers and statistics
   virtual void print_timers();
--- a/src/share/vm/graal/graalGlobals.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalGlobals.hpp	Fri May 02 00:36:27 2014 +0200
@@ -52,6 +52,9 @@
   COMPILERGRAAL_PRESENT(product(bool, BootstrapGraal, true,                 \
           "Bootstrap Graal before running Java main method"))               \
                                                                             \
+  COMPILERGRAAL_PRESENT(product(bool, UseGraalCompilationQueue, false,      \
+          "Use non-native compilation queue for Graal"))                    \
+                                                                            \
   product(bool, ForceGraalInitialization, false,                            \
           "Force VM to initialize the compiler even if not used")           \
                                                                             \
--- a/src/share/vm/graal/graalJavaAccess.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Fri May 02 00:36:27 2014 +0200
@@ -88,6 +88,7 @@
     oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;")                                                     \
     int_field(HotSpotCompiledNmethod, entryBCI)                                                                                                                \
     int_field(HotSpotCompiledNmethod, id)                                                                                                                      \
+    long_field(HotSpotCompiledNmethod, ctask)                                                                                                                  \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledRuntimeStub)                                                                                                                      \
     oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;")                                                                                      \
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 02 00:36:27 2014 +0200
@@ -111,7 +111,7 @@
   check_pending_exception("Error while calling finalizeOptions");
 }
 
-void VMToCompiler::compileMethod(Method* method, int entry_bci, jboolean blocking) {
+void VMToCompiler::compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking) {
   assert(method != NULL, "just checking");
   Thread* THREAD = Thread::current();
   JavaValue result(T_VOID);
@@ -119,6 +119,7 @@
   args.push_oop(instance());
   args.push_long((jlong) (address) method);
   args.push_int(entry_bci);
+  args.push_long(ctask);
   args.push_int(blocking);
   JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileMethod");
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 02 00:36:27 2014 +0200
@@ -60,8 +60,8 @@
   // public static void HotSpotOptions.finalizeOptions(boolean ciTime);
   static void finalizeOptions(jboolean ciTime);
 
-  // public abstract boolean compileMethod(long vmId, int entry_bci, boolean blocking);
-  static void compileMethod(Method* method, int entry_bci, jboolean blocking);
+  // public abstract boolean compileMethod(long metaspaceMethod, int entryBCI, long ctask, boolean blocking);
+  static void compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking);
 
   // public abstract void shutdownCompiler();
   static void shutdownCompiler();
--- a/src/share/vm/interpreter/linkResolver.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/interpreter/linkResolver.cpp	Fri May 02 00:36:27 2014 +0200
@@ -113,7 +113,7 @@
     // Note: with several active threads, the must_be_compiled may be true
     //       while can_be_compiled is false; remove assert
     // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
-    if (THREAD->is_Compiler_thread()) {
+    if (!THREAD->can_call_java()) {
       // don't force compilation, resolve was on behalf of compiler
       return;
     }
@@ -364,7 +364,7 @@
         return;
       }
     } else if (iid == vmIntrinsics::_invokeGeneric
-               && !THREAD->is_Compiler_thread()
+               && THREAD->can_call_java()
                && appendix_result_or_null != NULL) {
       // This is a method with type-checking semantics.
       // We will ask Java code to spin an adapter method for it.
--- a/src/share/vm/oops/method.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/oops/method.cpp	Fri May 02 00:36:27 2014 +0200
@@ -1314,7 +1314,7 @@
 
 // These two methods are static since a GC may move the Method
 bool Method::load_signature_classes(methodHandle m, TRAPS) {
-  if (THREAD->is_Compiler_thread()) {
+  if (!THREAD->can_call_java()) {
     // There is nothing useful this routine can do from within the Compile thread.
     // Hopefully, the signature contains only well-known classes.
     // We could scan for this and return true/false, but the caller won't care.
--- a/src/share/vm/prims/jni.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/prims/jni.cpp	Fri May 02 00:36:27 2014 +0200
@@ -5174,15 +5174,19 @@
     *(JNIEnv**)penv = thread->jni_environment();
 
 #ifdef GRAAL
-    // GraalCompiler needs to have been created in compileBroker.cpp
-    GraalCompiler* graal_compiler = GraalCompiler::instance();
-    if (ForceGraalInitialization && graal_compiler == NULL) {
-      graal_compiler = new GraalCompiler();
-    }
-    if (graal_compiler != NULL) {
-      graal_compiler->initialize();
+    if (COMPILERGRAAL_PRESENT(UseGraalCompilationQueue) NOT_COMPILERGRAAL(true)) {
+      // GraalCompiler needs to have been created in compileBroker.cpp
+      GraalCompiler* graal_compiler = GraalCompiler::instance();
+      if (ForceGraalInitialization && graal_compiler == NULL) {
+        graal_compiler = new GraalCompiler();
+      }
+      if (graal_compiler != NULL) {
+        graal_compiler->initialize();
+      } else {
+        assert(!UseCompiler, "why isn't there any compiler?");
+      }
     } else {
-      assert(!UseCompiler, "why isn't there any compiler?");
+      // Graal is initialized on a CompilerThread
     }
 #endif
 
--- a/src/share/vm/runtime/javaCalls.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/runtime/javaCalls.cpp	Fri May 02 00:36:27 2014 +0200
@@ -52,7 +52,7 @@
 
   guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");
   assert(!thread->owns_locks(), "must release all locks when leaving VM");
-  guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");
+  guarantee(thread->can_call_java(), "cannot make java calls from the compiler");
   _result   = result;
 
   // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub,
@@ -366,7 +366,7 @@
 #endif
 
 
-  assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");
+  assert(thread->can_call_java(), "cannot compile from the compiler");
   if (CompilationPolicy::must_be_compiled(method)) {
     CompileBroker::compile_method(method, InvocationEntryBci,
                                   CompilationPolicy::policy()->initial_compile_level(),
--- a/src/share/vm/runtime/thread.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/runtime/thread.cpp	Fri May 02 00:36:27 2014 +0200
@@ -2253,7 +2253,7 @@
 
   // Do not throw asynchronous exceptions against the compiler thread
   // (the compiler thread should not be a Java thread -- fix in 1.4.2)
-  if (is_Compiler_thread()) return;
+  if (!can_call_java()) return;
 
   {
     // Actually throw the Throwable against the target Thread - however
@@ -3311,6 +3311,12 @@
 #endif
 }
 
+#ifdef COMPILERGRAAL
+bool CompilerThread::can_call_java() const {
+  return _compiler != NULL && _compiler->is_graal();
+}
+#endif
+
 void CompilerThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
   JavaThread::oops_do(f, cld_f, cf);
   if (_scanned_nmethod != NULL && cf != NULL) {
@@ -4334,7 +4340,7 @@
   {
     MutexLockerEx ml(doLock ? Threads_lock : NULL);
     ALL_JAVA_THREADS(p) {
-      if (p->is_Compiler_thread()) continue;
+      if (!p->can_call_java()) continue;
 
       address pending = (address)p->current_pending_monitor();
       if (pending == monitor) {             // found a match
--- a/src/share/vm/runtime/thread.hpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/runtime/thread.hpp	Fri May 02 00:36:27 2014 +0200
@@ -321,6 +321,9 @@
   virtual bool is_Named_thread() const               { return false; }
   virtual bool is_Worker_thread() const              { return false; }
 
+  // Can this thread make Java upcalls
+  virtual bool can_call_java() const                 { return true;  }
+
   // Casts
   virtual WorkerThread* as_Worker_thread() const     { return NULL; }
 
@@ -1876,8 +1879,13 @@
   CompilerThread(CompileQueue* queue, CompilerCounters* counters);
 
   bool is_Compiler_thread() const                { return true; }
+
+#ifdef COMPILERGRAAL
+  virtual bool can_call_java() const;
+#endif
+
   // Hide this compiler thread from external view.
-  bool is_hidden_from_external_view() const      { return true; }
+  bool is_hidden_from_external_view() const      { return !can_call_java(); }
 
   void set_compiler(AbstractCompiler* c)         { _compiler = c; }
   AbstractCompiler* compiler() const             { return _compiler; }
--- a/src/share/vm/runtime/vmStructs.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri May 02 00:36:27 2014 +0200
@@ -1307,6 +1307,7 @@
   nonstatic_field(CompileTask,                 _osr_bci,                                     int)                                    \
   nonstatic_field(CompileTask,                 _comp_level,                                  int)                                    \
   nonstatic_field(CompileTask,                 _compile_id,                                  uint)                                   \
+  nonstatic_field(CompileTask,                 _num_inlined_bytecodes,                       int)                                    \
   nonstatic_field(CompileTask,                 _next,                                        CompileTask*)                           \
   nonstatic_field(CompileTask,                 _prev,                                        CompileTask*)                           \
                                                                                                                                      \
--- a/src/share/vm/utilities/exceptions.cpp	Fri May 02 00:17:40 2014 +0200
+++ b/src/share/vm/utilities/exceptions.cpp	Fri May 02 00:36:27 2014 +0200
@@ -84,7 +84,7 @@
 #endif // ASSERT
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread() ) {
+      || !thread->can_call_java() ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
     thread->set_pending_exception(Universe::vm_exception(), file, line);
@@ -107,7 +107,7 @@
   }
 
   if (thread->is_VM_thread()
-      || thread->is_Compiler_thread() ) {
+      || !thread->can_call_java() ) {
     // We do not care what kind of exception we get for the vm-thread or a thread which
     // is compiling.  We just install a dummy exception object
     thread->set_pending_exception(Universe::vm_exception(), file, line);