Top


定義場所(file name)

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

名前(function name)

void MacroAssembler::call_VM_base(
  Register        oop_result,
  Register        thread_cache,
  Register        last_java_sp,
  address         entry_point,
  int             number_of_arguments,
  bool            check_exceptions)
{

本体部(body)

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

      assert_not_delayed();

  {- -------------------------------------------
  (1) (引数で last_java_sp に使うレジスタが指定されていなければ, SP を使うこととする)

      (通常は SP でいいが, 既に save が実行されている場合などは FP を使う必要があるため, 
       このように指定できるようになっている.
       See: MacroAssembler::call_VM())
      ---------------------------------------- -}

      // determine last_java_sp register
      if (!last_java_sp->is_valid()) {
        last_java_sp = SP;
      }

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

      // debugging support
      assert(number_of_arguments >= 0   , "cannot have negative number of arguments");

  {- -------------------------------------------
  (1) コード生成:
      「call 命令で, 引数で指定されたエントリポイントを呼び出す.
        (第一引数として, カレントスレッドを表す JavaThread を渡す)」

      (なお, 呼び出しの前後で G2_thread の退避/復帰を行っている. 
       See: MacroAssembler::save_thread(), MacroAssembler::restore_thread())
      (なお, 呼び出しの前後で JavaFrameAnchor のセット/クリアも行っている. 
       See: MacroAssembler::set_last_Java_frame(), MacroAssembler::reset_last_Java_frame())

      (また, VerifyThread はデバッグ用のオプション. 
       指定されている場合には G2_thread を早めに O0 に移しておく必要がある)
      ---------------------------------------- -}

      // 64-bit last_java_sp is biased!
      set_last_Java_frame(last_java_sp, noreg);
      if (VerifyThread)  mov(G2_thread, O0); // about to be smashed; pass early
      save_thread(thread_cache);
      // do the call
      call(entry_point, relocInfo::runtime_call_type);
      if (!VerifyThread)
        delayed()->mov(G2_thread, O0);  // pass thread as first argument
      else
        delayed()->nop();             // (thread already passed)
      restore_thread(thread_cache);
      reset_last_Java_frame();

  {- -------------------------------------------
  (1) コード生成: (ただし, 引数で例外チェックコードを生成するように
                 指定されている場合(check_exeptions が true の場合)にのみ生成する)
      「MacroAssembler::check_and_forward_exception() が生成するコードで例外のチェックを行う.
        例外が発生していた場合には, ここで例外ハンドリング処理を呼び出す.」
      ---------------------------------------- -}

      // check for pending exceptions. use Gtemp as scratch register.
      if (check_exceptions) {
        check_and_forward_exception(Gtemp);
      }

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

    #ifdef ASSERT
      set(badHeapWordVal, G3);
      set(badHeapWordVal, G4);
      set(badHeapWordVal, G5);
    #endif

  {- -------------------------------------------
  (1) コード生成: (ただし, 引数で指定された oop_result が valid な場合にのみ生成する)
      「MacroAssembler::get_vm_result() が生成するコードにより
        呼び出し結果(返値)をカレントスレッドの JavaThread::vm_result フィールドから取り出し, 
        引数で指定された oop_result レジスタ内に格納する.
        (ついでに, 取り出した後で JavaThread::vm_result フィールドは 0 クリアしておく)」
      ---------------------------------------- -}

      // get oop result if there is one and reset the value in the thread
      if (oop_result->is_valid()) {
        get_vm_result(oop_result);
      }
    }

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