执行引擎就是一个运算器,识别指令并运算最终返回结果
汇编执行流程大概先取指令,执行指令,PC+1(取下一条指令)一直循环,最终完成程序逻辑
但是Java的汇编执行流程有极大不同.取指令,执行指令,跳转至下一条指令,注意,是跳转!(当然C1,C2可以优化,但模版解释器呵呵)
JVM首先调用CallStub例程和zerolocals例程,为函数创建栈帧,创建完栈帧后会调用以下逻辑
address interpreterGenerator::generate_normal_entry(bool sync){
//...
address entry_point = __ pc();
//..
generate_fixed_frame(false);//创建栈帧
//..
__ dispatch_next(vtos);//跳转到第一条字节码指令
//..
}
__ dispatch_next(vtos)函数式一个平台相关的函数
void InterpreterMacroAssembler::dispatch_next(TosState state, int step){
load_unsigned_byte(rbx, Address(rsi, step));//读取指令
increment(rsi, step);//字节码下一条
dispatch_base(state, Interpreter::dispatch_table(state));//获取下一条指令
}
movzbl ox1(%esi), %ebx
inc %esi
jmp *_dispatch_table(,%ebx, state)
先看看总览
方框部分为bipush字节码的取指令机器码,方框之前是bipush本身的逻辑
方框为iadd取指,之前为本身逻辑
汇编指令是有长度的,因为一些有操作数,一些没有,而字节码同样遵循了这一规则
Hotspot内部模版解释器来执行字节码指令,所有的字节码指令都会通过TemplateInterpreterGenerator::generate_and_dispatch()来生成对应的机器指令
void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out){
int step;
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();
//..
}
t->generate(_masm);//生成机器码
if (t->does_dispatch()){
__ should_not_reach_here();
} else {
__ dispatch_epilog(tos_out, step);//取下一条字节码指令
}
}
这个函数为Java字节码指令生成对应的汇编指令,实现字节码指令跳转.Template*便是每一条字节码指令的模版
class AbstractAssembler : public ResourceObj {
protected:
address _code_begin;
address _code_pos;
//..
void emit_byte(int x);//向代码区写入一个字节数据/指令
void emit_word(int x);
//...
}
inline void AbstractAssembler::emit_byte(int x){
*(unsigned char*) _code_pos = (unsigned char)x;
_code_pos += sizeof(unsigned char);
sync();
}
封装一层
class Assembler : public AbstractAssembler{
//..
void decl(Register dst);
void decl(Address dst);
void incl(Register dst);
//...
}
void Assembler::push(int32_t imm32){
emit_byte(0x68);
emit_long(imm32);
}
栈顶缓存
一种优化技术,JVM运算是基于栈这中数据结构,但是JVM没有走寻常路,为了追求性能, JVM在运算时会优先将数据存放在寄存器.
与java代码逻辑有关.
JVM基础差不多完结.
一个java类由源代码-》字节码-》jvm解析并开始实例化,调用方法
Java的new,调用api已经完成,其余的都在jdk源码里面了.rt.jar走起
当然GC更是重中之重