Sunday, November 30, 2008

初探HotSpot——JNI_CreateJavaVM源码剖析

        HotSpot是Sun的Java虚拟机的代号。我们从JNI_GetCreatedJavaVMs做为研究HotSpot代码的起点,其实现在文件prims/jni.cpp中:
        _JNI_IMPORT_OR_EXPORT_ jint JNICALL
                 JNI_CreateJavaVM(JavaVM **vm, 
                                                      void **penv,
                                                      void *args) {
             HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, 
                                                        vm, penv, args);
                     // 这是给Solarias上面的dtrace用的,参考文件utilities\
                     // dtrace.hpp。关于dtrace的更多信息,参考这里
                     // 后文将忽略dtrace相关内容。
             jint result = JNI_ERR;
             DT_RETURN_MARK(CreateJavaVM, jint, 
                                                      (const jint&)result);
                     // 这也是给dtrace用的,该宏的定义可以在jni.cpp中找到。
             if (Atomic::xchg(1, &vm_created) == 1) {
                     // 这里不能直接判断vm_created是否为1,因为在有些
                     // CPU上该操作并非原子操作。(记得Win32的
                     // InterlockedExchange吗?)
                     // 在x86平台上,这是通过汇编指令实现的。
                     // 见文件atomic_windows_x86.inline.hpp。
                return JNI_ERR;
                     // 由于目前虚拟机有些信息是存储在全局变量里,所以
                     // 一个进程里只能有一个虚拟机。
             }
            if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
                return JNI_ERR;
                     // 之前创建虚拟机失败了,且不允许再次创建。
            }

            bool can_try_again = true;

            result = Threads::create_vm((JavaVMInitArgs*) args, 
                                                                 &can_try_again);
                      // 这里完成虚拟机的创建
            if (result == JNI_OK) {
               JavaThread *thread = JavaThread::current();
               *vm = (JavaVM *)(&main_vm);
                       // main_vm是个全局变量,定义在jni.cpp内。
               *(JNIEnv**)penv = thread->jni_environment();
                       // 在之前的文章中我们提到,JNIEnv是线程相关的。
               RuntimeService::record_application_start();

               if (JvmtiExport::should_post_thread_life()) {
                   JvmtiExport::post_thread_start(thread);
               }
                        // JVMTI是JVM Tool Interface的缩写,用来给本地
                        // 工具提供监视虚拟机和Java程序运行状态的功能。
                        // 这是另外一个话题,具体参考这里
               NOT_PRODUCT(if (CompileTheWorld)
                                                  ClassLoader::compile_the_world();)
               ThreadStateTransition::transition_and_fence(thread,
                        _thread_in_vm, _thread_in_native);
            } else {
               if (can_try_again) {
                  safe_to_recreate_vm = 1;
               }

              *vm = 0;
              *(JNIEnv**)penv = 0;
              OrderAccess::release_store(&vm_created, 0);
                    // OrderAccess是为了处理IA32的内存模型。
                    // 可以参考runtime/orderAccess.hpp中的注释。
                    // 更多信息在这里
           }

           return result;
         } 

No comments: