hotspot/src/share/vm/classfile/systemDictionary.cpp
コメントによると, この関数は SystemDictionary::resolve_from_stream() とよく似た関数だが, 補助的なデータ構造の更新を一切行わない点が違う.
// Note: this method is much like resolve_from_stream, but
// updates no supplemental data structures.
// TODO consolidate the two methods with a helper routine?
klassOop SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
KlassHandle host_klass,
GrowableArray<Handle>* cp_patches,
TRAPS) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
TempNewSymbol parsed_name = NULL;
{- -------------------------------------------
(1) ClassFileParser::parseClassFile() を呼んで, クラスファイルの内容をパースする.
---------------------------------------- -}
// Parse the stream. Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
// Further note: a placeholder will be added for this class when
// super classes are loaded (resolve_super_or_fail). We expect this
// to be called for all classes but java.lang.Object; and we preload
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
class_loader,
protection_domain,
host_klass,
cp_patches,
parsed_name,
true,
THREAD);
{- -------------------------------------------
(1) (この関数では SystemDictionary 等を変更しないので, ここで PlaceholderEntry は全部片付けてしまっていい)
対応する PlaceholderEntry を片付けて排他を解除し,
待っているスレッドを notify_all() で起床させておく.
(ただし, クラス名を見つける前にエラーになっていた場合 (parsed_name が NULL の場合) には,
片付ける必要はないので, この処理はパスして次に進む)
---------------------------------------- -}
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
// data structures).
// Parsed name could be null if we threw an error before we got far
// enough along to parse it -- in that case, there is nothing to clean up.
if (parsed_name != NULL) {
unsigned int p_hash = placeholders()->compute_hash(parsed_name,
class_loader);
int p_index = placeholders()->hash_to_index(p_hash);
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, parsed_name, class_loader, THREAD);
SystemDictionary_lock->notify_all();
}
}
{- -------------------------------------------
(1) パースが成功していた場合は, 以下のブロック内で初期化などを行う.
---------------------------------------- -}
if (host_klass.not_null() && k.not_null()) {
assert(EnableInvokeDynamic, "");
{- -------------------------------------------
(1.1) instanceKlass::set_host_klass() を呼んで, ...
---------------------------------------- -}
// If it's anonymous, initialize it now, since nobody else will.
k->set_host_klass(host_klass());
{- -------------------------------------------
(1.1) SystemDictionary::add_to_hierarchy() を呼んで ...(#TODO) する.
(なお, SystemDictionary への登録は行わない)
---------------------------------------- -}
{
MutexLocker mu_r(Compile_lock, THREAD);
// Add to class hierarchy, initialize vtables, and do possible
// deoptimizations.
add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
// But, do not add to system dictionary.
}
{- -------------------------------------------
(1.1) (デバッグ用の処理) (関連する develop オプションが指定されている場合にのみ実行) (See: EagerInitialization)
---------------------------------------- -}
k->eager_initialize(THREAD);
{- -------------------------------------------
(1.1) (JVMTI のフック点)
---------------------------------------- -}
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_load((JavaThread *) THREAD, k());
}
}
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return k();
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.