欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java Main 如何是如何被执行的?(1)

来源: javaer 分享于  点击 45392 次 点评:43

Java Main 如何是如何被执行的?(1)


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方法:

  1. // do call 
  2.   { JavaCallWrapper link(method, receiver, result, CHECK); 
  3.     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner 
  4.  
  5.       StubRoutines::call_stub()( 
  6.         (address)&link, 
  7.         // (intptr_t*)&(result->_value), // see NOTE above (compiler problem) 
  8.         result_val_address,          // see NOTE above (compiler problem) 
  9.         result_type, 
  10.         method(), 
  11.         entry_point, 
  12.         args->parameters(), 
  13.         args->size_of_parameters(), 
  14.         CHECK 
  15.       ); 
  16.  
  17.       result = link.result();  // circumvent MS C++ 5.0 compiler bug (result is clobbered across call) 
  18.       // Preserve oop return value across possible gc points 
  19.       if (oop_result_flag) { 
  20.         thread->set_vm_result((oop) result->get_jobject()); 
  21.       } 
  22.     } 
  23.   } 

call_stub()定义在/hotspot/src/share/vm/runtime/stubRoutines.h中,实际上返回的就 是CallStub函数指针_call_stub_entry,该指针指向call_stub的汇编实现的目标代码指令地址,即call_stub的例程 入口。

  1. // Calls to Java 
  2.   typedef void (*CallStub)( 
  3.     address   link, 
  4.     intptr_t* result, 
  5.     BasicType result_type, 
  6.     methodOopDesc* method, 
  7.     address   entry_point, 
  8.     intptr_t* parameters, 
  9.     int       size_of_parameters, 
  10.     TRAPS 
  11.   ); 
  12.   static CallStub call_stub()   { return CAST_TO_FN_PTR(CallStub, _call_stub_entry); } 

在分析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 位操作,下表描述了各寄存器的命名和作用

Java Main如何被执行?

此外,还有16个128位的XMM寄存器,分别为xmm0-15,x84-64的寄存器遵循调用约定(Calling Conventions):

https://msdn.microsoft.com/en-US/library/zthk2dkh(v=vs.80).aspx




相关栏目:

用户点评