Top


定義場所(file name)

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

名前(function name)

JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
                                    const JNINativeMethod *methods,
                                    jint nMethods))

本体部(body)

  {- -------------------------------------------
  (1) (デバッグ用の処理)
      (See: JNIWrapper)
      ---------------------------------------- -}

      JNIWrapper("RegisterNatives");

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

      DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);

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

      jint ret = 0;

  {- -------------------------------------------
  (1) (DTrace のフック点)(リターン用) (See: DT_RETURN_MARK)
      ---------------------------------------- -}

      DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);

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

      KlassHandle h_k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));

  {- -------------------------------------------
  (1) 引数で指定されたメソッド数(= 登録処理を行うメソッド数)の分だけ, 以下の処理をループ
      ---------------------------------------- -}

      for (int index = 0; index < nMethods; index++) {

    {- -------------------------------------------
  (1.1) まず, 指定されたメソッド名とシグネチャを元に, 対応するシンボルをシンボルテーブル内から探す.
        (引数でクラスオブジェクトも渡されているので (= クラスはロード済みなので), シンボルもインターンされているはず)
        もしシンボルが見つからなければ, NoSuchMethodError.
        ---------------------------------------- -}

        const char* meth_name = methods[index].name;
        const char* meth_sig = methods[index].signature;
        int meth_name_len = (int)strlen(meth_name);

        // The class should have been loaded (we have an instance of the class
        // passed in) so the method and signature should already be in the symbol
        // table.  If they're not there, the method doesn't exist.
        TempNewSymbol  name = SymbolTable::probe(meth_name, meth_name_len);
        TempNewSymbol  signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));

        if (name == NULL || signature == NULL) {
          ResourceMark rm;
          stringStream st;
          st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig);
          // Must return negative value on failure
          THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
        }

    {- -------------------------------------------
  (1.1) register_native() を呼び出して, 対応する methodOop 内に指定のアドレスをセットする
        ---------------------------------------- -}

        bool res = register_native(h_k, name, signature,
                                   (address) methods[index].fnPtr, THREAD);
        if (!res) {
          ret = -1;
          break;
        }
      }

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

      return ret;
    JNI_END

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