无标Ubuntu 14.04 GDB調試OpenJDK8(二)-

2017-10-31  本文已影响9人  小小帽2010

接著來看下JavaMain函式,首先這是一個線程,所以參數類型是void*。進入InitializeJVM,再進入ifn->CreateJavaVM,CreateJavaVM是函式指標,調用hotspot中jni.cpp中的JNI_CreateJavaVM。

JNI_CreateJavaVM

注意,JNI_CreateJavaVM為STDCALL,函式自己清空調用堆棧。

_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args)

一路往下,注意兩個重要變數的賦值,thread::create_vm先跳過。其中,在下圖完成賦值,JNIInvokeInterface_裡面都是一些函式指標。

JNI.cpp:JavaVM,JNIEnv JNIInvokeInterface_

JNIEnv是一個大結構體,可見主要是對functions賦值,過程如下:

JNI.h

1. 執行上述的Thread::create_vm -> JavaThread* main_thread = new JavaThread() -> initialize() ->set_jni_functions(jni_functions());

2. jni_functions返回jni_NativeInterface,jni_NativeInterface是在jni.cpp中的一個結構體。

JNI.cpp

3. set_jni_functions完成設置。

thread.hpp

回到JavaMain,接著調用LoadMainClass,會加在LauncherHelper.java中的checkAndLoadMain方法。之後就是hotspot層面的一些工作:GetStaticMethodID、CallStaticMethodID,這些都是宏,比較難跟蹤,舉一個例子說明。

JNI.CPP

1. 最終會調get_method_id,之前的宏採用預處理一下,僅編譯JNI.cpp(gcc工程自行修改,這裡用Visual Studio 2010)。

2. 預處理後的代碼:

After Preprocessor

3. 最後調用LEAVE()這個宏,銷毀虛擬機的一些工作。

4. Thread::create_vm較複雜,有興趣的自己分析。

上一篇下一篇

猜你喜欢

热点阅读