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方法都有一个进入解释器的入口点.此条目用于从解释方法跳转到另一个解释方法.
>所有参数都在堆栈中传递,从下到上.
> rbx包含一个指向Method *结构的指针 – 一个内部元数据
被调用的方法.
> r13保存sender_sp – 调用方法的堆栈指针.如果使用c2i适配器,它可能与rsp 8不同(见下文).
有关HotSpot源代码中的解释器条目的更多详细信息:templateInterpreter_x86_64.cpp.
2.编入条目
编译后的方法有自己的入口点.编译代码通过此条目调用编译的方法.
>寄存器中最多传递6个第一个整数参数:rsi,rdx,rcx,r8,r9,rdi.非静态方法接收此引用作为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方法可能还有两个入口点:c2i和i2c适配器.这些适配器是动态生成的代码片段,它们将编译的调用约定转换为解释器布局,反之亦然. с2i和i2c入口点用于分别从已编译的代码和已解释的代码中编译的方法调用解释的方法.
附:通常JVM如何在内部调用方法并不重要,因为这些只是对最终用户不透明的实现细节.此外,即使在较小的JDK更新中,这些细节也可能会发生变化.但是,我知道至少有一种情况,当Java调用约定的知识可能看起来很有用时 – 分析JVM崩溃转储时.
总结以上是内存溢出为你收集整理的Linux平台中Java代码的调用约定是什么?全部内容,希望文章能够帮你解决Linux平台中Java代码的调用约定是什么?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)