java - Java 代码在 Linux 平台上的调用约定是什么?

标签 java jvm

我们知道 c/的调用约定是“前六个整数或指针参数在寄存器 RDI、RSI、RDX、RCX(Linux 内核接口(interface)中的 R10[17]:124)、R8 和 R9 中传递”基于以下文章的 Linux 平台中的 c++ 代码。 https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions

然而,Java 代码在 Linux 平台上的调用约定是什么(假设 JVM 是热点)?下面是例子,四个参数存放在哪些寄存器中?

protected void caller( ) {
callee(1,"123", 123,1)
}

protected void callee(int a,String b, Integer c,Object d) {

}

最佳答案

没有指定 JVM 在内部如何调用 Java 方法。各种 JVM 实现可能遵循不同的调用约定。以下是它在 Linux x64 上的 HotSpot JVM 中的工作方式。

  • Java 方法可以在解释器中运行,也可以是 JIT 编译的。
  • 解释和编译代码使用不同的调用约定。

1。解释器方法入口

每个 Java 方法都有一个进入解释器的入口点。此条目用于从一个解释方法跳转到另一个解释方法。

  • 所有参数都在堆栈上传递,从下到上。
  • rbx 包含指向 Method* 结构的指针 - 一个的内部元数据 正在调用的方法。
  • r13 包含 sender_sp - 调用方方法的堆栈指针。如果使用 c2i 适配器,它可能与 rsp + 8 不同(见下文)。

有关 HotSpot 源代码中解释器条目的更多详细信息:templateInterpreter_x86_64.cpp .

2。编译入口

编译后的方法有自己的入口点。编译后的代码通过这个条目调用编译后的方法。

  • 在寄存器中传递最多 6 个第一个整数参数:rsirdxrcxr8r9rdi。非静态方法接收 this 引用作为 rsi 中的第一个参数。
  • xmm0 ... xmm7 寄存器中传递最多 8 个浮点参数。
  • 所有其他参数在堆栈上从上到下传递。

此约定在 assembler_x86.hpp 中得到了很好的说明。 :

    |-------------------------------------------------------|
    | 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    |
    |-------------------------------------------------------|

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

3。适配器

Java 方法可能还有两个入口点:c2ii2c 适配器。这些适配器是动态生成的代码片段,可将已编译的调用约定转换为解释器布局,反之亦然。 с2ii2c入口点分别用于从编译代码调用解释方法和从解释代码调用编译方法。


P.S. JVM 如何在内部调用方法通常并不重要,因为这些只是对最终用户不透明的实现细节。此外,即使在 JDK 的次要更新中,这些细节也可能发生变化。但是,我知道至少在一种情况下,Java 调用约定的知识可能会显得有用 - 在分析 JVM 故障转储时。

关于java - Java 代码在 Linux 平台上的调用约定是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41693637/

相关文章:

java - JSF 无法显示表中的数据

java - MethodHandle 示例在调用 invokeExact 时抛出 WrongMethodTypeException

java - volatile 变量读取 : Who performs the taks JVM or OS?

Java重生过程

java - jdbc 在 sql server 2008 r2 中存储的 png 图像给出的数据不完整

java - 从五对中找出一对

java - Android Studio 中隐藏和取消隐藏布局中的堆栈

java - 我可以通过 HTML 代码控制小程序字体吗?

java - 启动 JVM 进行内联

java - 是否有等效的 super 用于将方法调用重定向到包装类中的内部字段