hotspot/src/share/vm/classfile/javaClasses.cpp
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(k->java_mirror() == NULL, "should only assign mirror once");
{- -------------------------------------------
(1)
---------------------------------------- -}
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
// the cached flags after the class file is parsed, but before the
// class is put into the system dictionary.
int computed_modifiers = k->compute_modifier_flags(CHECK_0);
k->set_modifier_flags(computed_modifiers);
{- -------------------------------------------
(1) (以下の処理は, 次の条件の両方が成り立つかどうかで分岐.
* java.lang.Class オブジェクトがロード済み (= SystemDictionary::Class_klass_loaded() が true)
* 処理対象(k)は, インスタンスクラスまたは配列クラス
成り立つ場合は, 新しい mirror オブジェクトを生成し初期化した後, その mirror オブジェクトをリターンする.
成り立たない場合は, 何もせずに NULL をリターンするだけ.)
---------------------------------------- -}
if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) {
{- -------------------------------------------
(1.1) (以下は条件が成り立つ場合のパス)
---------------------------------------- -}
{- -------------------------------------------
(1.1) 新しい mirror オブジェクトを確保する
---------------------------------------- -}
// Allocate mirror (java.lang.Class instance)
Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
{- -------------------------------------------
(1.1) mirror オブジェクトと処理対象の Klass の間に相互参照を張る.
---------------------------------------- -}
// Setup indirections
mirror->obj_field_put(klass_offset, k());
k->set_java_mirror(mirror());
{- -------------------------------------------
(1.1) mirror オブジェクトの初期化を行う
---------------------------------------- -}
instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
java_lang_Class::set_oop_size(mirror(), mk->instance_size(k));
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
{- -------------------------------------------
(1.1)
---------------------------------------- -}
// It might also have a component mirror. This mirror must already exist.
if (k->oop_is_javaArray()) {
Handle comp_mirror;
if (k->oop_is_typeArray()) {
BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type();
comp_mirror = Universe::java_mirror(type);
assert(comp_mirror.not_null(), "must have primitive mirror");
} else if (k->oop_is_objArray()) {
klassOop element_klass = objArrayKlass::cast(k->as_klassOop())->element_klass();
if (element_klass != NULL
&& (Klass::cast(element_klass)->oop_is_instance() ||
Klass::cast(element_klass)->oop_is_javaArray())) {
comp_mirror = Klass::cast(element_klass)->java_mirror();
assert(comp_mirror.not_null(), "must have element mirror");
}
// else some object array internal to the VM, like systemObjArrayKlassObj
}
if (comp_mirror.not_null()) {
// Two-way link between the array klass and its component mirror:
arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
set_array_klass(comp_mirror(), k->as_klassOop());
}
} else if (k->oop_is_instance()) {
// Initialize static fields
instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
}
{- -------------------------------------------
(1.1) 生成した mirror オブジェクトをリターン
---------------------------------------- -}
return mirror();
{- -------------------------------------------
(1.1) (以下は条件が成り立たない場合のパス)
NULL をリターンするだけ
---------------------------------------- -}
} else {
return NULL;
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.