模板解释器

模板解释器

解释器如果按照前述switch-case方式执行会产生性能问题,为了解决该问题,引入了模板解释器。

定义

模板解释器可以理解为将每个字节码的汇编实现都预先定义好,然后将其作为标准模板放入模板表。

模板

由于每个字节码的行为不同,因此将模板做了以下定义

/*templateTable.hpp*/
class Template {
...
	int       _flags;  //标志位,不同位标定该函数具有哪些行为,例如读取字节码后一位,调用运行时函数等
	TosState  _tos_in; //进入栈顶状态
	TosState  _tos_out; //输出栈顶状态
	generator _gen;     //这是一个函数指针,指向的是字节码的具体实现函数               
	int       _arg;     //字节码实现函数的输入参数
...
}

举例说明,例如iadd字节码,其定义为将栈顶的2个整型相加,结果推向栈顶,那么其输入栈顶状态为整型,输出栈顶状态为整型,假设字节码生成的汇编的函数名为iop2,参数为枚举值add,那么该模板可以定义为

Template* t;
t._tos_in = itos;
t._tos_out= itos;
t._gen=iop2;
t._arg=add;

除此之外,_flags参数用于说明字节码函数实现时的行为

const int  ____ = 0;
const int  ubcp = 1 << Template::uses_bcp_bit; //需要使用字节码指针向后读取参数
const int  disp = 1 << Template::does_dispatch_bit;//是否会执行跳转操作
const int  clvm = 1 << Template::calls_vm_bit;//是否会调运行时函数
const int  iswd = 1 << Template::wide_bit;//是否支持宽指令

举例说明bipush字节码

该字节码的定义为将字节码后跟的数字推送至栈顶。假设把整数10推送至栈顶。那么字节码的形式如下

bipush 10

如果此时字节码指针指向bipush字节,那么当执行字节码时则必须向后移动一位实现参数10的读取。

模板表

模板表本质上是一个Template类型的数组。定义如下

/*templateTable.hpp*/
class TemplateTable: AllStatic {
...
    static Template        _template_table     [Bytecodes::number_of_codes];
...
}

模板表是一个静态变量,这意味着在内存中的位置常驻且不会发生动态改变。

模板表的初始化过程使得每个模板的定义都放在模板表中的对应位置

/*templateTable.cpp*/
void TemplateTable::initialize() {
    ...
   // Java spec bytecodes ubcp|disp|clvm|iswd  in    out   generator  argument
  def(Bytecodes::_nop ,   ____|____|____|____, vtos, vtos, nop,        _);
    ...
  def(Bytecodes::_bipush ,ubcp|____|____|____, vtos, itos, bipush,     _);
  ...
}

这里的def函数的作用是将模板表中的字节码对象取出来,然后通过initialize函数进行属性赋值。

void TemplateTable::def(Bytecodes::Code code, int flags, TosState in, TosState out, void (*gen)(int arg), int arg) {
  ...
  //在模板表中取出对应字节码的对象
  Template* t = is_wide ? template_for_wide(code) : template_for(code);
  //将传入的参数赋值给该对象
  t->initialize(flags, in, out, gen, arg);
}

经过上述步骤,模板表中的所有模板已完成定义。

模板生成

在模板表中将每个字节码定义完毕后,回到前文所述,在转发表中设置每个字节码指令的入口过程,转发表中的字节码对应从模板表中取出的指令模板对象,然后为该模板对象加入各种栈顶状态的入口地址

/*templateTableGenerator.cpp*/
void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
    ...
    if (Bytecodes::is_defined(code)) {
    Template* t = TemplateTable::template_for(code);
    ...
    set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
    ...
}

在这里插入图片描述
set_short_entry_points过程中实现了个字节码模板的汇编生成

/*templateTableGenerator.cpp*/
void TemplateInterpreterGenerator::set_short_entry_points(Template* t,...){
    ...
    generate_and_dispatch(t);
    ...
}

void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, ...){
    // generate template
  t->generate(_masm);//这里_masm为指定平台的汇编器
}

bipush字节码为例,在模板表中定义bipush字节码实现为bipush函数

def(Bytecodes::_bipush ,ubcp|____|____|____, vtos, itos, bipush,     _);

这里Bytecodes::_bipushbipush字节码的值,其对应的实现为bipush函数。在x86平台的实现如下

/*templateTable_x86.cpp*/
void TemplateTable::bipush() {
  transition(vtos, itos);
  //把字节码指针后一个字节的值放入rax寄存器
  __ load_signed_byte(rax, at_bcp(1));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值