Top


定義場所(file name)

hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp

名前(function name)

void TemplateTable::tableswitch() {

本体部(body)

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      Label default_case, continue_execution;

  {- -------------------------------------------
  (1) (assert) (See: TemplateTable::transition())
      ---------------------------------------- -}

      transition(itos, vtos);

  {- -------------------------------------------
  (1) コード生成:
      「現在の r13 から 1byte 以上先で 4bytes-align なアドレス(= defaultbytes 情報の先頭)を算出し, 
       rbx レジスタにセットする」
       (1byte は, tableswitch 命令自体が 1byte(0xaa) 占めているため)
      ---------------------------------------- -}

      // align r13
      __ lea(rbx, at_bcp(BytesPerInt));
      __ andptr(rbx, -BytesPerInt);

  {- -------------------------------------------
  (1) コード生成:
      「命令中に埋まっている lowbytes 情報と highbytes 情報をロードし, 
       それぞれ rcx レジスタと rdx レジスタに入れておく.
       (なお, 埋まっている値はビッグエンディアンなのでバイトオーダーも変更している) 」
      ---------------------------------------- -}

      // load lo & hi
      __ movl(rcx, Address(rbx, BytesPerInt));
      __ movl(rdx, Address(rbx, 2 * BytesPerInt));
      __ bswapl(rcx);
      __ bswapl(rdx);

  {- -------------------------------------------
  (1) コード生成:
      「TOS(rax) に入っている index を, lowbytes 及び highbytes と比較する.
       もし index が範囲外であれば (JVM仕様に基づき) default_case ラベルに分岐」
      ---------------------------------------- -}

      // check against lo & hi
      __ cmpl(rax, rcx);
      __ jcc(Assembler::less, default_case);
      __ cmpl(rax, rdx);
      __ jcc(Assembler::greater, default_case);

  {- -------------------------------------------
  (1) コード生成:
      「index が示す位置に格納されているジャンプ先のオフセット値を rdx レジスタにロード」

       (なお, InterpreterMacroAssembler::profile_switch_case() が生成するコードで
       JIT コンパイラ用のプロファイル情報の取得も行っている. (See: [here](no2935fdD.html) for details))
      ---------------------------------------- -}

      // lookup dispatch offset
      __ subl(rax, rcx);
      __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * BytesPerInt));
      __ profile_switch_case(rax, rbx, rcx);

  {- -------------------------------------------
  (1) コード生成:
      「(ここが continue_execution ラベルの位置)」
      「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);

  {- -------------------------------------------
  (1) コード生成:
      「(ここが default_case ラベルの位置)」
      「defaultbytes の位置に格納されているジャンプ先のオフセット値を rdx レジスタにロードし, 
       continue_execution ラベルにジャンプ」

       (なお, InterpreterMacroAssembler::profile_switch_default() が生成するコードで
       JIT コンパイラ用のプロファイル情報の取得も行っている. (See: [here](no2935fdD.html) for details))
      ---------------------------------------- -}

      // handle default
      __ bind(default_case);
      __ profile_switch_default(rax);
      __ movl(rdx, Address(rbx, 0));
      __ jmp(continue_execution);
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.