模板解释器
模板解释器解释器如果按照前述的switch-case方式执行会产生性能问题为了解决该问题引入了模板解释器。定义模板解释器可以理解为将每个字节码的汇编实现都预先定义好然后将其作为标准模板放入模板表。模板由于每个字节码的行为不同因此将模板做了以下定义/*templateTable.hpp*/classTemplate{...int_flags;//标志位不同位标定该函数具有哪些行为例如读取字节码后一位调用运行时函数等TosState _tos_in;//进入栈顶状态TosState _tos_out;//输出栈顶状态generator _gen;//这是一个函数指针指向的是字节码的具体实现函数int_arg;//字节码实现函数的输入参数...}举例说明例如iadd字节码其定义为将栈顶的2个整型相加结果推向栈顶那么其输入栈顶状态为整型输出栈顶状态为整型假设字节码生成的汇编的函数名为iop2参数为枚举值add那么该模板可以定义为Template*t;t._tos_initos;t._tos_outitos;t._geniop2;t._argadd;除此之外_flags参数用于说明字节码函数实现时的行为constint____0;constintubcp1Template::uses_bcp_bit;//需要使用字节码指针向后读取参数constintdisp1Template::does_dispatch_bit;//是否会执行跳转操作constintclvm1Template::calls_vm_bit;//是否会调运行时函数constintiswd1Template::wide_bit;//是否支持宽指令举例说明bipush字节码该字节码的定义为将字节码后跟的数字推送至栈顶。假设把整数10推送至栈顶。那么字节码的形式如下bipush10如果此时字节码指针指向bipush字节那么当执行字节码时则必须向后移动一位实现参数10的读取。模板表模板表本质上是一个Template类型的数组。定义如下/*templateTable.hpp*/classTemplateTable:AllStatic{...staticTemplate _template_table[Bytecodes::number_of_codes];...}模板表是一个静态变量这意味着在内存中的位置常驻且不会发生动态改变。模板表的初始化过程使得每个模板的定义都放在模板表中的对应位置/*templateTable.cpp*/voidTemplateTable::initialize(){...// Java spec bytecodes ubcp|disp|clvm|iswd in out generator argumentdef(Bytecodes::_nop,____|____|____|____,vtos,vtos,nop,_);...def(Bytecodes::_bipush,ubcp|____|____|____,vtos,itos,bipush,_);...}这里的def函数的作用是将模板表中的字节码对象取出来然后通过initialize函数进行属性赋值。voidTemplateTable::def(Bytecodes::Code code,intflags,TosState in,TosState out,void(*gen)(intarg),intarg){...//在模板表中取出对应字节码的对象Template*tis_wide?template_for_wide(code):template_for(code);//将传入的参数赋值给该对象t-initialize(flags,in,out,gen,arg);}经过上述步骤模板表中的所有模板已完成定义。模板生成在模板表中将每个字节码定义完毕后回到前文所述在转发表中设置每个字节码指令的入口过程转发表中的字节码对应从模板表中取出的指令模板对象然后为该模板对象加入各种栈顶状态的入口地址/*templateTableGenerator.cpp*/voidTemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code){...if(Bytecodes::is_defined(code)){Template*tTemplateTable::template_for(code);...set_short_entry_points(t,bep,cep,sep,aep,iep,lep,fep,dep,vep);...}在set_short_entry_points过程中实现了个字节码模板的汇编生成/*templateTableGenerator.cpp*/voidTemplateInterpreterGenerator::set_short_entry_points(Template*t,...){...generate_and_dispatch(t);...}voidTemplateInterpreterGenerator::generate_and_dispatch(Template*t,...){// generate templatet-generate(_masm);//这里_masm为指定平台的汇编器}以bipush字节码为例在模板表中定义bipush字节码实现为bipush函数def(Bytecodes::_bipush,ubcp|____|____|____,vtos,itos,bipush,_);这里Bytecodes::_bipush为bipush字节码的值其对应的实现为bipush函数。在x86平台的实现如下/*templateTable_x86.cpp*/voidTemplateTable::bipush(){transition(vtos,itos);//把字节码指针后一个字节的值放入rax寄存器__load_signed_byte(rax,at_bcp(1));}