hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
void TemplateTable::tableswitch() {
{- -------------------------------------------
(1) (assert) (See: TemplateTable::transition())
---------------------------------------- -}
transition(itos, vtos);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Label default_case, continue_execution;
{- -------------------------------------------
(1) コード生成:
「現在の Lbcp から 1byte 以上先で 4bytes-align なアドレス(= defaultbytes 情報の先頭)を算出し,
O1 レジスタにセットする」
(1byte は, tableswitch 命令自体が 1byte(0xaa) 占めているため)
---------------------------------------- -}
// align bcp
__ add(Lbcp, BytesPerInt, O1);
__ and3(O1, -BytesPerInt, O1);
{- -------------------------------------------
(1) コード生成:
「命令中に埋まっている lowbytes 情報と highbytes 情報をロードし,
それぞれ O2 レジスタと O3 レジスタに入れておく」
---------------------------------------- -}
// load lo, hi
__ ld(O1, 1 * BytesPerInt, O2); // Low Byte
__ ld(O1, 2 * BytesPerInt, O3); // High Byte
{- -------------------------------------------
(1) コード生成: (64bits 環境の場合にのみ生成)
「TOS に入っている index 情報を符号拡張しておく (JVM仕様により符号付き整数なので)」
---------------------------------------- -}
#ifdef _LP64
// Sign extend the 32 bits
__ sra ( Otos_i, 0, Otos_i );
#endif /* _LP64 */
{- -------------------------------------------
(1) コード生成:
「TOS に入っている index を, lowbytes 及び highbytes と比較する.
もし index が範囲外であれば (JVM仕様に基づき) default_case ラベルに分岐」
---------------------------------------- -}
// check against lo & hi
__ cmp( Otos_i, O2);
__ br( Assembler::less, false, Assembler::pn, default_case);
__ delayed()->cmp( Otos_i, O3 );
__ br( Assembler::greater, false, Assembler::pn, default_case);
{- -------------------------------------------
(1) コード生成:
「index が示す位置に格納されているジャンプ先のオフセット値を O2 レジスタにロードし,
continue_execution ラベルにジャンプ」
(なお, InterpreterMacroAssembler::profile_switch_case() が生成するコードで
JIT コンパイラ用のプロファイル情報の取得も行っている. (See: [here](no2935fdD.html) for details))
---------------------------------------- -}
// lookup dispatch offset
__ delayed()->sub(Otos_i, O2, O2);
__ profile_switch_case(O2, O3, G3_scratch, G4_scratch);
__ sll(O2, LogBytesPerInt, O2);
__ add(O2, 3 * BytesPerInt, O2);
__ ba(false, continue_execution);
__ delayed()->ld(O1, O2, O2);
{- -------------------------------------------
(1) コード生成:
「(ここが default_case ラベルの位置)」
「defaultbytes の位置に格納されているジャンプ先のオフセット値を O2 レジスタにロード」
(なお, InterpreterMacroAssembler::profile_switch_default() が生成するコードで
JIT コンパイラ用のプロファイル情報の取得も行っている. (See: [here](no2935fdD.html) for details))
---------------------------------------- -}
// handle default
__ bind(default_case);
__ profile_switch_default(O3);
__ ld(O1, 0, O2); // get default offset
{- -------------------------------------------
(1) コード生成:
「Lbcp の値を更新する (O2 に入っているジャンプ先のオフセット分を足す)」
---------------------------------------- -}
// continue execution
__ bind(continue_execution);
__ add(Lbcp, O2, Lbcp);
{- -------------------------------------------
(1) コード生成:
「dispatch_next() が生成するコードで,
次のバイトコードに対応するテンプレートへとジャンプする」
---------------------------------------- -}
__ dispatch_next(vtos);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.