duke@435: /* duke@435: * Copyright 2003-2007 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/_classify.cpp.incl" duke@435: duke@435: duke@435: const char* ClassifyObjectClosure::object_type_name[number_object_types] = { duke@435: "unknown", duke@435: "instance", duke@435: "instanceRef", duke@435: "objArray", duke@435: "symbol", duke@435: "klass", duke@435: "instanceKlass", duke@435: "method", duke@435: "constMethod", duke@435: "methodData", duke@435: "constantPool", duke@435: "constantPoolCache", duke@435: "typeArray", duke@435: "compiledICHolder" duke@435: }; duke@435: duke@435: duke@435: object_type ClassifyObjectClosure::classify_object(oop obj, bool count) { duke@435: object_type type = unknown_type; duke@435: duke@435: Klass* k = obj->blueprint(); duke@435: duke@435: if (k->as_klassOop() == SystemDictionary::object_klass()) { duke@435: tty->print_cr("Found the class!"); duke@435: } duke@435: duke@435: if (count) { duke@435: k->set_alloc_count(k->alloc_count() + 1); duke@435: } duke@435: duke@435: if (obj->is_instance()) { duke@435: if (k->oop_is_instanceRef()) { duke@435: type = instanceRef_type; duke@435: } else { duke@435: type = instance_type; duke@435: } duke@435: } else if (obj->is_typeArray()) { duke@435: type = typeArray_type; duke@435: } else if (obj->is_objArray()) { duke@435: type = objArray_type; duke@435: } else if (obj->is_symbol()) { duke@435: type = symbol_type; duke@435: } else if (obj->is_klass()) { duke@435: Klass* k = ((klassOop)obj)->klass_part(); duke@435: if (k->oop_is_instance()) { duke@435: type = instanceKlass_type; duke@435: } else { duke@435: type = klass_type; duke@435: } duke@435: } else if (obj->is_method()) { duke@435: type = method_type; duke@435: } else if (obj->is_constMethod()) { duke@435: type = constMethod_type; duke@435: } else if (obj->is_methodData()) { duke@435: ShouldNotReachHere(); duke@435: } else if (obj->is_constantPool()) { duke@435: type = constantPool_type; duke@435: } else if (obj->is_constantPoolCache()) { duke@435: type = constantPoolCache_type; duke@435: } else if (obj->is_compiledICHolder()) { duke@435: type = compiledICHolder_type; duke@435: } else { duke@435: ShouldNotReachHere(); duke@435: } duke@435: duke@435: assert(type != unknown_type, "found object of unknown type."); duke@435: return type; duke@435: } duke@435: duke@435: duke@435: void ClassifyObjectClosure::reset() { duke@435: for (int i = 0; i < number_object_types; ++i) { duke@435: object_count[i] = 0; duke@435: object_size[i] = 0; duke@435: } duke@435: total_object_count = 0; duke@435: total_object_size = 0; duke@435: } duke@435: duke@435: duke@435: void ClassifyObjectClosure::do_object(oop obj) { duke@435: int i = classify_object(obj, true); duke@435: ++object_count[i]; duke@435: ++total_object_count; duke@435: size_t size = obj->size() * HeapWordSize; duke@435: object_size[i] += size; duke@435: total_object_size += size; duke@435: } duke@435: duke@435: duke@435: size_t ClassifyObjectClosure::print() { duke@435: int num_objects = 0; duke@435: size_t size_objects = 0; duke@435: for (int i = 0; i < number_object_types; ++i) { duke@435: if (object_count[i] != 0) { duke@435: tty->print_cr("%8d %-22s (%8d bytes, %5.2f bytes/object)", duke@435: object_count[i], object_type_name[i], object_size[i], duke@435: (float)object_size[i]/(float)object_count[i]); duke@435: } duke@435: num_objects += object_count[i]; duke@435: size_objects += object_size[i]; duke@435: } duke@435: assert(num_objects == total_object_count, "Object count mismatch!"); duke@435: assert(size_objects == total_object_size, "Object size mismatch!"); duke@435: duke@435: tty->print_cr(" Total: %d objects, %d bytes", total_object_count, duke@435: total_object_size); duke@435: return total_object_size; duke@435: } duke@435: duke@435: duke@435: void ClassifyInstanceKlassClosure::do_object(oop obj) { duke@435: int type = classify_object(obj, false); duke@435: if (type == instanceKlass_type || type == klass_type) { duke@435: Klass* k = ((klassOop)obj)->klass_part(); duke@435: if (k->alloc_count() > 0) { duke@435: ResourceMark rm; duke@435: const char *name; duke@435: if (k->name() == NULL) { duke@435: duke@435: if (obj == Universe::klassKlassObj()) { duke@435: name = "_klassKlassObj"; duke@435: } else if (obj == Universe::arrayKlassKlassObj()) { duke@435: name = "_arrayKlassKlassObj"; duke@435: } else if (obj == Universe::objArrayKlassKlassObj()) { duke@435: name = "_objArrayKlassKlassObj"; duke@435: } else if (obj == Universe::typeArrayKlassKlassObj()) { duke@435: name = "_typeArrayKlassKlassObj"; duke@435: } else if (obj == Universe::instanceKlassKlassObj()) { duke@435: name = "_instanceKlassKlassObj"; duke@435: } else if (obj == Universe::symbolKlassObj()) { duke@435: name = "_symbolKlassObj"; duke@435: } else if (obj == Universe::methodKlassObj()) { duke@435: name = "_methodKlassObj"; duke@435: } else if (obj == Universe::constMethodKlassObj()) { duke@435: name = "_constMethodKlassObj"; duke@435: } else if (obj == Universe::constantPoolKlassObj()) { duke@435: name = "_constantPoolKlassObj"; duke@435: } else if (obj == Universe::constantPoolCacheKlassObj()) { duke@435: name = "_constantPoolCacheKlassObj"; duke@435: } else if (obj == Universe::compiledICHolderKlassObj()) { duke@435: name = "_compiledICHolderKlassObj"; duke@435: } else if (obj == Universe::systemObjArrayKlassObj()) { duke@435: name = "_systemObjArrayKlassObj"; duke@435: } else { duke@435: name = "[unnamed]"; duke@435: } duke@435: } else { duke@435: name = k->external_name(); duke@435: } duke@435: tty->print_cr("% 8d instances of %s", k->alloc_count(), name); duke@435: } duke@435: total_instances += k->alloc_count(); duke@435: } duke@435: } duke@435: duke@435: duke@435: void ClassifyInstanceKlassClosure::print() { duke@435: tty->print_cr(" Total instances: %d.", total_instances); duke@435: } duke@435: duke@435: duke@435: void ClassifyInstanceKlassClosure::reset() { duke@435: total_instances = 0; duke@435: }