解释器的初始化
JNI_CreateJavaVM
|
|--> Threads::create_vm
|
|--> init_globals
|
|-->interpreter_init
|
|-->AbstractInterpreter::initialize
|
|-->TemplateTable::initialize
JNI_CreateJavaVM
|
|--> Threads::create_vm
|
|--> init_globals
|
|-->interpreter_init
|
|-->AbstractInterpreter::initialize
|
|-->TemplateTable::initialize
通常提到解释器的时候,对其实现都是这样一个印象:
一个解释器就是不断地读取当前的指令,然后是一个大的switch语句。
HotSpot的解释器和这个方法有所不同。HotSpot的解释器综合运用了传统的解释器技术和汇编技术。
所谓传统解释器技术,是指对于java的bytecode,仍是其处理的基本单位。但是对于每个bytecode
的实现,则是采用的汇编技术。
所谓传统解释器技术,是指对于java的bytecode,仍是其处理的基本单位。但是对于每个bytecode
的实现,则是采用的汇编技术。
先看一段代码
void TemplateTable::iconst(int value) {
transition(vtos, itos);
if (value == 0) {
__ xorl(eax, eax);
} else {
__ movl(eax, value);
}
}
void TemplateTable::iconst(int value) {
transition(vtos, itos);
if (value == 0) {
__ xorl(eax, eax);
} else {
__ movl(eax, value);
}
}
TemplateTable是解释器对这种技术的一个称呼。每一个java bytecode对应一个Template,
所有的Template构成TemplateTable。
上面的代码就是iconst_<i>的实现。
所有的Template构成TemplateTable。
上面的代码就是iconst_<i>的实现。
有几点要注意
一、方法TemplateTable::iconst的实现和CPU相关。上面的代码实际上是intel CPU下的代码,
其位于:\hotspot\src\cpu\i486\vm\templateTable_i486.cpp
二、__ xorl(eax, eax); 中的 __ 是什么?
#define __ _masm->
所以 __ xorl(eax, eax); <==> _masm->xorl(eax, eax);
而_masm的定义是 static InterpreterMacroAssembler* _masm; (templateTable.hpp line92)
#define __ _masm->
所以 __ xorl(eax, eax); <==> _masm->xorl(eax, eax);
而_masm的定义是 static InterpreterMacroAssembler* _masm; (templateTable.hpp line92)
三、InterpreterMacroAssembler的实现又是和CPU相关的。
InterpreterMacroAssembler的父类是:Assembler,它的实现也是和CPU相关的。
下面是xorl的一个实现
void Assembler::xorl(Register dst, Register src) {
emit_arith(0x33, 0xC0, dst, src);
}
emit_arith的调用了emit_byte方法,而emit_byte的核心代码是:
inline void AbstractAssembler::emit_byte(int x) {
// ...
*(unsigned char*)_code_pos = (unsigned char)x;
_code_pos += sizeof(unsigned char);
// ...
}
其中的_code_pos是一个内存缓冲区。
0x33 0xC0对应的Intel汇编语言正是:xor eax, eax
InterpreterMacroAssembler的父类是:Assembler,它的实现也是和CPU相关的。
下面是xorl的一个实现
void Assembler::xorl(Register dst, Register src) {
emit_arith(0x33, 0xC0, dst, src);
}
emit_arith的调用了emit_byte方法,而emit_byte的核心代码是:
inline void AbstractAssembler::emit_byte(int x) {
// ...
*(unsigned char*)_code_pos = (unsigned char)x;
_code_pos += sizeof(unsigned char);
// ...
}
其中的_code_pos是一个内存缓冲区。
0x33 0xC0对应的Intel汇编语言正是:xor eax, eax