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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 return "V8.GC_" #scope; | 50 return "V8.GC_" #scope; |
51 switch (id) { | 51 switch (id) { |
52 TRACER_SCOPES(CASE) | 52 TRACER_SCOPES(CASE) |
53 case Scope::NUMBER_OF_SCOPES: | 53 case Scope::NUMBER_OF_SCOPES: |
54 break; | 54 break; |
55 } | 55 } |
56 #undef CASE | 56 #undef CASE |
57 return "(unknown)"; | 57 return "(unknown)"; |
58 } | 58 } |
59 | 59 |
60 GCTracer::Event::Event(Type type, const char* gc_reason, | 60 GCTracer::Event::Event(Type type, GarbageCollectionReason gc_reason, |
61 const char* collector_reason) | 61 const char* collector_reason) |
62 : type(type), | 62 : type(type), |
63 gc_reason(gc_reason), | 63 gc_reason(gc_reason), |
64 collector_reason(collector_reason), | 64 collector_reason(collector_reason), |
65 start_time(0.0), | 65 start_time(0.0), |
66 end_time(0.0), | 66 end_time(0.0), |
67 reduce_memory(false), | 67 reduce_memory(false), |
68 start_object_size(0), | 68 start_object_size(0), |
69 end_object_size(0), | 69 end_object_size(0), |
70 start_memory_size(0), | 70 start_memory_size(0), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 return "st"; | 103 return "st"; |
104 } else { | 104 } else { |
105 return "Start"; | 105 return "Start"; |
106 } | 106 } |
107 } | 107 } |
108 return "Unknown Event Type"; | 108 return "Unknown Event Type"; |
109 } | 109 } |
110 | 110 |
111 GCTracer::GCTracer(Heap* heap) | 111 GCTracer::GCTracer(Heap* heap) |
112 : heap_(heap), | 112 : heap_(heap), |
113 current_(Event::START, nullptr, nullptr), | 113 current_(Event::START, GarbageCollectionReason::kUnknown, nullptr), |
114 previous_(current_), | 114 previous_(current_), |
115 previous_incremental_mark_compactor_event_(current_), | 115 previous_incremental_mark_compactor_event_(current_), |
116 cumulative_incremental_marking_bytes_(0), | 116 cumulative_incremental_marking_bytes_(0), |
117 cumulative_incremental_marking_duration_(0.0), | 117 cumulative_incremental_marking_duration_(0.0), |
118 cumulative_pure_incremental_marking_duration_(0.0), | 118 cumulative_pure_incremental_marking_duration_(0.0), |
119 cumulative_marking_duration_(0.0), | 119 cumulative_marking_duration_(0.0), |
120 cumulative_sweeping_duration_(0.0), | 120 cumulative_sweeping_duration_(0.0), |
121 allocation_time_ms_(0.0), | 121 allocation_time_ms_(0.0), |
122 new_space_allocation_counter_bytes_(0), | 122 new_space_allocation_counter_bytes_(0), |
123 old_generation_allocation_counter_bytes_(0), | 123 old_generation_allocation_counter_bytes_(0), |
124 allocation_duration_since_gc_(0.0), | 124 allocation_duration_since_gc_(0.0), |
125 new_space_allocation_in_bytes_since_gc_(0), | 125 new_space_allocation_in_bytes_since_gc_(0), |
126 old_generation_allocation_in_bytes_since_gc_(0), | 126 old_generation_allocation_in_bytes_since_gc_(0), |
127 combined_mark_compact_speed_cache_(0.0), | 127 combined_mark_compact_speed_cache_(0.0), |
128 start_counter_(0) { | 128 start_counter_(0) { |
129 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); | 129 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); |
130 } | 130 } |
131 | 131 |
132 void GCTracer::ResetForTesting() { | 132 void GCTracer::ResetForTesting() { |
133 current_ = Event(Event::START, NULL, NULL); | 133 current_ = Event(Event::START, GarbageCollectionReason::kTesting, nullptr); |
134 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); | 134 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); |
135 previous_ = previous_incremental_mark_compactor_event_ = current_; | 135 previous_ = previous_incremental_mark_compactor_event_ = current_; |
136 cumulative_incremental_marking_bytes_ = 0.0; | 136 cumulative_incremental_marking_bytes_ = 0.0; |
137 cumulative_incremental_marking_duration_ = 0.0; | 137 cumulative_incremental_marking_duration_ = 0.0; |
138 cumulative_pure_incremental_marking_duration_ = 0.0; | 138 cumulative_pure_incremental_marking_duration_ = 0.0; |
139 cumulative_marking_duration_ = 0.0; | 139 cumulative_marking_duration_ = 0.0; |
140 for (int i = 0; i < Scope::NUMBER_OF_INCREMENTAL_SCOPES; i++) { | 140 for (int i = 0; i < Scope::NUMBER_OF_INCREMENTAL_SCOPES; i++) { |
141 incremental_marking_scopes_[i].cumulative_duration = 0.0; | 141 incremental_marking_scopes_[i].cumulative_duration = 0.0; |
142 incremental_marking_scopes_[i].steps = 0; | 142 incremental_marking_scopes_[i].steps = 0; |
143 incremental_marking_scopes_[i].longest_step = 0.0; | 143 incremental_marking_scopes_[i].longest_step = 0.0; |
(...skipping 11 matching lines...) Expand all Loading... |
155 recorded_compactions_.Reset(); | 155 recorded_compactions_.Reset(); |
156 recorded_mark_compacts_.Reset(); | 156 recorded_mark_compacts_.Reset(); |
157 recorded_incremental_mark_compacts_.Reset(); | 157 recorded_incremental_mark_compacts_.Reset(); |
158 recorded_new_generation_allocations_.Reset(); | 158 recorded_new_generation_allocations_.Reset(); |
159 recorded_old_generation_allocations_.Reset(); | 159 recorded_old_generation_allocations_.Reset(); |
160 recorded_context_disposal_times_.Reset(); | 160 recorded_context_disposal_times_.Reset(); |
161 recorded_survival_ratios_.Reset(); | 161 recorded_survival_ratios_.Reset(); |
162 start_counter_ = 0; | 162 start_counter_ = 0; |
163 } | 163 } |
164 | 164 |
165 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, | 165 void GCTracer::Start(GarbageCollector collector, |
| 166 GarbageCollectionReason gc_reason, |
166 const char* collector_reason) { | 167 const char* collector_reason) { |
167 start_counter_++; | 168 start_counter_++; |
168 if (start_counter_ != 1) return; | 169 if (start_counter_ != 1) return; |
169 | 170 |
170 previous_ = current_; | 171 previous_ = current_; |
171 double start_time = heap_->MonotonicallyIncreasingTimeInMs(); | 172 double start_time = heap_->MonotonicallyIncreasingTimeInMs(); |
172 SampleAllocation(start_time, heap_->NewSpaceAllocationCounter(), | 173 SampleAllocation(start_time, heap_->NewSpaceAllocationCounter(), |
173 heap_->OldGenerationAllocationCounter()); | 174 heap_->OldGenerationAllocationCounter()); |
174 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) | 175 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) |
175 previous_incremental_mark_compactor_event_ = current_; | 176 previous_incremental_mark_compactor_event_ = current_; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 char raw_buffer[kBufferSize]; | 405 char raw_buffer[kBufferSize]; |
405 Vector<char> buffer(raw_buffer, kBufferSize); | 406 Vector<char> buffer(raw_buffer, kBufferSize); |
406 va_list arguments2; | 407 va_list arguments2; |
407 va_start(arguments2, format); | 408 va_start(arguments2, format); |
408 VSNPrintF(buffer, format, arguments2); | 409 VSNPrintF(buffer, format, arguments2); |
409 va_end(arguments2); | 410 va_end(arguments2); |
410 | 411 |
411 heap_->AddToRingBuffer(buffer.start()); | 412 heap_->AddToRingBuffer(buffer.start()); |
412 } | 413 } |
413 | 414 |
| 415 const char* GCTracer::GarbageCollectionReasonToString( |
| 416 GarbageCollectionReason gc_reason) { |
| 417 switch (gc_reason) { |
| 418 case GarbageCollectionReason::kAllocationFailure: |
| 419 return "allocation failure"; |
| 420 case GarbageCollectionReason::kAllocationLimit: |
| 421 return "allocation limit"; |
| 422 case GarbageCollectionReason::kContextDisposal: |
| 423 return "context disposal"; |
| 424 case GarbageCollectionReason::kCountersExtension: |
| 425 return "counters extension"; |
| 426 case GarbageCollectionReason::kDebugger: |
| 427 return "debugger"; |
| 428 case GarbageCollectionReason::kDeserializer: |
| 429 return "deserialize"; |
| 430 case GarbageCollectionReason::kExternalMemoryPressure: |
| 431 return "external memory pressure"; |
| 432 case GarbageCollectionReason::kFinalizeMarkingViaStackGuard: |
| 433 return "finalize incremental marking via stack guard"; |
| 434 case GarbageCollectionReason::kFinalizeMarkingViaTask: |
| 435 return "finalize incremental marking via task"; |
| 436 case GarbageCollectionReason::kFullHashtable: |
| 437 return "full hash-table"; |
| 438 case GarbageCollectionReason::kHeapProfiler: |
| 439 return "heap profiler"; |
| 440 case GarbageCollectionReason::kIdleTask: |
| 441 return "idle task"; |
| 442 case GarbageCollectionReason::kLastResort: |
| 443 return "last resort"; |
| 444 case GarbageCollectionReason::kLowMemoryNotification: |
| 445 return "low memory notification"; |
| 446 case GarbageCollectionReason::kMakeHeapIterable: |
| 447 return "make heap iterable"; |
| 448 case GarbageCollectionReason::kMemoryPressure: |
| 449 return "memory pressure"; |
| 450 case GarbageCollectionReason::kMemoryReducer: |
| 451 return "memory reducer"; |
| 452 case GarbageCollectionReason::kRuntime: |
| 453 return "runtime"; |
| 454 case GarbageCollectionReason::kSamplingProfiler: |
| 455 return "sampling profiler"; |
| 456 case GarbageCollectionReason::kSnapshotCreator: |
| 457 return "snapshot creator"; |
| 458 case GarbageCollectionReason::kTesting: |
| 459 return "testing"; |
| 460 case GarbageCollectionReason::kUnknown: |
| 461 return "unknown"; |
| 462 } |
| 463 UNREACHABLE(); |
| 464 return ""; |
| 465 } |
414 | 466 |
415 void GCTracer::Print() const { | 467 void GCTracer::Print() const { |
416 double duration = current_.end_time - current_.start_time; | 468 double duration = current_.end_time - current_.start_time; |
417 const size_t kIncrementalStatsSize = 128; | 469 const size_t kIncrementalStatsSize = 128; |
418 char incremental_buffer[kIncrementalStatsSize] = {0}; | 470 char incremental_buffer[kIncrementalStatsSize] = {0}; |
419 | 471 |
420 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { | 472 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { |
421 base::OS::SNPrintF( | 473 base::OS::SNPrintF( |
422 incremental_buffer, kIncrementalStatsSize, | 474 incremental_buffer, kIncrementalStatsSize, |
423 " (+ %.1f ms in %d steps since start of marking, " | 475 " (+ %.1f ms in %d steps since start of marking, " |
(...skipping 12 matching lines...) Expand all Loading... |
436 "%s %.1f (%.1f) -> %.1f (%.1f) MB, " | 488 "%s %.1f (%.1f) -> %.1f (%.1f) MB, " |
437 "%.1f / %.1f ms %s %s %s\n", | 489 "%.1f / %.1f ms %s %s %s\n", |
438 base::OS::GetCurrentProcessId(), | 490 base::OS::GetCurrentProcessId(), |
439 reinterpret_cast<void*>(heap_->isolate()), | 491 reinterpret_cast<void*>(heap_->isolate()), |
440 heap_->isolate()->time_millis_since_init(), current_.TypeName(false), | 492 heap_->isolate()->time_millis_since_init(), current_.TypeName(false), |
441 static_cast<double>(current_.start_object_size) / MB, | 493 static_cast<double>(current_.start_object_size) / MB, |
442 static_cast<double>(current_.start_memory_size) / MB, | 494 static_cast<double>(current_.start_memory_size) / MB, |
443 static_cast<double>(current_.end_object_size) / MB, | 495 static_cast<double>(current_.end_object_size) / MB, |
444 static_cast<double>(current_.end_memory_size) / MB, duration, | 496 static_cast<double>(current_.end_memory_size) / MB, duration, |
445 TotalExternalTime(), incremental_buffer, | 497 TotalExternalTime(), incremental_buffer, |
446 current_.gc_reason != nullptr ? current_.gc_reason : "", | 498 GarbageCollectionReasonToString(current_.gc_reason), |
447 current_.collector_reason != nullptr ? current_.collector_reason : ""); | 499 current_.collector_reason != nullptr ? current_.collector_reason : ""); |
448 } | 500 } |
449 | 501 |
450 | 502 |
451 void GCTracer::PrintNVP() const { | 503 void GCTracer::PrintNVP() const { |
452 double duration = current_.end_time - current_.start_time; | 504 double duration = current_.end_time - current_.start_time; |
453 double spent_in_mutator = current_.start_time - previous_.end_time; | 505 double spent_in_mutator = current_.start_time - previous_.end_time; |
454 intptr_t allocated_since_last_gc = | 506 intptr_t allocated_since_last_gc = |
455 current_.start_object_size - previous_.end_object_size; | 507 current_.start_object_size - previous_.end_object_size; |
456 | 508 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 } | 879 } |
828 | 880 |
829 void GCTracer::ResetSurvivalEvents() { recorded_survival_ratios_.Reset(); } | 881 void GCTracer::ResetSurvivalEvents() { recorded_survival_ratios_.Reset(); } |
830 | 882 |
831 void GCTracer::NotifyIncrementalMarkingStart() { | 883 void GCTracer::NotifyIncrementalMarkingStart() { |
832 incremental_marking_start_time_ = heap_->MonotonicallyIncreasingTimeInMs(); | 884 incremental_marking_start_time_ = heap_->MonotonicallyIncreasingTimeInMs(); |
833 } | 885 } |
834 | 886 |
835 } // namespace internal | 887 } // namespace internal |
836 } // namespace v8 | 888 } // namespace v8 |
OLD | NEW |