[inside hotspot] 汇编模板解释器(Template Interpreter)和字节码执行 (4)

这里定义的意思就是,istore使用无参数的生成器istore函数生成例程,这个生成器正是之前提到的那个很短的汇编代码:

void TemplateTable::istore() { transition(itos, vtos); locals_index(rbx); __ movl(iaddress(rbx), rax); }

ubcp表示使用字节码指针,所谓字节码指针指的是该字节码的操作数是否存在于字节码里面,一图胜千言:

istore的index紧跟在istore(0x36)后面,所以istore需要移动字节码指针以获取index。

istore还规定执行前栈顶缓存int值(itos),执行后不缓存(vtos),且istore还有一个wide版本,这个版本使用两个字节的index。

有了这些信息,可以试着解释多出的汇编是怎么回事了。set_entry_points()为istore和wide版本的istore生成代码,
我们选择普通版本的istore解释,wide版本的依样画葫芦即可。它又进一步调用了set_short_entry_points():

void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { ... if (Bytecodes::is_defined(code)) { Template* t = TemplateTable::template_for(code); assert(t->is_valid(), "just checking"); set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); } if (Bytecodes::wide_is_defined(code)) { Template* t = TemplateTable::template_for_wide(code); assert(t->is_valid(), "just checking"); set_wide_entry_point(t, wep); } ... } void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { assert(t->is_valid(), "template must exist"); switch (t->tos_in()) { case btos: case ztos: case ctos: case stos: ShouldNotReachHere(); // btos/ctos/stos should use itos. break; case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; default : ShouldNotReachHere(); break; } }

set_short_entry_points会根据该指令执行前是否需要栈顶缓存pop数据,istore使用了itos缓存,所以需要pop:

// hotspot\src\cpu\x86\vm\interp_masm_x86.cpps void InterpreterMacroAssembler::pop_i(Register r) { // XXX can't use pop currently, upper half non clean movl(r, Address(rsp, 0)); addptr(rsp, wordSize); }

稍微需要注意的是这里说的pop是一个弹出的概念,实际生成的代码是mov,试着解释那一大堆汇编:
mov指令

---------------------------------------------------------------------- istore 54 istore [0x00000192d1972ba0, 0x00000192d1972c00] 96 bytes ;获取栈顶int缓存 0x00000192d1972ba0: mov (%rsp),%eax 0x00000192d1972ba3: add $0x8,%rsp 0x00000192d1972ba7: movzbl 0x1(%r13),%ebx 0x00000192d1972bac: neg %rbx 0x00000192d1972baf: mov %eax,(%r14,%rbx,8) 0x00000192d1972bb3: movzbl 0x2(%r13),%ebx 0x00000192d1972bb8: add $0x2,%r13 0x00000192d1972bbc: movabs $0x7fffd56e0fa0,%r10 0x00000192d1972bc6: jmpq *(%r10,%rbx,8) 0x00000192d1972bca: mov (%rsp),%eax 0x00000192d1972bcd: add $0x8,%rsp 0x00000192d1972bd1: movzwl 0x2(%r13),%ebx 0x00000192d1972bd6: bswap %ebx 0x00000192d1972bd8: shr $0x10,%ebx 0x00000192d1972bdb: neg %rbx 0x00000192d1972bde: mov %eax,(%r14,%rbx,8) 0x00000192d1972be2: movzbl 0x4(%r13),%ebx 0x00000192d1972be7: add $0x4,%r13 0x00000192d1972beb: movabs $0x7fffd56e0fa0,%r10 0x00000192d1972bf5: jmpq *(%r10,%rbx,8) 0x00000192d1972bf9: nopl 0x0(%rax)

接着generate_and_dispatch()又分为执行前(dispatch_prolog)+执行字节码(t->generate())+执行后三部分(dispatch_epilog):

void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { ... int step = 0; if (!t->does_dispatch()) { step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); if (tos_out == ilgl) tos_out = t->tos_out(); // compute bytecode size assert(step > 0, "just checkin'"); // setup stuff for dispatching next bytecode if (ProfileInterpreter && VerifyDataPointer && MethodData::bytecode_has_profile(t->bytecode())) { __ verify_method_data_pointer(); } __ dispatch_prolog(tos_out, step); } // generate template t->generate(_masm); // advance if (t->does_dispatch()) { #ifdef ASSERT // make sure execution doesn't go beyond this point if code is broken __ should_not_reach_here(); #endif // ASSERT } else { // dispatch to next bytecode __ dispatch_epilog(tos_out, step); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjpxz.html