void klassKlass::oop_verify_on(oop obj, outputStream* st) { Klass::oop_verify_on(obj, st); guarantee(obj->is_perm(), "should be in permspace"); guarantee(obj->is_klass(), "should be klass"); Klass* k = Klass::cast(klassOop(obj)); if (k->super() != NULL) { guarantee(k->super()->is_perm(), "should be in permspace"); guarantee(k->super()->is_klass(), "should be klass"); } klassOop ko = k->secondary_super_cache(); if( ko != NULL ) { guarantee(ko->is_perm(), "should be in permspace"); guarantee(ko->is_klass(), "should be klass"); } for( uint i = 0; i < primary_super_limit(); i++ ) { oop ko = k->adr_primary_supers()[i]; // Cannot use normal accessor because it asserts if( ko != NULL ) { guarantee(ko->is_perm(), "should be in permspace"); guarantee(ko->is_klass(), "should be klass"); } } if (k->java_mirror() != NULL || (k->oop_is_instance() && instanceKlass::cast(klassOop(obj))->is_loaded())) { guarantee(k->java_mirror() != NULL, "should be allocated"); guarantee(k->java_mirror()->is_perm(), "should be in permspace"); guarantee(k->java_mirror()->is_instance(), "should be instance"); } if (k->name() != NULL) { guarantee(Universe::heap()->is_in_permanent(k->name()), "should be in permspace"); guarantee(k->name()->is_symbol(), "should be symbol"); } }
// Sets the do_print flag for every superclass and subclass of the specified class. void KlassHierarchy::set_do_print_for_class_hierarchy(KlassInfoEntry* cie, KlassInfoTable* cit, bool print_subclasses) { // Set do_print for all superclasses of this class. Klass* super = ((InstanceKlass*)cie->klass())->java_super(); while (super != NULL) { KlassInfoEntry* super_cie = cit->lookup(super); super_cie->set_do_print(true); super = super->super(); } // Set do_print for this class and all of its subclasses. Stack <KlassInfoEntry*, mtClass> class_stack; class_stack.push(cie); while (!class_stack.is_empty()) { KlassInfoEntry* curr_cie = class_stack.pop(); curr_cie->set_do_print(true); if (print_subclasses && curr_cie->subclasses() != NULL) { // Current class has subclasses, so push all of them onto the stack. for (int i = 0; i < curr_cie->subclasses()->length(); i++) { KlassInfoEntry* cie = curr_cie->subclasses()->at(i); class_stack.push(cie); } } } }
bool Klass::is_subclass_of(const Klass* k) const { // Run up the super chain and check if (this == k) return true; Klass* t = const_cast<Klass*>(this)->super(); while (t != NULL) { if (t == k) return true; t = t->super(); } return false; }
// ------------------------------------------------------------------ // ciFieldLayout::fill_in_instance_fields // // Set up the instance fields in this ciFieldLayout. void ciFieldLayout::fill_in_instance_fields(GrowableArray<BasicType>* fieldtypes, GrowableArray<int>* fieldoffsets, GrowableArray<int>* aflags, int& pos, klassOop current) { Klass* k = current->klass_part(); assert(k->oop_is_instance(), "must be instanceKlass"); instanceKlass* ik = (instanceKlass*)k; klassOop super = k->super(); if (super) { fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, super); } // Fill in this klass's instance fields. typeArrayOop field_list = ik->fields(); constantPoolOop cpool = ik->constants(); uint num_fields = field_list->length(); for (uint i = 0; i < num_fields; i += instanceKlass::next_offset) { AccessFlags flags; flags.set_flags(field_list->short_at(i + instanceKlass::access_flags_offset)); if (!flags.is_static()) { // This is an instance field. Add it to our list. int field_offset = ik->offset_from_fields( i ); // Add the type to our list. symbolOop type_sym = cpool->symbol_at(field_list->short_at(i+ instanceKlass::signature_index_offset)); BasicType field_type; field_type = type2field[FieldType::basic_type(type_sym)]; fieldtypes->at_put_grow(pos, field_type, T_VOID); aflags->at_put_grow(pos, flags.as_int(), 0); // The field offset we set here includes the header_size fieldoffsets->at_put_grow(pos, field_offset, 0); pos++; } } }
void KlassHierarchy::print_class(outputStream* st, KlassInfoEntry* cie, bool print_interfaces) { ResourceMark rm; InstanceKlass* klass = (InstanceKlass*)cie->klass(); int indent = 0; // Print indentation with proper indicators of superclass. Klass* super = klass->super(); while (super != NULL) { super = super->super(); indent++; } print_indent(st, indent); if (indent != 0) st->print("--"); // Print the class name, its unique ClassLoader identifer, and if it is an interface. print_classname(st, klass); if (klass->is_interface()) { st->print(" (intf)"); } st->print("\n"); // Print any interfaces the class has. if (print_interfaces) { Array<Klass*>* local_intfs = klass->local_interfaces(); Array<Klass*>* trans_intfs = klass->transitive_interfaces(); for (int i = 0; i < local_intfs->length(); i++) { print_interface(st, local_intfs->at(i), "declared", indent); } for (int i = 0; i < trans_intfs->length(); i++) { Klass* trans_interface = trans_intfs->at(i); // Only print transitive interfaces if they are not also declared. if (!local_intfs->contains(trans_interface)) { print_interface(st, trans_interface, "inherited", indent); } } } }
void Klass::initialize_supers(Klass* k, TRAPS) { if (FastSuperclassLimit == 0) { // None of the other machinery matters. set_super(k); return; } if (k == NULL) { set_super(NULL); _primary_supers[0] = this; assert(super_depth() == 0, "Object must already be initialized properly"); } else if (k != super() || k == SystemDictionary::Object_klass()) { assert(super() == NULL || super() == SystemDictionary::Object_klass(), "initialize this only once to a non-trivial value"); set_super(k); Klass* sup = k; int sup_depth = sup->super_depth(); juint my_depth = MIN2(sup_depth + 1, (int)primary_super_limit()); if (!can_be_primary_super_slow()) my_depth = primary_super_limit(); for (juint i = 0; i < my_depth; i++) { _primary_supers[i] = sup->_primary_supers[i]; } Klass* *super_check_cell; if (my_depth < primary_super_limit()) { _primary_supers[my_depth] = this; super_check_cell = &_primary_supers[my_depth]; } else { // Overflow of the primary_supers array forces me to be secondary. super_check_cell = &_secondary_super_cache; } set_super_check_offset((address)super_check_cell - (address) this); #ifdef ASSERT { juint j = super_depth(); assert(j == my_depth, "computed accessor gets right answer"); Klass* t = this; while (!t->can_be_primary_super()) { t = t->super(); j = t->super_depth(); } for (juint j1 = j+1; j1 < primary_super_limit(); j1++) { assert(primary_super_of_depth(j1) == NULL, "super list padding"); } while (t != NULL) { assert(primary_super_of_depth(j) == t, "super list initialization"); t = t->super(); --j; } assert(j == (juint)-1, "correct depth count"); } #endif } if (secondary_supers() == NULL) { KlassHandle this_kh (THREAD, this); // Now compute the list of secondary supertypes. // Secondaries can occasionally be on the super chain, // if the inline "_primary_supers" array overflows. int extras = 0; Klass* p; for (p = super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) { ++extras; } ResourceMark rm(THREAD); // need to reclaim GrowableArrays allocated below // Compute the "real" non-extra secondaries. GrowableArray<Klass*>* secondaries = compute_secondary_supers(extras); if (secondaries == NULL) { // secondary_supers set by compute_secondary_supers return; } GrowableArray<Klass*>* primaries = new GrowableArray<Klass*>(extras); for (p = this_kh->super(); !(p == NULL || p->can_be_primary_super()); p = p->super()) { int i; // Scan for overflow primaries being duplicates of 2nd'arys // This happens frequently for very deeply nested arrays: the // primary superclass chain overflows into the secondary. The // secondary list contains the element_klass's secondaries with // an extra array dimension added. If the element_klass's // secondary list already contains some primary overflows, they // (with the extra level of array-ness) will collide with the // normal primary superclass overflows. for( i = 0; i < secondaries->length(); i++ ) { if( secondaries->at(i) == p ) break; } if( i < secondaries->length() ) continue; // It's a dup, don't put it in primaries->push(p); } // Combine the two arrays into a metadata object to pack the array. // The primaries are added in the reverse order, then the secondaries. int new_length = primaries->length() + secondaries->length(); Array<Klass*>* s2 = MetadataFactory::new_array<Klass*>( class_loader_data(), new_length, CHECK); int fill_p = primaries->length(); for (int j = 0; j < fill_p; j++) { s2->at_put(j, primaries->pop()); // add primaries in reverse order. } for( int j = 0; j < secondaries->length(); j++ ) { s2->at_put(j+fill_p, secondaries->at(j)); // add secondaries on the end. } #ifdef ASSERT // We must not copy any NULL placeholders left over from bootstrap. for (int j = 0; j < s2->length(); j++) { assert(s2->at(j) != NULL, "correct bootstrapping order"); } #endif this_kh->set_secondary_supers(s2); } }
void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) { klassKlass::oop_verify_on(obj, st); if (!obj->partially_loaded()) { Thread *thread = Thread::current(); instanceKlass* ik = instanceKlass::cast(klassOop(obj)); // Avoid redundant verifies if (ik->_verify_count == Universe::verify_count()) return; ik->_verify_count = Universe::verify_count(); // Verify that klass is present in SystemDictionary if (ik->is_loaded()) { symbolHandle h_name (thread, ik->name()); Handle h_loader (thread, ik->class_loader()); SystemDictionary::verify_obj_klass_present(obj, h_name, h_loader); } // Verify static fields VerifyFieldClosure blk; ik->iterate_static_fields(&blk); // Verify vtables if (ik->is_linked()) { ResourceMark rm(thread); // $$$ This used to be done only for m/s collections. Doing it // always seemed a valid generalization. (DLD -- 6/00) ik->vtable()->verify(st); } // Verify oop map cache if (ik->oop_map_cache() != NULL) { ik->oop_map_cache()->verify(); } // Verify first subklass if (ik->subklass_oop() != NULL) { guarantee(ik->subklass_oop()->is_perm(), "should be in permspace"); guarantee(ik->subklass_oop()->is_klass(), "should be klass"); } // Verify siblings klassOop super = ik->super(); Klass* sib = ik->next_sibling(); int sib_count = 0; while (sib != NULL) { if (sib == ik) { fatal1("subclass cycle of length %d", sib_count); } if (sib_count >= 100000) { fatal1("suspiciously long subclass list %d", sib_count); } guarantee(sib->as_klassOop()->is_klass(), "should be klass"); guarantee(sib->as_klassOop()->is_perm(), "should be in permspace"); guarantee(sib->super() == super, "siblings should have same superklass"); sib = sib->next_sibling(); } // Verify implementor field if (ik->implementor() != NULL) { guarantee(ik->is_interface(), "only interfaces should have implementor set"); guarantee(ik->nof_implementors() == 1, "should only have one implementor"); klassOop im = ik->implementor(); guarantee(im->is_perm(), "should be in permspace"); guarantee(im->is_klass(), "should be klass"); guarantee(!Klass::cast(klassOop(im))->is_interface(), "implementors cannot be interfaces"); } // Verify local interfaces objArrayOop local_interfaces = ik->local_interfaces(); guarantee(local_interfaces->is_perm(), "should be in permspace"); guarantee(local_interfaces->is_objArray(), "should be obj array"); int j; for (j = 0; j < local_interfaces->length(); j++) { oop e = local_interfaces->obj_at(j); guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid local interface"); } // Verify transitive interfaces objArrayOop transitive_interfaces = ik->transitive_interfaces(); guarantee(transitive_interfaces->is_perm(), "should be in permspace"); guarantee(transitive_interfaces->is_objArray(), "should be obj array"); for (j = 0; j < transitive_interfaces->length(); j++) { oop e = transitive_interfaces->obj_at(j); guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid transitive interface"); } // Verify methods objArrayOop methods = ik->methods(); guarantee(methods->is_perm(), "should be in permspace"); guarantee(methods->is_objArray(), "should be obj array"); for (j = 0; j < methods->length(); j++) { guarantee(methods->obj_at(j)->is_method(), "non-method in methods array"); } for (j = 0; j < methods->length() - 1; j++) { methodOop m1 = methodOop(methods->obj_at(j)); methodOop m2 = methodOop(methods->obj_at(j + 1)); guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly"); } // Verify method ordering typeArrayOop method_ordering = ik->method_ordering(); guarantee(method_ordering->is_perm(), "should be in permspace"); guarantee(method_ordering->is_typeArray(), "should be type array"); int length = method_ordering->length(); if (jvmdi::enabled()) { guarantee(length == methods->length(), "invalid method ordering length"); jlong sum = 0; for (j = 0; j < length; j++) { int original_index = method_ordering->int_at(j); guarantee(original_index >= 0 && original_index < length, "invalid method ordering index"); sum += original_index; } // Verify sum of indices 0,1,...,length-1 guarantee(sum == ((jlong)length*(length-1))/2, "invalid method ordering sum"); } else { guarantee(length == 0, "invalid method ordering length"); } // Verify JNI static field/method identifiers if (ik->jni_ids() != NULL) { ik->jni_ids()->verify(ik->as_klassOop()); } // Verify other fields if (ik->array_klasses() != NULL) { guarantee(ik->array_klasses()->is_perm(), "should be in permspace"); guarantee(ik->array_klasses()->is_klass(), "should be klass"); } guarantee(ik->fields()->is_perm(), "should be in permspace"); guarantee(ik->fields()->is_typeArray(), "should be type array"); guarantee(ik->constants()->is_perm(), "should be in permspace"); guarantee(ik->constants()->is_constantPool(), "should be constant pool"); guarantee(ik->inner_classes()->is_perm(), "should be in permspace"); guarantee(ik->inner_classes()->is_typeArray(), "should be type array"); if (ik->source_file_name() != NULL) { guarantee(ik->source_file_name()->is_perm(), "should be in permspace"); guarantee(ik->source_file_name()->is_symbol(), "should be symbol"); } if (ik->source_debug_extension() != NULL) { guarantee(ik->source_debug_extension()->is_perm(), "should be in permspace"); guarantee(ik->source_debug_extension()->is_symbol(), "should be symbol"); } if (ik->protection_domain() != NULL) { guarantee(ik->protection_domain()->is_oop(), "should be oop"); } if (ik->signers() != NULL) { guarantee(ik->signers()->is_objArray(), "should be obj array"); } } }