Top


定義場所(file name)

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

名前(function name)

void TemplateTable::resolve_cache_and_index(int byte_no,
                                            Register result,
                                            Register Rcache,
                                            Register index,
                                            size_t index_size) {

本体部(body)

  {- -------------------------------------------
  (1) (cpCacheOop のレイアウトに依存していることに注意!)
      ---------------------------------------- -}

      // Depends on cpCacheOop layout!

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

      Label resolved;

  {- -------------------------------------------
  (1) InterpreterMacroAssembler::get_cache_and_index_at_bcp() を呼んで, 以下のようなコードを生成.
      「現在箇所のバイトコード(bcp)に対応する CPCache エントリのアドレスを Rcache に取得.
      (ただし, まだ対応する CPCache エントリのアドレスを作っていなかった場合は, ...#TODO が取得される)」
      ---------------------------------------- -}

      __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);

  {- -------------------------------------------
  (1) 引数の byte_no に応じて以下の 2通りのコードを生成する.
      どちらの場合も, ...#TODO
      * f1_oop の場合: 
        「取得した CPCache エントリの f1 フィールドをロードし, NULL かどうかチェックする.
        NULL でなければ(= 既にそのエントリは作成済みであれば), resolved ラベルまでジャンプする.
        そうでなければ, このままフォールスルーして作成処理を行う.」
      * それ以外の場合 (f1_byte または f2_byte): 
        「取得した CPCache エントリの ...  かどうかチェックする. #TODO
        同じであれば(= 既にそのエントリは作成済みであれば), resolved ラベルまでジャンプする.
        そうでなければ, このままフォールスルーして作成処理を行う.」
      ---------------------------------------- -}

      if (byte_no == f1_oop) {
        // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
        // This kind of CP cache entry does not need to match the flags byte, because
        // there is a 1-1 relation between bytecode type and CP entry type.
        assert_different_registers(result, Rcache);
        __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
                  ConstantPoolCacheEntry::f1_offset(), result);
        __ tst(result);
        __ br(Assembler::notEqual, false, Assembler::pt, resolved);
        __ delayed()->set((int)bytecode(), O1);
      } else {
        assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
        assert(result == noreg, "");  //else change code for setting result
        const int shift_count = (1 + byte_no)*BitsPerByte;

        __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
                  ConstantPoolCacheEntry::indices_offset(), Lbyte_code);

        __ srl(  Lbyte_code, shift_count, Lbyte_code );
        __ and3( Lbyte_code,        0xFF, Lbyte_code );
        __ cmp(  Lbyte_code, (int)bytecode());
        __ br(   Assembler::equal, false, Assembler::pt, resolved);
        __ delayed()->set((int)bytecode(), O1);
      }

  {- -------------------------------------------
  (1) (変数宣言など)
      (entry は, まだ CPCache エントリが生成されてなかった場合に呼び出すべき関数 (CPCache エントリ生成用の関数).
       以下の通り, 現在箇所のバイトコードに応じて呼び出す関数は変わる.)
      ---------------------------------------- -}

      address entry;
      switch (bytecode()) {
        case Bytecodes::_getstatic      : // fall through
        case Bytecodes::_putstatic      : // fall through
        case Bytecodes::_getfield       : // fall through
        case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
        case Bytecodes::_invokevirtual  : // fall through
        case Bytecodes::_invokespecial  : // fall through
        case Bytecodes::_invokestatic   : // fall through
        case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
        case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
        case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
        case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
        default                         : ShouldNotReachHere();                                 break;
      }

  {- -------------------------------------------
  (1) コード生成:
      「CPCache エントリ生成用の関数(以下の entry)を呼び出す.
       その後, 改めて get_cache_and_index_at_bcp() が生成したコードを実行し, 
      現在箇所のバイトコード(bcp)に対応する CPCache エントリのアドレスを Rcache に取得する.」

      (もし...#TODO であれば, 以下のコードも生成しておく.
      「取得しなおした CPCache エントリの f1 フィールドを, result レジスタにロードする.」)
      ---------------------------------------- -}

      // first time invocation - must resolve first
      __ call_VM(noreg, entry, O1);
      // Update registers with resolved info
      __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
      if (result != noreg)
        __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
                  ConstantPoolCacheEntry::f1_offset(), result);

  {- -------------------------------------------
  (1) (ここが resolved ラベルの位置.
       CPCache エントリが既に生成されていた場合は, この地点まで飛んでくる)
      ---------------------------------------- -}

      __ bind(resolved);
    }

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