Linux平台中Java代码的调用约定是什么?
我们知道调用约定“前六个整数或指针参数在寄存器RDI,RSI,RDX,RCX(
Linux内核接口中的R10:124),R8和R9”中传递给c / c代码Linux平台基于以下文章.
https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions 然而,Linux平台中Java代码的调用约定是什么(假设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方法都有一个进入解释器的入口点.此条目用于从解释方法跳转到另一个解释方法. >所有参数都在堆栈中传递,从下到上. 有关HotSpot源代码中的解释器条目的更多详细信息:templateInterpreter_x86_64.cpp. 2.编入条目 编译后的方法有自己的入口点.编译代码通过此条目调用编译的方法. >寄存器中最多传递6个第一个整数参数:rsi,rdx,rcx,r8,r9,rdi.非静态方法接收此引用作为rsi中的第一个参数. 这个惯例在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方法可能还有两个入口点:c2i和i2c适配器.这些适配器是动态生成的代码片段,它们将编译的调用约定转换为解释器布局,反之亦然. с2i和i2c入口点用于分别从已编译的代码和已解释的代码中编译的方法调用解释的方法. 附:通常JVM如何在内部调用方法并不重要,因为这些只是对最终用户不透明的实现细节.此外,即使在较小的JDK更新中,这些细节也可能会发生变化.但是,我知道至少有一种情况,当Java调用约定的知识可能看起来很有用时 – 分析JVM崩溃转储时. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |