java应用程序的启动在在/hotspot/src/share/tools/launcher/java.c的main()函数中,而在虚拟机 初始化过程中,将创建并启动Java的Main线程。最后将调用JNIEnv的CallStaticVoidMethod()来执行main方法。
CallStaticVoidMethod()对应的jni函数为jni_CallStaticVoidMethod,定义在/hotspot /src/share/vm/prims/jni.cpp中,而jni_CallStaticVoidMethod()又调用了 jni_invoke_static(),jni_invoke_static()通过JavaCalls的call()发起对Java方法的调用
所有来自虚拟机对Java函数的调用最终都将由JavaCalls模块来完成,JavaCalls将通过call_helper()来执行Java方法并返回调用结果,并最终调用StubRoutines::call_stub()来执行Java方法:
call_stub()定义在/hotspot/src/share/vm/runtime/stubRoutines.h中,实际上返回的就 是CallStub函数指针_call_stub_entry,该指针指向call_stub的汇编实现的目标代码指令地址,即call_stub的例程 入口。
在分析call_stub的汇编代码之前,先了解下x86寄存器和栈帧以及函数调用的相关知识。
x86-64的所有寄存器都是与 机器字长(数据总线位宽)相同,即64位的,x86-64将x86的8个32位通用寄存器扩展为64位(eax、ebx、ecx、edx、eci、 edi、ebp、esp),并且增加了8个新的64位寄存器(r8-r15),在命名方式上,也从”exx”变为”rxx”,但仍保留”exx”进行32 位操作,下表描述了各寄存器的命名和作用
此外,还有16个128位的XMM寄存器,分别为xmm0-15,x84-64的寄存器遵循调用约定(Calling Conventions):
https://msdn.microsoft.com/en-US/library/zthk2dkh(v=vs.80).aspx