Mercurial > hg > truffle
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()) { |