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

x86的字节码执行前不会做任何事,所以没有其他代码:

---------------------------------------------------------------------- istore 54 istore [0x00000192d1972ba0, 0x00000192d1972c00] 96 bytes ;获取栈顶int缓存 0x00000192d1972ba0: mov (%rsp),%eax 0x00000192d1972ba3: add $0x8,%rsp ; 执行istore,即移动bcp指针获取index,放入局部变量槽 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)

执行后调用的是dispatch_prolog:

void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) { dispatch_next(state, step); } void InterpreterMacroAssembler::dispatch_next(TosState state, int step) { // load next bytecode (load before advancing _bcp_register to prevent AGI) load_unsigned_byte(rbx, Address(_bcp_register, step)); // advance _bcp_register increment(_bcp_register, step); dispatch_base(state, Interpreter::dispatch_table(state)); } void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, bool verifyoop) { verify_FPU(1, state); if (VerifyActivationFrameSize) { Label L; mov(rcx, rbp); subptr(rcx, rsp); int32_t min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; cmpptr(rcx, (int32_t)min_frame_size); jcc(Assembler::greaterEqual, L); stop("broken stack frame"); bind(L); } if (verifyoop) { verify_oop(rax, state); } #ifdef _LP64 // 防止意外执行到死代码 lea(rscratch1, ExternalAddress((address)table)); jmp(Address(rscratch1, rbx, Address::times_8)); #else Address index(noreg, rbx, Address::times_ptr); ExternalAddress tbl((address)table); ArrayAddress dispatch(tbl, index); jump(dispatch); #endif // _LP64 } ---------------------------------------------------------------------- istore 54 istore [0x00000192d1972ba0, 0x00000192d1972c00] 96 bytes ; 获取栈顶int缓存 0x00000192d1972ba0: mov (%rsp),%eax 0x00000192d1972ba3: add $0x8,%rsp ; 执行istore,即移动bcp指针获取index,放入局部变量槽 0x00000192d1972ba7: movzbl 0x1(%r13),%ebx 0x00000192d1972bac: neg %rbx 0x00000192d1972baf: mov %eax,(%r14,%rbx,8) ; 加载下一个字节码,istore后面一个字节是index,所以需要r13+2 0x00000192d1972bb3: movzbl 0x2(%r13),%ebx 0x00000192d1972bb8: add $0x2,%r13 ; 防止意外执行到死代码 0x00000192d1972bbc: movabs $0x7fffd56e0fa0,%r10 0x00000192d1972bc6: jmpq *(%r10,%rbx,8) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 之前提到istore有一个wide版本的也会一并生成,wide istore格式如下 ; wide istore byte1, byte2 [四个字节] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 获取栈顶缓存的int 0x00000192d1972bca: mov (%rsp),%eax 0x00000192d1972bcd: add $0x8,%rsp ; 获取两个字节的index 0x00000192d1972bd1: movzwl 0x2(%r13),%ebx ; 除两个字节的index外0填充,比如当前index分别为2,2,扩展后ebx=0x00000202 0x00000192d1972bd6: bswap %ebx ; 4个字节反序,ebx=0x02020000 0x00000192d1972bd8: shr $0x10,%ebx ; ebx=0x00000202 0x00000192d1972bdb: neg %rbx ; 取负数 0x00000192d1972bde: mov %eax,(%r14,%rbx,8) ; r14-rbx*8, ; 加载下一个字节码,wide istore byte1,byte2 所以r13+4 0x00000192d1972be2: movzbl 0x4(%r13),%ebx 0x00000192d1972be7: add $0x4,%r13 ; 防止意外执行到死代码 0x00000192d1972beb: movabs $0x7fffd56e0fa0,%r10 0x00000192d1972bf5: jmpq *(%r10,%rbx,8) 0x00000192d1972bf9: nopl 0x0(%rax)

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

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