hotspot/src/share/vm/oops/klassVtable.cpp
// Revised lookup semantics introduced 1.3 (Kestral beta)
void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// Note: Arrays can have intermediate array supers. Use java_super to skip them.
KlassHandle super (THREAD, klass()->java_super());
int nofNewEntries = 0;
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (PrintVtables && !klass()->oop_is_array()) {
ResourceMark rm(THREAD);
tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
}
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
oop* end_of_obj = (oop*)_klass() + _klass()->size();
oop* end_of_vtable = (oop*)&table()[_length];
assert(end_of_vtable <= end_of_obj, "vtable extends beyond end");
#endif
{- -------------------------------------------
(1) 起動中であれば (= Universe::is_bootstrapping() が true であれば),
単にクリアするだけにして, ここでリターン.
---------------------------------------- -}
if (Universe::is_bootstrapping()) {
// just clear everything
for (int i = 0; i < _length; i++) table()[i].clear();
return;
}
{- -------------------------------------------
(1) klassVtable::initialize_from_super() を呼んで,
スーパークラスの vtable の中身をコピーする.
---------------------------------------- -}
int super_vtable_len = initialize_from_super(super);
{- -------------------------------------------
(1) 配列クラスの場合は, (新しいメソッドが追加されることはないので) ここで終了
---------------------------------------- -}
if (klass()->oop_is_array()) {
assert(super_vtable_len == _length, "arrays shouldn't introduce new methods");
{- -------------------------------------------
(1) 配列クラスでない場合は, 以下のブロック内で
新しいエントリを vtable に追加する.
---------------------------------------- -}
} else {
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(_klass->oop_is_instance(), "must be instanceKlass");
{- -------------------------------------------
(1.1) 定義されているメソッドを辿り
それぞれについて klassVtable::update_inherited_vtable() を呼んで
vtable エントリに追加する必要があるかどうか調べる.
必要がある場合は, klassVtable::put_method_at() を呼んで vtable に追加する.
(新しい要素は, スーパークラスのメソッドをコピーした領域の後ろに順番に追加している)
---------------------------------------- -}
objArrayHandle methods(THREAD, ik()->methods());
int len = methods()->length();
int initialized = super_vtable_len;
// update_inherited_vtable can stop for gc - ensure using handles
for (int i = 0; i < len; i++) {
HandleMark hm(THREAD);
assert(methods()->obj_at(i)->is_method(), "must be a methodOop");
methodHandle mh(THREAD, (methodOop)methods()->obj_at(i));
bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK);
if (needs_new_entry) {
put_method_at(mh(), initialized);
mh()->set_vtable_index(initialized); // set primary vtable index
initialized++;
}
}
{- -------------------------------------------
(1.1)
---------------------------------------- -}
// add miranda methods; it will also update the value of initialized
fill_in_mirandas(initialized);
{- -------------------------------------------
(1.1) vtable に領域が残っている場合は, NULL を詰めておく
(コメントによると, vtable が埋まらないケースもある模様)
---------------------------------------- -}
// In class hierarchies where the accessibility is not increasing (i.e., going from private ->
// package_private -> publicprotected), the vtable might actually be smaller than our initial
// calculation.
assert(initialized <= _length, "vtable initialization failed");
for(;initialized < _length; initialized++) {
put_method_at(NULL, initialized);
}
{- -------------------------------------------
(1.1) (デバッグ用の処理) (NOT_PRODUCT 時にのみ実行)
---------------------------------------- -}
NOT_PRODUCT(verify(tty, true));
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.