void KlassInfoHisto::print_class_stats(outputStream* st, bool csv_format, const char *columns) { ResourceMark rm; KlassSizeStats sz, sz_sum; int i; julong *col_table = (julong*)(&sz); julong *colsum_table = (julong*)(&sz_sum); int width_table[KlassSizeStats::_num_columns]; bool selected[KlassSizeStats::_num_columns]; _selected_columns = columns; memset(&sz_sum, 0, sizeof(sz_sum)); for (int c=0; c<KlassSizeStats::_num_columns; c++) { selected[c] = is_selected(name_table[c]); } for(i=0; i < elements()->length(); i++) { elements()->at(i)->set_index(i+1); } for (int pass=1; pass<=2; pass++) { if (pass == 2) { print_title(st, csv_format, selected, width_table, name_table); } for(i=0; i < elements()->length(); i++) { KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i); const Klass* k = e->klass(); memset(&sz, 0, sizeof(sz)); sz._inst_count = e->count(); sz._inst_bytes = HeapWordSize * e->words(); k->collect_statistics(&sz); sz._total_bytes = sz._ro_bytes + sz._rw_bytes; if (pass == 1) { for (int c=0; c<KlassSizeStats::_num_columns; c++) { colsum_table[c] += col_table[c]; } } else { int super_index = -1; if (k->oop_is_instance()) { Klass* super = ((InstanceKlass*)k)->java_super(); if (super) { KlassInfoEntry* super_e = _cit->lookup(super); if (super_e) { super_index = super_e->index(); } } } if (csv_format) { st->print("%d,%d", e->index(), super_index); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);} } st->print(",%s",e->name()); } else { st->print("%5d %5d", e->index(), super_index); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {print_julong(st, width_table[c], col_table[c]);} } st->print(" %s", e->name()); } if (is_selected("ClassLoader")) { ClassLoaderData* loader_data = k->class_loader_data(); st->print(","); loader_data->print_value_on(st); } st->cr(); } } if (pass == 1) { for (int c=0; c<KlassSizeStats::_num_columns; c++) { width_table[c] = col_width(colsum_table[c], name_table[c]); } } } sz_sum._inst_size = 0; if (csv_format) { st->print(","); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);} } } else { st->print(" "); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);} } st->print(" Total"); if (sz_sum._total_bytes > 0) { st->cr(); st->print(" "); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) { switch (c) { case KlassSizeStats::_index_inst_size: case KlassSizeStats::_index_inst_count: case KlassSizeStats::_index_method_count: PRAGMA_DIAG_PUSH PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(str_fmt(width_table[c]), "-"); PRAGMA_DIAG_POP break; default: { double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; PRAGMA_DIAG_PUSH PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL st->print(perc_fmt(width_table[c]), perc); PRAGMA_DIAG_POP } } } } } }
void KlassInfoHisto::print_class_stats(outputStream* st, bool csv_format, const char *columns) { ResourceMark rm; KlassSizeStats sz, sz_sum; int i; julong *col_table = (julong*)(&sz); julong *colsum_table = (julong*)(&sz_sum); int width_table[KlassSizeStats::_num_columns]; bool selected[KlassSizeStats::_num_columns]; _selected_columns = columns; memset(&sz_sum, 0, sizeof(sz_sum)); for (int c=0; c<KlassSizeStats::_num_columns; c++) { selected[c] = is_selected(name_table[c]); } for(i=0; i < elements()->length(); i++) { elements()->at(i)->set_index(i+1); } // First iteration is for accumulating stats totals in colsum_table[]. // Second iteration is for printing stats for each class. for (int pass=1; pass<=2; pass++) { if (pass == 2) { print_title(st, csv_format, selected, width_table, name_table); } for(i=0; i < elements()->length(); i++) { KlassInfoEntry* e = (KlassInfoEntry*)elements()->at(i); const Klass* k = e->klass(); // Get the stats for this class. memset(&sz, 0, sizeof(sz)); sz._inst_count = e->count(); sz._inst_bytes = HeapWordSize * e->words(); k->collect_statistics(&sz); sz._total_bytes = sz._ro_bytes + sz._rw_bytes; if (pass == 1) { // Add the stats for this class to the overall totals. for (int c=0; c<KlassSizeStats::_num_columns; c++) { colsum_table[c] += col_table[c]; } } else { int super_index = -1; // Print the stats for this class. if (k->is_instance_klass()) { Klass* super = k->super(); if (super) { KlassInfoEntry* super_e = _cit->lookup(super); if (super_e) { super_index = super_e->index(); } } } if (csv_format) { st->print("%ld,%d", e->index(), super_index); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {st->print("," JULONG_FORMAT, col_table[c]);} } st->print(",%s",e->name()); } else { st->print("%5ld %5d", e->index(), super_index); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {print_julong(st, width_table[c], col_table[c]);} } st->print(" %s", e->name()); } if (is_selected("ClassLoader")) { ClassLoaderData* loader_data = k->class_loader_data(); st->print(","); loader_data->print_value_on(st); } st->cr(); } } if (pass == 1) { // Calculate the minimum width needed for the column by accounting for the // column header width and the width of the largest value in the column. for (int c=0; c<KlassSizeStats::_num_columns; c++) { width_table[c] = col_width(colsum_table[c], name_table[c]); } } } sz_sum._inst_size = 0; // Print the column totals. if (csv_format) { st->print(","); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {st->print("," JULONG_FORMAT, colsum_table[c]);} } } else { st->print(" "); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) {print_julong(st, width_table[c], colsum_table[c]);} } st->print(" Total"); if (sz_sum._total_bytes > 0) { st->cr(); st->print(" "); for (int c=0; c<KlassSizeStats::_num_columns; c++) { if (selected[c]) { switch (c) { case KlassSizeStats::_index_inst_size: case KlassSizeStats::_index_inst_count: case KlassSizeStats::_index_method_count: st->print("%*s", width_table[c], "-"); break; default: { double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes; st->print("%*.1f%%", width_table[c]-1, perc); } } } } } } st->cr(); if (!csv_format) { print_title(st, csv_format, selected, width_table, name_table); } }