hotspot/src/share/vm/prims/jni.cpp
JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
const JNINativeMethod *methods,
jint nMethods))
{- -------------------------------------------
(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.