OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/gc-tracer.h" | 5 #include "src/heap/gc-tracer.h" |
6 | 6 |
7 #include "src/counters.h" | 7 #include "src/counters.h" |
8 #include "src/heap/heap-inl.h" | 8 #include "src/heap/heap-inl.h" |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
10 | 10 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 i <= Scope::LAST_INCREMENTAL_SCOPE; i++) { | 221 i <= Scope::LAST_INCREMENTAL_SCOPE; i++) { |
222 current_.scopes[i] = | 222 current_.scopes[i] = |
223 current_.incremental_marking_scopes[i].cumulative_duration - | 223 current_.incremental_marking_scopes[i].cumulative_duration - |
224 baseline.incremental_marking_scopes[i].cumulative_duration; | 224 baseline.incremental_marking_scopes[i].cumulative_duration; |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 void GCTracer::Stop(GarbageCollector collector) { | 228 void GCTracer::Stop(GarbageCollector collector) { |
229 start_counter_--; | 229 start_counter_--; |
230 if (start_counter_ != 0) { | 230 if (start_counter_ != 0) { |
231 PrintIsolate(heap_->isolate(), "[Finished reentrant %s during %s.]\n", | 231 heap_->isolate()->PrintWithTimestamp( |
232 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", | 232 "[Finished reentrant %s during %s.]\n", |
233 current_.TypeName(false)); | 233 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", |
| 234 current_.TypeName(false)); |
234 return; | 235 return; |
235 } | 236 } |
236 | 237 |
237 DCHECK(start_counter_ >= 0); | 238 DCHECK(start_counter_ >= 0); |
238 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || | 239 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || |
239 (collector == MARK_COMPACTOR && | 240 (collector == MARK_COMPACTOR && |
240 (current_.type == Event::MARK_COMPACTOR || | 241 (current_.type == Event::MARK_COMPACTOR || |
241 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); | 242 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); |
242 | 243 |
243 for (int i = Scope::FIRST_INCREMENTAL_SCOPE; | 244 for (int i = Scope::FIRST_INCREMENTAL_SCOPE; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 | 402 |
402 heap_->AddToRingBuffer(buffer.start()); | 403 heap_->AddToRingBuffer(buffer.start()); |
403 } | 404 } |
404 | 405 |
405 | 406 |
406 void GCTracer::Print() const { | 407 void GCTracer::Print() const { |
407 double duration = current_.end_time - current_.start_time; | 408 double duration = current_.end_time - current_.start_time; |
408 const size_t kIncrementalStatsSize = 128; | 409 const size_t kIncrementalStatsSize = 128; |
409 char incremental_buffer[kIncrementalStatsSize] = {0}; | 410 char incremental_buffer[kIncrementalStatsSize] = {0}; |
410 | 411 |
411 if (current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps > 0) { | 412 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { |
412 if (current_.type == Event::SCAVENGER) { | 413 base::OS::SNPrintF( |
413 base::OS::SNPrintF( | 414 incremental_buffer, kIncrementalStatsSize, |
414 incremental_buffer, kIncrementalStatsSize, | 415 " (+ %.1f ms in %d steps since start of marking, " |
415 " (+ %.1f ms in %d steps since last GC)", | 416 "biggest step %.1f ms, walltime since start of marking %.f ms)", |
416 current_.scopes[Scope::MC_INCREMENTAL], | 417 current_.scopes[Scope::MC_INCREMENTAL], |
417 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps); | 418 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps, |
418 } else { | 419 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].longest_step, |
419 base::OS::SNPrintF( | 420 current_.end_time - incremental_marking_start_time_); |
420 incremental_buffer, kIncrementalStatsSize, | |
421 " (+ %.1f ms in %d steps since start of marking, " | |
422 "biggest step %.1f ms)", | |
423 current_.scopes[Scope::MC_INCREMENTAL], | |
424 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps, | |
425 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL] | |
426 .longest_step); | |
427 } | |
428 } | 421 } |
429 | 422 |
430 // Avoid PrintF as Output also appends the string to the tracing ring buffer | 423 // Avoid PrintF as Output also appends the string to the tracing ring buffer |
431 // that gets printed on OOM failures. | 424 // that gets printed on OOM failures. |
432 Output( | 425 Output( |
433 "[%d:%p] " | 426 "[%d:%p] " |
434 "%8.0f ms: " | 427 "%8.0f ms: " |
435 "%s %.1f (%.1f) -> %.1f (%.1f) MB, " | 428 "%s %.1f (%.1f) -> %.1f (%.1f) MB, " |
436 "%.1f / %.1f ms %s %s %s\n", | 429 "%.1f / %.1f ms %s %s %s\n", |
437 base::OS::GetCurrentProcessId(), | 430 base::OS::GetCurrentProcessId(), |
438 reinterpret_cast<void*>(heap_->isolate()), | 431 reinterpret_cast<void*>(heap_->isolate()), |
439 heap_->isolate()->time_millis_since_init(), current_.TypeName(false), | 432 heap_->isolate()->time_millis_since_init(), current_.TypeName(false), |
440 static_cast<double>(current_.start_object_size) / MB, | 433 static_cast<double>(current_.start_object_size) / MB, |
441 static_cast<double>(current_.start_memory_size) / MB, | 434 static_cast<double>(current_.start_memory_size) / MB, |
442 static_cast<double>(current_.end_object_size) / MB, | 435 static_cast<double>(current_.end_object_size) / MB, |
443 static_cast<double>(current_.end_memory_size) / MB, duration, | 436 static_cast<double>(current_.end_memory_size) / MB, duration, |
444 TotalExternalTime(), incremental_buffer, | 437 TotalExternalTime(), incremental_buffer, |
445 current_.gc_reason != nullptr ? current_.gc_reason : "", | 438 current_.gc_reason != nullptr ? current_.gc_reason : "", |
446 current_.collector_reason != nullptr ? current_.collector_reason : ""); | 439 current_.collector_reason != nullptr ? current_.collector_reason : ""); |
447 } | 440 } |
448 | 441 |
449 | 442 |
450 void GCTracer::PrintNVP() const { | 443 void GCTracer::PrintNVP() const { |
451 double duration = current_.end_time - current_.start_time; | 444 double duration = current_.end_time - current_.start_time; |
452 double spent_in_mutator = current_.start_time - previous_.end_time; | 445 double spent_in_mutator = current_.start_time - previous_.end_time; |
453 intptr_t allocated_since_last_gc = | 446 intptr_t allocated_since_last_gc = |
454 current_.start_object_size - previous_.end_object_size; | 447 current_.start_object_size - previous_.end_object_size; |
455 | 448 |
| 449 double incremental_walltime_duration = 0; |
| 450 |
| 451 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { |
| 452 incremental_walltime_duration = |
| 453 current_.end_time - incremental_marking_start_time_; |
| 454 } |
| 455 |
456 switch (current_.type) { | 456 switch (current_.type) { |
457 case Event::SCAVENGER: | 457 case Event::SCAVENGER: |
458 PrintIsolate( | 458 heap_->isolate()->PrintWithTimestamp( |
459 heap_->isolate(), | |
460 "%8.0f ms: " | |
461 "pause=%.1f " | 459 "pause=%.1f " |
462 "mutator=%.1f " | 460 "mutator=%.1f " |
463 "gc=%s " | 461 "gc=%s " |
464 "reduce_memory=%d " | 462 "reduce_memory=%d " |
465 "scavenge=%.2f " | 463 "scavenge=%.2f " |
466 "old_new=%.2f " | 464 "old_new=%.2f " |
467 "weak=%.2f " | 465 "weak=%.2f " |
468 "roots=%.2f " | 466 "roots=%.2f " |
469 "code=%.2f " | 467 "code=%.2f " |
470 "semispace=%.2f " | 468 "semispace=%.2f " |
(...skipping 20 matching lines...) Expand all Loading... |
491 " " | 489 " " |
492 "nodes_died_in_new=%d " | 490 "nodes_died_in_new=%d " |
493 "nodes_copied_in_new=%d " | 491 "nodes_copied_in_new=%d " |
494 "nodes_promoted=%d " | 492 "nodes_promoted=%d " |
495 "promotion_ratio=%.1f%% " | 493 "promotion_ratio=%.1f%% " |
496 "average_survival_ratio=%.1f%% " | 494 "average_survival_ratio=%.1f%% " |
497 "promotion_rate=%.1f%% " | 495 "promotion_rate=%.1f%% " |
498 "semi_space_copy_rate=%.1f%% " | 496 "semi_space_copy_rate=%.1f%% " |
499 "new_space_allocation_throughput=%.1f " | 497 "new_space_allocation_throughput=%.1f " |
500 "context_disposal_rate=%.1f\n", | 498 "context_disposal_rate=%.1f\n", |
501 heap_->isolate()->time_millis_since_init(), duration, | 499 duration, spent_in_mutator, current_.TypeName(true), |
502 spent_in_mutator, current_.TypeName(true), current_.reduce_memory, | 500 current_.reduce_memory, current_.scopes[Scope::SCAVENGER_SCAVENGE], |
503 current_.scopes[Scope::SCAVENGER_SCAVENGE], | |
504 current_.scopes[Scope::SCAVENGER_OLD_TO_NEW_POINTERS], | 501 current_.scopes[Scope::SCAVENGER_OLD_TO_NEW_POINTERS], |
505 current_.scopes[Scope::SCAVENGER_WEAK], | 502 current_.scopes[Scope::SCAVENGER_WEAK], |
506 current_.scopes[Scope::SCAVENGER_ROOTS], | 503 current_.scopes[Scope::SCAVENGER_ROOTS], |
507 current_.scopes[Scope::SCAVENGER_CODE_FLUSH_CANDIDATES], | 504 current_.scopes[Scope::SCAVENGER_CODE_FLUSH_CANDIDATES], |
508 current_.scopes[Scope::SCAVENGER_SEMISPACE], | 505 current_.scopes[Scope::SCAVENGER_SEMISPACE], |
509 current_.scopes[Scope::SCAVENGER_OBJECT_GROUPS], | 506 current_.scopes[Scope::SCAVENGER_OBJECT_GROUPS], |
510 current_.scopes[Scope::SCAVENGER_EXTERNAL_PROLOGUE], | 507 current_.scopes[Scope::SCAVENGER_EXTERNAL_PROLOGUE], |
511 current_.scopes[Scope::SCAVENGER_EXTERNAL_EPILOGUE], | 508 current_.scopes[Scope::SCAVENGER_EXTERNAL_EPILOGUE], |
512 current_.scopes[Scope::EXTERNAL_WEAK_GLOBAL_HANDLES], | 509 current_.scopes[Scope::EXTERNAL_WEAK_GLOBAL_HANDLES], |
513 current_.incremental_marking_scopes[GCTracer::Scope::MC_INCREMENTAL] | 510 current_.incremental_marking_scopes[GCTracer::Scope::MC_INCREMENTAL] |
514 .steps, | 511 .steps, |
515 current_.scopes[Scope::MC_INCREMENTAL], | 512 current_.scopes[Scope::MC_INCREMENTAL], |
516 ScavengeSpeedInBytesPerMillisecond(), current_.start_object_size, | 513 ScavengeSpeedInBytesPerMillisecond(), current_.start_object_size, |
517 current_.end_object_size, current_.start_holes_size, | 514 current_.end_object_size, current_.start_holes_size, |
518 current_.end_holes_size, allocated_since_last_gc, | 515 current_.end_holes_size, allocated_since_last_gc, |
519 heap_->promoted_objects_size(), | 516 heap_->promoted_objects_size(), |
520 heap_->semi_space_copied_object_size(), | 517 heap_->semi_space_copied_object_size(), |
521 heap_->nodes_died_in_new_space_, heap_->nodes_copied_in_new_space_, | 518 heap_->nodes_died_in_new_space_, heap_->nodes_copied_in_new_space_, |
522 heap_->nodes_promoted_, heap_->promotion_ratio_, | 519 heap_->nodes_promoted_, heap_->promotion_ratio_, |
523 AverageSurvivalRatio(), heap_->promotion_rate_, | 520 AverageSurvivalRatio(), heap_->promotion_rate_, |
524 heap_->semi_space_copied_rate_, | 521 heap_->semi_space_copied_rate_, |
525 NewSpaceAllocationThroughputInBytesPerMillisecond(), | 522 NewSpaceAllocationThroughputInBytesPerMillisecond(), |
526 ContextDisposalRateInMilliseconds()); | 523 ContextDisposalRateInMilliseconds()); |
527 break; | 524 break; |
528 case Event::MARK_COMPACTOR: | 525 case Event::MARK_COMPACTOR: |
529 case Event::INCREMENTAL_MARK_COMPACTOR: | 526 case Event::INCREMENTAL_MARK_COMPACTOR: |
530 PrintIsolate( | 527 heap_->isolate()->PrintWithTimestamp( |
531 heap_->isolate(), | |
532 "%8.0f ms: " | |
533 "pause=%.1f " | 528 "pause=%.1f " |
534 "mutator=%.1f " | 529 "mutator=%.1f " |
535 "gc=%s " | 530 "gc=%s " |
536 "reduce_memory=%d " | 531 "reduce_memory=%d " |
537 "clear=%1.f " | 532 "clear=%1.f " |
538 "clear.code_flush=%.1f " | 533 "clear.code_flush=%.1f " |
539 "clear.dependent_code=%.1f " | 534 "clear.dependent_code=%.1f " |
540 "clear.global_handles=%.1f " | 535 "clear.global_handles=%.1f " |
541 "clear.maps=%.1f " | 536 "clear.maps=%.1f " |
542 "clear.slots_buffer=%.1f " | 537 "clear.slots_buffer=%.1f " |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 "incremental.finalize.external.epilogue=%.1f " | 576 "incremental.finalize.external.epilogue=%.1f " |
582 "incremental.finalize.object_grouping=%.1f " | 577 "incremental.finalize.object_grouping=%.1f " |
583 "incremental.wrapper_prologue=%.1f " | 578 "incremental.wrapper_prologue=%.1f " |
584 "incremental.wrapper_tracing=%.1f " | 579 "incremental.wrapper_tracing=%.1f " |
585 "incremental_wrapper_tracing_longest_step=%.1f " | 580 "incremental_wrapper_tracing_longest_step=%.1f " |
586 "incremental_finalize_longest_step=%.1f " | 581 "incremental_finalize_longest_step=%.1f " |
587 "incremental_finalize_steps_count=%d " | 582 "incremental_finalize_steps_count=%d " |
588 "incremental_longest_step=%.1f " | 583 "incremental_longest_step=%.1f " |
589 "incremental_steps_count=%d " | 584 "incremental_steps_count=%d " |
590 "incremental_marking_throughput=%.f " | 585 "incremental_marking_throughput=%.f " |
| 586 "incremental_walltime_duration=%.f " |
591 "total_size_before=%" V8PRIdPTR | 587 "total_size_before=%" V8PRIdPTR |
592 " " | 588 " " |
593 "total_size_after=%" V8PRIdPTR | 589 "total_size_after=%" V8PRIdPTR |
594 " " | 590 " " |
595 "holes_size_before=%" V8PRIdPTR | 591 "holes_size_before=%" V8PRIdPTR |
596 " " | 592 " " |
597 "holes_size_after=%" V8PRIdPTR | 593 "holes_size_after=%" V8PRIdPTR |
598 " " | 594 " " |
599 "allocated=%" V8PRIdPTR | 595 "allocated=%" V8PRIdPTR |
600 " " | 596 " " |
601 "promoted=%" V8PRIdPTR | 597 "promoted=%" V8PRIdPTR |
602 " " | 598 " " |
603 "semi_space_copied=%" V8PRIdPTR | 599 "semi_space_copied=%" V8PRIdPTR |
604 " " | 600 " " |
605 "nodes_died_in_new=%d " | 601 "nodes_died_in_new=%d " |
606 "nodes_copied_in_new=%d " | 602 "nodes_copied_in_new=%d " |
607 "nodes_promoted=%d " | 603 "nodes_promoted=%d " |
608 "promotion_ratio=%.1f%% " | 604 "promotion_ratio=%.1f%% " |
609 "average_survival_ratio=%.1f%% " | 605 "average_survival_ratio=%.1f%% " |
610 "promotion_rate=%.1f%% " | 606 "promotion_rate=%.1f%% " |
611 "semi_space_copy_rate=%.1f%% " | 607 "semi_space_copy_rate=%.1f%% " |
612 "new_space_allocation_throughput=%.1f " | 608 "new_space_allocation_throughput=%.1f " |
613 "context_disposal_rate=%.1f " | 609 "context_disposal_rate=%.1f " |
614 "compaction_speed=%.f\n", | 610 "compaction_speed=%.f\n", |
615 heap_->isolate()->time_millis_since_init(), duration, | 611 duration, spent_in_mutator, current_.TypeName(true), |
616 spent_in_mutator, current_.TypeName(true), current_.reduce_memory, | 612 current_.reduce_memory, current_.scopes[Scope::MC_CLEAR], |
617 current_.scopes[Scope::MC_CLEAR], | |
618 current_.scopes[Scope::MC_CLEAR_CODE_FLUSH], | 613 current_.scopes[Scope::MC_CLEAR_CODE_FLUSH], |
619 current_.scopes[Scope::MC_CLEAR_DEPENDENT_CODE], | 614 current_.scopes[Scope::MC_CLEAR_DEPENDENT_CODE], |
620 current_.scopes[Scope::MC_CLEAR_GLOBAL_HANDLES], | 615 current_.scopes[Scope::MC_CLEAR_GLOBAL_HANDLES], |
621 current_.scopes[Scope::MC_CLEAR_MAPS], | 616 current_.scopes[Scope::MC_CLEAR_MAPS], |
622 current_.scopes[Scope::MC_CLEAR_SLOTS_BUFFER], | 617 current_.scopes[Scope::MC_CLEAR_SLOTS_BUFFER], |
623 current_.scopes[Scope::MC_CLEAR_STORE_BUFFER], | 618 current_.scopes[Scope::MC_CLEAR_STORE_BUFFER], |
624 current_.scopes[Scope::MC_CLEAR_STRING_TABLE], | 619 current_.scopes[Scope::MC_CLEAR_STRING_TABLE], |
625 current_.scopes[Scope::MC_CLEAR_WEAK_CELLS], | 620 current_.scopes[Scope::MC_CLEAR_WEAK_CELLS], |
626 current_.scopes[Scope::MC_CLEAR_WEAK_COLLECTIONS], | 621 current_.scopes[Scope::MC_CLEAR_WEAK_COLLECTIONS], |
627 current_.scopes[Scope::MC_CLEAR_WEAK_LISTS], | 622 current_.scopes[Scope::MC_CLEAR_WEAK_LISTS], |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 current_ | 662 current_ |
668 .incremental_marking_scopes[Scope::MC_INCREMENTAL_FINALIZE_BODY] | 663 .incremental_marking_scopes[Scope::MC_INCREMENTAL_FINALIZE_BODY] |
669 .longest_step, | 664 .longest_step, |
670 current_ | 665 current_ |
671 .incremental_marking_scopes[Scope::MC_INCREMENTAL_FINALIZE_BODY] | 666 .incremental_marking_scopes[Scope::MC_INCREMENTAL_FINALIZE_BODY] |
672 .steps, | 667 .steps, |
673 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL] | 668 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL] |
674 .longest_step, | 669 .longest_step, |
675 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps, | 670 current_.incremental_marking_scopes[Scope::MC_INCREMENTAL].steps, |
676 IncrementalMarkingSpeedInBytesPerMillisecond(), | 671 IncrementalMarkingSpeedInBytesPerMillisecond(), |
677 current_.start_object_size, current_.end_object_size, | 672 incremental_walltime_duration, current_.start_object_size, |
678 current_.start_holes_size, current_.end_holes_size, | 673 current_.end_object_size, current_.start_holes_size, |
679 allocated_since_last_gc, heap_->promoted_objects_size(), | 674 current_.end_holes_size, allocated_since_last_gc, |
| 675 heap_->promoted_objects_size(), |
680 heap_->semi_space_copied_object_size(), | 676 heap_->semi_space_copied_object_size(), |
681 heap_->nodes_died_in_new_space_, heap_->nodes_copied_in_new_space_, | 677 heap_->nodes_died_in_new_space_, heap_->nodes_copied_in_new_space_, |
682 heap_->nodes_promoted_, heap_->promotion_ratio_, | 678 heap_->nodes_promoted_, heap_->promotion_ratio_, |
683 AverageSurvivalRatio(), heap_->promotion_rate_, | 679 AverageSurvivalRatio(), heap_->promotion_rate_, |
684 heap_->semi_space_copied_rate_, | 680 heap_->semi_space_copied_rate_, |
685 NewSpaceAllocationThroughputInBytesPerMillisecond(), | 681 NewSpaceAllocationThroughputInBytesPerMillisecond(), |
686 ContextDisposalRateInMilliseconds(), | 682 ContextDisposalRateInMilliseconds(), |
687 CompactionSpeedInBytesPerMillisecond()); | 683 CompactionSpeedInBytesPerMillisecond()); |
688 break; | 684 break; |
689 case Event::START: | 685 case Event::START: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 double sum = recorded_survival_ratios_.Sum( | 810 double sum = recorded_survival_ratios_.Sum( |
815 [](double a, double b) { return a + b; }, 0.0); | 811 [](double a, double b) { return a + b; }, 0.0); |
816 return sum / recorded_survival_ratios_.Count(); | 812 return sum / recorded_survival_ratios_.Count(); |
817 } | 813 } |
818 | 814 |
819 bool GCTracer::SurvivalEventsRecorded() const { | 815 bool GCTracer::SurvivalEventsRecorded() const { |
820 return recorded_survival_ratios_.Count() > 0; | 816 return recorded_survival_ratios_.Count() > 0; |
821 } | 817 } |
822 | 818 |
823 void GCTracer::ResetSurvivalEvents() { recorded_survival_ratios_.Reset(); } | 819 void GCTracer::ResetSurvivalEvents() { recorded_survival_ratios_.Reset(); } |
| 820 |
| 821 void GCTracer::NotifyIncrementalMarkingStart() { |
| 822 incremental_marking_start_time_ = heap_->MonotonicallyIncreasingTimeInMs(); |
| 823 } |
| 824 |
824 } // namespace internal | 825 } // namespace internal |
825 } // namespace v8 | 826 } // namespace v8 |
OLD | NEW |