// Revised lookup semantics introduced 1.3 (Kestral beta) void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { // Note: Arrays can have intermediate array supers. Use java_super to skip them. KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; if (PrintVtables && !klass()->oop_is_array()) { ResourceMark rm(THREAD); tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); } #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 if (Universe::is_bootstrapping()) { // just clear everything for (int i = 0; i < _length; i++) table()[i].clear(); return; } int super_vtable_len = initialize_from_super(super); if (klass()->oop_is_array()) { assert(super_vtable_len == _length, "arrays shouldn't introduce new methods"); } else { assert(_klass->oop_is_instance(), "must be instanceKlass"); 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++; } } // add miranda methods; it will also update the value of initialized fill_in_mirandas(initialized); // 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); } NOT_PRODUCT(verify(tty, true)); } }
inline instanceKlass* klassVtable::ik() const { Klass* k = _klass()->klass_part(); assert(k->oop_is_instance(), "not an instanceKlass"); return (instanceKlass*)k; }
// accessors vtableEntry* table() const { return (vtableEntry*)(address(_klass()) + _tableOffset); }