Hotspot JVM 底层C/C++ 源码 入门12执行引擎 解释器

执行引擎就是一个运算器,识别指令并运算最终返回结果

汇编执行流程大概先取指令,执行指令,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更是重中之重

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值