hotspot/src/share/vm/prims/jni.cpp
JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
{- -------------------------------------------
(1) (デバッグ用の処理)
(See: JNIWrapper)
---------------------------------------- -}
JNIWrapper("FindClass");
{- -------------------------------------------
(1) (DTrace のフック点)
---------------------------------------- -}
DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
jclass result = NULL;
{- -------------------------------------------
(1) (DTrace のフック点)(リターン用) (See: DT_RETURN_MARK)
---------------------------------------- -}
DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
{- -------------------------------------------
(1) (first_time_FindClass は, 初期値が true の static 変数.
ここで false にしてしまうため, jni_FindClass が最初に呼ばれた時のみ true になっている.
この値は後で使用する.)
---------------------------------------- -}
// Remember if we are the first invocation of jni_FindClass
bool first_time = first_time_FindClass;
first_time_FindClass = false;
{- -------------------------------------------
(1) クラス名が NULL だったり, あるいは
クラス名が長すぎる場合(Symbol::max_length() を超えている場合)は, NoClassDefFoundError.
---------------------------------------- -}
// Sanity check the name: it cannot be null or larger than the maximum size
// name we can fit in the constant pool.
if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
}
{- -------------------------------------------
(1) (変数宣言など)
(loader は, クラスの探索時に使用するクラスローダ.
protection_domain は, クラスの探索時に使用する protection domain)
---------------------------------------- -}
//%note jni_3
Handle loader;
Handle protection_domain;
{- -------------------------------------------
(1) クラスの探索時に使用するクラスローダ(loader)と protection_domain を適切に設定しておく.
#TODO
---------------------------------------- -}
// Find calling class
instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
if (k.not_null()) {
loader = Handle(THREAD, k->class_loader());
// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
// in the correct class context.
if (loader.is_null() &&
k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result, k,
vmSymbols::getFromClass_name(),
vmSymbols::void_class_signature(),
thread);
if (HAS_PENDING_EXCEPTION) {
Handle ex(thread, thread->pending_exception());
CLEAR_PENDING_EXCEPTION;
THROW_HANDLE_0(ex);
}
oop mirror = (oop) result.get_jobject();
loader = Handle(THREAD,
instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->class_loader());
protection_domain = Handle(THREAD,
instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->protection_domain());
}
} else {
// We call ClassLoader.getSystemClassLoader to obtain the system class loader.
loader = Handle(THREAD, SystemDictionary::java_system_loader());
}
{- -------------------------------------------
(1) find_class_from_class_loader() を呼んで, 指定されたクラスを探し出す.
---------------------------------------- -}
TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
result = find_class_from_class_loader(env, sym, true, loader,
protection_domain, true, thread);
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (TraceClassResolution && result != NULL) {
trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
}
{- -------------------------------------------
(1) もし今回が jni_FindClass の初回の呼び出しであれば,
CompilationPolicy::completed_vm_startup() を呼び出して JIT コンパイルが有効な状態にしておく.
---------------------------------------- -}
// If we were the first invocation of jni_FindClass, we enable compilation again
// rather than just allowing invocation counter to overflow and decay.
// Controlled by flag DelayCompilationDuringStartup.
if (first_time && !CompileTheWorld)
CompilationPolicy::completed_vm_startup();
{- -------------------------------------------
(1) 結果をリターン.
---------------------------------------- -}
return result;
JNI_END
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.