哪个寄存器用于通过solaris/linux中的JNI方法的JNIEnv? [英] which register used to pass the JNIEnv for JNI methods in solaris/linux?

查看:86
本文介绍了哪个寄存器用于通过solaris/linux中的JNI方法的JNIEnv?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道以下调用会话与此线程相关, Linux中Java代码的调用约定是什么平台? 并解释说

We know the following calling conversation the this thread, What's the calling convention for the Java code in Linux platform? And also it explained that

您可能会注意到Java调用约定看起来与C调用约定相似,但只向右移了一个参数.这样做是有意避免在调用JNI方法时产生额外的寄存器改组(您知道,JNI方法具有额外的JNIEnv *参数方法参数)."

"You may notice that Java calling convention looks similar to C calling convention but shifted by one argument right. This is done intentionally to avoid extra register shuffling when calling JNI methods (you know, JNI methods have extra JNIEnv* argument prepended to method parameters)."

所以这意味着当我们调用诸如jclass FindClass(JNIEnv * env,const char * name)之类的JNI函数时;然后将JNIEnv值env传递给rdi,并将名称传递给rsi,但是,当我们调用通用的非JNI Java方法(例如void printClassName(int Integer1,Object obj))时,则将Integer1传递给rsi,而obj是传递给堆栈,因为它不是整数,对吗?

So does it mean when we called the JNI function such as jclass FindClass(JNIEnv *env, const char *name); then JNIEnv value env would be passed to the rdi, and name passed to rsi, however when we called the general non-JNI Java method such as void printClassName(int Integer1 ,Object obj), then Integer1 is passed to rsi, and obj was passed to the stack as it is not a Integer,it is right?

如果我错了,请纠正我.

please correct me if I'm wrong.

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

The given table describes how VM calls Java methods.

例如调用Java方法void print(int i, Object o)时会通过

E.g. when calling Java method void print(int i, Object o) it passes

    RSI (j_rarg0) 中的
  • this 中的
  • i
  • RCX (j_rarg2)中的
  • o-对象引用也传递到通用寄存器中.
  • this in RSI (j_rarg0)
  • i in RDX (j_rarg1)
  • o in RCX (j_rarg2) - object references are also passed in general purpose registers.

无论方法是否声明为native,调用约定都是相同的.对于本地方法,将有一个本地实现

The calling convention is the same, whether a method is declared native or not. For a native method there will be a native implementation

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

此本机函数遵循标准平台ABI ,即

This native function follows the standard platform ABI, that is,

  • env转到RDI (c_rarg0)
  • thisRSI (c_rarg1)
  • iRDX (c_rarg2)
  • oRCX (c_rarg3)
  • env goes to RDI (c_rarg0)
  • this to RSI (c_rarg1)
  • i to RDX (c_rarg2)
  • o to RCX (c_rarg3)

请注意,由于j_rargsc_rargs的明智选择,参数保留在相同的寄存器中.

Note that due to a wise choice of j_rargs vs. c_rargs, parameters remained in the same registers.

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

JNI functions like FindClass have nothing to do with VM calling convention. They must follow the platform ABI. Therefore, the first argument JNIEnv* is passed in RDI on Linux/x64.

这篇关于哪个寄存器用于通过solaris/linux中的JNI方法的JNIEnv?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆