hotspot/src/share/vm/prims/nativeLookup.cpp
address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
address entry;
{- -------------------------------------------
(1) 探索する関数名(以下の jni_name)を作成する.
(os::print_jni_name_prefix_on() や os::print_jni_name_suffix_on() の部分については,
引数に応じて付けるかどうかを決定)
---------------------------------------- -}
// Compute complete JNI name for style
stringStream st;
if (os_style) os::print_jni_name_prefix_on(&st, args_size);
st.print_raw(pure_name);
st.print_raw(long_name);
if (os_style) os::print_jni_name_suffix_on(&st, args_size);
char* jni_name = st.as_string();
{- -------------------------------------------
(1) もし, 対象のクラスがシステムクラスであれば,
まず lookup_special_native() で特別な(対応付けがハードコーディングされた)関数かどうかを調べ,
それで駄目なら os::dll_lookup() で調べる.
どちらかで探索対象の関数が見つかれば, ここでリターン.
(なお, in_base_library はデバッグ用)
---------------------------------------- -}
// If the loader is null we have a system class, so we attempt a lookup in
// the native Java library. This takes care of any bootstrapping problems.
// Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
// gets found the first time around - otherwise an infinite loop can occure. This is
// another VM/library dependency
Handle loader(THREAD,
instanceKlass::cast(method->method_holder())->class_loader());
if (loader.is_null()) {
entry = lookup_special_native(jni_name);
if (entry == NULL) {
entry = (address) os::dll_lookup(os::native_java_library(), jni_name);
}
if (entry != NULL) {
in_base_library = true;
return entry;
}
}
{- -------------------------------------------
(1) 次に, Java の ClassLoader オブジェクトの findNative() メソッドを呼び出して探索を行う.
---------------------------------------- -}
// Otherwise call static method findNative in ClassLoader
KlassHandle klass (THREAD, SystemDictionary::ClassLoader_klass());
Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);
JavaValue result(T_LONG);
JavaCalls::call_static(&result,
klass,
vmSymbols::findNative_name(),
vmSymbols::classloader_string_long_signature(),
// Arguments
loader,
name_arg,
CHECK_NULL);
entry = (address) (intptr_t) result.get_jlong();
{- -------------------------------------------
(1) もしまだ探索対象が見つかっていなければ,
JVMTI agent としてロードしたライブラリ内を os::dll_lookup() で探索する.
探索対象の関数が見つかれば, ここでリターン.
---------------------------------------- -}
if (entry == NULL) {
// findNative didn't find it, if there are any agent libraries look in them
AgentLibrary* agent;
for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
entry = (address) os::dll_lookup(agent->os_lib(), jni_name);
if (entry != NULL) {
return entry;
}
}
}
{- -------------------------------------------
(1) 以上の探索処理の結果をリターン.
---------------------------------------- -}
return entry;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.