2017-02-18 30 views
0

我們知道下面的通話談話的主題, What's the calling convention for the Java code in Linux platform? 並且還解釋說,哪些寄存器用於在solaris/linux中爲JNI方法傳遞JNIEnv?

「你可能會注意到的Java調用約定類似於C調用約定,而是由一個說法正確的,這是有意這樣做的移調用JNI方法時避免額外的寄存器混洗(您知道,JNI方法在方法參數前面有額外的JNIEnv *參數)。「所以當我們調用JNI函數,如jclass FindClass(JNIEnv * env,const char * name)時,這意味着什麼?那麼JNIEnv值env將被傳遞給rdi,並將名稱傳遞給rsi,但是當我們調用諸如void printClassName(int Integer1,Object obj)之類的通用非JNI Java方法時,則Integer1被傳遞給rsi,而obj被傳遞傳遞給堆棧,因爲它不是一個整數,它是正確的?

如果我錯了,請糾正我。

|-------------------------------------------------------| 
| c_rarg0 c_rarg1 c_rarg2 c_rarg3 c_rarg4 c_rarg5 | 
|-------------------------------------------------------| 
| rcx  rdx  r8  r9  rdi* rsi*  | windows (* not a c_rarg) 
| rdi  rsi  rdx  rcx  r8  r9   | solaris/linux 
|-------------------------------------------------------| 
| j_rarg5 j_rarg0 j_rarg1 j_rarg2 j_rarg3 j_rarg4 | 
|-------------------------------------------------------| 
+0

您試圖解決什麼問題? –

+1

研究調試知識。 –

回答

0

給出的表描述VM如何調用的Java方法。

E.g.調用Java方法時void print(int i, Object o)它通過

  • RSI (j_rarg0)
  • ithisRDX (j_rarg1)
  • oRCX (j_rarg2) - 對象的引用也被傳在通用寄存器。

調用約定是相同的,不管方法是否聲明爲native或不是。對於一個本地方法會有一個本地實現

void Java_ClassName_print(JNIEnv* env, jobject this, jint i, jobject o); 

這個本地函數遵循標準platform ABI,就是

  • envRDI (c_rarg0)
  • thisRSI (c_rarg1)
  • iRDX (c_rarg2)
  • oRCX (c_rarg3)

注意的是,由於j_rargsc_rargs的一個明智的選擇,參數保持在相同的寄存器。


FindClass這樣的JNI函數與虛擬機調用約定無關。他們必須遵循平臺ABI。因此,第一個參數JNIEnv*在Linux/x64上的RDI中傳遞。

+0

非常感謝你的清楚解釋,你是如此的親切。然而,正如你曾經提到的「在寄存器中傳遞多達6個第一整數參數:rsi,rdx,rcx,r8,r9,rdi,」在http://stackoverflow.com/questions/41693637/whats-the-calling-convention -for-the-java-code-in-linux-platform,因爲Object o是對象引用而不是整數,爲什麼它也通過RCX傳遞? openjdk文章也表達了與你說的六個Integer相同的含義... https://wiki.openjdk.java.net/display/HotSpot/CallingSequences,我想我有些誤解。 –

+0

@Jacky在上面的引用中,我用「整數」作爲「浮點數」的反義詞。對象引用(地址/指針/壓縮指針或其他)也是適合通用(整數)寄存器的值。 – apangin

+0

非常感謝您的優秀解釋。 –

相關問題