Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/concurrentMark.cpp @ 2435:371bbc844bf1
7027766: G1: introduce flag to dump the liveness information per region at the end of marking
Summary: Repurpose the existing flag G1PrintRegionLivenessInfo to print out the liveness distribution across the regions in the heap at the end of marking.
Reviewed-by: iveresov, jwilhelm
author | tonyp |
---|---|
date | Mon, 04 Apr 2011 14:23:17 -0400 |
parents | 92da084fefc9 |
children | 8f1042ff784d |
comparison
equal
deleted
inserted
replaced
2434:c84ee870e0b9 | 2435:371bbc844bf1 |
---|---|
1201 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0); | 1201 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0); |
1202 _remark_times.add((now - start) * 1000.0); | 1202 _remark_times.add((now - start) * 1000.0); |
1203 | 1203 |
1204 g1p->record_concurrent_mark_remark_end(); | 1204 g1p->record_concurrent_mark_remark_end(); |
1205 } | 1205 } |
1206 | |
1207 | 1206 |
1208 #define CARD_BM_TEST_MODE 0 | 1207 #define CARD_BM_TEST_MODE 0 |
1209 | 1208 |
1210 class CalcLiveObjectsClosure: public HeapRegionClosure { | 1209 class CalcLiveObjectsClosure: public HeapRegionClosure { |
1211 | 1210 |
1723 gclog_or_tty->print_cr("Cleanup:"); | 1722 gclog_or_tty->print_cr("Cleanup:"); |
1724 gclog_or_tty->print_cr(" Finalize counting: %8.3f ms", | 1723 gclog_or_tty->print_cr(" Finalize counting: %8.3f ms", |
1725 this_final_counting_time*1000.0); | 1724 this_final_counting_time*1000.0); |
1726 } | 1725 } |
1727 _total_counting_time += this_final_counting_time; | 1726 _total_counting_time += this_final_counting_time; |
1727 | |
1728 if (G1PrintRegionLivenessInfo) { | |
1729 G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Marking"); | |
1730 _g1h->heap_region_iterate(&cl); | |
1731 } | |
1728 | 1732 |
1729 // Install newly created mark bitMap as "prev". | 1733 // Install newly created mark bitMap as "prev". |
1730 swapMarkBitMaps(); | 1734 swapMarkBitMaps(); |
1731 | 1735 |
1732 g1h->reset_gc_time_stamp(); | 1736 g1h->reset_gc_time_stamp(); |
4421 statsOnly( _clock_due_to_scanning = 0; | 4425 statsOnly( _clock_due_to_scanning = 0; |
4422 _clock_due_to_marking = 0 ); | 4426 _clock_due_to_marking = 0 ); |
4423 | 4427 |
4424 _marking_step_diffs_ms.add(0.5); | 4428 _marking_step_diffs_ms.add(0.5); |
4425 } | 4429 } |
4430 | |
4431 // These are formatting macros that are used below to ensure | |
4432 // consistent formatting. The *_H_* versions are used to format the | |
4433 // header for a particular value and they should be kept consistent | |
4434 // with the corresponding macro. Also note that most of the macros add | |
4435 // the necessary white space (as a prefix) which makes them a bit | |
4436 // easier to compose. | |
4437 | |
4438 // All the output lines are prefixed with this string to be able to | |
4439 // identify them easily in a large log file. | |
4440 #define G1PPRL_LINE_PREFIX "###" | |
4441 | |
4442 #define G1PPRL_ADDR_BASE_FORMAT " "PTR_FORMAT"-"PTR_FORMAT | |
4443 #ifdef _LP64 | |
4444 #define G1PPRL_ADDR_BASE_H_FORMAT " %37s" | |
4445 #else // _LP64 | |
4446 #define G1PPRL_ADDR_BASE_H_FORMAT " %21s" | |
4447 #endif // _LP64 | |
4448 | |
4449 // For per-region info | |
4450 #define G1PPRL_TYPE_FORMAT " %-4s" | |
4451 #define G1PPRL_TYPE_H_FORMAT " %4s" | |
4452 #define G1PPRL_BYTE_FORMAT " "SIZE_FORMAT_W(9) | |
4453 #define G1PPRL_BYTE_H_FORMAT " %9s" | |
4454 #define G1PPRL_DOUBLE_FORMAT " %14.1f" | |
4455 #define G1PPRL_DOUBLE_H_FORMAT " %14s" | |
4456 | |
4457 // For summary info | |
4458 #define G1PPRL_SUM_ADDR_FORMAT(tag) " "tag":"G1PPRL_ADDR_BASE_FORMAT | |
4459 #define G1PPRL_SUM_BYTE_FORMAT(tag) " "tag": "SIZE_FORMAT | |
4460 #define G1PPRL_SUM_MB_FORMAT(tag) " "tag": %1.2f MB" | |
4461 #define G1PPRL_SUM_MB_PERC_FORMAT(tag) G1PPRL_SUM_MB_FORMAT(tag)" / %1.2f %%" | |
4462 | |
4463 G1PrintRegionLivenessInfoClosure:: | |
4464 G1PrintRegionLivenessInfoClosure(outputStream* out, const char* phase_name) | |
4465 : _out(out), | |
4466 _total_used_bytes(0), _total_capacity_bytes(0), | |
4467 _total_prev_live_bytes(0), _total_next_live_bytes(0), | |
4468 _hum_used_bytes(0), _hum_capacity_bytes(0), | |
4469 _hum_prev_live_bytes(0), _hum_next_live_bytes(0) { | |
4470 G1CollectedHeap* g1h = G1CollectedHeap::heap(); | |
4471 MemRegion g1_committed = g1h->g1_committed(); | |
4472 MemRegion g1_reserved = g1h->g1_reserved(); | |
4473 double now = os::elapsedTime(); | |
4474 | |
4475 // Print the header of the output. | |
4476 _out->cr(); | |
4477 _out->print_cr(G1PPRL_LINE_PREFIX" PHASE %s @ %1.3f", phase_name, now); | |
4478 _out->print_cr(G1PPRL_LINE_PREFIX" HEAP" | |
4479 G1PPRL_SUM_ADDR_FORMAT("committed") | |
4480 G1PPRL_SUM_ADDR_FORMAT("reserved") | |
4481 G1PPRL_SUM_BYTE_FORMAT("region-size"), | |
4482 g1_committed.start(), g1_committed.end(), | |
4483 g1_reserved.start(), g1_reserved.end(), | |
4484 HeapRegion::GrainBytes); | |
4485 _out->print_cr(G1PPRL_LINE_PREFIX); | |
4486 _out->print_cr(G1PPRL_LINE_PREFIX | |
4487 G1PPRL_TYPE_H_FORMAT | |
4488 G1PPRL_ADDR_BASE_H_FORMAT | |
4489 G1PPRL_BYTE_H_FORMAT | |
4490 G1PPRL_BYTE_H_FORMAT | |
4491 G1PPRL_BYTE_H_FORMAT | |
4492 G1PPRL_DOUBLE_H_FORMAT, | |
4493 "type", "address-range", | |
4494 "used", "prev-live", "next-live", "gc-eff"); | |
4495 } | |
4496 | |
4497 // It takes as a parameter a reference to one of the _hum_* fields, it | |
4498 // deduces the corresponding value for a region in a humongous region | |
4499 // series (either the region size, or what's left if the _hum_* field | |
4500 // is < the region size), and updates the _hum_* field accordingly. | |
4501 size_t G1PrintRegionLivenessInfoClosure::get_hum_bytes(size_t* hum_bytes) { | |
4502 size_t bytes = 0; | |
4503 // The > 0 check is to deal with the prev and next live bytes which | |
4504 // could be 0. | |
4505 if (*hum_bytes > 0) { | |
4506 bytes = MIN2((size_t) HeapRegion::GrainBytes, *hum_bytes); | |
4507 *hum_bytes -= bytes; | |
4508 } | |
4509 return bytes; | |
4510 } | |
4511 | |
4512 // It deduces the values for a region in a humongous region series | |
4513 // from the _hum_* fields and updates those accordingly. It assumes | |
4514 // that that _hum_* fields have already been set up from the "starts | |
4515 // humongous" region and we visit the regions in address order. | |
4516 void G1PrintRegionLivenessInfoClosure::get_hum_bytes(size_t* used_bytes, | |
4517 size_t* capacity_bytes, | |
4518 size_t* prev_live_bytes, | |
4519 size_t* next_live_bytes) { | |
4520 assert(_hum_used_bytes > 0 && _hum_capacity_bytes > 0, "pre-condition"); | |
4521 *used_bytes = get_hum_bytes(&_hum_used_bytes); | |
4522 *capacity_bytes = get_hum_bytes(&_hum_capacity_bytes); | |
4523 *prev_live_bytes = get_hum_bytes(&_hum_prev_live_bytes); | |
4524 *next_live_bytes = get_hum_bytes(&_hum_next_live_bytes); | |
4525 } | |
4526 | |
4527 bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) { | |
4528 const char* type = ""; | |
4529 HeapWord* bottom = r->bottom(); | |
4530 HeapWord* end = r->end(); | |
4531 size_t capacity_bytes = r->capacity(); | |
4532 size_t used_bytes = r->used(); | |
4533 size_t prev_live_bytes = r->live_bytes(); | |
4534 size_t next_live_bytes = r->next_live_bytes(); | |
4535 double gc_eff = r->gc_efficiency(); | |
4536 if (r->used() == 0) { | |
4537 type = "FREE"; | |
4538 } else if (r->is_survivor()) { | |
4539 type = "SURV"; | |
4540 } else if (r->is_young()) { | |
4541 type = "EDEN"; | |
4542 } else if (r->startsHumongous()) { | |
4543 type = "HUMS"; | |
4544 | |
4545 assert(_hum_used_bytes == 0 && _hum_capacity_bytes == 0 && | |
4546 _hum_prev_live_bytes == 0 && _hum_next_live_bytes == 0, | |
4547 "they should have been zeroed after the last time we used them"); | |
4548 // Set up the _hum_* fields. | |
4549 _hum_capacity_bytes = capacity_bytes; | |
4550 _hum_used_bytes = used_bytes; | |
4551 _hum_prev_live_bytes = prev_live_bytes; | |
4552 _hum_next_live_bytes = next_live_bytes; | |
4553 get_hum_bytes(&used_bytes, &capacity_bytes, | |
4554 &prev_live_bytes, &next_live_bytes); | |
4555 end = bottom + HeapRegion::GrainWords; | |
4556 } else if (r->continuesHumongous()) { | |
4557 type = "HUMC"; | |
4558 get_hum_bytes(&used_bytes, &capacity_bytes, | |
4559 &prev_live_bytes, &next_live_bytes); | |
4560 assert(end == bottom + HeapRegion::GrainWords, "invariant"); | |
4561 } else { | |
4562 type = "OLD"; | |
4563 } | |
4564 | |
4565 _total_used_bytes += used_bytes; | |
4566 _total_capacity_bytes += capacity_bytes; | |
4567 _total_prev_live_bytes += prev_live_bytes; | |
4568 _total_next_live_bytes += next_live_bytes; | |
4569 | |
4570 // Print a line for this particular region. | |
4571 _out->print_cr(G1PPRL_LINE_PREFIX | |
4572 G1PPRL_TYPE_FORMAT | |
4573 G1PPRL_ADDR_BASE_FORMAT | |
4574 G1PPRL_BYTE_FORMAT | |
4575 G1PPRL_BYTE_FORMAT | |
4576 G1PPRL_BYTE_FORMAT | |
4577 G1PPRL_DOUBLE_FORMAT, | |
4578 type, bottom, end, | |
4579 used_bytes, prev_live_bytes, next_live_bytes, gc_eff); | |
4580 | |
4581 return false; | |
4582 } | |
4583 | |
4584 G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { | |
4585 // Print the footer of the output. | |
4586 _out->print_cr(G1PPRL_LINE_PREFIX); | |
4587 _out->print_cr(G1PPRL_LINE_PREFIX | |
4588 " SUMMARY" | |
4589 G1PPRL_SUM_MB_FORMAT("capacity") | |
4590 G1PPRL_SUM_MB_PERC_FORMAT("used") | |
4591 G1PPRL_SUM_MB_PERC_FORMAT("prev-live") | |
4592 G1PPRL_SUM_MB_PERC_FORMAT("next-live"), | |
4593 bytes_to_mb(_total_capacity_bytes), | |
4594 bytes_to_mb(_total_used_bytes), | |
4595 perc(_total_used_bytes, _total_capacity_bytes), | |
4596 bytes_to_mb(_total_prev_live_bytes), | |
4597 perc(_total_prev_live_bytes, _total_capacity_bytes), | |
4598 bytes_to_mb(_total_next_live_bytes), | |
4599 perc(_total_next_live_bytes, _total_capacity_bytes)); | |
4600 _out->cr(); | |
4601 } |