duke@435: /* xdono@631: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: duke@435: # include "incls/_precompiled.incl" duke@435: # include "incls/_klass.cpp.incl" duke@435: duke@435: duke@435: bool Klass::is_subclass_of(klassOop k) const { duke@435: // Run up the super chain and check duke@435: klassOop t = as_klassOop(); duke@435: duke@435: if (t == k) return true; duke@435: t = Klass::cast(t)->super(); duke@435: duke@435: while (t != NULL) { duke@435: if (t == k) return true; duke@435: t = Klass::cast(t)->super(); duke@435: } duke@435: return false; duke@435: } duke@435: duke@435: bool Klass::search_secondary_supers(klassOop k) const { duke@435: // Put some extra logic here out-of-line, before the search proper. duke@435: // This cuts down the size of the inline method. duke@435: duke@435: // This is necessary, since I am never in my own secondary_super list. duke@435: if (this->as_klassOop() == k) duke@435: return true; duke@435: // Scan the array-of-objects for a match duke@435: int cnt = secondary_supers()->length(); duke@435: for (int i = 0; i < cnt; i++) { duke@435: if (secondary_supers()->obj_at(i) == k) { duke@435: ((Klass*)this)->set_secondary_super_cache(k); duke@435: return true; duke@435: } duke@435: } duke@435: return false; duke@435: } duke@435: duke@435: // Return self, except for abstract classes with exactly 1 duke@435: // implementor. Then return the 1 concrete implementation. duke@435: Klass *Klass::up_cast_abstract() { duke@435: Klass *r = this; duke@435: while( r->is_abstract() ) { // Receiver is abstract? duke@435: Klass *s = r->subklass(); // Check for exactly 1 subklass duke@435: if( !s || s->next_sibling() ) // Oops; wrong count; give up duke@435: return this; // Return 'this' as a no-progress flag duke@435: r = s; // Loop till find concrete class duke@435: } duke@435: return r; // Return the 1 concrete class duke@435: } duke@435: twisti@1040: // Find LCA in class hierarchy duke@435: Klass *Klass::LCA( Klass *k2 ) { duke@435: Klass *k1 = this; duke@435: while( 1 ) { duke@435: if( k1->is_subtype_of(k2->as_klassOop()) ) return k2; duke@435: if( k2->is_subtype_of(k1->as_klassOop()) ) return k1; duke@435: k1 = k1->super()->klass_part(); duke@435: k2 = k2->super()->klass_part(); duke@435: } duke@435: } duke@435: duke@435: duke@435: void Klass::check_valid_for_instantiation(bool throwError, TRAPS) { duke@435: ResourceMark rm(THREAD); duke@435: THROW_MSG(throwError ? vmSymbols::java_lang_InstantiationError() duke@435: : vmSymbols::java_lang_InstantiationException(), external_name()); duke@435: } duke@435: duke@435: duke@435: void Klass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) { duke@435: THROW(vmSymbols::java_lang_ArrayStoreException()); duke@435: } duke@435: duke@435: duke@435: void Klass::initialize(TRAPS) { duke@435: ShouldNotReachHere(); duke@435: } duke@435: duke@435: bool Klass::compute_is_subtype_of(klassOop k) { duke@435: assert(k->is_klass(), "argument must be a class"); duke@435: return is_subclass_of(k); duke@435: } duke@435: duke@435: duke@435: methodOop Klass::uncached_lookup_method(symbolOop name, symbolOop signature) const { duke@435: #ifdef ASSERT duke@435: tty->print_cr("Error: uncached_lookup_method called on a klass oop." duke@435: " Likely error: reflection method does not correctly" duke@435: " wrap return value in a mirror object."); duke@435: #endif duke@435: ShouldNotReachHere(); duke@435: return NULL; duke@435: } duke@435: duke@435: klassOop Klass::base_create_klass_oop(KlassHandle& klass, int size, duke@435: const Klass_vtbl& vtbl, TRAPS) { duke@435: size = align_object_size(size); duke@435: // allocate and initialize vtable duke@435: Klass* kl = (Klass*) vtbl.allocate_permanent(klass, size, CHECK_NULL); duke@435: klassOop k = kl->as_klassOop(); duke@435: duke@435: { // Preinitialize supertype information. duke@435: // A later call to initialize_supers() may update these settings: duke@435: kl->set_super(NULL); duke@435: for (juint i = 0; i < Klass::primary_super_limit(); i++) { duke@435: kl->_primary_supers[i] = NULL; duke@435: } duke@435: kl->set_secondary_supers(NULL); duke@435: oop_store_without_check((oop*) &kl->_primary_supers[0], k); duke@435: kl->set_super_check_offset(primary_supers_offset_in_bytes() + sizeof(oopDesc)); duke@435: } duke@435: duke@435: kl->set_java_mirror(NULL); duke@435: kl->set_modifier_flags(0); duke@435: kl->set_layout_helper(Klass::_lh_neutral_value); duke@435: kl->set_name(NULL); duke@435: AccessFlags af; duke@435: af.set_flags(0); duke@435: kl->set_access_flags(af); duke@435: kl->set_subklass(NULL); duke@435: kl->set_next_sibling(NULL); duke@435: kl->set_alloc_count(0); duke@435: kl->set_alloc_size(0); duke@435: duke@435: kl->set_prototype_header(markOopDesc::prototype()); duke@435: kl->set_biased_lock_revocation_count(0); duke@435: kl->set_last_biased_lock_bulk_revocation_time(0); duke@435: duke@435: return k; duke@435: } duke@435: duke@435: KlassHandle Klass::base_create_klass(KlassHandle& klass, int size, duke@435: const Klass_vtbl& vtbl, TRAPS) { duke@435: klassOop ek = base_create_klass_oop(klass, size, vtbl, THREAD); duke@435: return KlassHandle(THREAD, ek); duke@435: } duke@435: duke@435: void Klass_vtbl::post_new_init_klass(KlassHandle& klass, duke@435: klassOop new_klass, duke@435: int size) const { duke@435: assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass"); duke@435: CollectedHeap::post_allocation_install_obj_klass(klass, new_klass, size); duke@435: } duke@435: duke@435: void* Klass_vtbl::operator new(size_t ignored, KlassHandle& klass, duke@435: int size, TRAPS) { duke@435: // The vtable pointer is installed during the execution of duke@435: // constructors in the call to permanent_obj_allocate(). Delay duke@435: // the installation of the klass pointer into the new klass "k" duke@435: // until after the vtable pointer has been installed (i.e., until duke@435: // after the return of permanent_obj_allocate(). duke@435: klassOop k = duke@435: (klassOop) CollectedHeap::permanent_obj_allocate_no_klass_install(klass, duke@435: size, CHECK_NULL); duke@435: return k->klass_part(); duke@435: } duke@435: duke@435: jint Klass::array_layout_helper(BasicType etype) { duke@435: assert(etype >= T_BOOLEAN && etype <= T_OBJECT, "valid etype"); duke@435: // Note that T_ARRAY is not allowed here. duke@435: int hsize = arrayOopDesc::base_offset_in_bytes(etype); kvn@464: int esize = type2aelembytes(etype); duke@435: bool isobj = (etype == T_OBJECT); duke@435: int tag = isobj ? _lh_array_tag_obj_value : _lh_array_tag_type_value; duke@435: int lh = array_layout_helper(tag, hsize, etype, exact_log2(esize)); duke@435: duke@435: assert(lh < (int)_lh_neutral_value, "must look like an array layout"); duke@435: assert(layout_helper_is_javaArray(lh), "correct kind"); duke@435: assert(layout_helper_is_objArray(lh) == isobj, "correct kind"); duke@435: assert(layout_helper_is_typeArray(lh) == !isobj, "correct kind"); duke@435: assert(layout_helper_header_size(lh) == hsize, "correct decode"); duke@435: assert(layout_helper_element_type(lh) == etype, "correct decode"); duke@435: assert(1 << layout_helper_log2_element_size(lh) == esize, "correct decode"); duke@435: duke@435: return lh; duke@435: } duke@435: duke@435: bool Klass::can_be_primary_super_slow() const { duke@435: if (super() == NULL) duke@435: return true; duke@435: else if (super()->klass_part()->super_depth() >= primary_super_limit()-1) duke@435: return false; duke@435: else duke@435: return true; duke@435: } duke@435: duke@435: void Klass::initialize_supers(klassOop k, TRAPS) { duke@435: if (FastSuperclassLimit == 0) { duke@435: // None of the other machinery matters. duke@435: set_super(k); duke@435: return; duke@435: } duke@435: if (k == NULL) { duke@435: set_super(NULL); duke@435: oop_store_without_check((oop*) &_primary_supers[0], (oop) this->as_klassOop()); duke@435: assert(super_depth() == 0, "Object must already be initialized properly"); never@1577: } else if (k != super() || k == SystemDictionary::Object_klass()) { never@1577: assert(super() == NULL || super() == SystemDictionary::Object_klass(), duke@435: "initialize this only once to a non-trivial value"); duke@435: set_super(k); duke@435: Klass* sup = k->klass_part(); duke@435: int sup_depth = sup->super_depth(); duke@435: juint my_depth = MIN2(sup_depth + 1, (int)primary_super_limit()); duke@435: if (!can_be_primary_super_slow()) duke@435: my_depth = primary_super_limit(); duke@435: for (juint i = 0; i < my_depth; i++) { duke@435: oop_store_without_check((oop*) &_primary_supers[i], (oop) sup->_primary_supers[i]); duke@435: } duke@435: klassOop *super_check_cell; duke@435: if (my_depth < primary_super_limit()) { duke@435: oop_store_without_check((oop*) &_primary_supers[my_depth], (oop) this->as_klassOop()); duke@435: super_check_cell = &_primary_supers[my_depth]; duke@435: } else { duke@435: // Overflow of the primary_supers array forces me to be secondary. duke@435: super_check_cell = &_secondary_super_cache; duke@435: } duke@435: set_super_check_offset((address)super_check_cell - (address) this->as_klassOop()); duke@435: duke@435: #ifdef ASSERT duke@435: { duke@435: juint j = super_depth(); duke@435: assert(j == my_depth, "computed accessor gets right answer"); duke@435: klassOop t = as_klassOop(); duke@435: while (!Klass::cast(t)->can_be_primary_super()) { duke@435: t = Klass::cast(t)->super(); duke@435: j = Klass::cast(t)->super_depth(); duke@435: } duke@435: for (juint j1 = j+1; j1 < primary_super_limit(); j1++) { duke@435: assert(primary_super_of_depth(j1) == NULL, "super list padding"); duke@435: } duke@435: while (t != NULL) { duke@435: assert(primary_super_of_depth(j) == t, "super list initialization"); duke@435: t = Klass::cast(t)->super(); duke@435: --j; duke@435: } duke@435: assert(j == (juint)-1, "correct depth count"); duke@435: } duke@435: #endif duke@435: } duke@435: duke@435: if (secondary_supers() == NULL) { duke@435: KlassHandle this_kh (THREAD, this); duke@435: duke@435: // Now compute the list of secondary supertypes. duke@435: // Secondaries can occasionally be on the super chain, duke@435: // if the inline "_primary_supers" array overflows. duke@435: int extras = 0; duke@435: klassOop p; duke@435: for (p = super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) { duke@435: ++extras; duke@435: } duke@435: duke@435: // Compute the "real" non-extra secondaries. duke@435: objArrayOop secondary_oops = compute_secondary_supers(extras, CHECK); duke@435: objArrayHandle secondaries (THREAD, secondary_oops); duke@435: duke@435: // Store the extra secondaries in the first array positions: duke@435: int fillp = extras; duke@435: for (p = this_kh->super(); !(p == NULL || p->klass_part()->can_be_primary_super()); p = p->klass_part()->super()) { duke@435: int i; // Scan for overflow primaries being duplicates of 2nd'arys duke@435: duke@435: // This happens frequently for very deeply nested arrays: the duke@435: // primary superclass chain overflows into the secondary. The duke@435: // secondary list contains the element_klass's secondaries with duke@435: // an extra array dimension added. If the element_klass's duke@435: // secondary list already contains some primary overflows, they duke@435: // (with the extra level of array-ness) will collide with the duke@435: // normal primary superclass overflows. duke@435: for( i = extras; i < secondaries->length(); i++ ) duke@435: if( secondaries->obj_at(i) == p ) duke@435: break; duke@435: if( i < secondaries->length() ) duke@435: continue; // It's a dup, don't put it in duke@435: secondaries->obj_at_put(--fillp, p); duke@435: } duke@435: // See if we had some dup's, so the array has holes in it. duke@435: if( fillp > 0 ) { duke@435: // Pack the array. Drop the old secondaries array on the floor duke@435: // and let GC reclaim it. duke@435: objArrayOop s2 = oopFactory::new_system_objArray(secondaries->length() - fillp, CHECK); duke@435: for( int i = 0; i < s2->length(); i++ ) duke@435: s2->obj_at_put( i, secondaries->obj_at(i+fillp) ); duke@435: secondaries = objArrayHandle(THREAD, s2); duke@435: } duke@435: duke@435: #ifdef ASSERT duke@435: if (secondaries() != Universe::the_array_interfaces_array()) { duke@435: // We must not copy any NULL placeholders left over from bootstrap. duke@435: for (int j = 0; j < secondaries->length(); j++) { duke@435: assert(secondaries->obj_at(j) != NULL, "correct bootstrapping order"); duke@435: } duke@435: } duke@435: #endif duke@435: duke@435: this_kh->set_secondary_supers(secondaries()); duke@435: } duke@435: } duke@435: duke@435: objArrayOop Klass::compute_secondary_supers(int num_extra_slots, TRAPS) { duke@435: assert(num_extra_slots == 0, "override for complex klasses"); duke@435: return Universe::the_empty_system_obj_array(); duke@435: } duke@435: duke@435: duke@435: Klass* Klass::subklass() const { duke@435: return _subklass == NULL ? NULL : Klass::cast(_subklass); duke@435: } duke@435: duke@435: instanceKlass* Klass::superklass() const { duke@435: assert(super() == NULL || super()->klass_part()->oop_is_instance(), "must be instance klass"); duke@435: return _super == NULL ? NULL : instanceKlass::cast(_super); duke@435: } duke@435: duke@435: Klass* Klass::next_sibling() const { duke@435: return _next_sibling == NULL ? NULL : Klass::cast(_next_sibling); duke@435: } duke@435: duke@435: void Klass::set_subklass(klassOop s) { duke@435: assert(s != as_klassOop(), "sanity check"); duke@435: oop_store_without_check((oop*)&_subklass, s); duke@435: } duke@435: duke@435: void Klass::set_next_sibling(klassOop s) { duke@435: assert(s != as_klassOop(), "sanity check"); duke@435: oop_store_without_check((oop*)&_next_sibling, s); duke@435: } duke@435: duke@435: void Klass::append_to_sibling_list() { duke@435: debug_only(if (!SharedSkipVerify) as_klassOop()->verify();) duke@435: // add ourselves to superklass' subklass list duke@435: instanceKlass* super = superklass(); duke@435: if (super == NULL) return; // special case: class Object duke@435: assert(SharedSkipVerify || duke@435: (!super->is_interface() // interfaces cannot be supers duke@435: && (super->superklass() == NULL || !is_interface())), duke@435: "an interface can only be a subklass of Object"); duke@435: klassOop prev_first_subklass = super->subklass_oop(); duke@435: if (prev_first_subklass != NULL) { duke@435: // set our sibling to be the superklass' previous first subklass duke@435: set_next_sibling(prev_first_subklass); duke@435: } duke@435: // make ourselves the superklass' first subklass duke@435: super->set_subklass(as_klassOop()); duke@435: debug_only(if (!SharedSkipVerify) as_klassOop()->verify();) duke@435: } duke@435: duke@435: void Klass::remove_from_sibling_list() { duke@435: // remove receiver from sibling list duke@435: instanceKlass* super = superklass(); never@1577: assert(super != NULL || as_klassOop() == SystemDictionary::Object_klass(), "should have super"); duke@435: if (super == NULL) return; // special case: class Object duke@435: if (super->subklass() == this) { duke@435: // first subklass duke@435: super->set_subklass(_next_sibling); duke@435: } else { duke@435: Klass* sib = super->subklass(); duke@435: while (sib->next_sibling() != this) { duke@435: sib = sib->next_sibling(); duke@435: }; duke@435: sib->set_next_sibling(_next_sibling); duke@435: } duke@435: } duke@435: duke@435: void Klass::follow_weak_klass_links( BoolObjectClosure* is_alive, OopClosure* keep_alive) { duke@435: // This klass is alive but the subklass and siblings are not followed/updated. duke@435: // We update the subklass link and the subklass' sibling links here. duke@435: // Our own sibling link will be updated by our superclass (which must be alive duke@435: // since we are). duke@435: assert(is_alive->do_object_b(as_klassOop()), "just checking, this should be live"); duke@435: if (ClassUnloading) { duke@435: klassOop sub = subklass_oop(); duke@435: if (sub != NULL && !is_alive->do_object_b(sub)) { duke@435: // first subklass not alive, find first one alive duke@435: do { duke@435: #ifndef PRODUCT duke@435: if (TraceClassUnloading && WizardMode) { duke@435: ResourceMark rm; duke@435: tty->print_cr("[Unlinking class (subclass) %s]", sub->klass_part()->external_name()); duke@435: } duke@435: #endif duke@435: sub = sub->klass_part()->next_sibling_oop(); duke@435: } while (sub != NULL && !is_alive->do_object_b(sub)); duke@435: set_subklass(sub); duke@435: } duke@435: // now update the subklass' sibling list duke@435: while (sub != NULL) { duke@435: klassOop next = sub->klass_part()->next_sibling_oop(); duke@435: if (next != NULL && !is_alive->do_object_b(next)) { duke@435: // first sibling not alive, find first one alive duke@435: do { duke@435: #ifndef PRODUCT duke@435: if (TraceClassUnloading && WizardMode) { duke@435: ResourceMark rm; duke@435: tty->print_cr("[Unlinking class (sibling) %s]", next->klass_part()->external_name()); duke@435: } duke@435: #endif duke@435: next = next->klass_part()->next_sibling_oop(); duke@435: } while (next != NULL && !is_alive->do_object_b(next)); duke@435: sub->klass_part()->set_next_sibling(next); duke@435: } duke@435: sub = next; duke@435: } duke@435: } else { duke@435: // Always follow subklass and sibling link. This will prevent any klasses from duke@435: // being unloaded (all classes are transitively linked from java.lang.Object). duke@435: keep_alive->do_oop(adr_subklass()); duke@435: keep_alive->do_oop(adr_next_sibling()); duke@435: } duke@435: } duke@435: duke@435: duke@435: void Klass::remove_unshareable_info() { duke@435: if (oop_is_instance()) { duke@435: instanceKlass* ik = (instanceKlass*)this; duke@435: if (ik->is_linked()) { duke@435: ik->unlink_class(); duke@435: } duke@435: } duke@435: set_subklass(NULL); duke@435: set_next_sibling(NULL); duke@435: } duke@435: duke@435: duke@435: klassOop Klass::array_klass_or_null(int rank) { duke@435: EXCEPTION_MARK; duke@435: // No exception can be thrown by array_klass_impl when called with or_null == true. duke@435: // (In anycase, the execption mark will fail if it do so) duke@435: return array_klass_impl(true, rank, THREAD); duke@435: } duke@435: duke@435: duke@435: klassOop Klass::array_klass_or_null() { duke@435: EXCEPTION_MARK; duke@435: // No exception can be thrown by array_klass_impl when called with or_null == true. duke@435: // (In anycase, the execption mark will fail if it do so) duke@435: return array_klass_impl(true, THREAD); duke@435: } duke@435: duke@435: duke@435: klassOop Klass::array_klass_impl(bool or_null, int rank, TRAPS) { duke@435: fatal("array_klass should be dispatched to instanceKlass, objArrayKlass or typeArrayKlass"); duke@435: return NULL; duke@435: } duke@435: duke@435: duke@435: klassOop Klass::array_klass_impl(bool or_null, TRAPS) { duke@435: fatal("array_klass should be dispatched to instanceKlass, objArrayKlass or typeArrayKlass"); duke@435: return NULL; duke@435: } duke@435: duke@435: duke@435: void Klass::with_array_klasses_do(void f(klassOop k)) { duke@435: f(as_klassOop()); duke@435: } duke@435: duke@435: duke@435: const char* Klass::external_name() const { jrose@866: if (oop_is_instance()) { jrose@866: instanceKlass* ik = (instanceKlass*) this; jrose@866: if (ik->is_anonymous()) { jrose@866: assert(AnonymousClasses, ""); jrose@866: intptr_t hash = ik->java_mirror()->identity_hash(); jrose@866: char hash_buf[40]; jrose@866: sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash); jrose@866: size_t hash_len = strlen(hash_buf); jrose@866: jrose@866: size_t result_len = name()->utf8_length(); jrose@866: char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); jrose@866: name()->as_klass_external_name(result, (int) result_len + 1); jrose@866: assert(strlen(result) == result_len, ""); jrose@866: strcpy(result + result_len, hash_buf); jrose@866: assert(strlen(result) == result_len + hash_len, ""); jrose@866: return result; jrose@866: } jrose@866: } jrose@1474: if (name() == NULL) return ""; duke@435: return name()->as_klass_external_name(); duke@435: } duke@435: duke@435: jrose@1474: const char* Klass::signature_name() const { jrose@1474: if (name() == NULL) return ""; duke@435: return name()->as_C_string(); duke@435: } duke@435: duke@435: // Unless overridden, modifier_flags is 0. duke@435: jint Klass::compute_modifier_flags(TRAPS) const { duke@435: return 0; duke@435: } duke@435: duke@435: int Klass::atomic_incr_biased_lock_revocation_count() { duke@435: return (int) Atomic::add(1, &_biased_lock_revocation_count); duke@435: } duke@435: duke@435: // Unless overridden, jvmti_class_status has no flags set. duke@435: jint Klass::jvmti_class_status() const { duke@435: return 0; duke@435: } duke@435: duke@435: #ifndef PRODUCT duke@435: duke@435: // Printing duke@435: duke@435: void Klass::oop_print_on(oop obj, outputStream* st) { duke@435: ResourceMark rm; duke@435: // print title duke@435: st->print_cr("%s ", internal_name()); duke@435: obj->print_address_on(st); duke@435: duke@435: if (WizardMode) { duke@435: // print header duke@435: obj->mark()->print_on(st); duke@435: } duke@435: duke@435: // print class duke@435: st->print(" - klass: "); duke@435: obj->klass()->print_value_on(st); duke@435: st->cr(); duke@435: } duke@435: jrose@1590: #endif //PRODUCT duke@435: duke@435: void Klass::oop_print_value_on(oop obj, outputStream* st) { duke@435: // print title duke@435: ResourceMark rm; // Cannot print in debug mode without this duke@435: st->print("%s", internal_name()); duke@435: obj->print_address_on(st); duke@435: } duke@435: duke@435: // Verification duke@435: duke@435: void Klass::oop_verify_on(oop obj, outputStream* st) { duke@435: guarantee(obj->is_oop(), "should be oop"); duke@435: guarantee(obj->klass()->is_perm(), "should be in permspace"); duke@435: guarantee(obj->klass()->is_klass(), "klass field is not a klass"); duke@435: } duke@435: duke@435: duke@435: void Klass::oop_verify_old_oop(oop obj, oop* p, bool allow_dirty) { duke@435: /* $$$ I think this functionality should be handled by verification of duke@435: RememberedSet::verify_old_oop(obj, p, allow_dirty, false); duke@435: the card table. */ duke@435: } coleenp@548: void Klass::oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty) { } duke@435: duke@435: #ifndef PRODUCT duke@435: duke@435: void Klass::verify_vtable_index(int i) { duke@435: assert(oop_is_instance() || oop_is_array(), "only instanceKlass and arrayKlass have vtables"); duke@435: if (oop_is_instance()) { duke@435: assert(i>=0 && i<((instanceKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); duke@435: } else { duke@435: assert(i>=0 && i<((arrayKlass*)this)->vtable_length()/vtableEntry::size(), "index out of bounds"); duke@435: } duke@435: } duke@435: duke@435: #endif