# HG changeset patch # User Doug Simon # Date 1399930048 -7200 # Node ID d556971b409ca9f5ff13900d8b7b82549fd1f17a # Parent b7fb36e57da85206f01101918db6ffd9b66706c9# Parent 4aeb0b80324f86bb12976dbb3964e15929c5c718 Merge. diff -r 4aeb0b80324f -r d556971b409c CHANGELOG.md --- a/CHANGELOG.md Mon May 12 22:37:14 2014 +0200 +++ b/CHANGELOG.md Mon May 12 23:27:28 2014 +0200 @@ -2,7 +2,7 @@ ## `tip` ### Graal -* ... +* Made initialization of Graal runtime lazy in hosted mode. ### Truffle * `truffle.jar`: strip out build-time only dependency into a seperated JAR file (`truffle-dsl-processor.jar`) diff -r 4aeb0b80324f -r d556971b409c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon May 12 22:37:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon May 12 23:27:28 2014 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*; +import static sun.reflect.Reflection.*; import java.lang.reflect.*; import java.util.*; @@ -54,9 +55,26 @@ */ public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider, StackIntrospection { - private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime(); + private static final HotSpotGraalRuntime instance; + + /** + * Initializes the native part of the Graal runtime. + */ + private static native void init(Class compilerToVMClass); + static { + init(CompilerToVMImpl.class); + + // The options must be processed before any code using them... + HotSpotOptions.initialize(); + + // ... including code in the constructor + instance = new HotSpotGraalRuntime(); + + // Why deferred initialization? See comment in completeInitialization(). instance.completeInitialization(); + + registerFieldsToFilter(HotSpotGraalRuntime.class, "instance"); } /** @@ -75,10 +93,6 @@ return instance; } - static { - Reflection.registerFieldsToFilter(HotSpotGraalRuntime.class, "instance"); - } - /** * Do deferred initialization. */ @@ -104,6 +118,8 @@ this.vmToCompiler = toCompiler; this.compilerToVm = toVM; + + this.vmToCompiler.startRuntime(); } // Options must not be directly declared in HotSpotGraalRuntime - see VerifyOptionsPhase diff -r 4aeb0b80324f -r d556971b409c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Mon May 12 22:37:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Mon May 12 23:27:28 2014 +0200 @@ -87,7 +87,7 @@ try { for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) { if (!line.startsWith("#")) { - if (!setOption(line)) { + if (!parseOption(line, null)) { throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions); } } @@ -98,14 +98,39 @@ } } + /** + * Gets the Graal specific options specified to HotSpot (e.g., on the command line). + * + * @param timeCompilations (out) true if the CITime or CITimeEach HotSpot VM options are set + */ + private static native String[] getVMOptions(boolean[] timeCompilations); + static { initializeOptions(); loadOptionOverrides(); + + boolean[] timeCompilations = {false}; + for (String option : getVMOptions(timeCompilations)) { + if (!parseOption(option, null)) { + throw new InternalError("Invalid Graal option \"-G:" + option + "\""); + } + } + + if (timeCompilations[0] || PrintCompRate.getValue() != 0) { + unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes"); + unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime"); + } + assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " + + "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName(); + if (areDebugScopePatternsEnabled()) { + System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); + } } - // Called from VM code - public static boolean setOption(String option) { - return parseOption(option, null); + /** + * Ensures {@link HotSpotOptions} is initialized. + */ + public static void initialize() { } interface OptionConsumer { @@ -238,24 +263,6 @@ } /** - * Called from VM code once all Graal command line options have been processed by - * {@link #setOption(String)}. - * - * @param timeCompilations true if the CITime or CITimeEach HotSpot VM options are set - */ - public static void finalizeOptions(boolean timeCompilations) { - if (timeCompilations || PrintCompRate.getValue() != 0) { - unconditionallyEnableTimerOrMetric(InliningUtil.class, "InlinedBytecodes"); - unconditionallyEnableTimerOrMetric(CompilationTask.class, "CompilationTime"); - } - assert !Debug.Initialization.isDebugInitialized() : "The class " + Debug.class.getName() + " must not be initialized before the Graal runtime has been initialized. " + - "This can be fixed by placing a call to " + Graal.class.getName() + ".runtime() on the path that triggers initialization of " + Debug.class.getName(); - if (areDebugScopePatternsEnabled()) { - System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); - } - } - - /** * Wraps some given text to one or more lines of a given maximum width. * * @param text text to wrap diff -r 4aeb0b80324f -r d556971b409c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Mon May 12 22:37:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Mon May 12 23:27:28 2014 +0200 @@ -30,7 +30,7 @@ */ public interface VMToCompiler { - void startRuntime() throws Throwable; + void startRuntime(); void startCompiler(boolean bootstrapEnabled) throws Throwable; diff -r 4aeb0b80324f -r d556971b409c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon May 12 22:37:14 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon May 12 23:27:28 2014 +0200 @@ -142,7 +142,7 @@ this.runtime = runtime; } - public void startRuntime() throws Throwable { + public void startRuntime() { if (LogFile.getValue() != null) { try { diff -r 4aeb0b80324f -r d556971b409c graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Mon May 12 22:37:14 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Mon May 12 23:27:28 2014 +0200 @@ -33,7 +33,14 @@ private static final TruffleRuntime RUNTIME; - private static native TruffleRuntime initializeRuntime(); + /** + * Creates a new {@link TruffleRuntime} instance if the runtime has a specialized + * implementation. + * + * @throws UnsatisfiedLinkError if the runtime does not have a specialized implementation of + * {@link TruffleRuntime} + */ + private static native TruffleRuntime createRuntime(); public static TruffleRuntime getRuntime() { return RUNTIME; @@ -42,7 +49,7 @@ static { TruffleRuntime runtime; try { - runtime = initializeRuntime(); + runtime = createRuntime(); } catch (UnsatisfiedLinkError e) { runtime = new DefaultTruffleRuntime(); } diff -r 4aeb0b80324f -r d556971b409c src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon May 12 23:27:28 2014 +0200 @@ -297,8 +297,6 @@ template(com_oracle_graal_graph_NodeClass, "com/oracle/graal/graph/NodeClass") \ /* graal.hotspot */ \ template(com_oracle_graal_hotspot_HotSpotGraalRuntime, "com/oracle/graal/hotspot/HotSpotGraalRuntime") \ - template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ - template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode, "com/oracle/graal/hotspot/HotSpotCompiledCode") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment") \ template(com_oracle_graal_hotspot_HotSpotCompiledNmethod, "com/oracle/graal/hotspot/HotSpotCompiledNmethod") \ diff -r 4aeb0b80324f -r d556971b409c src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Mon May 12 23:27:28 2014 +0200 @@ -48,8 +48,6 @@ return; } - GraalRuntime::initialize(); - BufferBlob* buffer_blob = GraalRuntime::initialize_buffer_blob(); if (!UseGraalCompilationQueue) { // This path is used for initialization both by the native queue and the graal queue @@ -68,7 +66,11 @@ bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal); VMToCompiler::startCompiler(bootstrap); _started = true; + + // Graal is considered as application code so we need to + // stop the VM deferring compilation now. CompilationPolicy::completed_vm_startup(); + if (bootstrap) { // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping. FlagSetting a(UseInterpreter, true); diff -r 4aeb0b80324f -r d556971b409c src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Mon May 12 23:27:28 2014 +0200 @@ -37,97 +37,30 @@ #include "utilities/debug.hpp" address GraalRuntime::_external_deopt_i2c_entry = NULL; -volatile GraalRuntime::State GraalRuntime::_state = uninitialized; -Thread* GraalRuntime::_initializingThread = NULL; -bool GraalRuntime::should_perform_init() { - JavaThread* THREAD = JavaThread::current(); - if (_state != initialized) { - if (THREAD == _initializingThread) { - return false; - } - MutexLocker locker(GraalInitialization_lock); - if (_state == uninitialized) { - _state = initializing; - _initializingThread = THREAD; - return true; - } else { - while (_state == initializing) { - GraalInitialization_lock->wait(); - } - } - } - return false; -} - -void GraalRuntime::initialize() { - if (!should_perform_init()) { - return; - } - +void GraalRuntime::initialize_natives(JNIEnv *env, jclass c2vmClass) { 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")); JavaThread* THREAD = JavaThread::current(); - ThreadToNativeFromVM trans(THREAD); - 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"); - } + ThreadToNativeFromVM trans(THREAD); - graal_compute_offsets(); - - // Ensure _non_oop_bits is initialized - Universe::non_oop_word(); - - { - GRAAL_VM_ENTRY_MARK; + ResourceMark rm; 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); + + graal_compute_offsets(); _external_deopt_i2c_entry = create_external_deopt_i2c(); - VMToCompiler::startRuntime(); - - { - MutexLocker locker(GraalInitialization_lock); - _state = initialized; - _initializingThread = NULL; - } + // Ensure _non_oop_bits is initialized + Universe::non_oop_word(); -#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 + env->RegisterNatives(c2vmClass, CompilerToVM_methods, CompilerToVM_methods_count()); } + check_pending_exception("Could not register natives"); } BufferBlob* GraalRuntime::initialize_buffer_blob() { @@ -703,14 +636,32 @@ } JRT_END -// JVM_InitializeGraalRuntime -JVM_ENTRY(jobject, JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass)) - GraalRuntime::initialize(); +// private static GraalRuntime Graal.initializeRuntime() +JVM_ENTRY(jobject, JVM_GetGraalRuntime(JNIEnv *env, jclass c)) return VMToCompiler::get_HotSpotGraalRuntime_jobject(); JVM_END -// JVM_InitializeTruffleRuntime -JVM_ENTRY(jobject, JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass)) - GraalRuntime::initialize(); +// private static TruffleRuntime Truffle.createRuntime() +JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c)) return JNIHandles::make_local(VMToCompiler::create_HotSpotTruffleRuntime()()); JVM_END + +// private static void HotSpotGraalRuntime.init(Class compilerToVMClass) +JVM_ENTRY(void, JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass c2vmClass)) + GraalRuntime::initialize_natives(env, c2vmClass); +JVM_END + +// private static String[] HotSpotOptions.getVMOptions(boolean[] timeCompilations) +JVM_ENTRY(jobject, JVM_GetGraalOptions(JNIEnv *env, jclass c, jobject timeCompilations)) + HandleMark hm; + int numOptions = Arguments::num_graal_args(); + objArrayOop options = oopFactory::new_objArray(SystemDictionary::String_klass(), + numOptions, CHECK_NULL); + objArrayHandle optionsHandle(THREAD, options); + for (int i = 0; i < numOptions; i++) { + Handle option = java_lang_String::create_from_str(Arguments::graal_args_array()[i], CHECK_NULL); + optionsHandle->obj_at_put(i, option()); + } + ((typeArrayOop) JNIHandles::resolve(timeCompilations))->bool_at_put(0, CITime || CITimeEach); + return JNIHandles::make_local(THREAD, optionsHandle()); +JVM_END diff -r 4aeb0b80324f -r d556971b409c src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Mon May 12 23:27:28 2014 +0200 @@ -33,14 +33,9 @@ static address _external_deopt_i2c_entry; - enum State { uninitialized, initializing, initialized }; - static volatile State _state; - static Thread* _initializingThread; - static bool should_perform_init(); - public: - static /*synchronized*/ void initialize(); + static void initialize_natives(JNIEnv *env, jclass c2vmClass); static BufferBlob* initialize_buffer_blob(); static BasicType kindToBasicType(jchar ch); static address create_external_deopt_i2c(); diff -r 4aeb0b80324f -r d556971b409c src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/prims/jni.cpp Mon May 12 23:27:28 2014 +0200 @@ -35,6 +35,7 @@ #include "utilities/macros.hpp" #ifdef GRAAL #include "graal/graalCompiler.hpp" +#include "graal/graalVMToCompiler.hpp" #endif #if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" @@ -5210,7 +5211,19 @@ #endif // Check if we should compile all classes on bootclasspath +#ifdef GRAAL +#ifndef COMPILERGRAAL + if (CompileTheWorld) { + // Graal is considered as application code so we need to + // stop the VM deferring compilation now. + CompilationPolicy::completed_vm_startup(); + + VMToCompiler::compileTheWorld(); + } +#endif +#else if (CompileTheWorld) ClassLoader::compile_the_world(); +#endif if (ReplayCompiles) ciReplay::replay(thread); // Some platforms (like Win*) need a wrapper around these test diff -r 4aeb0b80324f -r d556971b409c src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Mon May 12 22:37:14 2014 +0200 +++ b/src/share/vm/prims/nativeLookup.cpp Mon May 12 23:27:28 2014 +0200 @@ -124,8 +124,10 @@ void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass); void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass); #ifdef GRAAL - jobject JNICALL JVM_InitializeGraalRuntime(JNIEnv *env, jclass graalclass); - jobject JNICALL JVM_InitializeTruffleRuntime(JNIEnv *env, jclass graalclass); + void JNICALL JVM_InitializeGraalNatives(JNIEnv *env, jclass c, jclass compilerToVMClass); + jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_GetGraalOptions(JNIEnv *env, jclass hotspotOptionsClass, jobject timeCompilations); #endif } @@ -138,8 +140,10 @@ { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) }, #ifdef GRAAL - { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_InitializeGraalRuntime) }, - { CC"Java_com_oracle_truffle_api_Truffle_initializeRuntime", NULL, FN_PTR(JVM_InitializeTruffleRuntime) }, + { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, + { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotGraalRuntime_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_getVMOptions", NULL, FN_PTR(JVM_GetGraalOptions) }, #endif };