hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
void TemplateTable::fast_linearswitch() {
{- -------------------------------------------
(1) (assert) (See: TemplateTable::transition())
---------------------------------------- -}
transition(itos, vtos);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
Label loop_entry, loop, found, continue_execution;
{- -------------------------------------------
(1) コード生成:
「TOS(rax)の値のバイトオーダーを逆転しておく.」
(命令中に埋まっているキーの値はビッグエンディアンなので.
埋まっているキーを全部逆にするくらいなら TOS だけ逆にした方がいい)
---------------------------------------- -}
// bswap rax so we can avoid bswapping the table entries
__ bswapl(rax);
{- -------------------------------------------
(1) コード生成:
「現在の r13 から 1byte 以上先で 4bytes-align なアドレス(= defaultbytes 情報の先頭)を算出し,
rbx レジスタにセットする」
(1byte は, _fast_linearswitch 命令自体が 1byte 占めているため)
---------------------------------------- -}
// align r13
__ lea(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of
// this instruction (change offsets
// below)
__ andptr(rbx, -BytesPerInt);
{- -------------------------------------------
(1) コード生成:
「ペアの数を rcx にセットした状態で,
loop_entry ラベルにジャンプして探索を開始する」
(なお, ペアの数もビッグエンディアンで埋まっているのでバイトオーダーも変更している)
---------------------------------------- -}
// set counter
__ movl(rcx, Address(rbx, BytesPerInt));
__ bswapl(rcx);
__ jmpb(loop_entry);
{- -------------------------------------------
(1) (ここからが, 該当するエントリを探索するループ)
---------------------------------------- -}
// table search
__ bind(loop);
{- -------------------------------------------
(1) コード生成:
「現在のペアのキーの値と対象のキーの値(rax)を比較する.
一致した場合は, (探索対象が見つかったので) found ラベルに分岐
一致しなかった場合は, フォールスルー」
---------------------------------------- -}
__ cmpl(rax, Address(rbx, rcx, Address::times_8, 2 * BytesPerInt));
__ jcc(Assembler::equal, found);
{- -------------------------------------------
(1) コード生成:
「残りのペアの数(rcx)をデクリメントする.
もし結果が 0 以上であれば(= まだ残りがあれば), loop ラベルに分岐.
もうペアがなければこのままフォールスルー」
---------------------------------------- -}
__ bind(loop_entry);
__ decrementl(rcx);
__ jcc(Assembler::greaterEqual, loop);
{- -------------------------------------------
(1) (以下は, 一致するペアが見つからなかった場合の処理)
---------------------------------------- -}
// default case
{- -------------------------------------------
(1.1) コード生成: (JIT コンパイラ用のプロファイル情報の取得) (See: [here](no2935fdD.html) for details)
---------------------------------------- -}
__ profile_switch_default(rax);
{- -------------------------------------------
(1.1) コード生成:
「default offset を rdx レジスタにロードする.」
---------------------------------------- -}
__ movl(rdx, Address(rbx, 0));
{- -------------------------------------------
(1.1) コード生成:
「continue_execution ラベルまで飛ぶことで,
ペアが見つかった場合のプロファイル情報取得処理を実行してしまわないようにする」
---------------------------------------- -}
__ jmp(continue_execution);
{- -------------------------------------------
(1) (以下は, 一致するペアが見つかった場合の処理)
---------------------------------------- -}
// entry found -> get offset
__ bind(found);
{- -------------------------------------------
(1.1) コード生成:
「見つかったペアにおけるジャンプ先オフセットを rdx レジスタにロードする.」
---------------------------------------- -}
__ movl(rdx, Address(rbx, rcx, Address::times_8, 3 * BytesPerInt));
{- -------------------------------------------
(1.1) コード生成: (JIT コンパイラ用のプロファイル情報の取得) (See: [here](no2935fdD.html) for details)
---------------------------------------- -}
__ profile_switch_case(rcx, rax, rbx);
{- -------------------------------------------
(1) コード生成:
「r13 の値を更新し (rdx に入っているジャンプ先のオフセット分を足す),
rbx に次のバイトコードのセットした後,
dispatch_only() が生成するコードで
次のバイトコードに対応するテンプレートへとジャンプする」
---------------------------------------- -}
// continue execution
__ bind(continue_execution);
__ bswapl(rdx);
__ movl2ptr(rdx, rdx);
__ load_unsigned_byte(rbx, Address(r13, rdx, Address::times_1));
__ addptr(r13, rdx);
__ dispatch_only(vtos);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.