hotspot/src/share/vm/oops/instanceKlass.cpp
bool instanceKlass::link_class_impl(
instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
{- -------------------------------------------
(1) 初期化しようとしてエラーが起こった状態であれば, NoClassDefFoundError
---------------------------------------- -}
// check for error state
if (this_oop->is_in_error_state()) {
ResourceMark rm(THREAD);
THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
this_oop->external_name(), false);
}
{- -------------------------------------------
(1) 既にリンク済みであれば, (することがないので) ここでリターン.
---------------------------------------- -}
// return if already verified
if (this_oop->is_linked()) {
return true;
}
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// Timing
// timer handles recursion
assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
JavaThread* jt = (JavaThread*)THREAD;
{- -------------------------------------------
(1) まずスーパークラスに対して instanceKlass::link_class_impl() を呼び出し,
リンク処理を行っておく.
---------------------------------------- -}
// link super class before linking this class
instanceKlassHandle super(THREAD, this_oop->super());
if (super.not_null()) {
if (super->is_interface()) { // check if super class is an interface
ResourceMark rm(THREAD);
Exceptions::fthrow(
THREAD_AND_LOCATION,
vmSymbols::java_lang_IncompatibleClassChangeError(),
"class %s has interface %s as super class",
this_oop->external_name(),
super->external_name()
);
return false;
}
link_class_impl(super, throw_verifyerror, CHECK_false);
}
{- -------------------------------------------
(1) 次に, 実装しているインターフェース全てに対して
instanceKlass::link_class_impl() を呼び出し,
リンク処理を行っておく.
---------------------------------------- -}
// link all interfaces implemented by this class before linking this class
objArrayHandle interfaces (THREAD, this_oop->local_interfaces());
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
HandleMark hm(THREAD);
instanceKlassHandle ih(THREAD, klassOop(interfaces->obj_at(index)));
link_class_impl(ih, throw_verifyerror, CHECK_false);
}
{- -------------------------------------------
(1) 既にリンク済みであれば, (することがないので) ここでリターン.
(コメントによると, これはスーパークラスのリンク中に
このクラスまでリンクされたケース)
---------------------------------------- -}
// in case the class is linked in the process of linking its superclasses
if (this_oop->is_linked()) {
return true;
}
{- -------------------------------------------
(1) (プロファイル情報の記録) ("sun.cls.classLinkedTime", "sun.cls.classLinkedTime.self", "sun.cls.linkedClasses")
(See: PerfClassTraceTime, ClassLoader::perf_class_link_time(), ClassLoader::perf_class_link_selftime(), ClassLoader::perf_classes_linked())
---------------------------------------- -}
// trace only the link time for this klass that includes
// the verification time
PerfClassTraceTime vmtimer(ClassLoader::perf_class_link_time(),
ClassLoader::perf_class_link_selftime(),
ClassLoader::perf_classes_linked(),
jt->get_thread_stat()->perf_recursion_counts_addr(),
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LINK);
{- -------------------------------------------
(1) 以下のブロック内で, 対象クラスのリンク処理を行う.
---------------------------------------- -}
// verification & rewriting
{
{- -------------------------------------------
(1.1) (以下の処理は ... で排他した状態で行う)
---------------------------------------- -}
ObjectLocker ol(this_oop, THREAD);
{- -------------------------------------------
(1.1) 既にリンク済みであれば, (することがないので) 以下のブロックはスキップする
(というか残りの処理はリターンするだけ)
---------------------------------------- -}
// rewritten will have been set if loader constraint error found
// on an earlier link attempt
// don't verify or rewrite if already rewritten
if (!this_oop->is_linked()) {
{- -------------------------------------------
(1.1) まだ rewrite 処理が行われてなければ,
以下の if ブロック内で verification 処理と rewrite 処理を行う.
---------------------------------------- -}
if (!this_oop->is_rewritten()) {
{
{- -------------------------------------------
(1.1.1) (プロファイル情報の記録) ("sun.cls.classLinkedTime", "sun.cls.classLinkedTime.self", "sun.cls.linkedClasses")
(See: PerfClassTraceTime, ClassLoader::perf_class_verify_time(), ClassLoader::perf_class_verify_selftime(), ClassLoader::perf_classes_verified())
---------------------------------------- -}
// Timer includes any side effects of class verification (resolution,
// etc), but not recursive entry into verify_code().
PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
ClassLoader::perf_class_verify_selftime(),
ClassLoader::perf_classes_verified(),
jt->get_thread_stat()->perf_recursion_counts_addr(),
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_VERIFY);
{- -------------------------------------------
(1.1.1) instanceKlass::verify_code() を呼んで, バイトコードの verification を行う.
(もし verification が失敗すれば, ここでリターン)
---------------------------------------- -}
bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
if (!verify_ok) {
return false;
}
}
{- -------------------------------------------
(1.1.1) 既にリンク済みであれば, (することがないので) ここでリターン.
(コメントによると, これは verification 処理中に
このクラスがリンクされたケース.
変なクラスローダーを作ればあり得なくはない模様)
---------------------------------------- -}
// Just in case a side-effect of verify linked this class already
// (which can sometimes happen since the verifier loads classes
// using custom class loaders, which are free to initialize things)
if (this_oop->is_linked()) {
return true;
}
{- -------------------------------------------
(1.1.1) instanceKlass::rewrite_class() を呼んで, バイトコードの rewrite を行う.
---------------------------------------- -}
// also sets rewritten
this_oop->rewrite_class(CHECK_false);
}
{- -------------------------------------------
(1.1) instanceKlass::relocate_and_link_methods() を呼んで,
バイトコード中の再配置(?)を行う.
---------------------------------------- -}
// relocate jsrs and link methods after they are all rewritten
this_oop->relocate_and_link_methods(CHECK_false);
{- -------------------------------------------
(1.1) klassVtable::initialize_vtable() 及び klassVtable::initialize_itable() を呼んで,
vtable と itable を生成する.
---------------------------------------- -}
// Initialize the vtable and interface table after
// methods have been rewritten since rewrite may
// fabricate new methodOops.
// also does loader constraint checking
if (!this_oop()->is_shared()) {
ResourceMark rm(THREAD);
this_oop->vtable()->initialize_vtable(true, CHECK_false);
this_oop->itable()->initialize_itable(true, CHECK_false);
}
{- -------------------------------------------
(1.1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
else {
ResourceMark rm(THREAD);
this_oop->vtable()->verify(tty, true);
// In case itable verification is ever added.
// this_oop->itable()->verify(tty, true);
}
#endif
{- -------------------------------------------
(1.1)
---------------------------------------- -}
this_oop->set_init_state(linked);
{- -------------------------------------------
(1.1) (JVMTI のフック点)
---------------------------------------- -}
if (JvmtiExport::should_post_class_prepare()) {
Thread *thread = THREAD;
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop());
}
}
}
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return true;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.