diff -r c80f6ecb0bb3 -r 5f9eee6b383b hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Tue Mar 15 13:48:21 2016 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Mar 17 19:04:01 2016 +0000 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/moduleEntry.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -118,6 +119,9 @@ #include "runtime/rtmLocking.hpp" #endif +// Initialization after module runtime initialization +void universe_post_module_init(); // must happen after call_initPhase2 + #ifdef DTRACE_ENABLED // Only bother with this argument setup if dtrace is available @@ -997,15 +1001,6 @@ return thread_oop(); } -static void call_initializeSystemClass(TRAPS) { - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); - instanceKlassHandle klass (THREAD, k); - - JavaValue result(T_VOID); - JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(), - vmSymbols::void_method_signature(), CHECK); -} - char java_runtime_name[128] = ""; char java_runtime_version[128] = ""; @@ -3364,6 +3359,62 @@ // If CompilerThreads ever become non-JavaThreads, add them here } +// The system initialization in the library has three phases. +// +// Phase 1: java.lang.System class initialization +// java.lang.System is a primordial class loaded and initialized +// by the VM early during startup. java.lang.System. +// only does registerNatives and keeps the rest of the class +// initialization work later until thread initialization completes. +// +// System.initPhase1 initializes the system properties, the static +// fields in, out, and err. Set up java signal handlers, OS-specific +// system settings, and thread group of the main thread. +static void call_initPhase1(TRAPS) { + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); + instanceKlassHandle klass (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, klass, vmSymbols::initPhase1_name(), + vmSymbols::void_method_signature(), CHECK); +} + +// Phase 2. Module system initialization +// This will initialize the module system. Only java.base classes +// can be loaded until phase 2 completes. +// +// Call System.initPhase2 after the compiler initialization and jsr292 +// classes get initialized because module initialization runs a lot of java +// code, that for performance reasons, should be compiled. Also, this will +// enable the startup code to use lambda and other language features in this +// phase and onward. +// +// After phase 2, The VM will begin search classes from -Xbootclasspath/a. +static void call_initPhase2(TRAPS) { + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); + instanceKlassHandle klass (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, klass, vmSymbols::initPhase2_name(), + vmSymbols::void_method_signature(), CHECK); + universe_post_module_init(); +} + +// Phase 3. final setup - set security manager, system class loader and TCCL +// +// This will instantiate and set the security manager, set the system class +// loader as well as the thread context class loader. The security manager +// and system class loader may be a custom class loaded from -Xbootclasspath/a, +// other modules or the application's classpath. +static void call_initPhase3(TRAPS) { + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); + instanceKlassHandle klass (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, klass, vmSymbols::initPhase3_name(), + vmSymbols::void_method_signature(), CHECK); +} + void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { TraceStartupTime timer("Initialize java.lang classes"); @@ -3391,10 +3442,15 @@ java_lang_Thread::set_thread_status(thread_object, java_lang_Thread::RUNNABLE); + // The VM creates objects of this class. + initialize_class(vmSymbols::java_lang_reflect_Module(), CHECK); + // The VM preresolves methods to these classes. Make sure that they get initialized initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK); initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK); - call_initializeSystemClass(CHECK); + + // Phase 1 of the system initialization in the library, java.lang.System class initialization + call_initPhase1(CHECK); // get the Java runtime name after java.lang.System is initialized JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); @@ -3612,10 +3668,10 @@ // Always call even when there are not JVMTI environments yet, since environments // may be attached late and JVMTI must track phases of VM execution - JvmtiExport::enter_start_phase(); + JvmtiExport::enter_early_start_phase(); // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents. - JvmtiExport::post_vm_start(); + JvmtiExport::post_early_vm_start(); initialize_java_lang_classes(main_thread, CHECK_JNI_ERR); @@ -3643,12 +3699,9 @@ Management::record_vm_init_completed(); #endif // INCLUDE_MANAGEMENT - // Compute system loader. Note that this has to occur after set_init_completed, since - // valid exceptions may be thrown in the process. // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and // set_init_completed has just been called, causing exceptions not to be shortcut // anymore. We call vm_exit_during_initialization directly instead. - SystemDictionary::compute_java_system_loader(CHECK_(JNI_ERR)); #if INCLUDE_ALL_GCS // Support for ConcurrentMarkSweep. This should be cleaned up @@ -3663,10 +3716,6 @@ } #endif // INCLUDE_ALL_GCS - // Always call even when there are not JVMTI environments yet, since environments - // may be attached late and JVMTI must track phases of VM execution - JvmtiExport::enter_live_phase(); - // Signal Dispatcher needs to be started before VMInit event is posted os::signal_init(); @@ -3685,13 +3734,6 @@ create_vm_init_libraries(); } - // Notify JVMTI agents that VM initialization is complete - nop if no agents. - JvmtiExport::post_vm_initialized(); - - if (TRACE_START() != JNI_OK) { - vm_exit_during_initialization("Failed to start tracing backend."); - } - if (CleanChunkPoolAsync) { Chunk::start_chunk_pool_cleaner_task(); } @@ -3716,6 +3758,34 @@ // (see SystemDictionary::find_method_handle_intrinsic). initialize_jsr292_core_classes(CHECK_JNI_ERR); + // This will initialize the module system. Only java.base classes can be + // loaded until phase 2 completes + call_initPhase2(CHECK_JNI_ERR); + + // Always call even when there are not JVMTI environments yet, since environments + // may be attached late and JVMTI must track phases of VM execution + JvmtiExport::enter_start_phase(); + + // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents. + JvmtiExport::post_vm_start(); + + // Final system initialization including security manager and system class loader + call_initPhase3(CHECK_JNI_ERR); + + // cache the system class loader + SystemDictionary::compute_java_system_loader(CHECK_(JNI_ERR)); + + // Always call even when there are not JVMTI environments yet, since environments + // may be attached late and JVMTI must track phases of VM execution + JvmtiExport::enter_live_phase(); + + // Notify JVMTI agents that VM initialization is complete - nop if no agents. + JvmtiExport::post_vm_initialized(); + + if (TRACE_START() != JNI_OK) { + vm_exit_during_initialization("Failed to start tracing backend."); + } + #if INCLUDE_MANAGEMENT Management::initialize(THREAD);