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/_instanceKlassKlass.cpp.incl" duke@435: duke@435: klassOop instanceKlassKlass::create_klass(TRAPS) { duke@435: instanceKlassKlass o; duke@435: KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); duke@435: KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); duke@435: // Make sure size calculation is right duke@435: assert(k()->size() == align_object_size(header_size()), "wrong size for object"); duke@435: java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror duke@435: return k(); duke@435: } duke@435: duke@435: int instanceKlassKlass::oop_size(oop obj) const { duke@435: assert(obj->is_klass(), "must be klass"); duke@435: return instanceKlass::cast(klassOop(obj))->object_size(); duke@435: } duke@435: duke@435: bool instanceKlassKlass::oop_is_parsable(oop obj) const { duke@435: assert(obj->is_klass(), "must be klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: return (!ik->null_vtbl()) && ik->object_is_parsable(); duke@435: } duke@435: duke@435: void instanceKlassKlass::iterate_c_heap_oops(instanceKlass* ik, duke@435: OopClosure* closure) { duke@435: if (ik->oop_map_cache() != NULL) { duke@435: ik->oop_map_cache()->oop_iterate(closure); duke@435: } duke@435: duke@435: if (ik->jni_ids() != NULL) { duke@435: ik->jni_ids()->oops_do(closure); duke@435: } duke@435: } duke@435: duke@435: void instanceKlassKlass::oop_follow_contents(oop obj) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); duke@435: duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->follow_static_fields(); duke@435: { duke@435: HandleMark hm; duke@435: ik->vtable()->oop_follow_contents(); duke@435: ik->itable()->oop_follow_contents(); duke@435: } duke@435: duke@435: MarkSweep::mark_and_push(ik->adr_array_klasses()); duke@435: MarkSweep::mark_and_push(ik->adr_methods()); duke@435: MarkSweep::mark_and_push(ik->adr_method_ordering()); duke@435: MarkSweep::mark_and_push(ik->adr_local_interfaces()); duke@435: MarkSweep::mark_and_push(ik->adr_transitive_interfaces()); duke@435: MarkSweep::mark_and_push(ik->adr_fields()); duke@435: MarkSweep::mark_and_push(ik->adr_constants()); duke@435: MarkSweep::mark_and_push(ik->adr_class_loader()); duke@435: MarkSweep::mark_and_push(ik->adr_source_file_name()); duke@435: MarkSweep::mark_and_push(ik->adr_source_debug_extension()); duke@435: MarkSweep::mark_and_push(ik->adr_inner_classes()); duke@435: MarkSweep::mark_and_push(ik->adr_protection_domain()); duke@435: MarkSweep::mark_and_push(ik->adr_signers()); duke@435: MarkSweep::mark_and_push(ik->adr_generic_signature()); duke@435: MarkSweep::mark_and_push(ik->adr_class_annotations()); duke@435: MarkSweep::mark_and_push(ik->adr_fields_annotations()); duke@435: MarkSweep::mark_and_push(ik->adr_methods_annotations()); duke@435: MarkSweep::mark_and_push(ik->adr_methods_parameter_annotations()); duke@435: MarkSweep::mark_and_push(ik->adr_methods_default_annotations()); duke@435: duke@435: // We do not follow adr_implementors() here. It is followed later duke@435: // in instanceKlass::follow_weak_klass_links() duke@435: duke@435: klassKlass::oop_follow_contents(obj); duke@435: duke@435: iterate_c_heap_oops(ik, &MarkSweep::mark_and_push_closure); duke@435: } duke@435: duke@435: #ifndef SERIALGC duke@435: void instanceKlassKlass::oop_follow_contents(ParCompactionManager* cm, duke@435: oop obj) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); duke@435: duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->follow_static_fields(cm); duke@435: ik->vtable()->oop_follow_contents(cm); duke@435: ik->itable()->oop_follow_contents(cm); duke@435: duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_array_klasses()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_methods()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_method_ordering()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_local_interfaces()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_transitive_interfaces()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_fields()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_constants()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_class_loader()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_source_file_name()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_signers()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_methods_annotations()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_methods_parameter_annotations()); duke@435: PSParallelCompact::mark_and_push(cm, ik->adr_methods_default_annotations()); duke@435: duke@435: // We do not follow adr_implementor() here. It is followed later duke@435: // in instanceKlass::follow_weak_klass_links() duke@435: duke@435: klassKlass::oop_follow_contents(cm, obj); duke@435: duke@435: PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); duke@435: iterate_c_heap_oops(ik, &mark_and_push_closure); duke@435: } duke@435: #endif // SERIALGC duke@435: duke@435: int instanceKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: // Get size before changing pointers. duke@435: // Don't call size() or oop_size() since that is a virtual call. duke@435: int size = ik->object_size(); duke@435: duke@435: ik->iterate_static_fields(blk); duke@435: ik->vtable()->oop_oop_iterate(blk); duke@435: ik->itable()->oop_oop_iterate(blk); duke@435: duke@435: blk->do_oop(ik->adr_array_klasses()); duke@435: blk->do_oop(ik->adr_methods()); duke@435: blk->do_oop(ik->adr_method_ordering()); duke@435: blk->do_oop(ik->adr_local_interfaces()); duke@435: blk->do_oop(ik->adr_transitive_interfaces()); duke@435: blk->do_oop(ik->adr_fields()); duke@435: blk->do_oop(ik->adr_constants()); duke@435: blk->do_oop(ik->adr_class_loader()); duke@435: blk->do_oop(ik->adr_protection_domain()); duke@435: blk->do_oop(ik->adr_signers()); duke@435: blk->do_oop(ik->adr_source_file_name()); duke@435: blk->do_oop(ik->adr_source_debug_extension()); duke@435: blk->do_oop(ik->adr_inner_classes()); duke@435: for (int i = 0; i < instanceKlass::implementors_limit; i++) { duke@435: blk->do_oop(&ik->adr_implementors()[i]); duke@435: } duke@435: blk->do_oop(ik->adr_generic_signature()); duke@435: blk->do_oop(ik->adr_class_annotations()); duke@435: blk->do_oop(ik->adr_fields_annotations()); duke@435: blk->do_oop(ik->adr_methods_annotations()); duke@435: blk->do_oop(ik->adr_methods_parameter_annotations()); duke@435: blk->do_oop(ik->adr_methods_default_annotations()); duke@435: duke@435: klassKlass::oop_oop_iterate(obj, blk); duke@435: duke@435: if(ik->oop_map_cache() != NULL) ik->oop_map_cache()->oop_iterate(blk); duke@435: return size; duke@435: } duke@435: duke@435: int instanceKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, duke@435: MemRegion mr) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: // Get size before changing pointers. duke@435: // Don't call size() or oop_size() since that is a virtual call. duke@435: int size = ik->object_size(); duke@435: duke@435: ik->iterate_static_fields(blk, mr); duke@435: ik->vtable()->oop_oop_iterate_m(blk, mr); duke@435: ik->itable()->oop_oop_iterate_m(blk, mr); duke@435: duke@435: oop* adr; duke@435: adr = ik->adr_array_klasses(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_methods(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_method_ordering(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_local_interfaces(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_transitive_interfaces(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_fields(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_constants(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_class_loader(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_protection_domain(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_signers(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_source_file_name(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_source_debug_extension(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_inner_classes(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_implementors(); duke@435: for (int i = 0; i < instanceKlass::implementors_limit; i++) { duke@435: if (mr.contains(&adr[i])) blk->do_oop(&adr[i]); duke@435: } duke@435: adr = ik->adr_generic_signature(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_class_annotations(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_fields_annotations(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_methods_annotations(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_methods_parameter_annotations(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: adr = ik->adr_methods_default_annotations(); duke@435: if (mr.contains(adr)) blk->do_oop(adr); duke@435: duke@435: klassKlass::oop_oop_iterate_m(obj, blk, mr); duke@435: duke@435: if(ik->oop_map_cache() != NULL) ik->oop_map_cache()->oop_iterate(blk, mr); duke@435: return size; duke@435: } duke@435: duke@435: int instanceKlassKlass::oop_adjust_pointers(oop obj) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass"); duke@435: duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->adjust_static_fields(); duke@435: ik->vtable()->oop_adjust_pointers(); duke@435: ik->itable()->oop_adjust_pointers(); duke@435: duke@435: MarkSweep::adjust_pointer(ik->adr_array_klasses()); duke@435: MarkSweep::adjust_pointer(ik->adr_methods()); duke@435: MarkSweep::adjust_pointer(ik->adr_method_ordering()); duke@435: MarkSweep::adjust_pointer(ik->adr_local_interfaces()); duke@435: MarkSweep::adjust_pointer(ik->adr_transitive_interfaces()); duke@435: MarkSweep::adjust_pointer(ik->adr_fields()); duke@435: MarkSweep::adjust_pointer(ik->adr_constants()); duke@435: MarkSweep::adjust_pointer(ik->adr_class_loader()); duke@435: MarkSweep::adjust_pointer(ik->adr_protection_domain()); duke@435: MarkSweep::adjust_pointer(ik->adr_signers()); duke@435: MarkSweep::adjust_pointer(ik->adr_source_file_name()); duke@435: MarkSweep::adjust_pointer(ik->adr_source_debug_extension()); duke@435: MarkSweep::adjust_pointer(ik->adr_inner_classes()); duke@435: for (int i = 0; i < instanceKlass::implementors_limit; i++) { duke@435: MarkSweep::adjust_pointer(&ik->adr_implementors()[i]); duke@435: } duke@435: MarkSweep::adjust_pointer(ik->adr_generic_signature()); duke@435: MarkSweep::adjust_pointer(ik->adr_class_annotations()); duke@435: MarkSweep::adjust_pointer(ik->adr_fields_annotations()); duke@435: MarkSweep::adjust_pointer(ik->adr_methods_annotations()); duke@435: MarkSweep::adjust_pointer(ik->adr_methods_parameter_annotations()); duke@435: MarkSweep::adjust_pointer(ik->adr_methods_default_annotations()); duke@435: duke@435: iterate_c_heap_oops(ik, &MarkSweep::adjust_root_pointer_closure); duke@435: duke@435: return klassKlass::oop_adjust_pointers(obj); duke@435: } duke@435: duke@435: #ifndef SERIALGC duke@435: void instanceKlassKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { duke@435: assert(!pm->depth_first(), "invariant"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->copy_static_fields(pm); duke@435: duke@435: oop* loader_addr = ik->adr_class_loader(); coleenp@548: if (PSScavenge::should_scavenge(loader_addr)) { duke@435: pm->claim_or_forward_breadth(loader_addr); duke@435: } duke@435: duke@435: oop* pd_addr = ik->adr_protection_domain(); coleenp@548: if (PSScavenge::should_scavenge(pd_addr)) { duke@435: pm->claim_or_forward_breadth(pd_addr); duke@435: } duke@435: duke@435: oop* sg_addr = ik->adr_signers(); coleenp@548: if (PSScavenge::should_scavenge(sg_addr)) { duke@435: pm->claim_or_forward_breadth(sg_addr); duke@435: } duke@435: duke@435: klassKlass::oop_copy_contents(pm, obj); duke@435: } duke@435: duke@435: void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { duke@435: assert(pm->depth_first(), "invariant"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->push_static_fields(pm); duke@435: duke@435: oop* loader_addr = ik->adr_class_loader(); coleenp@548: if (PSScavenge::should_scavenge(loader_addr)) { duke@435: pm->claim_or_forward_depth(loader_addr); duke@435: } duke@435: duke@435: oop* pd_addr = ik->adr_protection_domain(); coleenp@548: if (PSScavenge::should_scavenge(pd_addr)) { duke@435: pm->claim_or_forward_depth(pd_addr); duke@435: } duke@435: duke@435: oop* sg_addr = ik->adr_signers(); coleenp@548: if (PSScavenge::should_scavenge(sg_addr)) { duke@435: pm->claim_or_forward_depth(sg_addr); duke@435: } duke@435: duke@435: klassKlass::oop_copy_contents(pm, obj); duke@435: } duke@435: duke@435: int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), duke@435: "must be instance klass"); duke@435: duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->update_static_fields(); duke@435: ik->vtable()->oop_update_pointers(cm); duke@435: ik->itable()->oop_update_pointers(cm); duke@435: duke@435: oop* const beg_oop = ik->oop_block_beg(); duke@435: oop* const end_oop = ik->oop_block_end(); duke@435: for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { duke@435: PSParallelCompact::adjust_pointer(cur_oop); duke@435: } duke@435: duke@435: OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); duke@435: iterate_c_heap_oops(ik, closure); duke@435: duke@435: klassKlass::oop_update_pointers(cm, obj); duke@435: return ik->object_size(); duke@435: } duke@435: duke@435: int instanceKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, duke@435: HeapWord* beg_addr, duke@435: HeapWord* end_addr) { duke@435: assert(obj->is_klass(),"must be a klass"); duke@435: assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), duke@435: "must be instance klass"); duke@435: duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->update_static_fields(beg_addr, end_addr); duke@435: ik->vtable()->oop_update_pointers(cm, beg_addr, end_addr); duke@435: ik->itable()->oop_update_pointers(cm, beg_addr, end_addr); duke@435: duke@435: oop* const beg_oop = MAX2((oop*)beg_addr, ik->oop_block_beg()); duke@435: oop* const end_oop = MIN2((oop*)end_addr, ik->oop_block_end()); duke@435: for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) { duke@435: PSParallelCompact::adjust_pointer(cur_oop); duke@435: } duke@435: duke@435: // The oop_map_cache, jni_ids and jni_id_map are allocated from the C heap, duke@435: // and so don't lie within any 'Chunk' boundaries. Update them when the duke@435: // lowest addressed oop in the instanceKlass 'oop_block' is updated. duke@435: if (beg_oop == ik->oop_block_beg()) { duke@435: OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure(); duke@435: iterate_c_heap_oops(ik, closure); duke@435: } duke@435: duke@435: klassKlass::oop_update_pointers(cm, obj, beg_addr, end_addr); duke@435: return ik->object_size(); duke@435: } duke@435: #endif // SERIALGC duke@435: duke@435: klassOop instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len, int static_field_size, duke@435: int nonstatic_oop_map_size, ReferenceType rt, TRAPS) { duke@435: duke@435: int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + static_field_size + nonstatic_oop_map_size); duke@435: duke@435: // Allocation duke@435: KlassHandle h_this_klass(THREAD, as_klassOop()); duke@435: KlassHandle k; duke@435: if (rt == REF_NONE) { duke@435: // regular klass duke@435: instanceKlass o; duke@435: k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); duke@435: } else { duke@435: // reference klass duke@435: instanceRefKlass o; duke@435: k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL); duke@435: } duke@435: { duke@435: No_Safepoint_Verifier no_safepoint; // until k becomes parsable duke@435: instanceKlass* ik = (instanceKlass*) k()->klass_part(); duke@435: assert(!k()->is_parsable(), "not expecting parsability yet."); duke@435: duke@435: // The sizes of these these three variables are used for determining the duke@435: // size of the instanceKlassOop. It is critical that these are set to the right duke@435: // sizes before the first GC, i.e., when we allocate the mirror. duke@435: ik->set_vtable_length(vtable_len); duke@435: ik->set_itable_length(itable_len); duke@435: ik->set_static_field_size(static_field_size); duke@435: ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size); duke@435: assert(k()->size() == size, "wrong size for object"); duke@435: duke@435: ik->set_array_klasses(NULL); duke@435: ik->set_methods(NULL); duke@435: ik->set_method_ordering(NULL); duke@435: ik->set_local_interfaces(NULL); duke@435: ik->set_transitive_interfaces(NULL); duke@435: ik->init_implementor(); duke@435: ik->set_fields(NULL); duke@435: ik->set_constants(NULL); duke@435: ik->set_class_loader(NULL); duke@435: ik->set_protection_domain(NULL); duke@435: ik->set_signers(NULL); duke@435: ik->set_source_file_name(NULL); duke@435: ik->set_source_debug_extension(NULL); duke@435: ik->set_inner_classes(NULL); duke@435: ik->set_static_oop_field_size(0); duke@435: ik->set_nonstatic_field_size(0); duke@435: ik->set_is_marked_dependent(false); duke@435: ik->set_init_state(instanceKlass::allocated); duke@435: ik->set_init_thread(NULL); duke@435: ik->set_reference_type(rt); duke@435: ik->set_oop_map_cache(NULL); duke@435: ik->set_jni_ids(NULL); duke@435: ik->set_osr_nmethods_head(NULL); duke@435: ik->set_breakpoints(NULL); duke@435: ik->init_previous_versions(); duke@435: ik->set_generic_signature(NULL); duke@435: ik->release_set_methods_jmethod_ids(NULL); duke@435: ik->release_set_methods_cached_itable_indices(NULL); duke@435: ik->set_class_annotations(NULL); duke@435: ik->set_fields_annotations(NULL); duke@435: ik->set_methods_annotations(NULL); duke@435: ik->set_methods_parameter_annotations(NULL); duke@435: ik->set_methods_default_annotations(NULL); duke@435: ik->set_enclosing_method_indices(0, 0); duke@435: ik->set_jvmti_cached_class_field_map(NULL); duke@435: ik->set_initial_method_idnum(0); duke@435: assert(k()->is_parsable(), "should be parsable here."); duke@435: duke@435: // initialize the non-header words to zero duke@435: intptr_t* p = (intptr_t*)k(); duke@435: for (int index = instanceKlass::header_size(); index < size; index++) { duke@435: p[index] = NULL_WORD; duke@435: } duke@435: duke@435: // To get verify to work - must be set to partial loaded before first GC point. duke@435: k()->set_partially_loaded(); duke@435: } duke@435: duke@435: // GC can happen here duke@435: java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror duke@435: return k(); duke@435: } duke@435: duke@435: duke@435: duke@435: #ifndef PRODUCT duke@435: duke@435: // Printing duke@435: duke@435: static const char* state_names[] = { duke@435: "unparseable_by_gc", "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" duke@435: }; duke@435: duke@435: duke@435: void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) { duke@435: assert(obj->is_klass(), "must be klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: klassKlass::oop_print_on(obj, st); duke@435: duke@435: st->print(" - instance size: %d", ik->size_helper()); st->cr(); duke@435: st->print(" - klass size: %d", ik->object_size()); st->cr(); duke@435: st->print(" - access: "); ik->access_flags().print_on(st); st->cr(); duke@435: st->print(" - state: "); st->print_cr(state_names[ik->_init_state]); duke@435: st->print(" - name: "); ik->name()->print_value_on(st); st->cr(); duke@435: st->print(" - super: "); ik->super()->print_value_on(st); st->cr(); duke@435: st->print(" - sub: "); duke@435: Klass* sub = ik->subklass(); duke@435: int n; duke@435: for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) { duke@435: if (n < MaxSubklassPrintSize) { duke@435: sub->as_klassOop()->print_value_on(st); duke@435: st->print(" "); duke@435: } duke@435: } duke@435: if (n >= MaxSubklassPrintSize) st->print("(%d more klasses...)", n - MaxSubklassPrintSize); duke@435: st->cr(); duke@435: duke@435: if (ik->is_interface()) { duke@435: st->print_cr(" - nof implementors: %d", ik->nof_implementors()); duke@435: int print_impl = 0; duke@435: for (int i = 0; i < instanceKlass::implementors_limit; i++) { duke@435: if (ik->implementor(i) != NULL) { duke@435: if (++print_impl == 1) duke@435: st->print_cr(" - implementor: "); duke@435: st->print(" "); duke@435: ik->implementor(i)->print_value_on(st); duke@435: } duke@435: } duke@435: if (print_impl > 0) st->cr(); duke@435: } duke@435: duke@435: st->print(" - arrays: "); ik->array_klasses()->print_value_on(st); st->cr(); duke@435: st->print(" - methods: "); ik->methods()->print_value_on(st); st->cr(); duke@435: if (Verbose) { duke@435: objArrayOop methods = ik->methods(); duke@435: for(int i = 0; i < methods->length(); i++) { duke@435: tty->print("%d : ", i); methods->obj_at(i)->print_value(); tty->cr(); duke@435: } duke@435: } duke@435: st->print(" - method ordering: "); ik->method_ordering()->print_value_on(st); st->cr(); duke@435: st->print(" - local interfaces: "); ik->local_interfaces()->print_value_on(st); st->cr(); duke@435: st->print(" - trans. interfaces: "); ik->transitive_interfaces()->print_value_on(st); st->cr(); duke@435: st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr(); duke@435: st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr(); duke@435: st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr(); duke@435: st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr(); duke@435: if (ik->source_file_name() != NULL) { duke@435: st->print(" - source file: "); duke@435: ik->source_file_name()->print_value_on(st); duke@435: st->cr(); duke@435: } duke@435: if (ik->source_debug_extension() != NULL) { duke@435: st->print(" - source debug extension: "); duke@435: ik->source_debug_extension()->print_value_on(st); duke@435: st->cr(); duke@435: } duke@435: duke@435: st->print_cr(" - previous version: "); duke@435: { duke@435: ResourceMark rm; duke@435: // PreviousVersionInfo objects returned via PreviousVersionWalker duke@435: // contain a GrowableArray of handles. We have to clean up the duke@435: // GrowableArray _after_ the PreviousVersionWalker destructor duke@435: // has destroyed the handles. duke@435: { duke@435: PreviousVersionWalker pvw(ik); duke@435: for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); duke@435: pv_info != NULL; pv_info = pvw.next_previous_version()) { duke@435: pv_info->prev_constant_pool_handle()()->print_value_on(st); duke@435: } duke@435: st->cr(); duke@435: } // pvw is cleaned up duke@435: } // rm is cleaned up duke@435: duke@435: if (ik->generic_signature() != NULL) { duke@435: st->print(" - generic signature: "); duke@435: ik->generic_signature()->print_value_on(st); duke@435: } duke@435: st->print(" - inner classes: "); ik->inner_classes()->print_value_on(st); st->cr(); duke@435: st->print(" - java mirror: "); ik->java_mirror()->print_value_on(st); st->cr(); duke@435: st->print(" - vtable length %d (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable()); st->cr(); duke@435: st->print(" - itable length %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr(); duke@435: st->print_cr(" - static fields:"); duke@435: FieldPrinter print_static_field(st); duke@435: ik->do_local_static_fields(&print_static_field); duke@435: st->print_cr(" - non-static fields:"); duke@435: FieldPrinter print_nonstatic_field(st, obj); duke@435: ik->do_nonstatic_fields(&print_nonstatic_field); duke@435: duke@435: st->print(" - static oop maps: "); duke@435: if (ik->static_oop_field_size() > 0) { duke@435: int first_offset = ik->offset_of_static_fields(); duke@435: st->print("%d-%d", first_offset, first_offset + ik->static_oop_field_size() - 1); duke@435: } duke@435: st->cr(); duke@435: duke@435: st->print(" - non-static oop maps: "); duke@435: OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); duke@435: OopMapBlock* end_map = map + ik->nonstatic_oop_map_size(); duke@435: while (map < end_map) { kvn@600: st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->length() - 1)); duke@435: map++; duke@435: } duke@435: st->cr(); duke@435: } duke@435: duke@435: duke@435: void instanceKlassKlass::oop_print_value_on(oop obj, outputStream* st) { duke@435: assert(obj->is_klass(), "must be klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: ik->name()->print_value_on(st); duke@435: } duke@435: duke@435: #endif // PRODUCT duke@435: duke@435: const char* instanceKlassKlass::internal_name() const { duke@435: return "{instance class}"; duke@435: } duke@435: duke@435: // Verification duke@435: duke@435: class VerifyFieldClosure: public OopClosure { coleenp@548: protected: coleenp@548: template void do_oop_work(T* p) { coleenp@548: guarantee(Universe::heap()->is_in(p), "should be in heap"); coleenp@548: oop obj = oopDesc::load_decode_heap_oop(p); coleenp@548: guarantee(obj->is_oop_or_null(), "should be in heap"); coleenp@548: } duke@435: public: coleenp@548: virtual void do_oop(oop* p) { VerifyFieldClosure::do_oop_work(p); } coleenp@548: virtual void do_oop(narrowOop* p) { VerifyFieldClosure::do_oop_work(p); } duke@435: }; duke@435: duke@435: void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) { duke@435: klassKlass::oop_verify_on(obj, st); duke@435: if (!obj->partially_loaded()) { duke@435: Thread *thread = Thread::current(); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: duke@435: #ifndef PRODUCT duke@435: // Avoid redundant verifies duke@435: if (ik->_verify_count == Universe::verify_count()) return; duke@435: ik->_verify_count = Universe::verify_count(); duke@435: #endif duke@435: // Verify that klass is present in SystemDictionary duke@435: if (ik->is_loaded()) { duke@435: symbolHandle h_name (thread, ik->name()); duke@435: Handle h_loader (thread, ik->class_loader()); duke@435: Handle h_obj(thread, obj); duke@435: SystemDictionary::verify_obj_klass_present(h_obj, h_name, h_loader); duke@435: } duke@435: duke@435: // Verify static fields duke@435: VerifyFieldClosure blk; duke@435: ik->iterate_static_fields(&blk); duke@435: duke@435: // Verify vtables duke@435: if (ik->is_linked()) { duke@435: ResourceMark rm(thread); duke@435: // $$$ This used to be done only for m/s collections. Doing it duke@435: // always seemed a valid generalization. (DLD -- 6/00) duke@435: ik->vtable()->verify(st); duke@435: } duke@435: duke@435: // Verify oop map cache duke@435: if (ik->oop_map_cache() != NULL) { duke@435: ik->oop_map_cache()->verify(); duke@435: } duke@435: duke@435: // Verify first subklass duke@435: if (ik->subklass_oop() != NULL) { duke@435: guarantee(ik->subklass_oop()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->subklass_oop()->is_klass(), "should be klass"); duke@435: } duke@435: duke@435: // Verify siblings duke@435: klassOop super = ik->super(); duke@435: Klass* sib = ik->next_sibling(); duke@435: int sib_count = 0; duke@435: while (sib != NULL) { duke@435: if (sib == ik) { duke@435: fatal1("subclass cycle of length %d", sib_count); duke@435: } duke@435: if (sib_count >= 100000) { duke@435: fatal1("suspiciously long subclass list %d", sib_count); duke@435: } duke@435: guarantee(sib->as_klassOop()->is_klass(), "should be klass"); duke@435: guarantee(sib->as_klassOop()->is_perm(), "should be in permspace"); duke@435: guarantee(sib->super() == super, "siblings should have same superklass"); duke@435: sib = sib->next_sibling(); duke@435: } duke@435: duke@435: // Verify implementor fields duke@435: bool saw_null_impl = false; duke@435: for (int i = 0; i < instanceKlass::implementors_limit; i++) { duke@435: klassOop im = ik->implementor(i); duke@435: if (im == NULL) { saw_null_impl = true; continue; } duke@435: guarantee(!saw_null_impl, "non-nulls must preceded all nulls"); duke@435: guarantee(ik->is_interface(), "only interfaces should have implementor set"); duke@435: guarantee(i < ik->nof_implementors(), "should only have one implementor"); duke@435: guarantee(im->is_perm(), "should be in permspace"); duke@435: guarantee(im->is_klass(), "should be klass"); duke@435: guarantee(!Klass::cast(klassOop(im))->is_interface(), "implementors cannot be interfaces"); duke@435: } duke@435: duke@435: // Verify local interfaces duke@435: objArrayOop local_interfaces = ik->local_interfaces(); duke@435: guarantee(local_interfaces->is_perm(), "should be in permspace"); duke@435: guarantee(local_interfaces->is_objArray(), "should be obj array"); duke@435: int j; duke@435: for (j = 0; j < local_interfaces->length(); j++) { duke@435: oop e = local_interfaces->obj_at(j); duke@435: guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid local interface"); duke@435: } duke@435: duke@435: // Verify transitive interfaces duke@435: objArrayOop transitive_interfaces = ik->transitive_interfaces(); duke@435: guarantee(transitive_interfaces->is_perm(), "should be in permspace"); duke@435: guarantee(transitive_interfaces->is_objArray(), "should be obj array"); duke@435: for (j = 0; j < transitive_interfaces->length(); j++) { duke@435: oop e = transitive_interfaces->obj_at(j); duke@435: guarantee(e->is_klass() && Klass::cast(klassOop(e))->is_interface(), "invalid transitive interface"); duke@435: } duke@435: duke@435: // Verify methods duke@435: objArrayOop methods = ik->methods(); duke@435: guarantee(methods->is_perm(), "should be in permspace"); duke@435: guarantee(methods->is_objArray(), "should be obj array"); duke@435: for (j = 0; j < methods->length(); j++) { duke@435: guarantee(methods->obj_at(j)->is_method(), "non-method in methods array"); duke@435: } duke@435: for (j = 0; j < methods->length() - 1; j++) { duke@435: methodOop m1 = methodOop(methods->obj_at(j)); duke@435: methodOop m2 = methodOop(methods->obj_at(j + 1)); duke@435: guarantee(m1->name()->fast_compare(m2->name()) <= 0, "methods not sorted correctly"); duke@435: } duke@435: duke@435: // Verify method ordering duke@435: typeArrayOop method_ordering = ik->method_ordering(); duke@435: guarantee(method_ordering->is_perm(), "should be in permspace"); duke@435: guarantee(method_ordering->is_typeArray(), "should be type array"); duke@435: int length = method_ordering->length(); duke@435: if (JvmtiExport::can_maintain_original_method_order()) { duke@435: guarantee(length == methods->length(), "invalid method ordering length"); duke@435: jlong sum = 0; duke@435: for (j = 0; j < length; j++) { duke@435: int original_index = method_ordering->int_at(j); duke@435: guarantee(original_index >= 0 && original_index < length, "invalid method ordering index"); duke@435: sum += original_index; duke@435: } duke@435: // Verify sum of indices 0,1,...,length-1 duke@435: guarantee(sum == ((jlong)length*(length-1))/2, "invalid method ordering sum"); duke@435: } else { duke@435: guarantee(length == 0, "invalid method ordering length"); duke@435: } duke@435: duke@435: // Verify JNI static field identifiers duke@435: if (ik->jni_ids() != NULL) { duke@435: ik->jni_ids()->verify(ik->as_klassOop()); duke@435: } duke@435: duke@435: // Verify other fields duke@435: if (ik->array_klasses() != NULL) { duke@435: guarantee(ik->array_klasses()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->array_klasses()->is_klass(), "should be klass"); duke@435: } duke@435: guarantee(ik->fields()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->fields()->is_typeArray(), "should be type array"); duke@435: guarantee(ik->constants()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->constants()->is_constantPool(), "should be constant pool"); duke@435: guarantee(ik->inner_classes()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->inner_classes()->is_typeArray(), "should be type array"); duke@435: if (ik->source_file_name() != NULL) { duke@435: guarantee(ik->source_file_name()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->source_file_name()->is_symbol(), "should be symbol"); duke@435: } duke@435: if (ik->source_debug_extension() != NULL) { duke@435: guarantee(ik->source_debug_extension()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->source_debug_extension()->is_symbol(), "should be symbol"); duke@435: } duke@435: if (ik->protection_domain() != NULL) { duke@435: guarantee(ik->protection_domain()->is_oop(), "should be oop"); duke@435: } duke@435: if (ik->signers() != NULL) { duke@435: guarantee(ik->signers()->is_objArray(), "should be obj array"); duke@435: } duke@435: if (ik->generic_signature() != NULL) { duke@435: guarantee(ik->generic_signature()->is_perm(), "should be in permspace"); duke@435: guarantee(ik->generic_signature()->is_symbol(), "should be symbol"); duke@435: } duke@435: if (ik->class_annotations() != NULL) { duke@435: guarantee(ik->class_annotations()->is_typeArray(), "should be type array"); duke@435: } duke@435: if (ik->fields_annotations() != NULL) { duke@435: guarantee(ik->fields_annotations()->is_objArray(), "should be obj array"); duke@435: } duke@435: if (ik->methods_annotations() != NULL) { duke@435: guarantee(ik->methods_annotations()->is_objArray(), "should be obj array"); duke@435: } duke@435: if (ik->methods_parameter_annotations() != NULL) { duke@435: guarantee(ik->methods_parameter_annotations()->is_objArray(), "should be obj array"); duke@435: } duke@435: if (ik->methods_default_annotations() != NULL) { duke@435: guarantee(ik->methods_default_annotations()->is_objArray(), "should be obj array"); duke@435: } duke@435: } duke@435: } duke@435: duke@435: duke@435: bool instanceKlassKlass::oop_partially_loaded(oop obj) const { duke@435: assert(obj->is_klass(), "object must be klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: assert(ik->oop_is_instance(), "object must be instanceKlass"); duke@435: return ik->transitive_interfaces() == (objArrayOop) obj; // Check whether transitive_interfaces points to self duke@435: } duke@435: duke@435: duke@435: // The transitive_interfaces is the last field set when loading an object. duke@435: void instanceKlassKlass::oop_set_partially_loaded(oop obj) { duke@435: assert(obj->is_klass(), "object must be klass"); duke@435: instanceKlass* ik = instanceKlass::cast(klassOop(obj)); duke@435: // Set the layout helper to a place-holder value, until fuller initialization. duke@435: // (This allows asserts in oop_is_instance to succeed.) duke@435: ik->set_layout_helper(Klass::instance_layout_helper(0, true)); duke@435: assert(ik->oop_is_instance(), "object must be instanceKlass"); duke@435: assert(ik->transitive_interfaces() == NULL, "just checking"); duke@435: ik->set_transitive_interfaces((objArrayOop) obj); // Temporarily set transitive_interfaces to point to self duke@435: }