各バイトコードはそれぞれ以下のテンプレートで処理される.
| 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.