--- 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.<clinit>
+// 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);