天天看點

第4篇-JVM終于開始調用Java主類的main()方法啦

在前一篇 第3篇-callstub新棧幀的建立 中我們介紹了generate_call_stub()函數的部分實作,完成了向callstub棧幀中壓入參數的操作,此時的狀态如下圖所示。

第4篇-JVM終于開始調用Java主類的main()方法啦

繼續看generate_call_stub()函數的實作,接來下會加載線程寄存器,代碼如下:

生成的彙編代碼如下:

對照着上面的棧幀可看一下0x18(%rbp)這個位置存儲的是thread,将這個參數存儲到%r15寄存器中。

如果在調用函數時有參數的話需要傳遞參數,代碼如下:

這裡是個循環,用于傳遞參數,相當于如下代碼:

因為要調用java方法,是以會為java方法壓入實際的參數,也就是壓入parameter size個從parameters開始取的參數。壓入參數後的棧如下圖所示。

第4篇-JVM終于開始調用Java主類的main()方法啦

當把需要調用java方法的參數準備就緒後,接下來就會調用java方法。這裡需要重點提示一下java解釋執行時的方法調用約定,不像c/c++在x86下的調用約定一樣,不需要通過寄存器來傳遞參數,而是通過棧來傳遞參數的,說的更直白一些,是通過局部變量表來傳遞參數的,是以上圖callstub()函數棧幀中的argument word1 ... argument word n其實是​被調用的java方法局部變量表的一部分。

下面接着看調用java方法的代碼,如下:

注意調用callq指令後,會将callq指令的下一條指令的位址壓棧,再跳轉到第1操作數指定的位址,也就是*%rsi表示的位址。壓入下一條指令的位址是為了讓函數能通過跳轉到棧上的位址從子函數傳回。 

callq指令調用的是entry_point。entry_point在後面會詳細介紹。

公衆号 深入剖析java虛拟機hotspot 已經更新虛拟機源代碼剖析相關文章到60+,歡迎關注,如果有任何問題,可加作者微信mazhimazh,拉你入虛拟機群交流

第4篇-JVM終于開始調用Java主類的main()方法啦