hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
void TemplateTable::fast_linearswitch() {
{- -------------------------------------------
(1) (assert) (See: TemplateTable::transition())
---------------------------------------- -}
transition(itos, vtos);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Label loop_entry, loop, found, continue_execution;
{- -------------------------------------------
(1) コード生成:
「現在の Lbcp から 1byte 以上先で 4bytes-align なアドレス(= defaultbyte 情報の先頭)を算出し,
O1 レジスタにセットする」
(1byte は, _fast_linearswitch 命令自体が 1byte 占めているため)
---------------------------------------- -}
// align bcp
__ add(Lbcp, BytesPerInt, O1);
__ and3(O1, -BytesPerInt, O1);
{- -------------------------------------------
(1) コード生成:
「最初のペアのアドレスを O3 レジスタにセットし,
最後のペアのアドレスを O2 レジスタにセットした状態で,
loop_entry ラベルにジャンプして探索を開始する」
---------------------------------------- -}
// set counter
__ ld(O1, BytesPerInt, O2);
__ sll(O2, LogBytesPerInt + 1, O2); // in word-pairs
__ add(O1, 2 * BytesPerInt, O3); // set first pair addr
__ ba(false, loop_entry);
__ delayed()->add(O3, O2, O2); // counter now points past last pair
{- -------------------------------------------
(1) (ここからが, 該当するエントリを探索するループ)
---------------------------------------- -}
// table search
__ bind(loop);
{- -------------------------------------------
(1) コード生成:
「現在のペアのキーの値(O4)と対象のキーの値(Otos_i)を比較する.
一致した場合は, (探索対象が見つかったので) found ラベルに分岐
(ついでに, そのペアにおけるジャンプ先オフセットを O4 レジスタにロードしておく).
一致しなかった場合は, 現在のペアのアドレス(O3)を次のペアに進めて, フォールスルー」
---------------------------------------- -}
__ cmp(O4, Otos_i);
__ br(Assembler::equal, true, Assembler::pn, found);
__ delayed()->ld(O3, BytesPerInt, O4); // offset -> O4
__ inc(O3, 2 * BytesPerInt);
{- -------------------------------------------
(1) コード生成:
「現在のペアのアドレス(O3)と最後のペアのアドレス(O2)を比較する.
まだ残りがあれば, 次のキーの値を O4 にロードして, loop ラベルに分岐.
もうペアがなければこのままフォールスルー」
---------------------------------------- -}
__ bind(loop_entry);
__ cmp(O2, O3);
__ brx(Assembler::greaterUnsigned, true, Assembler::pt, loop);
__ delayed()->ld(O3, 0, O4);
{- -------------------------------------------
(1) (以下は, 一致するペアが見つからなかった場合の処理)
---------------------------------------- -}
// default case
{- -------------------------------------------
(1.1) コード生成:
「default offset を O4 レジスタにロードする.」
---------------------------------------- -}
__ ld(O1, 0, O4); // get default offset
{- -------------------------------------------
(1.1) コード生成: (JIT コンパイラ用のプロファイル情報の取得) (See: [here](no2935fdD.html) for details)
(なおこの場合は, 最後に continue_execution ラベルまで飛ぶことで,
ペアが見つかった場合のプロファイル情報取得処理を実行してしまわないようにしている)
---------------------------------------- -}
if (ProfileInterpreter) {
__ profile_switch_default(O3);
__ ba(false, continue_execution);
__ delayed()->nop();
}
{- -------------------------------------------
(1) (以下は, 一致するペアが見つかった場合の処理)
---------------------------------------- -}
// entry found -> get offset
__ bind(found);
{- -------------------------------------------
(1.1) コード生成: (JIT コンパイラ用のプロファイル情報の取得) (See: [here](no2935fdD.html) for details)
---------------------------------------- -}
if (ProfileInterpreter) {
__ sub(O3, O1, O3);
__ sub(O3, 2*BytesPerInt, O3);
__ srl(O3, LogBytesPerInt + 1, O3); // in word-pairs
__ profile_switch_case(O3, O1, O2, G3_scratch);
__ bind(continue_execution);
}
{- -------------------------------------------
(1) コード生成:
「Lbcp の値を更新する (O4 に入っているジャンプ先のオフセット分を足す)」
---------------------------------------- -}
__ add(Lbcp, O4, Lbcp);
{- -------------------------------------------
(1) コード生成:
「dispatch_next() が生成するコードで,
次のバイトコードに対応するテンプレートへとジャンプする」
---------------------------------------- -}
__ dispatch_next(vtos);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.