1 /* 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/systemDictionary.hpp" 27 #include "memory/classify.hpp" 28 29 30 const char* ClassifyObjectClosure::object_type_name[number_object_types] = { 31 "unknown", 32 "instance", 33 "instanceRef", 34 "objArray", 35 "symbol", 36 "klass", 37 "instanceKlass", 38 "method", 39 "constMethod", 40 "methodData", 41 "constantPool", 42 "constantPoolCache", 43 "typeArray", 44 "compiledICHolder" 45 }; 46 47 48 object_type ClassifyObjectClosure::classify_object(oop obj, bool count) { 49 object_type type = unknown_type; 50 51 Klass* k = obj->blueprint(); 52 53 if (k->as_klassOop() == SystemDictionary::Object_klass()) { 54 tty->print_cr("Found the class!"); 55 } 56 57 if (count) { 58 k->set_alloc_count(k->alloc_count() + 1); 59 } 60 61 if (obj->is_instance()) { 62 if (k->oop_is_instanceRef()) { 63 type = instanceRef_type; 64 } else { 65 type = instance_type; 66 } 67 } else if (obj->is_typeArray()) { 68 type = typeArray_type; 69 } else if (obj->is_objArray()) { 70 type = objArray_type; 71 } else if (obj->is_symbol()) { 72 type = symbol_type; 73 } else if (obj->is_klass()) { 74 Klass* k = ((klassOop)obj)->klass_part(); 75 if (k->oop_is_instance()) { 76 type = instanceKlass_type; 77 } else { 78 type = klass_type; 79 } 80 } else if (obj->is_method()) { 81 type = method_type; 82 } else if (obj->is_constMethod()) { 83 type = constMethod_type; 84 } else if (obj->is_methodData()) { 85 ShouldNotReachHere(); 86 } else if (obj->is_constantPool()) { 87 type = constantPool_type; 88 } else if (obj->is_constantPoolCache()) { 89 type = constantPoolCache_type; 90 } else if (obj->is_compiledICHolder()) { 91 type = compiledICHolder_type; 92 } else { 93 ShouldNotReachHere(); 94 } 95 96 assert(type != unknown_type, "found object of unknown type."); 97 return type; 98 } 99 100 101 void ClassifyObjectClosure::reset() { 102 for (int i = 0; i < number_object_types; ++i) { 103 object_count[i] = 0; 104 object_size[i] = 0; 105 } 106 total_object_count = 0; 107 total_object_size = 0; 108 } 109 110 111 void ClassifyObjectClosure::do_object(oop obj) { 112 int i = classify_object(obj, true); 113 ++object_count[i]; 114 ++total_object_count; 115 size_t size = obj->size() * HeapWordSize; 116 object_size[i] += size; 117 total_object_size += size; 118 } 119 120 121 size_t ClassifyObjectClosure::print() { 122 int num_objects = 0; 123 size_t size_objects = 0; 124 for (int i = 0; i < number_object_types; ++i) { 125 if (object_count[i] != 0) { 126 tty->print_cr("%8d %-22s (%8d bytes, %5.2f bytes/object)", 127 object_count[i], object_type_name[i], object_size[i], 128 (float)object_size[i]/(float)object_count[i]); 129 } 130 num_objects += object_count[i]; 131 size_objects += object_size[i]; 132 } 133 assert(num_objects == total_object_count, "Object count mismatch!"); 134 assert(size_objects == total_object_size, "Object size mismatch!"); 135 136 tty->print_cr(" Total: %d objects, %d bytes", total_object_count, 137 total_object_size); 138 return total_object_size; 139 } 140 141 142 void ClassifyInstanceKlassClosure::do_object(oop obj) { 143 int type = classify_object(obj, false); 144 if (type == instanceKlass_type || type == klass_type) { 145 Klass* k = ((klassOop)obj)->klass_part(); 146 if (k->alloc_count() > 0) { 147 ResourceMark rm; 148 const char *name; 149 if (k->name() == NULL) { 150 151 if (obj == Universe::klassKlassObj()) { 152 name = "_klassKlassObj"; 153 } else if (obj == Universe::arrayKlassKlassObj()) { 154 name = "_arrayKlassKlassObj"; 155 } else if (obj == Universe::objArrayKlassKlassObj()) { 156 name = "_objArrayKlassKlassObj"; 157 } else if (obj == Universe::typeArrayKlassKlassObj()) { 158 name = "_typeArrayKlassKlassObj"; 159 } else if (obj == Universe::instanceKlassKlassObj()) { 160 name = "_instanceKlassKlassObj"; 161 } else if (obj == Universe::symbolKlassObj()) { 162 name = "_symbolKlassObj"; 163 } else if (obj == Universe::methodKlassObj()) { 164 name = "_methodKlassObj"; 165 } else if (obj == Universe::constMethodKlassObj()) { 166 name = "_constMethodKlassObj"; 167 } else if (obj == Universe::constantPoolKlassObj()) { 168 name = "_constantPoolKlassObj"; 169 } else if (obj == Universe::constantPoolCacheKlassObj()) { 170 name = "_constantPoolCacheKlassObj"; 171 } else if (obj == Universe::compiledICHolderKlassObj()) { 172 name = "_compiledICHolderKlassObj"; 173 } else if (obj == Universe::systemObjArrayKlassObj()) { 174 name = "_systemObjArrayKlassObj"; 175 } else { 176 name = "[unnamed]"; 177 } 178 } else { 179 name = k->external_name(); 180 } 181 tty->print_cr("% 8d instances of %s", k->alloc_count(), name); 182 } 183 total_instances += k->alloc_count(); 184 } 185 } 186 187 188 void ClassifyInstanceKlassClosure::print() { 189 tty->print_cr(" Total instances: %d.", total_instances); 190 } 191 192 193 void ClassifyInstanceKlassClosure::reset() { 194 total_instances = 0; 195 }