关于编译出来的汇编代码的几个疑问?

Jefen 2013-08-23
前两天通过hsdis输出了汇编代码,但有几个问题想得不是很明白,不知道有没有哪个兄弟对这个比较了解的,x86的应该可能还是比较类似的...

1.我发现他里面用了很多寄存器,但前面并没有任何说明,这个寄存器是干吗用的,谁来分配的,是hotspot约定的吗,约定的原则又是什么,有没有相关的文档的,这个需要从代码里找吗?
2.我看很多寄存器都没定义就直接用了,然后在[Stub Code]这段发现这些寄存器的操作,所以我估计这段应该是函数执行前调用的吧?我看代码里有很多段,比如[Deopt Handler Code],pc-bytecode offsets:,不知道从哪能找到关于这方面的说明?
3.HOTSPOT的编译,是不是针对字节码进行编译的,然后逐步优化为本地化码的,那么其实最后我们看到的汇编其实就是本地化的功能,跟java已经一点没有关系了,我现在的猜想应该是这样的?

ps.找到了一个印度代理,终于可以正常访问iteye了...
RednaxelaFX 2013-08-26
Jefen 写道
1.我发现他里面用了很多寄存器,但前面并没有任何说明,这个寄存器是干吗用的,谁来分配的,是hotspot约定的吗,约定的原则又是什么,有没有相关的文档的,这个需要从代码里找吗?

在原本支持的平台上可以参考这个文档:https://wiki.openjdk.java.net/display/HotSpot/CallingSequences
在新的port上(外部贡献的PowerPC port、AArch64 port等)则还是看源码吧。C2使用寄存器的状况可以查ad文件:http://hg.openjdk.java.net/aarch64-port/jdk8/hotspot/file/356ebc1be1d9/src/cpu/aarch64/vm/aarch64.ad

Jefen 写道
2.我看很多寄存器都没定义就直接用了,然后在[Stub Code]这段发现这些寄存器的操作,所以我估计这段应该是函数执行前调用的吧?我看代码里有很多段,比如[Deopt Handler Code],pc-bytecode offsets:,不知道从哪能找到关于这方面的说明?

看代码吧。各种跟“stub”相关的代码都会用到人为事先定好的寄存器。

Jefen 写道
3.HOTSPOT的编译,是不是针对字节码进行编译的,然后逐步优化为本地化码的,那么其实最后我们看到的汇编其实就是本地化的功能,跟java已经一点没有关系了,我现在的猜想应该是这样的?

HotSpot VM的编译器的工作是把字节码编译成机器码。
是不是“逐步”要看您是怎么理解这个词的。在方法级上不是“逐步”,每个方法真要被编译的话整个都会被编译掉(C2的uncommon trap机制暂不讨论的话)。
最终生成的代码自然还是要反映Java的语义的。所以也不是跟原本的Java代码一点关系都没有。
Jefen 2013-09-03
RednaxelaFX 写道

.....


唉,发送失败,白码了半天字了....
感谢版主的回复

1.按照版主的提示,并根据相应的线索,找到下如下的寄存器定义,其中names数组的应该就是各个寄存器功能所对应的寄存器,.ad文件描述的内容,很多东西,并不是看得特别明白,如alloc_class与reg_class的说明?

//   r0-r7,r10-r26 volatile (caller save)
//   r27-r32 system (no save, no allocate)
//   r8-r9 invisible to the allocator (so we can use them as scratch regs)
reg_def R0      ( SOC, SOC, Op_RegI,  0, r0->as_VMReg());
reg_def R0_H    ( SOC, SOC, Op_RegI,  0, r0->as_VMReg()->next());
reg_def R1      ( SOC, SOC, Op_RegI,  1, r1->as_VMReg());
reg_def R1_H    ( SOC, SOC, Op_RegI,  1, r1->as_VMReg()->next() );
……
reg_def R31     (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()); // sp
reg_def R31_H   (  NS,  NS, Op_RegI, 31, r31_sp->as_VMReg()->next());

==============================================================
  const char* names[number_of_registers] = {
    "c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7",
    "rscratch1", "rscratch2",
    "r10", "r11", "r12", "r13", "r14", "r15", "r16",
    "r17", "r18", "r19",
    "resp", "rdispatch", "rbcp", "r23", "rlocals", "rmonitors", "rcpool", "rheapbase",
    "rthread", "rfp", "lr", "sp"
  }; 



2.关于stub部分还没有细看,不过目前看来,暂时不影响我汇编了,应该是有部分stub实现的参数的传递的,从enter来看,可以假设这些参数已经保存好了,直接使用就可以了。。。
3.这里我所说的没有关系,主要是指被局部编译的本地代码,之前一直有疑惑,本地代码和虚拟机指令是否存在一一对应的关系,逻辑上是否存在操作数栈,但现在看来,编译过后的代码逻辑上是不存在操作数栈的,其操作是按照处理器架构直接基于寄存器操作的,并不会还存在逻辑上的操作数栈,然后再弄到寄存器进行操作的?
版主所说的,应该是方法的调用\函数传递等这些全局的操作,其还是应该遵守虚拟机规范的吧
Global site tag (gtag.js) - Google Analytics