changeset 15582:063ec2920d21

made Graal runtime initialization in hosted mode lazy
author Doug Simon <doug.simon@oracle.com>
date Fri, 09 May 2014 18:46:41 +0200
parents 0dc0926cf0d8
children cad72380191d
files 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 src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp src/cpu/x86/vm/graalCodeInstaller_x86.cpp src/gpu/hsail/vm/gpu_hsail.cpp src/gpu/ptx/vm/gpu_ptx.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCompiler.cpp src/share/vm/graal/graalCompiler.hpp src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp src/share/vm/graal/graalVMToCompiler.cpp src/share/vm/graal/graalVMToCompiler.hpp src/share/vm/prims/jni.cpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/java.cpp src/share/vm/runtime/javaCalls.cpp src/share/vm/runtime/mutexLocker.cpp src/share/vm/runtime/mutexLocker.hpp
diffstat 20 files changed, 423 insertions(+), 299 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 09 17:59:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java	Fri May 09 18:46:41 2014 +0200
@@ -30,6 +30,12 @@
  */
 public interface VMToCompiler {
 
+    void startRuntime() throws Throwable;
+
+    void startCompiler(boolean bootstrapEnabled) throws Throwable;
+
+    void bootstrap() throws Throwable;
+
     /**
      * Compiles a method to machine code. This method is called from the VM
      * (VMToCompiler::compileMethod).
@@ -40,9 +46,7 @@
 
     void shutdownCompiler() throws Exception;
 
-    void startCompiler(boolean bootstrapEnabled) throws Throwable;
-
-    void bootstrap() throws Throwable;
+    void shutdownRuntime() throws Throwable;
 
     void compileTheWorld() throws Throwable;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 09 17:59:15 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri May 09 18:46:41 2014 +0200
@@ -136,15 +136,13 @@
 
     private PrintStream log = System.out;
 
-    private long compilerStartTime;
+    private long runtimeStartTime;
 
     public VMToCompilerImpl(HotSpotGraalRuntime runtime) {
         this.runtime = runtime;
     }
 
-    public void startCompiler(boolean bootstrapEnabled) throws Throwable {
-
-        bootstrapRunning = bootstrapEnabled;
+    public void startRuntime() throws Throwable {
 
         if (LogFile.getValue() != null) {
             try {
@@ -192,6 +190,15 @@
             }
         }
 
+        BenchmarkCounters.initialize(runtime.getCompilerToVM());
+
+        runtimeStartTime = System.nanoTime();
+    }
+
+    public void startCompiler(boolean bootstrapEnabled) throws Throwable {
+
+        bootstrapRunning = bootstrapEnabled;
+
         if (runtime.getConfig().useGraalCompilationQueue) {
 
             // Create compilation queue.
@@ -243,9 +250,6 @@
                 t.start();
             }
         }
-        BenchmarkCounters.initialize(runtime.getCompilerToVM());
-
-        compilerStartTime = System.nanoTime();
     }
 
     /**
@@ -274,7 +278,7 @@
             TTY.flush();
         }
 
-        long startTime = System.currentTimeMillis();
+        long boostrapStartTime = System.currentTimeMillis();
 
         boolean firstRun = true;
         do {
@@ -310,12 +314,12 @@
                 // Are we out of time?
                 final int timedBootstrap = TimedBootstrap.getValue();
                 if (timedBootstrap != -1) {
-                    if ((System.currentTimeMillis() - startTime) > timedBootstrap) {
+                    if ((System.currentTimeMillis() - boostrapStartTime) > timedBootstrap) {
                         break;
                     }
                 }
             }
-        } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue());
+        } while ((System.currentTimeMillis() - boostrapStartTime) <= TimedBootstrap.getValue());
 
         if (ResetDebugValuesAfterBootstrap.getValue()) {
             printDebugValues("bootstrap", true);
@@ -326,7 +330,7 @@
         bootstrapRunning = false;
 
         if (PrintBootstrap.getValue()) {
-            TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - startTime, compileQueue.getCompletedTaskCount());
+            TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - boostrapStartTime, compileQueue.getCompletedTaskCount());
         }
 
         System.gc();
@@ -366,11 +370,14 @@
                 });
             }
         }
+    }
+
+    public void shutdownRuntime() throws Exception {
         printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
         phaseTransition("final");
 
         SnippetCounter.printGroups(TTY.out().out());
-        BenchmarkCounters.shutdown(runtime.getCompilerToVM(), compilerStartTime);
+        BenchmarkCounters.shutdown(runtime.getCompilerToVM(), runtimeStartTime);
     }
 
     private void printDebugValues(String phase, boolean reset) throws GraalInternalError {
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Fri May 09 18:46:41 2014 +0200
@@ -22,7 +22,7 @@
  */
 
 #include "graal/graalCodeInstaller.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalCompilerToVM.hpp"
 #include "graal/graalJavaAccess.hpp"
 
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Fri May 09 18:46:41 2014 +0200
@@ -25,7 +25,6 @@
 #include "compiler/disassembler.hpp"
 #include "runtime/javaCalls.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
 #include "graal/graalCodeInstaller.hpp"
 #include "graal/graalJavaAccess.hpp"
 #include "graal/graalCompilerToVM.hpp"
--- a/src/gpu/hsail/vm/gpu_hsail.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/gpu/hsail/vm/gpu_hsail.cpp	Fri May 09 18:46:41 2014 +0200
@@ -33,7 +33,7 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalJavaAccess.hpp"
 #include "hsailKernelArguments.hpp"
 #include "hsailJavaCallArguments.hpp"
--- a/src/gpu/ptx/vm/gpu_ptx.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/gpu/ptx/vm/gpu_ptx.cpp	Fri May 09 18:46:41 2014 +0200
@@ -34,7 +34,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/vframe.hpp"
 #include "graal/graalEnv.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 
 #define T_BYTE_SIZE        1
 #define T_BOOLEAN_SIZE     4
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri May 09 18:46:41 2014 +0200
@@ -360,27 +360,13 @@
   template(com_oracle_graal_api_code_SpeculationLog,                 "com/oracle/graal/api/code/SpeculationLog")                      \
   /* graal.gpu */                                                                                                                     \
   template(com_oracle_graal_gpu_ExternalCompilationResult,           "com/oracle/graal/gpu/ExternalCompilationResult")                \
-  /* graal.truffle */                                                                                                                 \
-  template(com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime,   "com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime")        \
-  template(startCompiler_name,                    "startCompiler")                                                                    \
-  template(bootstrap_name,                        "bootstrap")                                                                        \
-  template(compileTheWorld_name,                  "compileTheWorld")                                                                  \
-  template(shutdownCompiler_name,                 "shutdownCompiler")                                                                 \
+  /* graal method and field names */                                                                                                  \
   template(compileMethod_name,                    "compileMethod")                                                                    \
   template(compileMethod_signature,               "(JIJZ)V")                                                                          \
   template(setOption_name,                        "setOption")                                                                        \
   template(setOption_signature,                   "(Ljava/lang/String;)Z")                                                            \
-  template(finalizeOptions_name,                  "finalizeOptions")                                                                  \
   template(getVMToCompiler_name,                  "getVMToCompiler")                                                                  \
   template(getVMToCompiler_signature,             "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;")                                 \
-  template(runtime_name,                          "runtime")                                                                          \
-  template(runtime_signature,                     "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;")                                 \
-  template(makeInstance_name,                     "makeInstance")                                                                     \
-  template(makeInstance_signature,                "()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;")                       \
-  template(initialize_name,                       "initialize")                                                                       \
-  template(forObject_name,                        "forObject")                                                                        \
-  template(callbackInternal_name,                 "callbackInternal")                                                                 \
-  template(callback_signature,                    "(Ljava/lang/Object;)Ljava/lang/Object;")                                           \
                                                                       \
   /* common method and field names */                                                             \
   template(object_initializer_name,                   "<init>")                                   \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri May 09 18:46:41 2014 +0200
@@ -202,7 +202,7 @@
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
   }
 
-  BasicType type = GraalCompiler::kindToBasicType(Kind::typeChar(Value::kind(value)));
+  BasicType type = GraalRuntime::kindToBasicType(Kind::typeChar(Value::kind(value)));
   Location::Type locationType = Location::normal;
   if (type == T_OBJECT || type == T_ARRAY) locationType = Location::oop;
 
@@ -382,7 +382,7 @@
 
 // constructor used to create a method
 GraalEnv::CodeInstallResult CodeInstaller::install(Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) {
-  BufferBlob* buffer_blob = GraalCompiler::initialize_buffer_blob();
+  BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob();
   if (buffer_blob == NULL) {
     return GraalEnv::cache_full;
   }
--- a/src/share/vm/graal/graalCompiler.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.cpp	Fri May 09 18:46:41 2014 +0200
@@ -25,39 +25,35 @@
 #include "memory/oopFactory.hpp"
 #include "runtime/javaCalls.hpp"
 #include "graal/graalCompiler.hpp"
-#include "graal/graalJavaAccess.hpp"
 #include "graal/graalVMToCompiler.hpp"
-#include "graal/graalCompilerToVM.hpp"
 #include "graal/graalEnv.hpp"
 #include "graal/graalRuntime.hpp"
-#include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/globals_extension.hpp"
 
 GraalCompiler* GraalCompiler::_instance = NULL;
 
 GraalCompiler::GraalCompiler() : AbstractCompiler(graal) {
-  _initialized = false;
+#ifdef COMPILERGRAAL
+  _started = false;
+#endif
   assert(_instance == NULL, "only one instance allowed");
   _instance = this;
 }
 
 // Initialization
 void GraalCompiler::initialize() {
-  if (!should_perform_init()) {
+#ifdef COMPILERGRAAL
+  if (!UseCompiler || !should_perform_init()) {
     return;
   }
 
-  uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
-  uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
-  AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
-  NOT_LP64(error("check TLAB allocation code for address space conflicts"));
+  GraalRuntime::initialize();
 
-  BufferBlob* buffer_blob = initialize_buffer_blob();
-#ifdef COMPILERGRAAL
+  BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob();
   if (!UseGraalCompilationQueue) {
     // This path is used for initialization both by the native queue and the graal queue
-    // but set_state acquired a lock which might not be safe during JVM_CreateJavaVM, so
+    // but set_state acquires a lock which might not be safe during JVM_CreateJavaVM, so
     // only update the state flag for the native queue.
     if (buffer_blob == NULL) {
       set_state(failed);
@@ -65,144 +61,61 @@
       set_state(initialized);
     }
   }
-#endif
-
-  ThreadToNativeFromVM trans(JavaThread::current());
-  JavaThread* THREAD = JavaThread::current();
-  TRACE_graal_1("GraalCompiler::initialize");
-
-  JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment();
-  jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl");
-  if (klass == NULL) {
-    tty->print_cr("graal CompilerToVMImpl class not found");
-    vm_abort(false);
-  }
-  env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count());
-  
-  ResourceMark rm;
-  HandleMark hm;
-  {
-    GRAAL_VM_ENTRY_MARK;
-    check_pending_exception("Could not register natives");
-  }
-
-  graal_compute_offsets();
-
-  // Ensure _non_oop_bits is initialized
-  Universe::non_oop_word();
 
   {
-    GRAAL_VM_ENTRY_MARK;
     HandleMark hm;
-    VMToCompiler::initOptions();
-    for (int i = 0; i < Arguments::num_graal_args(); ++i) {
-      const char* arg = Arguments::graal_args_array()[i];
-      Handle option = java_lang_String::create_from_str(arg, THREAD);
-      jboolean result = VMToCompiler::setOption(option);
-      if (!result) {
-        tty->print_cr("Invalid option for graal: -G:%s", arg);
-        vm_abort(false);
-      }
-    }
-    VMToCompiler::finalizeOptions(CITime || CITimeEach);
 
-    if (UseCompiler) {
-      _external_deopt_i2c_entry = create_external_deopt_i2c();
-#ifdef COMPILERGRAAL
-      bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
-#else
-      bool bootstrap = false;
+    bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal);
+    VMToCompiler::startCompiler(bootstrap);
+    _started = true;
+    CompilationPolicy::completed_vm_startup();
+    if (bootstrap) {
+      // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping.
+      FlagSetting a(UseInterpreter, true);
+      FlagSetting b(BackgroundCompilation, true);
+#ifndef PRODUCT
+      // Turn off CompileTheWorld during bootstrap so that a counter overflow event
+      // triggers further compilation (see NonTieredCompPolicy::event()) hence
+      // allowing a complete bootstrap
+      FlagSetting c(CompileTheWorld, false);
 #endif
-      VMToCompiler::startCompiler(bootstrap);
-      _initialized = true;
-      CompilationPolicy::completed_vm_startup();
-      if (bootstrap) {
-        // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping.
-        FlagSetting a(UseInterpreter, true);
-        FlagSetting b(BackgroundCompilation, true);
-#ifndef PRODUCT
-        // Turn off CompileTheWorld during bootstrap so that a counter overflow event
-        // triggers further compilation (see NonTieredCompPolicy::event()) hence
-        // allowing a complete bootstrap
-        FlagSetting c(CompileTheWorld, false);
-#endif
-        VMToCompiler::bootstrap();
-      }
+      VMToCompiler::bootstrap();
+    }
 
 #ifndef PRODUCT
-      if (CompileTheWorld) {
-        // We turn off CompileTheWorld so that Graal can
-        // be compiled by C1/C2 when Graal does a CTW.
-        CompileTheWorld = false;
-        VMToCompiler::compileTheWorld();
-      }
+    if (CompileTheWorld) {
+      VMToCompiler::compileTheWorld();
+    }
 #endif
-    }
   }
+#endif // COMPILERGRAAL
 }
 
-address GraalCompiler::create_external_deopt_i2c() {
-  ResourceMark rm;
-  BufferBlob* buffer = BufferBlob::create("externalDeopt", 1*K);
-  CodeBuffer cb(buffer);
-  short buffer_locs[20];
-  cb.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo));
-  MacroAssembler masm(&cb);
-
-  int total_args_passed = 5;
-
-  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
-  VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
-  int i = 0;
-  sig_bt[i++] = T_INT;
-  sig_bt[i++] = T_LONG;
-  sig_bt[i++] = T_VOID; // long stakes 2 slots
-  sig_bt[i++] = T_INT;
-  sig_bt[i++] = T_OBJECT;
-
-  int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
-
-  SharedRuntime::gen_i2c_adapter(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
-  masm.flush();
-
-  return AdapterBlob::create(&cb)->content_begin();
-}
-
-
-BufferBlob* GraalCompiler::initialize_buffer_blob() {
-  JavaThread* THREAD = JavaThread::current();
-  BufferBlob* buffer_blob = THREAD->get_buffer_blob();
-  if (buffer_blob == NULL) {
-    buffer_blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit);
-    if (buffer_blob != NULL) {
-      THREAD->set_buffer_blob(buffer_blob);
-    }
-  }
-  return buffer_blob;
-}
-
+#ifdef COMPILERGRAAL
 void GraalCompiler::compile_method(methodHandle method, int entry_bci, CompileTask* task, jboolean blocking) {
   GRAAL_EXCEPTION_CONTEXT
-  if (!_initialized) {
+  if (!_started) {
     CompilationPolicy::policy()->delay_compilation(method());
     return;
   }
 
-  assert(_initialized, "must already be initialized");
+  assert(_started, "must already be started");
   ResourceMark rm;
   thread->set_is_graal_compiling(true);
   VMToCompiler::compileMethod(method(), entry_bci, (jlong) (address) task, blocking);
   thread->set_is_graal_compiling(false);
 }
 
+
 // Compilation entry point for methods
 void GraalCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
   ShouldNotReachHere();
 }
 
-void GraalCompiler::exit() {
-  if (_initialized) {
+void GraalCompiler::shutdown() {
+  if (_started) {
     VMToCompiler::shutdownCompiler();
+    _started = false;
   }
 }
 
@@ -211,22 +124,4 @@
   TRACE_graal_1("GraalCompiler::print_timers");
 }
 
-BasicType GraalCompiler::kindToBasicType(jchar ch) {
-  switch(ch) {
-    case 'z': return T_BOOLEAN;
-    case 'b': return T_BYTE;
-    case 's': return T_SHORT;
-    case 'c': return T_CHAR;
-    case 'i': return T_INT;
-    case 'f': return T_FLOAT;
-    case 'j': return T_LONG;
-    case 'd': return T_DOUBLE;
-    case 'a': return T_OBJECT;
-    case 'r': return T_ADDRESS;
-    case '-': return T_ILLEGAL;
-    default:
-      fatal(err_msg("unexpected Kind: %c", ch));
-      break;
-  }
-  return T_ILLEGAL;
-}
+#endif // COMPILERGRAAL
--- a/src/share/vm/graal/graalCompiler.hpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalCompiler.hpp	Fri May 09 18:46:41 2014 +0200
@@ -26,23 +26,23 @@
 
 #include "compiler/abstractCompiler.hpp"
 
-#define LEAF_GRAPH_ARRAY_SIZE (8192)
-
 class GraalCompiler : public AbstractCompiler {
 
 private:
 
-  bool                  _initialized;
+#ifdef COMPILERGRAAL
+  // Set to true once VMToCompiler.startCompiler() returns
+  bool _started;
+#endif
 
   static GraalCompiler* _instance;
-  address               _external_deopt_i2c_entry;
+ 
 public:
 
   GraalCompiler();
 
   static GraalCompiler* instance() { return _instance; }
 
-
   virtual const char* name() { return "Graal"; }
 
   virtual bool supports_native()                 { return true; }
@@ -57,6 +57,7 @@
   // Initialization
   virtual void initialize();
 
+#ifdef COMPILERGRAAL
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
@@ -65,31 +66,8 @@
   // Print compilation timers and statistics
   virtual void print_timers();
 
-  void exit();
-
-  address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;}
-
-  static BasicType kindToBasicType(jchar ch);
-
-  static BufferBlob* initialize_buffer_blob();
-
-  static address create_external_deopt_i2c();
+  void shutdown();
+#endif
 };
 
-// Tracing macros
-
-#define IF_TRACE_graal_1 if (!(TraceGraal >= 1)) ; else
-#define IF_TRACE_graal_2 if (!(TraceGraal >= 2)) ; else
-#define IF_TRACE_graal_3 if (!(TraceGraal >= 3)) ; else
-#define IF_TRACE_graal_4 if (!(TraceGraal >= 4)) ; else
-#define IF_TRACE_graal_5 if (!(TraceGraal >= 5)) ; else
-
-// using commas and else to keep one-instruction semantics
-
-#define TRACE_graal_1 if (!(TraceGraal >= 1 && (tty->print("TraceGraal-1: "), true))) ; else tty->print_cr
-#define TRACE_graal_2 if (!(TraceGraal >= 2 && (tty->print("   TraceGraal-2: "), true))) ; else tty->print_cr
-#define TRACE_graal_3 if (!(TraceGraal >= 3 && (tty->print("      TraceGraal-3: "), true))) ; else tty->print_cr
-#define TRACE_graal_4 if (!(TraceGraal >= 4 && (tty->print("         TraceGraal-4: "), true))) ; else tty->print_cr
-#define TRACE_graal_5 if (!(TraceGraal >= 5 && (tty->print("            TraceGraal-5: "), true))) ; else tty->print_cr
-
 #endif // SHARE_VM_GRAAL_GRAAL_COMPILER_HPP
--- a/src/share/vm/graal/graalRuntime.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Fri May 09 18:46:41 2014 +0200
@@ -25,13 +25,156 @@
 #include "asm/codeBuffer.hpp"
 #include "graal/graalRuntime.hpp"
 #include "graal/graalVMToCompiler.hpp"
+#include "graal/graalCompilerToVM.hpp"
+#include "graal/graalJavaAccess.hpp"
+#include "graal/graalEnv.hpp"
 #include "memory/oopFactory.hpp"
 #include "prims/jvm.h"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/interfaceSupport.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/reflection.hpp"
 #include "utilities/debug.hpp"
 
+address GraalRuntime::_external_deopt_i2c_entry = NULL;
+volatile int GraalRuntime::_state = uninitialized;
+
+void GraalRuntime::initialize() {
+  {
+    MutexLocker locker(GraalInitialization_lock);
+    if (_state == uninitialized) {
+      _state = initializing;
+    } else {
+      while (_state == initializing) {
+        GraalInitialization_lock->wait();
+      }
+      return;
+    }
+  }
+
+  uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
+  uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024;
+  AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"));
+  NOT_LP64(error("check TLAB allocation code for address space conflicts"));
+
+  ThreadToNativeFromVM trans(JavaThread::current());
+  JavaThread* THREAD = JavaThread::current();
+  TRACE_graal_1("GraalRuntime::initialize");
+
+  JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment();
+  jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl");
+  if (klass == NULL) {
+    tty->print_cr("graal CompilerToVMImpl class not found");
+    vm_abort(false);
+  }
+  env->RegisterNatives(klass, CompilerToVM_methods, CompilerToVM_methods_count());
+
+  ResourceMark rm;
+  HandleMark hm;
+  {
+    GRAAL_VM_ENTRY_MARK;
+    check_pending_exception("Could not register natives");
+  }
+
+  graal_compute_offsets();
+
+  // Ensure _non_oop_bits is initialized
+  Universe::non_oop_word();
+
+  {
+    GRAAL_VM_ENTRY_MARK;
+    HandleMark hm;
+    VMToCompiler::initOptions();
+    for (int i = 0; i < Arguments::num_graal_args(); ++i) {
+      const char* arg = Arguments::graal_args_array()[i];
+      Handle option = java_lang_String::create_from_str(arg, THREAD);
+      jboolean result = VMToCompiler::setOption(option);
+      if (!result) {
+        tty->print_cr("Invalid option for graal: -G:%s", arg);
+        vm_abort(false);
+      }
+    }
+    VMToCompiler::finalizeOptions(CITime || CITimeEach);
+
+    _external_deopt_i2c_entry = create_external_deopt_i2c();
+
+    VMToCompiler::startRuntime();
+
+    {
+      MutexLocker locker(GraalInitialization_lock);
+      _state = initialized;
+    }
+
+#if !defined(PRODUCT) && !defined(COMPILERGRAAL)
+    // In COMPILERGRAAL, we want to allow GraalBootstrap
+    // to happen first so GraalCompiler::initialize()
+    // duplicates the following code.
+    if (CompileTheWorld) {
+      VMToCompiler::compileTheWorld();
+    }
+#endif
+  }
+}
+
+BufferBlob* GraalRuntime::initialize_buffer_blob() {
+  JavaThread* THREAD = JavaThread::current();
+  BufferBlob* buffer_blob = THREAD->get_buffer_blob();
+  if (buffer_blob == NULL) {
+    buffer_blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit);
+    if (buffer_blob != NULL) {
+      THREAD->set_buffer_blob(buffer_blob);
+    }
+  }
+  return buffer_blob;
+}
+
+address GraalRuntime::create_external_deopt_i2c() {
+  ResourceMark rm;
+  BufferBlob* buffer = BufferBlob::create("externalDeopt", 1*K);
+  CodeBuffer cb(buffer);
+  short buffer_locs[20];
+  cb.insts()->initialize_shared_locs((relocInfo*)buffer_locs, sizeof(buffer_locs)/sizeof(relocInfo));
+  MacroAssembler masm(&cb);
+
+  int total_args_passed = 5;
+
+  BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
+  VMRegPair* regs   = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
+  int i = 0;
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_LONG;
+  sig_bt[i++] = T_VOID; // long stakes 2 slots
+  sig_bt[i++] = T_INT;
+  sig_bt[i++] = T_OBJECT;
+
+  int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
+
+  SharedRuntime::gen_i2c_adapter(&masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
+  masm.flush();
+
+  return AdapterBlob::create(&cb)->content_begin();
+}
+
+BasicType GraalRuntime::kindToBasicType(jchar ch) {
+  switch(ch) {
+    case 'z': return T_BOOLEAN;
+    case 'b': return T_BYTE;
+    case 's': return T_SHORT;
+    case 'c': return T_CHAR;
+    case 'i': return T_INT;
+    case 'f': return T_FLOAT;
+    case 'j': return T_LONG;
+    case 'd': return T_DOUBLE;
+    case 'a': return T_OBJECT;
+    case 'r': return T_ADDRESS;
+    case '-': return T_ILLEGAL;
+    default:
+      fatal(err_msg("unexpected Kind: %c", ch));
+      break;
+  }
+  return T_ILLEGAL;
+}
+
 // Simple helper to see if the caller of a runtime stub which
 // entered the VM has been deoptimized
 
@@ -548,10 +691,12 @@
 
 // JVM_InitializeGraalRuntime
 JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass))
-  return VMToCompiler::graalRuntimePermObject();
+  GraalRuntime::initialize();
+  return VMToCompiler::get_HotSpotGraalRuntime_jobject();
 JVM_END
 
 // JVM_InitializeTruffleRuntime
 JVM_ENTRY(jobject, JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass))
-  return JNIHandles::make_local(VMToCompiler::truffleRuntime()());
+  GraalRuntime::initialize();
+  return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()());
 JVM_END
--- a/src/share/vm/graal/graalRuntime.hpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.hpp	Fri May 09 18:46:41 2014 +0200
@@ -28,8 +28,24 @@
 #include "memory/allocation.hpp"
 #include "runtime/deoptimization.hpp"
 
-class GraalRuntime: public AllStatic {
+class GraalRuntime: public CHeapObj<mtCompiler> {
+ private:
+
+  static address   _external_deopt_i2c_entry;
+
+  enum { uninitialized, initializing, initialized };
+  static volatile int _state;
+
  public:
+
+  static /*synchronized*/ void initialize();
+  static BufferBlob* initialize_buffer_blob();
+  static BasicType kindToBasicType(jchar ch);
+  static address create_external_deopt_i2c();
+  static address get_external_deopt_i2c_entry() {return _external_deopt_i2c_entry;}
+
+  // The following routines are all called from compiled Graal code
+
   static void new_instance(JavaThread* thread, Klass* klass);
   static void new_array(JavaThread* thread, Klass* klass, jint length);
   static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims);
@@ -60,4 +76,20 @@
   static void new_store_pre_barrier(JavaThread* thread);
 };
 
+// Tracing macros
+
+#define IF_TRACE_graal_1 if (!(TraceGraal >= 1)) ; else
+#define IF_TRACE_graal_2 if (!(TraceGraal >= 2)) ; else
+#define IF_TRACE_graal_3 if (!(TraceGraal >= 3)) ; else
+#define IF_TRACE_graal_4 if (!(TraceGraal >= 4)) ; else
+#define IF_TRACE_graal_5 if (!(TraceGraal >= 5)) ; else
+
+// using commas and else to keep one-instruction semantics
+
+#define TRACE_graal_1 if (!(TraceGraal >= 1 && (tty->print("TraceGraal-1: "), true))) ; else tty->print_cr
+#define TRACE_graal_2 if (!(TraceGraal >= 2 && (tty->print("   TraceGraal-2: "), true))) ; else tty->print_cr
+#define TRACE_graal_3 if (!(TraceGraal >= 3 && (tty->print("      TraceGraal-3: "), true))) ; else tty->print_cr
+#define TRACE_graal_4 if (!(TraceGraal >= 4 && (tty->print("         TraceGraal-4: "), true))) ; else tty->print_cr
+#define TRACE_graal_5 if (!(TraceGraal >= 5 && (tty->print("            TraceGraal-5: "), true))) ; else tty->print_cr
+
 #endif // SHARE_VM_GRAAL_GRAAL_RUNTIME_HPP
--- a/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.cpp	Fri May 09 18:46:41 2014 +0200
@@ -26,10 +26,10 @@
 #include "graal/graalVMToCompiler.hpp"
 #include "runtime/gpu.hpp"
 
-// this is a *global* handle
-jobject VMToCompiler::_graalRuntimePermObject = NULL;
-jobject VMToCompiler::_vmToCompilerPermObject = NULL;
-Klass* VMToCompiler::_vmToCompilerPermKlass = NULL;
+// these are *global* handles
+jobject VMToCompiler::_HotSpotGraalRuntime_instance = NULL;
+jobject VMToCompiler::_VMToCompiler_instance = NULL;
+Klass* VMToCompiler::_VMToCompiler_klass = NULL;
 
 static Klass* loadClass(Symbol* name) {
   Klass* klass = SystemDictionary::resolve_or_null(name, SystemDictionary::java_system_loader(), Handle(), Thread::current());
@@ -40,135 +40,184 @@
   return klass;
 }
 
-KlassHandle VMToCompiler::vmToCompilerKlass() {
-  if (_vmToCompilerPermKlass == NULL) {
-    Klass* result = loadClass(vmSymbols::com_oracle_graal_hotspot_bridge_VMToCompiler());
-    _vmToCompilerPermKlass = result;
+KlassHandle VMToCompiler::VMToCompiler_klass() {
+  if (_VMToCompiler_klass == NULL) {
+    TempNewSymbol VMToCompiler = SymbolTable::new_symbol("com/oracle/graal/hotspot/bridge/VMToCompiler", Thread::current());
+    Klass* result = loadClass(VMToCompiler);
+    _VMToCompiler_klass = result;
   }
-  return _vmToCompilerPermKlass;
+  return _VMToCompiler_klass;
 }
 
-Handle VMToCompiler::truffleRuntime() {
-  Symbol* name = vmSymbols::com_oracle_graal_truffle_hotspot_HotSpotTruffleRuntime();
+Handle VMToCompiler::create_HotSpotTruffleRuntime() {
+  Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", THREAD);
   KlassHandle klass = loadClass(name);
 
+  TempNewSymbol makeInstance = SymbolTable::new_symbol("makeInstance", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;", THREAD);
   JavaValue result(T_OBJECT);
-  JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current());
+  JavaCalls::call_static(&result, klass, makeInstance, sig, THREAD);
   check_pending_exception("Couldn't initialize HotSpotTruffleRuntime");
   return Handle((oop) result.get_jobject());
 }
 
-Handle VMToCompiler::graalRuntime() {
-  if (JNIHandles::resolve(_graalRuntimePermObject) == NULL) {
-    KlassHandle klass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime());
+Handle VMToCompiler::get_HotSpotGraalRuntime() {
+  if (JNIHandles::resolve(_HotSpotGraalRuntime_instance) == NULL) {
+    Thread* THREAD = Thread::current();
+    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD);
+    KlassHandle klass = loadClass(name);
+    TempNewSymbol runtime = SymbolTable::new_symbol("runtime", THREAD);
+    TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;", THREAD);
     JavaValue result(T_OBJECT);
-    JavaCalls::call_static(&result, klass, vmSymbols::runtime_name(), vmSymbols::runtime_signature(), Thread::current());
+    JavaCalls::call_static(&result, klass, runtime, sig, THREAD);
     check_pending_exception("Couldn't initialize HotSpotGraalRuntime");
-    _graalRuntimePermObject = JNIHandles::make_global((oop) result.get_jobject());
+    _HotSpotGraalRuntime_instance = JNIHandles::make_global((oop) result.get_jobject());
   }
-  return Handle(JNIHandles::resolve_non_null(_graalRuntimePermObject));
+  return Handle(JNIHandles::resolve_non_null(_HotSpotGraalRuntime_instance));
 }
 
-Handle VMToCompiler::instance() {
-  if (JNIHandles::resolve(_vmToCompilerPermObject) == NULL) {
-    KlassHandle compilerKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime());
-
+Handle VMToCompiler::VMToCompiler_instance() {
+  if (JNIHandles::resolve(_VMToCompiler_instance) == NULL) {
+    Thread* THREAD = Thread::current();
+    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD);
+    KlassHandle klass = loadClass(name);
+    TempNewSymbol getVMToCompiler = SymbolTable::new_symbol("getVMToCompiler", THREAD);
+    TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;", THREAD);
     JavaValue result(T_OBJECT);
     JavaCallArguments args;
-    args.set_receiver(graalRuntime());
-    JavaCalls::call_virtual(&result, compilerKlass, vmSymbols::getVMToCompiler_name(), vmSymbols::getVMToCompiler_signature(), &args, Thread::current());
+    args.set_receiver(get_HotSpotGraalRuntime());
+    JavaCalls::call_virtual(&result, klass, getVMToCompiler, sig, &args, THREAD);
     check_pending_exception("Couldn't get VMToCompiler");
-    _vmToCompilerPermObject = JNIHandles::make_global((oop) result.get_jobject());
+    _VMToCompiler_instance = JNIHandles::make_global((oop) result.get_jobject());
   }
-  return Handle(JNIHandles::resolve_non_null(_vmToCompilerPermObject));
+  return Handle(JNIHandles::resolve_non_null(_VMToCompiler_instance));
 }
 
 void VMToCompiler::initOptions() {
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   optionsKlass->initialize(THREAD);
   check_pending_exception("Error while calling initOptions");
 }
 
 jboolean VMToCompiler::setOption(Handle option) {
   assert(!option.is_null(), "");
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
-
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  TempNewSymbol setOption = SymbolTable::new_symbol("setOption", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   JavaValue result(T_BOOLEAN);
-  JavaCalls::call_static(&result, optionsKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD);
+  JavaCalls::call_static(&result, optionsKlass, setOption, sig, option, THREAD);
   check_pending_exception("Error while calling setOption");
   return result.get_jboolean();
 }
 
 void VMToCompiler::finalizeOptions(jboolean ciTime) {
-  KlassHandle optionsKlass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotOptions());
   Thread* THREAD = Thread::current();
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotOptions", THREAD);
+  TempNewSymbol finalizeOptions = SymbolTable::new_symbol("finalizeOptions", THREAD);
+  TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;)Z", THREAD);
+  KlassHandle optionsKlass = loadClass(name);
   JavaValue result(T_VOID);
   JavaCallArguments args;
   args.push_int(ciTime);
-  JavaCalls::call_static(&result, optionsKlass, vmSymbols::finalizeOptions_name(), vmSymbols::bool_void_signature(), &args, THREAD);
+  JavaCalls::call_static(&result, optionsKlass, finalizeOptions, vmSymbols::bool_void_signature(), &args, THREAD);
   check_pending_exception("Error while calling finalizeOptions");
 }
 
+void VMToCompiler::startRuntime() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol startRuntime = SymbolTable::new_symbol("startRuntime", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), startRuntime, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startRuntime");
+}
+
+#ifdef COMPILERGRAAL
+void VMToCompiler::bootstrap() {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol bootstrap = SymbolTable::new_symbol("bootstrap", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), bootstrap, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling bootstrap");
+}
+
+void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
+  JavaThread* THREAD = JavaThread::current();
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  TempNewSymbol startCompiler = SymbolTable::new_symbol("startCompiler", THREAD);
+  args.push_oop(VMToCompiler_instance());
+  args.push_int(bootstrap_enabled);
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), startCompiler, vmSymbols::bool_void_signature(), &args, THREAD);
+  check_pending_exception("Error while calling startCompiler");
+}
+
 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);
   JavaCallArguments args;
-  args.push_oop(instance());
+  args.push_oop(VMToCompiler_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);
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileMethod");
 }
 
 void VMToCompiler::shutdownCompiler() {
-  if (_graalRuntimePermObject != NULL) {
-    HandleMark hm;
+  JavaThread* THREAD = JavaThread::current();
+  HandleMark hm(THREAD);
+  TempNewSymbol shutdownCompiler = SymbolTable::new_symbol("shutdownCompiler", THREAD);
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), shutdownCompiler, vmSymbols::void_method_signature(), &args, THREAD);
+  check_pending_exception("Error while calling shutdownCompiler");
+}
+#endif // COMPILERGRAAL
+
+void VMToCompiler::shutdownRuntime() {
+  if (_HotSpotGraalRuntime_instance != NULL) {
     JavaThread* THREAD = JavaThread::current();
+    HandleMark hm(THREAD);
+    TempNewSymbol shutdownRuntime = SymbolTable::new_symbol("shutdownRuntime", THREAD);
     JavaValue result(T_VOID);
     JavaCallArguments args;
-    args.push_oop(instance());
-    JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::shutdownCompiler_name(), vmSymbols::void_method_signature(), &args, THREAD);
-    check_pending_exception("Error while calling shutdownCompiler");
+    args.push_oop(VMToCompiler_instance());
+    JavaCalls::call_interface(&result, VMToCompiler_klass(), shutdownRuntime, vmSymbols::void_method_signature(), &args, THREAD);
+    check_pending_exception("Error while calling shutdownRuntime");
 
-    JNIHandles::destroy_global(_graalRuntimePermObject);
-    JNIHandles::destroy_global(_vmToCompilerPermObject);
-    //JNIHandles::destroy_global(_vmToCompilerPermKlass);
+    JNIHandles::destroy_global(_HotSpotGraalRuntime_instance);
+    JNIHandles::destroy_global(_VMToCompiler_instance);
 
-    _graalRuntimePermObject = NULL;
-    _vmToCompilerPermObject = NULL;
-    _vmToCompilerPermKlass = NULL;
+    _HotSpotGraalRuntime_instance = NULL;
+    _VMToCompiler_instance = NULL;
+    _VMToCompiler_klass = NULL;
   }
 }
 
-void VMToCompiler::startCompiler(jboolean bootstrap_enabled) {
+#ifndef PRODUCT
+void VMToCompiler::compileTheWorld() {
+  // We turn off CompileTheWorld so that Graal can
+  // be compiled by C1/C2 when Graal does a CTW.
+  CompileTheWorld = false;
+
   JavaThread* THREAD = JavaThread::current();
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  args.push_int(bootstrap_enabled);
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::startCompiler_name(), vmSymbols::bool_void_signature(), &args, THREAD);
-  check_pending_exception("Error while calling startCompiler");
-}
-
-void VMToCompiler::bootstrap() {
-  JavaThread* THREAD = JavaThread::current();
+  TempNewSymbol compileTheWorld = SymbolTable::new_symbol("compileTheWorld", THREAD);
   JavaValue result(T_VOID);
   JavaCallArguments args;
-  args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::bootstrap_name(), vmSymbols::void_method_signature(), &args, THREAD);
-  check_pending_exception("Error while calling bootstrap");
-}
-
-void VMToCompiler::compileTheWorld() {
-  JavaThread* THREAD = JavaThread::current();
-  JavaValue result(T_VOID);
-  JavaCallArguments args;
-  args.push_oop(instance());
-  JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileTheWorld_name(), vmSymbols::void_method_signature(), &args, THREAD);
+  args.push_oop(VMToCompiler_instance());
+  JavaCalls::call_interface(&result, VMToCompiler_klass(), compileTheWorld, vmSymbols::void_method_signature(), &args, THREAD);
   check_pending_exception("Error while calling compileTheWorld");
 }
+#endif
--- a/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/graal/graalVMToCompiler.hpp	Fri May 09 18:46:41 2014 +0200
@@ -35,20 +35,24 @@
 class VMToCompiler : public AllStatic {
 
 private:
-  static jobject _graalRuntimePermObject;
-  static jobject _vmToCompilerPermObject;
-  static Klass* _vmToCompilerPermKlass;
+  static jobject _HotSpotGraalRuntime_instance;
+  static jobject _VMToCompiler_instance;
 
-  static KlassHandle vmToCompilerKlass();
-  static Handle instance();
+  static Klass* _VMToCompiler_klass;
+
+  static KlassHandle VMToCompiler_klass();
+  static Handle VMToCompiler_instance();
 
 public:
-  static Handle graalRuntime();
-  static Handle truffleRuntime();
+  // Gets the singleton HotSpotGraalRuntime instance, initializing it if necessary
+  static Handle get_HotSpotGraalRuntime();
 
-  static jobject graalRuntimePermObject() {
-    graalRuntime();
-    return _graalRuntimePermObject;
+  // Creates a new HotSpotTruffleRuntime object
+  static Handle create_HotSpotTruffleRuntime();
+
+  static jobject get_HotSpotGraalRuntime_jobject() {
+    get_HotSpotGraalRuntime();
+    return _HotSpotGraalRuntime_instance;
   }
 
   // public static boolean HotSpotOptions.<clinit>();
@@ -60,20 +64,30 @@
   // public static void HotSpotOptions.finalizeOptions(boolean ciTime);
   static void finalizeOptions(jboolean ciTime);
 
+  // public abstract void startRuntime();
+  static void startRuntime();
+
+#ifdef COMPILERGRAAL
+  // public abstract void startCompiler(boolean bootstrapEnabled);
+  static void startCompiler(jboolean bootstrap_enabled);
+
+  // public abstract void bootstrap();
+  static void bootstrap();
+
   // 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();
-  
-  // public abstract void startCompiler(boolean bootstrapEnabled);
-  static void startCompiler(jboolean bootstrap_enabled);
+#endif
   
-  // public abstract void bootstrap();
-  static void bootstrap();
-
+  // public abstract void shutdownRuntime();
+  static void shutdownRuntime();
+  
+#ifndef PRODUCT
   // public abstract void compileTheWorld();
   static void compileTheWorld();
+#endif
 };
 
 inline void check_pending_exception(const char* message, bool dump_core = false) {
--- a/src/share/vm/prims/jni.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/prims/jni.cpp	Fri May 09 18:46:41 2014 +0200
@@ -5173,9 +5173,9 @@
     *vm = (JavaVM *)(&main_vm);
     *(JNIEnv**)penv = thread->jni_environment();
 
-#ifdef GRAAL
-    if (COMPILERGRAAL_PRESENT(UseGraalCompilationQueue) NOT_COMPILERGRAAL(true)) {
-      // GraalCompiler needs to have been created in compileBroker.cpp
+#ifdef COMPILERGRAAL
+    if (UseGraalCompilationQueue) {
+      // GraalCompiler may have been created in compileBroker.cpp
       GraalCompiler* graal_compiler = GraalCompiler::instance();
       if (ForceGraalInitialization && graal_compiler == NULL) {
         graal_compiler = new GraalCompiler();
--- a/src/share/vm/runtime/deoptimization.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Fri May 09 18:46:41 2014 +0200
@@ -88,7 +88,7 @@
 #endif
 
 #ifdef GRAAL
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 #include "graal/graalJavaAccess.hpp"
 #endif
 
--- a/src/share/vm/runtime/java.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/runtime/java.cpp	Fri May 09 18:46:41 2014 +0200
@@ -32,6 +32,7 @@
 #include "interpreter/bytecodeHistogram.hpp"
 #ifdef GRAAL
 #include "graal/graalCompiler.hpp"
+#include "graal/graalVMToCompiler.hpp"
 #endif
 #include "memory/genCollectedHeap.hpp"
 #include "memory/oopFactory.hpp"
@@ -462,10 +463,13 @@
   static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN;
 
 #ifdef GRAAL
+#ifdef COMPILERGRAAL
   if (GraalCompiler::instance() != NULL) {
-    GraalCompiler::instance()->exit();
+    GraalCompiler::instance()->shutdown();
   }
 #endif
+  VMToCompiler::shutdownRuntime();
+#endif
 
   // Note: don't use a Mutex to guard the entire before_exit(), as
   // JVMTI post_thread_end_event and post_vm_death_event will run native code.
--- a/src/share/vm/runtime/javaCalls.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/runtime/javaCalls.cpp	Fri May 09 18:46:41 2014 +0200
@@ -41,7 +41,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.inline.hpp"
 #include "graal/graalJavaAccess.hpp"
-#include "graal/graalCompiler.hpp"
+#include "graal/graalRuntime.hpp"
 
 // -----------------------------------------------------
 // Implementation of JavaCallWrapper
@@ -413,7 +413,7 @@
       ((JavaThread*) THREAD)->set_graal_alternate_call_target(nm->verified_entry_point());
       oop graalInstalledCode = nm->graal_installed_code();
       if (graalInstalledCode != NULL && graalInstalledCode->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isExternal(graalInstalledCode)) {
-        entry_point = GraalCompiler::instance()->get_external_deopt_i2c_entry();
+        entry_point = GraalRuntime::get_external_deopt_i2c_entry();
       } else {
       entry_point = method->adapter()->get_i2c_entry();
       }
--- a/src/share/vm/runtime/mutexLocker.cpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.cpp	Fri May 09 18:46:41 2014 +0200
@@ -133,6 +133,10 @@
 Mutex*   JfrThreadGroups_lock         = NULL;
 #endif
 
+#ifdef GRAAL
+Monitor* GraalInitialization_lock     = NULL;
+#endif
+
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
 static int _num_mutex;
@@ -281,6 +285,9 @@
   def(JfrStacktrace_lock           , Mutex,   special,     true );
 #endif
 
+#ifdef GRAAL
+  def(GraalInitialization_lock     , Monitor, nonleaf+5,   false);
+#endif
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/src/share/vm/runtime/mutexLocker.hpp	Fri May 09 17:59:15 2014 +0200
+++ b/src/share/vm/runtime/mutexLocker.hpp	Fri May 09 18:46:41 2014 +0200
@@ -146,6 +146,10 @@
 extern Mutex*   JfrThreadGroups_lock;            // protects JFR access to Thread Groups
 #endif
 
+#ifdef GRAAL
+extern Monitor* GraalInitialization_lock;        // ensures exactly 1 thread initializes Graal
+#endif
+
 // A MutexLocker provides mutual exclusion with respect to a given mutex
 // for the scope which contains the locker.  The lock is an OS lock, not
 // an object lock, and the two do not interoperate.  Do not use Mutex-based