// 5. 调用主类的 main 方法 Invoke main method. // 整个调用过程由 JNI 变量 env 完成。 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
// 6. 销毁 JVM /* * Wait for all non-daemon threads to end, then destroy the VM. * This will actually create a trivial new Java waiter thread * named "DestroyJavaVM", but this will be seen as a different * thread from the one that executed main, even though they are * the same C thread. This allows mainThread.join() and * mainThread.isAlive() to work as expected. */ // DestroyJavaVM 其实现在 jni.cpp 中 jni_DestroyJavaVM (*vm)->DestroyJavaVM(vm);
加载虚拟机 LoadJavaVM
LoadJavaVM 在 java.c 的 main 函数中被调用 其定义在 java_md.c 中
// 3. 当 main_thread 放置成 TLS 中 // Attach the main thread to this os thread // main_thread->initialize_thread_local_storage 实现: // ThreadLocalStorage::set_thread(this); main_thread->initialize_thread_local_storage();
// ThreadLocalStorage 这个类是由不同平台实现的 // ThreadLocalStorage 类定义在 runtime/threadLocalStorage.hpp // Interface for thread local storage // Fast variant of ThreadLocalStorage::get_thread_slow extern"C"Thread* get_thread();
// Get raw thread id: e.g., %g7 on sparc, fs or gs on x86 extern"C"uintptr_t _raw_thread_id();
// Initialization // Called explicitly from VMThread::activate_system instead of init_globals. staticvoidinit(); staticboolis_initialized();
private: staticint _thread_index;
staticvoidgenerate_code_for_get_thread();
// Processor dependent parts of set_thread and initialization staticvoidpd_set_thread(Thread* thread); staticvoidpd_init(); // Invalidate any thread cacheing or optimization schemes. staticvoidpd_invalidate_all();
// The following ensure that any optimization tricks we have tried // did not backfire on us: guarantee(get_thread() == thread, "must be the same thread, quickly"); guarantee(get_thread_slow() == thread, "must be the same thread, slowly"); }
void ThreadLocalStorage::init() { assert(!is_initialized(), "More than one attempt to initialize threadLocalStorage"); // 在 win32 平台上面 pd_init 是空实现 pd_init(); // 初始化 thread_index 为一个 TLS index. set_thread_index(os::allocate_thread_local_storage()); generate_code_for_get_thread(); }
// -----win32 实现部分,----- // hotspot\src\os_cpu\windows_x86\vm\threadLS_windows_x86.cpp int ThreadLocalStorage::_thread_ptr_offset = 0;
staticvoidcall_wrapper_dummy(){}
// We need to call the os_exception_wrapper once so that it sets // up the offset from FS of the thread pointer. void ThreadLocalStorage::generate_code_for_get_thread() { os::os_exception_wrapper( (java_call_t)call_wrapper_dummy, NULL, NULL, NULL, NULL); }
// The first routine called by a new Java thread void JavaThread::run() { // ...
// Initialize thread local storage; set before calling MutexLocker // 调用 TLS ThreadLocalStorage::set_thread(this); this->initialize_thread_local_storage();