Top


定義場所(file name)

hotspot/src/share/vm/oops/methodOop.cpp

名前(function name)

void methodOopDesc::set_native_function(address function, bool post_event_flag) {

本体部(body)

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

      assert(function != NULL, "use clear_native_function to unregister natives");

  {- -------------------------------------------
  (1) もう既に誰かが同じアドレスへと登録を終えていたら, することはないので, ここでリターン.

      (これは, 複数のスレッドが同時に set_native_function() を呼ぶと起こりうる)
      ---------------------------------------- -}

      address* native_function = native_function_addr();

      // We can see racers trying to place the same native function into place. Once
      // is plenty.
      address current = *native_function;
      if (current == function) return;

  {- -------------------------------------------
  (1) (JVMTI のフック点)
      ---------------------------------------- -}

      if (post_event_flag && JvmtiExport::should_post_native_method_bind() &&
          function != NULL) {
        // native_method_throw_unsatisfied_link_error_entry() should only
        // be passed when post_event_flag is false.
        assert(function !=
          SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
          "post_event_flag mis-match");

        // post the bind event, and possible change the bind function
        JvmtiExport::post_native_method_bind(this, &function);
      }

  {- -------------------------------------------
  (1) methodOop の native_function_addr の位置に指定されたアドレスを書き込む.
      また, 古い内容に対して JIT compiled code が生成されていたら
      nmethod::make_not_entrant() で無効にしておく.
      ---------------------------------------- -}

      *native_function = function;
      // This function can be called more than once. We must make sure that we always
      // use the latest registered method -> check if a stub already has been generated.
      // If so, we have to make it not_entrant.
      nmethod* nm = code(); // Put it into local variable to guard against concurrent updates
      if (nm != NULL) {
        nm->make_not_entrant();
      }
    }

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