Jvm 在solaris/linux中,哪个寄存器用于传递JNIEnv for JNI方法?

Jvm 在solaris/linux中,哪个寄存器用于传递JNIEnv for JNI方法?,jvm,jit,Jvm,Jit,我们知道以下调用此线程的对话, 它还解释了 您可能会注意到Java调用约定看起来类似于C调用约定,但被右移了一个参数。这样做是为了在调用JNI方法时避免额外的寄存器混乱。您知道,JNI方法在方法参数前面有额外的JNIEnv*参数 那么这是否意味着当我们调用JNI函数时,比如jclass FindClassJNIEnv*env,const char*name;然后JNIEnv值env将被传递给rdi,名称将被传递给rsi,但是当我们调用一般的非JNI Java方法,例如void printClas

我们知道以下调用此线程的对话, 它还解释了

您可能会注意到Java调用约定看起来类似于C调用约定,但被右移了一个参数。这样做是为了在调用JNI方法时避免额外的寄存器混乱。您知道,JNI方法在方法参数前面有额外的JNIEnv*参数

那么这是否意味着当我们调用JNI函数时,比如jclass FindClassJNIEnv*env,const char*name;然后JNIEnv值env将被传递给rdi,名称将被传递给rsi,但是当我们调用一般的非JNI Java方法,例如void printClassNameint Integer1,Object obj时,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    |
|-------------------------------------------------------|

给定的表描述了VM如何调用Java方法

例如,当调用Java方法void printint i时,它会传递对象o

这在RSI j_rarg0中 我在RDX j_rarg1 o在RCX j_rarg2中,对象引用也在通用寄存器中传递。 无论方法是否声明为本机,调用约定都是相同的。对于本机方法,将有一个本机实现

void Java_ClassName_print(JNIEnv* env, jobject this, jint i, jobject o);
本机函数遵循标准,即

环境去RDI c_rarg0 这是RSI c_rarg1 i至RDX c_rarg2 o至RCX c_rarg3 请注意,由于j_rargs和c_rargs的明智选择,参数保留在相同的寄存器中


像FindClass这样的JNI函数与VM调用约定无关。他们必须遵循ABI平台。因此,第一个参数JNIEnv*在Linux/x64上通过RDI传递。

您试图解决的问题是什么?学习调试知识。非常感谢您如此清晰的解释,您非常友好。然而,正如您曾经提到的,最多有6个第一个整数参数在寄存器中传递:rsi、rdx、rcx、r8、r9、rdi、in,因为对象o是对象引用而不是整数,为什么它也在rcx中传递?openjdk文章也表达了与您所说的六个整数相同的含义,我想我有点误解了。@Jacky在上面的引文中,我使用整数作为浮点的对立面。对象引用地址/指针/压缩指针或其他任何对象,也是适合通用整数寄存器的值。