changeset 19920:7366593c0610

Make the native initialization path for Graal more robust
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Mon, 16 Mar 2015 17:37:32 -0700
parents df0608c34899
children ea280aa54d58
files src/share/vm/graal/graalRuntime.cpp src/share/vm/graal/graalRuntime.hpp
diffstat 2 files changed, 52 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/graal/graalRuntime.cpp	Mon Mar 16 16:38:17 2015 -0700
+++ b/src/share/vm/graal/graalRuntime.cpp	Mon Mar 16 17:37:32 2015 -0700
@@ -626,6 +626,7 @@
 
 // private static GraalRuntime Graal.initializeRuntime()
 JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c))
+  GraalRuntime::initialize_HotSpotGraalRuntime();
   return GraalRuntime::get_HotSpotGraalRuntime_jobject();
 JVM_END
 
@@ -688,21 +689,43 @@
   }
 }
 
-Handle GraalRuntime::get_HotSpotGraalRuntime() {
+Handle GraalRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) {
+  guarantee(!_HotSpotGraalRuntime_initialized, "cannot reinitialize HotSpotGraalRuntime");
+  Thread* THREAD = Thread::current();
+  check_generated_sources_sha1(CHECK_ABORT_(Handle()));
+
+  TempNewSymbol name = SymbolTable::new_symbol(className, CHECK_ABORT_(Handle()));
+  KlassHandle klass = load_required_class(name);
+  TempNewSymbol runtime = SymbolTable::new_symbol(methodName, CHECK_ABORT_(Handle()));
+  TempNewSymbol sig = SymbolTable::new_symbol(returnType, CHECK_ABORT_(Handle()));
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle()));
+  return Handle((oop)result.get_jobject());
+}
+
+void GraalRuntime::initialize_HotSpotGraalRuntime() {
   if (JNIHandles::resolve(_HotSpotGraalRuntime_instance) == NULL) {
-    guarantee(!_HotSpotGraalRuntime_initialized, "cannot reinitialize HotSpotGraalRuntime");
+#ifdef ASSERT
+    // This should only be called in the context of the Graal class being initialized
     Thread* THREAD = Thread::current();
-    check_generated_sources_sha1(CHECK_ABORT_(Handle()));
-    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", CHECK_ABORT_(Handle()));
-    KlassHandle klass = load_required_class(name);
-    TempNewSymbol runtime = SymbolTable::new_symbol("runtime", CHECK_ABORT_(Handle()));
-    TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;", CHECK_ABORT_(Handle()));
-    JavaValue result(T_OBJECT);
-    JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle()));
-    _HotSpotGraalRuntime_instance = JNIHandles::make_global((oop) result.get_jobject());
+    TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/api/runtime/Graal", CHECK_ABORT);
+    instanceKlassHandle klass = InstanceKlass::cast(load_required_class(name));
+    assert(klass->is_being_initialized() && klass->is_reentrant_initialization(THREAD),
+           "HotSpotGraalRuntime initialization should only be triggered through Graal initialization");
+#endif
+
+    Handle result = callInitializer("com/oracle/graal/hotspot/HotSpotGraalRuntime", "runtime",
+                                    "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;");
     _HotSpotGraalRuntime_initialized = true;
+    _HotSpotGraalRuntime_instance = JNIHandles::make_global(result());
   }
-  return Handle(JNIHandles::resolve_non_null(_HotSpotGraalRuntime_instance));
+}
+
+void GraalRuntime::initialize_Graal() {
+  if (JNIHandles::resolve(_HotSpotGraalRuntime_instance) == NULL) {
+    callInitializer("com/oracle/graal/api/runtime/Graal",     "getRuntime",      "()Lcom/oracle/graal/api/runtime/GraalRuntime;");
+  }
+  assert(_HotSpotGraalRuntime_initialized == true, "what?");
 }
 
 // private static void CompilerToVMImpl.init()
--- a/src/share/vm/graal/graalRuntime.hpp	Mon Mar 16 16:38:17 2015 -0700
+++ b/src/share/vm/graal/graalRuntime.hpp	Mon Mar 16 17:37:32 2015 -0700
@@ -138,13 +138,29 @@
   /**
    * Gets the singleton HotSpotGraalRuntime instance, initializing it if necessary
    */
-  static Handle get_HotSpotGraalRuntime();
+  static Handle get_HotSpotGraalRuntime() {
+    initialize_Graal();
+    return Handle(JNIHandles::resolve_non_null(_HotSpotGraalRuntime_instance));
+  }
 
   static jobject get_HotSpotGraalRuntime_jobject() {
-    get_HotSpotGraalRuntime();
+    initialize_Graal();
+    assert(_HotSpotGraalRuntime_initialized, "must be");
     return _HotSpotGraalRuntime_instance;
   }
 
+  static Handle callInitializer(const char* className, const char* methodName, const char* returnType);
+
+  /**
+   * Trigger initialization of HotSpotGraalRuntime through Graal.runtime()
+   */
+  static void initialize_Graal();
+
+  /**
+   * Explicitly initialize HotSpotGraalRuntime itself
+   */
+  static void initialize_HotSpotGraalRuntime();
+
   static void shutdown();
 
   static bool shutdown_called() {