HotSpot模板解释器目标代码生成过程源码分析

本文深入解析HotSpot虚拟机的模板解释器,介绍了如何将字节码转换为本地机器码以提高执行效率。讲解了HotSpot的解释模式、JIT编译、自适应优化和片上虚拟机等执行方式。详细阐述了模板解释器的初始化、TemplateTable、StubQueue以及InterpreterGenerator的工作流程,展示了字节码如何通过解释生成器转化为目标代码。
摘要由CSDN通过智能技术生成

虽然说解释执行模式是逐字逐句翻译给目标平台运行的,但这样的过程未免太过缓慢,如 果能把字节码说的话做成纸条,运行时只要把对应的纸条交给目标平台就可以了,这样,执行速度就会明显提升。JVM的Hotspot虚拟机的模板解释器就是 用这种方法来解释执行的。在开始分析之前,先了解一下JVM的执行方式。


(1).边解释边运行,即每次解释一条字节码并运行其解释的本地代码,这种执行引擎速度相对很慢


(2).JIT(即时编译)具有更快的运行速度但是需要更多的内存,方法被第一次调用时,字节码编译生成的本地代码将会被缓存,这样在该方法下次被调用的时候,将取出缓冲的本地代码直接运行


(3).自适应优化,对于经常被调用的方法,则会缓存其编译产生成的本地代码,对于其他较少被调用的代码,仍对其采用解释执行的方法。


(4).片上虚拟机,即虚拟机的执行引擎直接嵌入在片上


HotSpot虚拟机可以配置为以下运行模式:

-Xint:解释模式

-Xcomp:编译模式

-Xmixed:混合模式

(通过java -version就可以查看虚拟机的运行模式)


HotSpot在启动时,会为所有字节码创建在目标平台上运行的解释运行的机器码,并存放在CodeCache中,在解释执行字节码的过程中,就会从CodeCache中取出这些本地机器码并执行。


Hotspot虚拟机的细节技术实现值得借鉴,如果你觉得源码甚至汇编代码比较枯燥的话,也可以大致了解相关模块的组件、工作流程,对相关实现有一定的认识。


下面就从模板解释器的初始化开始,分析HotSpot的解释代码的生成。

在创建虚拟机时,在初始化全局模块过程中,会调用interpreter_init()初始化模板解释器,模板解释器的初始化包括抽象解释器AbstractInterpreter的初始化、模板表TemplateTable的初始化、CodeCache的Stub队列StubQueue的初始化、解释器生成器InterpreterGenerator的初始化。



void TemplateInterpreter::initialize() {
if (_code != NULL) return ;
// assertions
//...
AbstractInterpreter::initialize();
TemplateTable::initialize();
// generate interpreter
{ ResourceMark rm;
TraceTime timer( "Interpreter generation" , TraceStartupTime);
int code_size = InterpreterCodeSize;
NOT_PRODUCT(code_size *= 4 ;) // debug uses extra interpreter code space
_code = new StubQueue( new InterpreterCodeletInterface, code_size, NULL,
"Interpreter" );
InterpreterGenerator g(_code);
if (PrintInterpreter) print();
}
// initialize dispatch table
_active_table = _normal_table;
}


  1. AbstractInterpreter是基于汇编模型的解释器的共同基类,定义了解释器和解释器生成器的抽象接口。


  2. 模板表TemplateTable保存了各个字节码的模板(目标代码生成函数和参数)。TemplateTable的初始化调用def()将所有字节码的目标代码生成函数和参数保存在_template_table或_template_table_wide(wide指令)模板数组中


// interpr. templates

// Java spec bytecodes ubcp|disp|clvm|iswd in out generator argument

def(Bytecodes::_nop , ____|____|____|____, vtos, vtos, nop , _ );

def(Bytecodes::_aconst_null , ____|____|____|____, vtos, atos, aconst_null , _ );

def(Bytecodes::_iconst_m1 , ____|____|____|____, vtos, itos, iconst , -1 );

def(Bytecodes::_iconst_0 , ____|____|____|____, vtos, itos, iconst , 0 );

def(Bytecodes::_iconst_1 , ____|____|____|____, vtos, itos, iconst , 1 );

def(Bytecodes::_iconst_2 , ____|____|____|____, vtos, itos, iconst , 2 );

//...其他字节码的模板定义


其中,def()是查看数组对应项是否为空,若为空则初始化该数组项。


Template* t = is_wide ? template_for_wide(code) : template_for(code);
// setup entry
t->initialize(flags, in, out, gen, arg);


_template_table或_template_table_wide的数组项就是Template对象,即字节码的模板,Template的结构如下:


class Template VALUE_OBJ_CLASS_SPEC {
private:
enum Flags {
uses_bcp_bit, // set if template needs the bcp pointing to bytecode
does_dispatch_bit, // set if template dispatches on its own
calls_vm_bit, // set if template calls the vm
wide_bit // set if template belongs to a wide instruction
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值