OpenJDK9 Hotspot java 虚拟机入口

发布时间:2019-11-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了OpenJDK9 Hotspot java 虚拟机入口脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

假设 openjdk 代码目录为 jdk9dev@H_512_2@

main函数

main 函数在 jdk9dev/jdk/src/java.base/share/native/launcher/main.c,它处理完命令行参数后跳转到 JLI_Launch 函数

    int main(int argc, char** argv) {         // 处理命令行选项         ...          return JLI_Launch(margc, margv,                    sizeof(const_jargs) / sizeof(char *), const_jargs,                    appclassc, const_appclasspath,                    VERSION_STRING,                    DOT_VERSION,                    (const_PRogname != NULL) ? const_progname : *margv,                    (const_launcher != NULL) ? const_launcher : *margv,                    HAS_JAVA_ARGS,                    const_cpwildcard, const_javaw, const_ergo_class);     }

JLI_Launch

JLI_Launch 函数在 jdk9dev/jdk/src/java.base/share/native/libjli/java.c,
它调用 LoadJavaVM 加载 libjvm.dylib , 这个 libjvm.dylib 就是 hotspot 编译的产出!

    int JLI_Launch(...) {         ...          if (!LoadJavaVM(jvmpath, &ifn)) {             return (6);         }          ...          return JVMInIT(&ifn, threadStackSize, argc, argv, mode, what, ret);     }

LoadJavaVM

在 mac OSX 系统下 LoadJavaVM 在 jdk9dev/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c

jboolean LoadJavaVM(const char* jvmpath, InvocationFunctions* ifn) {     ... #ifndef statIC_BUILD     libjvm = dloPEn(jvmpath, RTLD_NOW + RTLD_GLOBAL); #else     libjvm = dlopen(NULL, RTLD_First); #endif     ifn->CreateJavaVM = (CreateJavaVM_t)        dlsym(libjvm, "JNI_CreateJavaVM");     if (ifn->CreateJavaVM == NULL) {         JLI_ReportErrorMessage(DLL_ERROR2, jvmpath, dlerror());         return JNI_FALSE;     }     ... }

使用 dlopen 加载动态库并获取 JNI_CreateJavaVM 函数入口地址

JVMInit

在 mac osx 系统下 JVMInit 在jdk9dev/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c

熟悉 objc 的同学,对下面的代码应该会感到很亲切:

int JVMInit(InvocationFunctions* ifn, jlong threadStackSize, ...) {     ...     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     {         JavaLaunchHelper* launcher = [[[JavaLaunchHelper alloc] init] autorelease];         [launcher performSelectorOnMainThread:@selector(launchJava:)                                    withObject:[NSValue valueWithPointer:(void*)&args]                                 waitUntilDone:YES];         rslt = [launcher getReturnValue];     }     [pool drain];     return rslt;     ... }

创建 JavaLaunchHelper 对象,并将控制流跳转到 launchJava

@implementation JavaLauncherHelper -(int) launchJava:(NSValue*) argsValue {     _returValue = JavaMain([argsValue pointerValue]); } @end

呵呵,在 objc 环境短暂停留后控制留又回到 c/c++ 的世界-JavaMain

JavaMain

JavaMain 函数在 jdk9dev/jdk/src/java.base/share/native/libjli/java.c,
在 JavaMain 函数中 会初始化 java 虚拟机,查找 main class,获取 main class 的 main 方法,并开始执行 java 字节码

int JNicalL JavaMain(void* _args) {     ...     // 初始化 jvm     if (!InitializeJVM(&vm, &env, &ifn)) {         ...     }      ...     // 加载 main class     mainClass = LoadMainClass(env, mode, what);      ...     // 获取 main 方法     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",                                        "([Ljava/lang/String;)V");      ...     // 调用 main 方法     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);      LEAVE();     }

脚本宝典总结

以上是脚本宝典为你收集整理的OpenJDK9 Hotspot java 虚拟机入口全部内容,希望文章能够帮你解决OpenJDK9 Hotspot java 虚拟机入口所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。