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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes; | 328 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes; |
329 allocation_duration_since_gc_ += duration; | 329 allocation_duration_since_gc_ += duration; |
330 new_space_allocation_in_bytes_since_gc_ += new_space_allocated_bytes; | 330 new_space_allocation_in_bytes_since_gc_ += new_space_allocated_bytes; |
331 old_generation_allocation_in_bytes_since_gc_ += | 331 old_generation_allocation_in_bytes_since_gc_ += |
332 old_generation_allocated_bytes; | 332 old_generation_allocated_bytes; |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 void GCTracer::AddAllocation(double current_ms) { | 336 void GCTracer::AddAllocation(double current_ms) { |
337 allocation_time_ms_ = current_ms; | 337 allocation_time_ms_ = current_ms; |
338 new_space_allocation_events_.push_front(AllocationEvent( | 338 if (allocation_duration_since_gc_ > 0) { |
339 allocation_duration_since_gc_, new_space_allocation_in_bytes_since_gc_)); | 339 new_space_allocation_events_.push_front( |
340 old_generation_allocation_events_.push_front( | 340 AllocationEvent(allocation_duration_since_gc_, |
341 AllocationEvent(allocation_duration_since_gc_, | 341 new_space_allocation_in_bytes_since_gc_)); |
342 old_generation_allocation_in_bytes_since_gc_)); | 342 old_generation_allocation_events_.push_front( |
| 343 AllocationEvent(allocation_duration_since_gc_, |
| 344 old_generation_allocation_in_bytes_since_gc_)); |
| 345 } |
343 allocation_duration_since_gc_ = 0; | 346 allocation_duration_since_gc_ = 0; |
344 new_space_allocation_in_bytes_since_gc_ = 0; | 347 new_space_allocation_in_bytes_since_gc_ = 0; |
345 old_generation_allocation_in_bytes_since_gc_ = 0; | 348 old_generation_allocation_in_bytes_since_gc_ = 0; |
346 } | 349 } |
347 | 350 |
348 | 351 |
349 void GCTracer::AddContextDisposalTime(double time) { | 352 void GCTracer::AddContextDisposalTime(double time) { |
350 context_disposal_events_.push_front(ContextDisposalEvent(time)); | 353 context_disposal_events_.push_front(ContextDisposalEvent(time)); |
351 } | 354 } |
352 | 355 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 "mutator=%.1f " | 465 "mutator=%.1f " |
463 "gc=%s " | 466 "gc=%s " |
464 "reduce_memory=%d " | 467 "reduce_memory=%d " |
465 "scavenge=%.2f " | 468 "scavenge=%.2f " |
466 "old_new=%.2f " | 469 "old_new=%.2f " |
467 "weak=%.2f " | 470 "weak=%.2f " |
468 "roots=%.2f " | 471 "roots=%.2f " |
469 "code=%.2f " | 472 "code=%.2f " |
470 "semispace=%.2f " | 473 "semispace=%.2f " |
471 "object_groups=%.2f " | 474 "object_groups=%.2f " |
472 "external_prologue=$.2f " | 475 "external_prologue=%.2f " |
473 "external_epilogue=$.2f " | 476 "external_epilogue=%.2f " |
474 "external_weak_global_handles=$.2f " | 477 "external_weak_global_handles=%.2f " |
475 "steps_count=%d " | 478 "steps_count=%d " |
476 "steps_took=%.1f " | 479 "steps_took=%.1f " |
477 "scavenge_throughput=%" V8_PTR_PREFIX | 480 "scavenge_throughput=%" V8_PTR_PREFIX |
478 "d " | 481 "d " |
479 "total_size_before=%" V8_PTR_PREFIX | 482 "total_size_before=%" V8_PTR_PREFIX |
480 "d " | 483 "d " |
481 "total_size_after=%" V8_PTR_PREFIX | 484 "total_size_after=%" V8_PTR_PREFIX |
482 "d " | 485 "d " |
483 "holes_size_before=%" V8_PTR_PREFIX | 486 "holes_size_before=%" V8_PTR_PREFIX |
484 "d " | 487 "d " |
485 "holes_size_after=%" V8_PTR_PREFIX | 488 "holes_size_after=%" V8_PTR_PREFIX |
486 "d " | 489 "d " |
487 "allocated=%" V8_PTR_PREFIX | 490 "allocated=%" V8_PTR_PREFIX |
488 "d " | 491 "d " |
489 "promoted=%" V8_PTR_PREFIX | 492 "promoted=%" V8_PTR_PREFIX |
490 "d " | 493 "d " |
491 "semi_space_copied=%" V8_PTR_PREFIX | 494 "semi_space_copied=%" V8_PTR_PREFIX |
492 "d " | 495 "d " |
493 "nodes_died_in_new=%d " | 496 "nodes_died_in_new=%d " |
494 "nodes_copied_in_new=%d " | 497 "nodes_copied_in_new=%d " |
495 "nodes_promoted=%d " | 498 "nodes_promoted=%d " |
496 "promotion_ratio=%.1f%% " | 499 "promotion_ratio=%.1f%% " |
497 "average_survival_ratio=%.1f%% " | 500 "average_survival_ratio=%.1f%% " |
498 "promotion_rate=%.1f%% " | 501 "promotion_rate=%.1f%% " |
499 "semi_space_copy_rate=%.1f%% " | 502 "semi_space_copy_rate=%.1f%% " |
500 "new_space_allocation_throughput=%" V8_PTR_PREFIX | 503 "new_space_allocation_throughput=%.1f " |
501 "d " | |
502 "context_disposal_rate=%.1f\n", | 504 "context_disposal_rate=%.1f\n", |
503 heap_->isolate()->time_millis_since_init(), duration, | 505 heap_->isolate()->time_millis_since_init(), duration, |
504 spent_in_mutator, current_.TypeName(true), | 506 spent_in_mutator, current_.TypeName(true), |
505 current_.reduce_memory, | 507 current_.reduce_memory, |
506 current_.scopes[Scope::SCAVENGER_SCAVENGE], | 508 current_.scopes[Scope::SCAVENGER_SCAVENGE], |
507 current_.scopes[Scope::SCAVENGER_OLD_TO_NEW_POINTERS], | 509 current_.scopes[Scope::SCAVENGER_OLD_TO_NEW_POINTERS], |
508 current_.scopes[Scope::SCAVENGER_WEAK], | 510 current_.scopes[Scope::SCAVENGER_WEAK], |
509 current_.scopes[Scope::SCAVENGER_ROOTS], | 511 current_.scopes[Scope::SCAVENGER_ROOTS], |
510 current_.scopes[Scope::SCAVENGER_CODE_FLUSH_CANDIDATES], | 512 current_.scopes[Scope::SCAVENGER_CODE_FLUSH_CANDIDATES], |
511 current_.scopes[Scope::SCAVENGER_SEMISPACE], | 513 current_.scopes[Scope::SCAVENGER_SEMISPACE], |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 "d " | 596 "d " |
595 "semi_space_copied=%" V8_PTR_PREFIX | 597 "semi_space_copied=%" V8_PTR_PREFIX |
596 "d " | 598 "d " |
597 "nodes_died_in_new=%d " | 599 "nodes_died_in_new=%d " |
598 "nodes_copied_in_new=%d " | 600 "nodes_copied_in_new=%d " |
599 "nodes_promoted=%d " | 601 "nodes_promoted=%d " |
600 "promotion_ratio=%.1f%% " | 602 "promotion_ratio=%.1f%% " |
601 "average_survival_ratio=%.1f%% " | 603 "average_survival_ratio=%.1f%% " |
602 "promotion_rate=%.1f%% " | 604 "promotion_rate=%.1f%% " |
603 "semi_space_copy_rate=%.1f%% " | 605 "semi_space_copy_rate=%.1f%% " |
604 "new_space_allocation_throughput=%" V8_PTR_PREFIX | 606 "new_space_allocation_throughput=%.1f " |
605 "d " | |
606 "context_disposal_rate=%.1f " | 607 "context_disposal_rate=%.1f " |
607 "compaction_speed=%" V8_PTR_PREFIX "d\n", | 608 "compaction_speed=%" V8_PTR_PREFIX "d\n", |
608 heap_->isolate()->time_millis_since_init(), duration, | 609 heap_->isolate()->time_millis_since_init(), duration, |
609 spent_in_mutator, current_.TypeName(true), current_.reduce_memory, | 610 spent_in_mutator, current_.TypeName(true), current_.reduce_memory, |
610 current_.scopes[Scope::MC_CLEAR], | 611 current_.scopes[Scope::MC_CLEAR], |
611 current_.scopes[Scope::MC_CLEAR_CODE_FLUSH], | 612 current_.scopes[Scope::MC_CLEAR_CODE_FLUSH], |
612 current_.scopes[Scope::MC_CLEAR_DEPENDENT_CODE], | 613 current_.scopes[Scope::MC_CLEAR_DEPENDENT_CODE], |
613 current_.scopes[Scope::MC_CLEAR_GLOBAL_HANDLES], | 614 current_.scopes[Scope::MC_CLEAR_GLOBAL_HANDLES], |
614 current_.scopes[Scope::MC_CLEAR_MAPS], | 615 current_.scopes[Scope::MC_CLEAR_MAPS], |
615 current_.scopes[Scope::MC_CLEAR_SLOTS_BUFFER], | 616 current_.scopes[Scope::MC_CLEAR_SLOTS_BUFFER], |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 combined_mark_compact_speed_cache_ = | 805 combined_mark_compact_speed_cache_ = |
805 static_cast<double>(MarkCompactSpeedInBytesPerMillisecond()); | 806 static_cast<double>(MarkCompactSpeedInBytesPerMillisecond()); |
806 } else { | 807 } else { |
807 // Combine the speed of incremental step and the speed of the final step. | 808 // Combine the speed of incremental step and the speed of the final step. |
808 // 1 / (1 / speed1 + 1 / speed2) = speed1 * speed2 / (speed1 + speed2). | 809 // 1 / (1 / speed1 + 1 / speed2) = speed1 * speed2 / (speed1 + speed2). |
809 combined_mark_compact_speed_cache_ = speed1 * speed2 / (speed1 + speed2); | 810 combined_mark_compact_speed_cache_ = speed1 * speed2 / (speed1 + speed2); |
810 } | 811 } |
811 return combined_mark_compact_speed_cache_; | 812 return combined_mark_compact_speed_cache_; |
812 } | 813 } |
813 | 814 |
814 | 815 double GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond( |
815 size_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond( | |
816 double time_ms) const { | 816 double time_ms) const { |
817 size_t bytes = new_space_allocation_in_bytes_since_gc_; | 817 size_t bytes = new_space_allocation_in_bytes_since_gc_; |
818 double durations = allocation_duration_since_gc_; | 818 double durations = allocation_duration_since_gc_; |
819 AllocationEventBuffer::const_iterator iter = | 819 AllocationEventBuffer::const_iterator iter = |
820 new_space_allocation_events_.begin(); | 820 new_space_allocation_events_.begin(); |
821 const size_t max_bytes = static_cast<size_t>(-1); | 821 const size_t max_bytes = static_cast<size_t>(-1); |
822 while (iter != new_space_allocation_events_.end() && | 822 while (iter != new_space_allocation_events_.end() && |
823 bytes < max_bytes - bytes && (time_ms == 0 || durations < time_ms)) { | 823 bytes < max_bytes - bytes && (time_ms == 0 || durations < time_ms)) { |
824 bytes += iter->allocation_in_bytes_; | 824 bytes += iter->allocation_in_bytes_; |
825 durations += iter->duration_; | 825 durations += iter->duration_; |
826 ++iter; | 826 ++iter; |
827 } | 827 } |
828 | 828 |
829 if (durations == 0.0) return 0; | 829 if (durations == 0.0) return 0; |
| 830 |
830 // Make sure the result is at least 1. | 831 // Make sure the result is at least 1. |
831 return Max<size_t>(static_cast<size_t>(bytes / durations + 0.5), 1); | 832 return Max<double>(bytes / durations, 1); |
832 } | 833 } |
833 | 834 |
834 | 835 double GCTracer::OldGenerationAllocationThroughputInBytesPerMillisecond( |
835 size_t GCTracer::OldGenerationAllocationThroughputInBytesPerMillisecond( | |
836 double time_ms) const { | 836 double time_ms) const { |
837 size_t bytes = old_generation_allocation_in_bytes_since_gc_; | 837 size_t bytes = old_generation_allocation_in_bytes_since_gc_; |
838 double durations = allocation_duration_since_gc_; | 838 double durations = allocation_duration_since_gc_; |
839 AllocationEventBuffer::const_iterator iter = | 839 AllocationEventBuffer::const_iterator iter = |
840 old_generation_allocation_events_.begin(); | 840 old_generation_allocation_events_.begin(); |
841 const size_t max_bytes = static_cast<size_t>(-1); | 841 const size_t max_bytes = static_cast<size_t>(-1); |
842 while (iter != old_generation_allocation_events_.end() && | 842 while (iter != old_generation_allocation_events_.end() && |
843 bytes < max_bytes - bytes && (time_ms == 0 || durations < time_ms)) { | 843 bytes < max_bytes - bytes && (time_ms == 0 || durations < time_ms)) { |
844 bytes += iter->allocation_in_bytes_; | 844 bytes += iter->allocation_in_bytes_; |
845 durations += iter->duration_; | 845 durations += iter->duration_; |
846 ++iter; | 846 ++iter; |
847 } | 847 } |
848 | 848 |
849 if (durations == 0.0) return 0; | 849 if (durations == 0.0) return 0; |
850 // Make sure the result is at least 1. | 850 // Make sure the result is at least 1. |
851 return Max<size_t>(static_cast<size_t>(bytes / durations + 0.5), 1); | 851 return Max<double>(bytes / durations, 1); |
852 } | 852 } |
853 | 853 |
854 | 854 double GCTracer::AllocationThroughputInBytesPerMillisecond( |
855 size_t GCTracer::AllocationThroughputInBytesPerMillisecond( | |
856 double time_ms) const { | 855 double time_ms) const { |
857 return NewSpaceAllocationThroughputInBytesPerMillisecond(time_ms) + | 856 return NewSpaceAllocationThroughputInBytesPerMillisecond(time_ms) + |
858 OldGenerationAllocationThroughputInBytesPerMillisecond(time_ms); | 857 OldGenerationAllocationThroughputInBytesPerMillisecond(time_ms); |
859 } | 858 } |
860 | 859 |
861 | 860 |
862 size_t GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const { | 861 size_t GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const { |
863 return AllocationThroughputInBytesPerMillisecond(kThroughputTimeFrameMs); | 862 return AllocationThroughputInBytesPerMillisecond(kThroughputTimeFrameMs); |
864 } | 863 } |
865 | 864 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 | 901 |
903 | 902 |
904 bool GCTracer::SurvivalEventsRecorded() const { | 903 bool GCTracer::SurvivalEventsRecorded() const { |
905 return survival_events_.size() > 0; | 904 return survival_events_.size() > 0; |
906 } | 905 } |
907 | 906 |
908 | 907 |
909 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); } | 908 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); } |
910 } // namespace internal | 909 } // namespace internal |
911 } // namespace v8 | 910 } // namespace v8 |
OLD | NEW |