Top


定義場所(file name)

hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp

名前(function name)

void TemplateTable::tableswitch() {

本体部(body)

  {- -------------------------------------------
  (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.