各バイトコードはそれぞれ以下のテンプレートで処理される.
Bytecode | Template |
---|---|
ifeq | TemplateTable::if_0cmp() |
ifne | TemplateTable::if_0cmp() |
iflt | TemplateTable::if_0cmp() |
ifge | TemplateTable::if_0cmp() |
ifgt | TemplateTable::if_0cmp() |
ifle | TemplateTable::if_0cmp() |
if_icmpeq | TemplateTable::if_icmp() |
if_icmpne | TemplateTable::if_icmp() |
if_icmplt | TemplateTable::if_icmp() |
if_icmpge | TemplateTable::if_icmp() |
if_icmpgt | TemplateTable::if_icmp() |
if_icmple | TemplateTable::if_icmp() |
if_acmpeq | TemplateTable::if_acmp() |
if_acmpne | TemplateTable::if_acmp() |
goto | TemplateTable::_goto() |
jsr | TemplateTable::jsr() |
ret | TemplateTable::ret() |
tableswitch | TemplateTable::tableswitch() |
lookupswitch | TemplateTable::lookupswitch() |
ifnull | TemplateTable::if_nullcmp() |
ifnonnull | TemplateTable::if_nullcmp() |
goto_w | TemplateTable::goto_w() |
jsr_w | TemplateTable::jsr_w() |
ret | TemplateTable::wide_ret() |
fast_linearswitch | TemplateTable::fast_linearswitch() |
fast_binaryswitch | TemplateTable::fast_binaryswitch() |
((cite: hotspot/src/share/vm/interpreter/templateTable.cpp))
// interpr. templates
// Java spec bytecodes ubcp|disp|clvm|iswd in out generator argument
...
def(Bytecodes::_ifeq , ubcp|____|clvm|____, itos, vtos, if_0cmp , equal );
def(Bytecodes::_ifne , ubcp|____|clvm|____, itos, vtos, if_0cmp , not_equal );
def(Bytecodes::_iflt , ubcp|____|clvm|____, itos, vtos, if_0cmp , less );
def(Bytecodes::_ifge , ubcp|____|clvm|____, itos, vtos, if_0cmp , greater_equal);
def(Bytecodes::_ifgt , ubcp|____|clvm|____, itos, vtos, if_0cmp , greater );
def(Bytecodes::_ifle , ubcp|____|clvm|____, itos, vtos, if_0cmp , less_equal );
def(Bytecodes::_if_icmpeq , ubcp|____|clvm|____, itos, vtos, if_icmp , equal );
def(Bytecodes::_if_icmpne , ubcp|____|clvm|____, itos, vtos, if_icmp , not_equal );
def(Bytecodes::_if_icmplt , ubcp|____|clvm|____, itos, vtos, if_icmp , less );
def(Bytecodes::_if_icmpge , ubcp|____|clvm|____, itos, vtos, if_icmp , greater_equal);
def(Bytecodes::_if_icmpgt , ubcp|____|clvm|____, itos, vtos, if_icmp , greater );
def(Bytecodes::_if_icmple , ubcp|____|clvm|____, itos, vtos, if_icmp , less_equal );
def(Bytecodes::_if_acmpeq , ubcp|____|clvm|____, atos, vtos, if_acmp , equal );
def(Bytecodes::_if_acmpne , ubcp|____|clvm|____, atos, vtos, if_acmp , not_equal );
def(Bytecodes::_goto , ubcp|disp|clvm|____, vtos, vtos, _goto , _ );
def(Bytecodes::_jsr , ubcp|disp|____|____, vtos, vtos, jsr , _ ); // result is not an oop, so do not transition to atos
def(Bytecodes::_ret , ubcp|disp|____|____, vtos, vtos, ret , _ );
def(Bytecodes::_tableswitch , ubcp|disp|____|____, itos, vtos, tableswitch , _ );
def(Bytecodes::_lookupswitch , ubcp|disp|____|____, itos, itos, lookupswitch , _ );
...
def(Bytecodes::_ifnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , equal );
def(Bytecodes::_ifnonnull , ubcp|____|clvm|____, atos, vtos, if_nullcmp , not_equal );
def(Bytecodes::_goto_w , ubcp|____|clvm|____, vtos, vtos, goto_w , _ );
def(Bytecodes::_jsr_w , ubcp|____|____|____, vtos, vtos, jsr_w , _ );
...
def(Bytecodes::_ret , ubcp|disp|____|iswd, vtos, vtos, wide_ret , _ );
...
def(Bytecodes::_fast_linearswitch , ubcp|disp|____|____, itos, vtos, fast_linearswitch , _ );
def(Bytecodes::_fast_binaryswitch , ubcp|disp|____|____, itos, vtos, fast_binaryswitch , _ );
...
fast_linearswitch や fast_binaryswitch は rewrite 処理により生成されるバイトコード (See: here for details)
一部の命令については, 逆向きの分岐(backward branch)の実行数が一定回数を超えると JIT コンパイルが実行されて高速化される (See: here for details)
TemplateTable::if_0cmp() が生成したコード -> InterpreterMacroAssembler::if_cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> * jsr 用のコードを生成する場合: -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード * jsr 以外用のコードを生成する場合: -> (1) backedge_counter のカウンタ値をインクリメントする -> InterpreterMacroAssembler::increment_backedge_counter() が生成したコード (1) methodDataOop に関するチェック (& 必要ならば methodDataOop の生成) を行う -> InterpreterMacroAssembler::test_invocation_counter_for_mdp() が生成したコード (1) カウンタ値と閾値を比較し, 閾値を超えていれば JIT コンパイルを行う. あるいは, 既に JIT コンパイル済みのコードがあれば, OSR を行ってそのコードに遷移する. (遷移した場合は以降の処理は実行されない) -> InterpreterMacroAssembler::test_backedge_count_for_osr() が生成したコード -> (See: here for details) (1) Lbcp の値を変更する (1) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::if_icmp() が生成したコード -> InterpreterMacroAssembler::if_cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::if_acmp() が生成したコード -> InterpreterMacroAssembler::if_cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::_goto() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::jsr() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::ret() が生成したコード -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::tableswitch() が生成したコード -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::lookupswitch() が生成したコード -> InterpreterMacroAssembler::stop() が生成したコード TemplateTable::if_nullcmp() が生成したコード -> InterpreterMacroAssembler::if_cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::goto_w() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::jsr_w() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::wide_ret() が生成したコード -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::fast_linearswitch() が生成したコード -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::fast_binaryswitch() が生成したコード -> (1) Lbcp の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード
TemplateTable::if_0cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> * jsr 用のコードを生成する場合: -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_only() が生成したコード * jsr 以外用のコードを生成する場合: -> (1) r13 の値を変更する (1) backedge_counter のカウンタ値をインクリメントする -> InterpreterMacroAssembler::increment_mask_and_jump() が生成したコード (1) methodDataOop に関するチェック (& 必要ならば methodDataOop の生成) を行う -> InterpreterMacroAssembler::test_method_data_pointer() が生成したコード -> InterpreterRuntime::profile_method() (1) カウンタ値と閾値を比較し, 閾値を超えていれば JIT コンパイルを行う. あるいは, 既に JIT コンパイル済みのコードがあれば, OSR を行ってそのコードに遷移する. (遷移した場合は以降の処理は実行されない) -> InterpreterRuntime::frequency_counter_overflow() -> (See: here for details) -> SharedRuntime::OSR_migration_begin() -> (See: here for details) (1) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_only() が生成したコード TemplateTable::if_icmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::if_acmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::_goto() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::jsr() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::ret() が生成したコード -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::tableswitch() が生成したコード -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_only() が生成したコード TemplateTable::lookupswitch() が生成したコード -> InterpreterMacroAssembler::stop() が生成したコード TemplateTable::if_nullcmp() が生成したコード -> InterpreterMacroAssembler::if_cmp() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::goto_w() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::jsr_w() が生成したコード -> TemplateTable::branch() が生成したコード -> (同上) TemplateTable::wide_ret() が生成したコード -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_next() が生成したコード TemplateTable::fast_linearswitch() が生成したコード -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_only() が生成したコード TemplateTable::fast_binaryswitch() が生成したコード -> (1) r13 の値を変更する (2) 次のバイトコードに対応するテンプレートへとジャンプする -> InterpreterMacroAssembler::dispatch_only() が生成したコード
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.