Top


定義場所(file name)

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

説明(description)

// Load compiled (i2c) or interpreter entry when calling from interpreted and
// do the call. Centralized so that all interpreter calls will do the same actions.
// If jvmti single stepping is on for a thread we must not call compiled code.

名前(function name)

void InterpreterMacroAssembler::call_from_interpreter(Register target, Register scratch, Register Rret) {

本体部(body)

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      // Assume we want to go compiled if available

  {- -------------------------------------------
  (1) コード生成:
      「呼び出し対象の methodOop から, from_interpreted フィールドの値を取り出す
        (これが呼び出し対象のエントリポイント)」
      ---------------------------------------- -}

      ld_ptr(G5_method, in_bytes(methodOopDesc::from_interpreted_offset()), target);

  {- -------------------------------------------
  (1) コード生成: (ただし, JvmtiExport::can_post_interpreter_events() が false であれば
                 interp_only_mode のチェックは不要なので生成しない)

      「(JVMTI の状況によっては, 実行がインタープリタのみに制限されることがある. See: [here](no3059eFS.html) for details)

        カレントスレッドの interp_only_mode フィールドの値を確認する.
        もし true であれば, インタープリタ実行用のエントリポイントを使わないといけないため, 
        呼び出し対象の methodOop から interpreter_entry フィールドの値を取り出す
        (これがインタープリタ実行用のエントリポイント.
         JIT 対象になったとしてもこちらのエントリポイントは変更されない. See: ...#TODO)」
      ---------------------------------------- -}

      if (JvmtiExport::can_post_interpreter_events()) {
        // JVMTI events, such as single-stepping, are implemented partly by avoiding running
        // compiled code in threads for which the event is enabled.  Check here for
        // interp_only_mode if these events CAN be enabled.
        verify_thread();
        Label skip_compiled_code;

        const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
        ld(interp_only, scratch);
        tst(scratch);
        br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
        delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
        bind(skip_compiled_code);
      }

  {- -------------------------------------------
  (1) (i2c アダプターは methodOop が G5_method レジスタに入っていると想定している(正しい??), とのこと)
      ---------------------------------------- -}

      // the i2c_adapters need methodOop in G5_method (right? %%%)

  {- -------------------------------------------
  (1) (以下で実際に呼び出しを行う)
      ---------------------------------------- -}

      // do the call

  {- -------------------------------------------
  (1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
      コード生成: (デバッグ用の処理)
      ---------------------------------------- -}

    #ifdef ASSERT
      {
        Label ok;
        br_notnull(target, false, Assembler::pt, ok);
        delayed()->nop();
        stop("null entry point");
        bind(ok);
      }
    #endif // ASSERT

  {- -------------------------------------------
  (1) コード生成:
      「あらかじめ取得しておいた return entry のアドレス(Rret)を O7 にセット.
        (ただし, frame::pc_return_offset 分だけ調整は行う).」
      ---------------------------------------- -}

      // Adjust Rret first so Llast_SP can be same as Rret
      add(Rret, -frame::pc_return_offset, O7);

  {- -------------------------------------------
  (1) コード生成:
      「Gargs レジスタに最終引数のアドレスを設定」

       (呼び出される側がこの値が入っていることを想定しているため)
      ---------------------------------------- -}

      add(Lesp, BytesPerWord, Gargs); // setup parameter pointer

  {- -------------------------------------------
  (1) コード生成:
      「SP の値を Llast_SP レジスタに保存しつつ, 飛び先にジャンプ」
      ---------------------------------------- -}

      // Record SP so we can remove any stack space allocated by adapter transition
      jmp(target, 0);
      delayed()->mov(SP, Llast_SP);
    }

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