Top


定義場所(file name)

hotspot/src/share/vm/prims/jvmtiEnvBase.cpp

説明(description)

// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked

名前(function name)

jvmtiError
JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) {

本体部(body)

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

      JavaThread* current_thread = JavaThread::current();
      HandleMark   hm(current_thread);
      uint32_t debug_bits = 0;

  {- -------------------------------------------
  (1) JvmtiThreadState::state_for() を呼んで, 
      処理対象のスレッド(java_thread)に対応する JvmtiThreadState を取得する.
      (もし対象のスレッドが JvmtiThreadState を持っていなければ, この中で確保処理が行われる)

      (なお, スレッドが既に死んでいる場合(もしくは確保処理が失敗した場合)は, ここでリターン(JVMTI_ERROR_THREAD_NOT_ALIVE エラー))
      ---------------------------------------- -}

      // retrieve or create the state
      JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
      if (state == NULL) {
        return JVMTI_ERROR_THREAD_NOT_ALIVE;
      }

  {- -------------------------------------------
  (1) 対象のスレッドが suspend されているかどうかを確認する.
      suspended されてなければ, ここでリターン(JVMTI_ERROR_THREAD_NOT_SUSPENDED).
      (これは JVMTI 仕様で要求されている挙動)
      ---------------------------------------- -}

      // Check if java_thread is fully suspended
      if (!is_thread_fully_suspended(java_thread,
                                     true /* wait for suspend completion */,
                                     &debug_bits)) {
        return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
      }

  {- -------------------------------------------
  (1) もし対象のスレッドが既に ForceEarlyReturn*() をかけられた状態であれば, ここでリターン(JVMTI_ERROR_INTERNAL).
      ---------------------------------------- -}

      // Check to see if a ForceEarlyReturn was already in progress
      if (state->is_earlyret_pending()) {
        // Probably possible for JVMTI clients to trigger this, but the
        // JPDA backend shouldn't allow this to happen
        return JVMTI_ERROR_INTERNAL;
      }

  {- -------------------------------------------
  (1) もしスレッドが MONITOR_WAIT 状態であれば, ここでリターン(JVMTI_ERROR_OPAQUE_FRAME).

      (この処理については bug 4812902 を参照とのこと #TODO)
      ---------------------------------------- -}

      {
        // The same as for PopFrame. Workaround bug:
        //  4812902: popFrame hangs if the method is waiting at a synchronize
        // Catch this condition and return an error to avoid hanging.
        // Now JVMTI spec allows an implementation to bail out with an opaque
        // frame error.
        OSThread* osThread = java_thread->osthread();
        if (osThread->get_state() == MONITOR_WAIT) {
          return JVMTI_ERROR_OPAQUE_FRAME;
        }
      }

  {- -------------------------------------------
  (1) JvmtiEnvBase::check_top_frame() を呼び出し, 
      JVMTI 仕様上での様々な制限が満たされているかどうかチェックする .
      チェックで問題が見つかればここでリターン.

      (ついでに, もし先頭のフレームが compiled frame なら deopt も行う)
      ---------------------------------------- -}

      Handle ret_ob_h = Handle();
      jvmtiError err = check_top_frame(current_thread, java_thread, value, tos, &ret_ob_h);
      if (err != JVMTI_ERROR_NONE) {
        return err;
      }

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

      assert(tos != atos || value.l == NULL || ret_ob_h() != NULL,
             "return object oop must not be NULL if jobject is not NULL");

  {- -------------------------------------------
  (1) 以下のフィールドを変更し, ForceEarlyReturn*() の対象になっていることを 
      JvmtiThreadState オブジェクト内に記録しておく.

      (これらは強制復帰処理を開始させるためのフラグ.
       実際の強制復帰処理は, deopt 処理または call_VM_base() からのリターン処理時に行われる.)

      * JvmtiThreadState::_earlyret_state フィールド
      * JvmtiThreadState::_earlyret_oop フィールド
      * JvmtiThreadState::_earlyret_tos フィールド
      * JvmtiThreadState::_earlyret_value フィールド
      * JvmtiThreadState::_pending_step_for_earlyret フィールド
      ---------------------------------------- -}

      // Update the thread state to reflect that the top frame must be
      // forced to return.
      // The current frame will be returned later when the suspended
      // thread is resumed and right before returning from VM to Java.
      // (see call_VM_base() in assembler_<cpu>.cpp).

      state->set_earlyret_pending();
      state->set_earlyret_oop(ret_ob_h());
      state->set_earlyret_value(value, tos);

      // Set pending step flag for this early return.
      // It is cleared when next step event is posted.
      state->set_pending_step_for_earlyret();

  {- -------------------------------------------
  (1) リターン
      ---------------------------------------- -}

      return JVMTI_ERROR_NONE;
    } /* end force_early_return */

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