comparison src/share/vm/memory/metaspaceShared.cpp @ 10376:a1ebd310d5c1

8014912: Restore PrintSharedSpaces functionality after NPG Summary: Added dumping of object sizes in CDS archive, sorted by MetaspaceObj::Type Reviewed-by: coleenp, acorn
author iklam
date Tue, 28 May 2013 16:36:19 -0700
parents 868d87ed63c8
children 221df7e37535
comparison
equal deleted inserted replaced
10353:9ea643afcaaf 10376:a1ebd310d5c1
241 } 241 }
242 242
243 bool reading() const { return false; } 243 bool reading() const { return false; }
244 }; 244 };
245 245
246 // This is for dumping detailed statistics for the allocations
247 // in the shared spaces.
248 class DumpAllocClosure : public Metaspace::AllocRecordClosure {
249 public:
250
251 // Here's poor man's enum inheritance
252 #define SHAREDSPACE_OBJ_TYPES_DO(f) \
253 METASPACE_OBJ_TYPES_DO(f) \
254 f(SymbolHashentry) \
255 f(SymbolBuckets) \
256 f(Other)
257
258 #define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
259 #define SHAREDSPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
260
261 enum Type {
262 // Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
263 SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_DECLARE)
264 _number_of_types
265 };
266
267 static const char * type_name(Type type) {
268 switch(type) {
269 SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_NAME_CASE)
270 default:
271 ShouldNotReachHere();
272 return NULL;
273 }
274 }
275
276 public:
277 enum {
278 RO = 0,
279 RW = 1
280 };
281
282 int _counts[2][_number_of_types];
283 int _bytes [2][_number_of_types];
284 int _which;
285
286 DumpAllocClosure() {
287 memset(_counts, 0, sizeof(_counts));
288 memset(_bytes, 0, sizeof(_bytes));
289 };
290
291 void iterate_metaspace(Metaspace* space, int which) {
292 assert(which == RO || which == RW, "sanity");
293 _which = which;
294 space->iterate(this);
295 }
296
297 virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) {
298 assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity");
299 _counts[_which][type] ++;
300 _bytes [_which][type] += byte_size;
301 }
302
303 void dump_stats(int ro_all, int rw_all, int md_all, int mc_all);
304 };
305
306 void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all) {
307 rw_all += (md_all + mc_all); // md and mc are all mapped Read/Write
308 int other_bytes = md_all + mc_all;
309
310 // Calculate size of data that was not allocated by Metaspace::allocate()
311 int symbol_count = _counts[RO][MetaspaceObj::SymbolType];
312 int symhash_bytes = symbol_count * sizeof (HashtableEntry<Symbol*, mtSymbol>);
313 int symbuck_count = SymbolTable::the_table()->table_size();
314 int symbuck_bytes = symbuck_count * sizeof(HashtableBucket<mtSymbol>);
315
316 _counts[RW][SymbolHashentryType] = symbol_count;
317 _bytes [RW][SymbolHashentryType] = symhash_bytes;
318 other_bytes -= symhash_bytes;
319
320 _counts[RW][SymbolBucketsType] = symbuck_count;
321 _bytes [RW][SymbolBucketsType] = symbuck_bytes;
322 other_bytes -= symbuck_bytes;
323
324 // TODO: count things like dictionary, vtable, etc
325 _bytes[RW][OtherType] = other_bytes;
326
327 // prevent divide-by-zero
328 if (ro_all < 1) {
329 ro_all = 1;
330 }
331 if (rw_all < 1) {
332 rw_all = 1;
333 }
334
335 int all_ro_count = 0;
336 int all_ro_bytes = 0;
337 int all_rw_count = 0;
338 int all_rw_bytes = 0;
339
340 const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f";
341 const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
342 const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %";
343
344 tty->print_cr("Detailed metadata info (rw includes md and mc):");
345 tty->print_cr(hdr);
346 tty->print_cr(sep);
347 for (int type = 0; type < int(_number_of_types); type ++) {
348 const char *name = type_name((Type)type);
349 int ro_count = _counts[RO][type];
350 int ro_bytes = _bytes [RO][type];
351 int rw_count = _counts[RW][type];
352 int rw_bytes = _bytes [RW][type];
353 int count = ro_count + rw_count;
354 int bytes = ro_bytes + rw_bytes;
355
356 double ro_perc = 100.0 * double(ro_bytes) / double(ro_all);
357 double rw_perc = 100.0 * double(rw_bytes) / double(rw_all);
358 double perc = 100.0 * double(bytes) / double(ro_all + rw_all);
359
360 tty->print_cr(fmt, name,
361 ro_count, ro_bytes, ro_perc,
362 rw_count, rw_bytes, rw_perc,
363 count, bytes, perc);
364
365 all_ro_count += ro_count;
366 all_ro_bytes += ro_bytes;
367 all_rw_count += rw_count;
368 all_rw_bytes += rw_bytes;
369 }
370
371 int all_count = all_ro_count + all_rw_count;
372 int all_bytes = all_ro_bytes + all_rw_bytes;
373
374 double all_ro_perc = 100.0 * double(all_ro_bytes) / double(ro_all);
375 double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all);
376 double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all);
377
378 tty->print_cr(sep);
379 tty->print_cr(fmt, "Total",
380 all_ro_count, all_ro_bytes, all_ro_perc,
381 all_rw_count, all_rw_bytes, all_rw_perc,
382 all_count, all_bytes, all_perc);
383
384 assert(all_ro_bytes == ro_all, "everything should have been counted");
385 assert(all_rw_bytes == rw_all, "everything should have been counted");
386 }
246 387
247 // Populate the shared space. 388 // Populate the shared space.
248 389
249 class VM_PopulateDumpSharedSpace: public VM_Operation { 390 class VM_PopulateDumpSharedSpace: public VM_Operation {
250 private: 391 private:
452 SharedMiscCodeSize, 593 SharedMiscCodeSize,
453 true, true); 594 true, true);
454 mapinfo->close(); 595 mapinfo->close();
455 596
456 memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*)); 597 memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
598
599 if (PrintSharedSpaces) {
600 DumpAllocClosure dac;
601 dac.iterate_metaspace(_loader_data->ro_metaspace(), DumpAllocClosure::RO);
602 dac.iterate_metaspace(_loader_data->rw_metaspace(), DumpAllocClosure::RW);
603
604 dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes));
605 }
457 } 606 }
458 607
459 static void link_shared_classes(Klass* obj, TRAPS) { 608 static void link_shared_classes(Klass* obj, TRAPS) {
460 Klass* k = obj; 609 Klass* k = obj;
461 if (k->oop_is_instance()) { 610 if (k->oop_is_instance()) {