1/*
2 * Copyright (c) 2002, 2018, 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/classLoaderData.inline.hpp"
27#include "classfile/classLoaderDataGraph.hpp"
28#include "classfile/moduleEntry.hpp"
29#include "classfile/systemDictionary.hpp"
30#include "gc/shared/collectedHeap.hpp"
31#include "memory/heapInspection.hpp"
32#include "memory/resourceArea.hpp"
33#include "memory/universe.hpp"
34#include "oops/oop.inline.hpp"
35#include "oops/reflectionAccessorImplKlassHelper.hpp"
36#include "runtime/os.hpp"
37#include "utilities/globalDefinitions.hpp"
38#include "utilities/macros.hpp"
39#include "utilities/stack.inline.hpp"
40
41// HeapInspection
42
43int KlassSizeStats::count(oop x) {
44 return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
45}
46
47int KlassSizeStats::count_array(objArrayOop x) {
48 return (HeapWordSize * (((x) != NULL) ? (x)->size() : 0));
49}
50
51inline KlassInfoEntry::~KlassInfoEntry() {
52 if (_subclasses != NULL) {
53 delete _subclasses;
54 }
55}
56
57inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie) {
58 if (_subclasses == NULL) {
59 _subclasses = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(4, true);
60 }
61 _subclasses->append(cie);
62}
63
64int KlassInfoEntry::compare(KlassInfoEntry* e1, KlassInfoEntry* e2) {
65 if(e1->_instance_words > e2->_instance_words) {
66 return -1;
67 } else if(e1->_instance_words < e2->_instance_words) {
68 return 1;
69 }
70 // Sort alphabetically, note 'Z' < '[' < 'a', but it's better to group
71 // the array classes before all the instance classes.
72 ResourceMark rm;
73 const char* name1 = e1->klass()->external_name();
74 const char* name2 = e2->klass()->external_name();
75 bool d1 = (name1[0] == '[');
76 bool d2 = (name2[0] == '[');
77 if (d1 && !d2) {
78 return -1;
79 } else if (d2 && !d1) {
80 return 1;
81 } else {
82 return strcmp(name1, name2);
83 }
84}
85
86const char* KlassInfoEntry::name() const {
87 const char* name;
88 if (_klass->name() != NULL) {
89 name = _klass->external_name();
90 } else {
91 if (_klass == Universe::boolArrayKlassObj()) name = "<boolArrayKlass>"; else
92 if (_klass == Universe::charArrayKlassObj()) name = "<charArrayKlass>"; else
93 if (_klass == Universe::floatArrayKlassObj()) name = "<floatArrayKlass>"; else
94 if (_klass == Universe::doubleArrayKlassObj()) name = "<doubleArrayKlass>"; else
95 if (_klass == Universe::byteArrayKlassObj()) name = "<byteArrayKlass>"; else
96 if (_klass == Universe::shortArrayKlassObj()) name = "<shortArrayKlass>"; else
97 if (_klass == Universe::intArrayKlassObj()) name = "<intArrayKlass>"; else
98 if (_klass == Universe::longArrayKlassObj()) name = "<longArrayKlass>"; else
99 name = "<no name>";
100 }
101 return name;
102}
103
104void KlassInfoEntry::print_on(outputStream* st) const {
105 ResourceMark rm;
106
107 // simplify the formatting (ILP32 vs LP64) - always cast the numbers to 64-bit
108 ModuleEntry* module = _klass->module();
109 if (module->is_named()) {
110 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s (%s@%s)",
111 (int64_t)_instance_count,
112 (uint64_t)_instance_words * HeapWordSize,
113 name(),
114 module->name()->as_C_string(),
115 module->version() != NULL ? module->version()->as_C_string() : "");
116 } else {
117 st->print_cr(INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13) " %s",
118 (int64_t)_instance_count,
119 (uint64_t)_instance_words * HeapWordSize,
120 name());
121 }
122}
123
124KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
125 // Can happen if k is an archived class that we haven't loaded yet.
126 if (k->java_mirror_no_keepalive() == NULL) {
127 return NULL;
128 }
129
130 KlassInfoEntry* elt = _list;
131 while (elt != NULL) {
132 if (elt->is_equal(k)) {
133 return elt;
134 }
135 elt = elt->next();
136 }
137 elt = new (std::nothrow) KlassInfoEntry(k, list());
138 // We may be out of space to allocate the new entry.
139 if (elt != NULL) {
140 set_list(elt);
141 }
142 return elt;
143}
144
145void KlassInfoBucket::iterate(KlassInfoClosure* cic) {
146 KlassInfoEntry* elt = _list;
147 while (elt != NULL) {
148 cic->do_cinfo(elt);
149 elt = elt->next();
150 }
151}
152
153void KlassInfoBucket::empty() {
154 KlassInfoEntry* elt = _list;
155 _list = NULL;
156 while (elt != NULL) {
157 KlassInfoEntry* next = elt->next();
158 delete elt;
159 elt = next;
160 }
161}
162
163class KlassInfoTable::AllClassesFinder : public LockedClassesDo {
164 KlassInfoTable *_table;
165public:
166 AllClassesFinder(KlassInfoTable* table) : _table(table) {}
167 virtual void do_klass(Klass* k) {
168 // This has the SIDE EFFECT of creating a KlassInfoEntry
169 // for <k>, if one doesn't exist yet.
170 _table->lookup(k);
171 }
172};
173
174
175KlassInfoTable::KlassInfoTable(bool add_all_classes) {
176 _size_of_instances_in_words = 0;
177 _ref = (HeapWord*) Universe::boolArrayKlassObj();
178 _buckets =
179 (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
180 mtInternal, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
181 if (_buckets != NULL) {
182 for (int index = 0; index < _num_buckets; index++) {
183 _buckets[index].initialize();
184 }
185 if (add_all_classes) {
186 AllClassesFinder finder(this);
187 ClassLoaderDataGraph::classes_do(&finder);
188 }
189 }
190}
191
192KlassInfoTable::~KlassInfoTable() {
193 if (_buckets != NULL) {
194 for (int index = 0; index < _num_buckets; index++) {
195 _buckets[index].empty();
196 }
197 FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
198 _buckets = NULL;
199 }
200}
201
202uint KlassInfoTable::hash(const Klass* p) {
203 return (uint)(((uintptr_t)p - (uintptr_t)_ref) >> 2);
204}
205
206KlassInfoEntry* KlassInfoTable::lookup(Klass* k) {
207 uint idx = hash(k) % _num_buckets;
208 assert(_buckets != NULL, "Allocation failure should have been caught");
209 KlassInfoEntry* e = _buckets[idx].lookup(k);
210 // Lookup may fail if this is a new klass for which we
211 // could not allocate space for an new entry, or if it's
212 // an archived class that we haven't loaded yet.
213 assert(e == NULL || k == e->klass(), "must be equal");
214 return e;
215}
216
217// Return false if the entry could not be recorded on account
218// of running out of space required to create a new entry.
219bool KlassInfoTable::record_instance(const oop obj) {
220 Klass* k = obj->klass();
221 KlassInfoEntry* elt = lookup(k);
222 // elt may be NULL if it's a new klass for which we
223 // could not allocate space for a new entry in the hashtable.
224 if (elt != NULL) {
225 elt->set_count(elt->count() + 1);
226 elt->set_words(elt->words() + obj->size());
227 _size_of_instances_in_words += obj->size();
228 return true;
229 } else {
230 return false;
231 }
232}
233
234void KlassInfoTable::iterate(KlassInfoClosure* cic) {
235 assert(_buckets != NULL, "Allocation failure should have been caught");
236 for (int index = 0; index < _num_buckets; index++) {
237 _buckets[index].iterate(cic);
238 }
239}
240
241size_t KlassInfoTable::size_of_instances_in_words() const {
242 return _size_of_instances_in_words;
243}
244
245int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
246 return (*e1)->compare(*e1,*e2);
247}
248
249KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit) :
250 _cit(cit) {
251 _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true);
252}
253
254KlassInfoHisto::~KlassInfoHisto() {
255 delete _elements;
256}
257
258void KlassInfoHisto::add(KlassInfoEntry* cie) {
259 elements()->append(cie);
260}
261
262void KlassInfoHisto::sort() {
263 elements()->sort(KlassInfoHisto::sort_helper);
264}
265
266void KlassInfoHisto::print_elements(outputStream* st) const {
267 // simplify the formatting (ILP32 vs LP64) - store the sum in 64-bit
268 int64_t total = 0;
269 uint64_t totalw = 0;
270 for(int i=0; i < elements()->length(); i++) {
271 st->print("%4d: ", i+1);
272 elements()->at(i)->print_on(st);
273 total += elements()->at(i)->count();
274 totalw += elements()->at(i)->words();
275 }
276 st->print_cr("Total " INT64_FORMAT_W(13) " " UINT64_FORMAT_W(13),
277 total, totalw * HeapWordSize);
278}
279
280#define MAKE_COL_NAME(field, name, help) #name,
281#define MAKE_COL_HELP(field, name, help) help,
282
283static const char *name_table[] = {
284 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_NAME)
285};
286
287static const char *help_table[] = {
288 HEAP_INSPECTION_COLUMNS_DO(MAKE_COL_HELP)
289};
290
291bool KlassInfoHisto::is_selected(const char *col_name) {
292 if (_selected_columns == NULL) {
293 return true;
294 }
295 if (strcmp(_selected_columns, col_name) == 0) {
296 return true;
297 }
298
299 const char *start = strstr(_selected_columns, col_name);
300 if (start == NULL) {
301 return false;
302 }
303
304 // The following must be true, because _selected_columns != col_name
305 if (start > _selected_columns && start[-1] != ',') {
306 return false;
307 }
308 char x = start[strlen(col_name)];
309 if (x != ',' && x != '\0') {
310 return false;
311 }
312
313 return true;
314}
315
316void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
317 bool selected[], int width_table[],
318 const char *name_table[]) {
319 if (csv_format) {
320 st->print("Index,Super");
321 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
322 if (selected[c]) {st->print(",%s", name_table[c]);}
323 }
324 st->print(",ClassName");
325 } else {
326 st->print("Index Super");
327 for (int c = 0; c < KlassSizeStats::_num_columns; c++) {
328 if (selected[c]) {
329 st->print("%*s", width_table[c], name_table[c]);
330 }
331 }
332 st->print(" ClassName");
333 }
334
335 if (is_selected("ClassLoader")) {
336 st->print(",ClassLoader");
337 }
338 st->cr();
339}
340
341class HierarchyClosure : public KlassInfoClosure {
342private:
343 GrowableArray<KlassInfoEntry*> *_elements;
344public:
345 HierarchyClosure(GrowableArray<KlassInfoEntry*> *_elements) : _elements(_elements) {}
346
347 void do_cinfo(KlassInfoEntry* cie) {
348 // ignore array classes
349 if (cie->klass()->is_instance_klass()) {
350 _elements->append(cie);
351 }
352 }
353};
354
355void KlassHierarchy::print_class_hierarchy(outputStream* st, bool print_interfaces,
356 bool print_subclasses, char* classname) {
357 ResourceMark rm;
358 Stack <KlassInfoEntry*, mtClass> class_stack;
359 GrowableArray<KlassInfoEntry*> elements;
360
361 // Add all classes to the KlassInfoTable, which allows for quick lookup.
362 // A KlassInfoEntry will be created for each class.
363 KlassInfoTable cit(true);
364 if (cit.allocation_failed()) {
365 st->print_cr("ERROR: Ran out of C-heap; hierarchy not generated");
366 return;
367 }
368
369 // Add all created KlassInfoEntry instances to the elements array for easy
370 // iteration, and to allow each KlassInfoEntry instance to have a unique index.
371 HierarchyClosure hc(&elements);
372 cit.iterate(&hc);
373
374 for(int i = 0; i < elements.length(); i++) {
375 KlassInfoEntry* cie = elements.at(i);
376 Klass* super = cie->klass()->super();
377
378 // Set the index for the class.
379 cie->set_index(i + 1);
380
381 // Add the class to the subclass array of its superclass.
382 if (super != NULL) {
383 KlassInfoEntry* super_cie = cit.lookup(super);
384 assert(super_cie != NULL, "could not lookup superclass");
385 super_cie->add_subclass(cie);
386 }
387 }
388
389 // Set the do_print flag for each class that should be printed.
390 for(int i = 0; i < elements.length(); i++) {
391 KlassInfoEntry* cie = elements.at(i);
392 if (classname == NULL) {
393 // We are printing all classes.
394 cie->set_do_print(true);
395 } else {
396 // We are only printing the hierarchy of a specific class.
397 if (strcmp(classname, cie->klass()->external_name()) == 0) {
398 KlassHierarchy::set_do_print_for_class_hierarchy(cie, &cit, print_subclasses);
399 }
400 }
401 }
402
403 // Now we do a depth first traversal of the class hierachry. The class_stack will
404 // maintain the list of classes we still need to process. Start things off
405 // by priming it with java.lang.Object.
406 KlassInfoEntry* jlo_cie = cit.lookup(SystemDictionary::Object_klass());
407 assert(jlo_cie != NULL, "could not lookup java.lang.Object");
408 class_stack.push(jlo_cie);
409
410 // Repeatedly pop the top item off the stack, print its class info,
411 // and push all of its subclasses on to the stack. Do this until there
412 // are no classes left on the stack.
413 while (!class_stack.is_empty()) {
414 KlassInfoEntry* curr_cie = class_stack.pop();
415 if (curr_cie->do_print()) {
416 print_class(st, curr_cie, print_interfaces);
417 if (curr_cie->subclasses() != NULL) {
418 // Current class has subclasses, so push all of them onto the stack.
419 for (int i = 0; i < curr_cie->subclasses()->length(); i++) {
420 KlassInfoEntry* cie = curr_cie->subclasses()->at(i);
421 if (cie->do_print()) {
422 class_stack.push(cie);
423 }
424 }
425 }
426 }
427 }
428
429 st->flush();
430}
431
432// Sets the do_print flag for every superclass and subclass of the specified class.
433void KlassHierarchy::set_do_print_for_class_hierarchy(KlassInfoEntry* cie, KlassInfoTable* cit,
434 bool print_subclasses) {
435 // Set do_print for all superclasses of this class.
436 Klass* super = ((InstanceKlass*)cie->klass())->java_super();
437 while (super != NULL) {
438 KlassInfoEntry* super_cie = cit->lookup(super);
439 super_cie->set_do_print(true);
440 super = super->super();
441 }
442
443 // Set do_print for this class and all of its subclasses.
444 Stack <KlassInfoEntry*, mtClass> class_stack;
445 class_stack.push(cie);
446 while (!class_stack.is_empty()) {
447 KlassInfoEntry* curr_cie = class_stack.pop();
448 curr_cie->set_do_print(true);
449 if (print_subclasses && curr_cie->subclasses() != NULL) {
450 // Current class has subclasses, so push all of them onto the stack.
451 for (int i = 0; i < curr_cie->subclasses()->length(); i++) {
452 KlassInfoEntry* cie = curr_cie->subclasses()->at(i);
453 class_stack.push(cie);
454 }
455 }
456 }
457}
458
459static void print_indent(outputStream* st, int indent) {
460 while (indent != 0) {
461 st->print("|");
462 indent--;
463 if (indent != 0) {
464 st->print(" ");
465 }
466 }
467}
468
469// Print the class name and its unique ClassLoader identifer.
470static void print_classname(outputStream* st, Klass* klass) {
471 oop loader_oop = klass->class_loader_data()->class_loader();
472 st->print("%s/", klass->external_name());
473 if (loader_oop == NULL) {
474 st->print("null");
475 } else {
476 st->print(INTPTR_FORMAT, p2i(klass->class_loader_data()));
477 }
478}
479
480static void print_interface(outputStream* st, InstanceKlass* intf_klass, const char* intf_type, int indent) {
481 print_indent(st, indent);
482 st->print(" implements ");
483 print_classname(st, intf_klass);
484 st->print(" (%s intf)\n", intf_type);
485}
486
487void KlassHierarchy::print_class(outputStream* st, KlassInfoEntry* cie, bool print_interfaces) {
488 ResourceMark rm;
489 InstanceKlass* klass = (InstanceKlass*)cie->klass();
490 int indent = 0;
491
492 // Print indentation with proper indicators of superclass.
493 Klass* super = klass->super();
494 while (super != NULL) {
495 super = super->super();
496 indent++;
497 }
498 print_indent(st, indent);
499 if (indent != 0) st->print("--");
500
501 // Print the class name, its unique ClassLoader identifer, and if it is an interface.
502 print_classname(st, klass);
503 if (klass->is_interface()) {
504 st->print(" (intf)");
505 }
506 // Special treatment for generated core reflection accessor classes: print invocation target.
507 if (ReflectionAccessorImplKlassHelper::is_generated_accessor(klass)) {
508 st->print(" (invokes: ");
509 ReflectionAccessorImplKlassHelper::print_invocation_target(st, klass);
510 st->print(")");
511 }
512 st->print("\n");
513
514 // Print any interfaces the class has.
515 if (print_interfaces) {
516 Array<InstanceKlass*>* local_intfs = klass->local_interfaces();
517 Array<InstanceKlass*>* trans_intfs = klass->transitive_interfaces();
518 for (int i = 0; i < local_intfs->length(); i++) {
519 print_interface(st, local_intfs->at(i), "declared", indent);
520 }
521 for (int i = 0; i < trans_intfs->length(); i++) {
522 InstanceKlass* trans_interface = trans_intfs->at(i);
523 // Only print transitive interfaces if they are not also declared.
524 if (!local_intfs->contains(trans_interface)) {
525 print_interface(st, trans_interface, "inherited", indent);
526 }
527 }
528 }
529}
530
531void KlassInfoHisto::print_class_stats(outputStream* st,
532 bool csv_format, const char *columns) {
533 ResourceMark rm;
534 KlassSizeStats sz, sz_sum;
535 int i;
536 julong *col_table = (julong*)(&sz);
537 julong *colsum_table = (julong*)(&sz_sum);
538 int width_table[KlassSizeStats::_num_columns];
539 bool selected[KlassSizeStats::_num_columns];
540
541 _selected_columns = columns;
542
543 memset(&sz_sum, 0, sizeof(sz_sum));
544 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
545 selected[c] = is_selected(name_table[c]);
546 }
547
548 for(i=0; i < elements()->length(); i++) {
549 elements()->at(i)->set_index(i+1);
550 }
551
552 // First iteration is for accumulating stats totals in colsum_table[].
553 // Second iteration is for printing stats for each class.
554 for (int pass=1; pass<=2; pass++) {
555 if (pass == 2) {
556 print_title(st, csv_format, selected, width_table, name_table);
557 }
558 for(i=0; i < elements()->length(); i++) {
559 KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i);
560 const Klass* k = e->klass();
561
562 // Get the stats for this class.
563 memset(&sz, 0, sizeof(sz));
564 sz._inst_count = e->count();
565 sz._inst_bytes = HeapWordSize * e->words();
566 k->collect_statistics(&sz);
567 sz._total_bytes = sz._ro_bytes + sz._rw_bytes;
568
569 if (pass == 1) {
570 // Add the stats for this class to the overall totals.
571 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
572 colsum_table[c] += col_table[c];
573 }
574 } else {
575 int super_index = -1;
576 // Print the stats for this class.
577 if (k->is_instance_klass()) {
578 Klass* super = k->super();
579 if (super) {
580 KlassInfoEntry* super_e = _cit->lookup(super);
581 if (super_e) {
582 super_index = super_e->index();
583 }
584 }
585 }
586
587 if (csv_format) {
588 st->print("%ld,%d", e->index(), super_index);
589 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
590 if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);}
591 }
592 st->print(",%s",e->name());
593 } else {
594 st->print("%5ld %5d", e->index(), super_index);
595 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
596 if (selected[c]) {print_julong(st, width_table[c], col_table[c]);}
597 }
598 st->print(" %s", e->name());
599 }
600 if (is_selected("ClassLoader")) {
601 ClassLoaderData* loader_data = k->class_loader_data();
602 st->print(",");
603 loader_data->print_value_on(st);
604 }
605 st->cr();
606 }
607 }
608
609 if (pass == 1) {
610 // Calculate the minimum width needed for the column by accounting for the
611 // column header width and the width of the largest value in the column.
612 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
613 width_table[c] = col_width(colsum_table[c], name_table[c]);
614 }
615 }
616 }
617
618 sz_sum._inst_size = 0;
619
620 // Print the column totals.
621 if (csv_format) {
622 st->print(",");
623 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
624 if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);}
625 }
626 } else {
627 st->print(" ");
628 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
629 if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);}
630 }
631 st->print(" Total");
632 if (sz_sum._total_bytes > 0) {
633 st->cr();
634 st->print(" ");
635 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
636 if (selected[c]) {
637 switch (c) {
638 case KlassSizeStats::_index_inst_size:
639 case KlassSizeStats::_index_inst_count:
640 case KlassSizeStats::_index_method_count:
641 st->print("%*s", width_table[c], "-");
642 break;
643 default:
644 {
645 double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
646 st->print("%*.1f%%", width_table[c]-1, perc);
647 }
648 }
649 }
650 }
651 }
652 }
653 st->cr();
654
655 if (!csv_format) {
656 print_title(st, csv_format, selected, width_table, name_table);
657 }
658}
659
660julong KlassInfoHisto::annotations_bytes(Array<AnnotationArray*>* p) const {
661 julong bytes = 0;
662 if (p != NULL) {
663 for (int i = 0; i < p->length(); i++) {
664 bytes += count_bytes_array(p->at(i));
665 }
666 bytes += count_bytes_array(p);
667 }
668 return bytes;
669}
670
671void KlassInfoHisto::print_histo_on(outputStream* st, bool print_stats,
672 bool csv_format, const char *columns) {
673 if (print_stats) {
674 print_class_stats(st, csv_format, columns);
675 } else {
676 st->print_cr(" num #instances #bytes class name (module)");
677 st->print_cr("-------------------------------------------------------");
678 print_elements(st);
679 }
680}
681
682class HistoClosure : public KlassInfoClosure {
683 private:
684 KlassInfoHisto* _cih;
685 public:
686 HistoClosure(KlassInfoHisto* cih) : _cih(cih) {}
687
688 void do_cinfo(KlassInfoEntry* cie) {
689 _cih->add(cie);
690 }
691};
692
693class RecordInstanceClosure : public ObjectClosure {
694 private:
695 KlassInfoTable* _cit;
696 size_t _missed_count;
697 BoolObjectClosure* _filter;
698 public:
699 RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
700 _cit(cit), _missed_count(0), _filter(filter) {}
701
702 void do_object(oop obj) {
703 if (should_visit(obj)) {
704 if (!_cit->record_instance(obj)) {
705 _missed_count++;
706 }
707 }
708 }
709
710 size_t missed_count() { return _missed_count; }
711
712 private:
713 bool should_visit(oop obj) {
714 return _filter == NULL || _filter->do_object_b(obj);
715 }
716};
717
718size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) {
719 ResourceMark rm;
720
721 RecordInstanceClosure ric(cit, filter);
722 Universe::heap()->safe_object_iterate(&ric);
723 return ric.missed_count();
724}
725
726void HeapInspection::heap_inspection(outputStream* st) {
727 ResourceMark rm;
728
729 if (_print_help) {
730 for (int c=0; c<KlassSizeStats::_num_columns; c++) {
731 st->print("%s:\n\t", name_table[c]);
732 const int max_col = 60;
733 int col = 0;
734 for (const char *p = help_table[c]; *p; p++,col++) {
735 if (col >= max_col && *p == ' ') {
736 st->print("\n\t");
737 col = 0;
738 } else {
739 st->print("%c", *p);
740 }
741 }
742 st->print_cr(".\n");
743 }
744 return;
745 }
746
747 KlassInfoTable cit(_print_class_stats);
748 if (!cit.allocation_failed()) {
749 // populate table with object allocation info
750 size_t missed_count = populate_table(&cit);
751 if (missed_count != 0) {
752 st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
753 " total instances in data below",
754 missed_count);
755 }
756
757 // Sort and print klass instance info
758 KlassInfoHisto histo(&cit);
759 HistoClosure hc(&histo);
760
761 cit.iterate(&hc);
762
763 histo.sort();
764 histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
765 } else {
766 st->print_cr("ERROR: Ran out of C-heap; histogram not generated");
767 }
768 st->flush();
769}
770
771class FindInstanceClosure : public ObjectClosure {
772 private:
773 Klass* _klass;
774 GrowableArray<oop>* _result;
775
776 public:
777 FindInstanceClosure(Klass* k, GrowableArray<oop>* result) : _klass(k), _result(result) {};
778
779 void do_object(oop obj) {
780 if (obj->is_a(_klass)) {
781 _result->append(obj);
782 }
783 }
784};
785
786void HeapInspection::find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) {
787 assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
788 assert(Heap_lock->is_locked(), "should have the Heap_lock");
789
790 // Ensure that the heap is parsable
791 Universe::heap()->ensure_parsability(false); // no need to retire TALBs
792
793 // Iterate over objects in the heap
794 FindInstanceClosure fic(k, result);
795 Universe::heap()->safe_object_iterate(&fic);
796}
797