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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/heap/gc-tracer.h" | 7 #include "src/heap/gc-tracer.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 const char* GCTracer::Event::TypeName(bool short_name) const { | 62 const char* GCTracer::Event::TypeName(bool short_name) const { |
63 switch (type) { | 63 switch (type) { |
64 case SCAVENGER: | 64 case SCAVENGER: |
65 if (short_name) { | 65 if (short_name) { |
66 return "s"; | 66 return "s"; |
67 } else { | 67 } else { |
68 return "Scavenge"; | 68 return "Scavenge"; |
69 } | 69 } |
70 case MARK_COMPACTOR: | 70 case MARK_COMPACTOR: |
| 71 case INCREMENTAL_MARK_COMPACTOR: |
71 if (short_name) { | 72 if (short_name) { |
72 return "ms"; | 73 return "ms"; |
73 } else { | 74 } else { |
74 return "Mark-sweep"; | 75 return "Mark-sweep"; |
75 } | 76 } |
76 case START: | 77 case START: |
77 if (short_name) { | 78 if (short_name) { |
78 return "st"; | 79 return "st"; |
79 } else { | 80 } else { |
80 return "Start"; | 81 return "Start"; |
81 } | 82 } |
82 } | 83 } |
83 return "Unknown Event Type"; | 84 return "Unknown Event Type"; |
84 } | 85 } |
85 | 86 |
86 | 87 |
87 GCTracer::GCTracer(Heap* heap) | 88 GCTracer::GCTracer(Heap* heap) |
88 : heap_(heap), | 89 : heap_(heap), |
89 cumulative_incremental_marking_steps_(0), | 90 cumulative_incremental_marking_steps_(0), |
90 cumulative_incremental_marking_bytes_(0), | 91 cumulative_incremental_marking_bytes_(0), |
91 cumulative_incremental_marking_duration_(0.0), | 92 cumulative_incremental_marking_duration_(0.0), |
92 cumulative_pure_incremental_marking_duration_(0.0), | 93 cumulative_pure_incremental_marking_duration_(0.0), |
93 longest_incremental_marking_step_(0.0), | 94 longest_incremental_marking_step_(0.0), |
94 cumulative_marking_duration_(0.0), | 95 cumulative_marking_duration_(0.0), |
95 cumulative_sweeping_duration_(0.0), | 96 cumulative_sweeping_duration_(0.0), |
96 new_space_top_after_gc_(0), | 97 new_space_top_after_gc_(0), |
97 start_counter_(0) { | 98 start_counter_(0) { |
98 current_ = Event(Event::START, NULL, NULL); | 99 current_ = Event(Event::START, NULL, NULL); |
99 current_.end_time = base::OS::TimeCurrentMillis(); | 100 current_.end_time = base::OS::TimeCurrentMillis(); |
100 previous_ = previous_mark_compactor_event_ = current_; | 101 previous_ = previous_incremental_mark_compactor_event_ = current_; |
101 } | 102 } |
102 | 103 |
103 | 104 |
104 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, | 105 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, |
105 const char* collector_reason) { | 106 const char* collector_reason) { |
106 start_counter_++; | 107 start_counter_++; |
107 if (start_counter_ != 1) return; | 108 if (start_counter_ != 1) return; |
108 | 109 |
109 previous_ = current_; | 110 previous_ = current_; |
110 double start_time = base::OS::TimeCurrentMillis(); | 111 double start_time = base::OS::TimeCurrentMillis(); |
111 if (new_space_top_after_gc_ != 0) { | 112 if (new_space_top_after_gc_ != 0) { |
112 AddNewSpaceAllocationTime( | 113 AddNewSpaceAllocationTime( |
113 start_time - previous_.end_time, | 114 start_time - previous_.end_time, |
114 reinterpret_cast<intptr_t>((heap_->new_space()->top()) - | 115 reinterpret_cast<intptr_t>((heap_->new_space()->top()) - |
115 new_space_top_after_gc_)); | 116 new_space_top_after_gc_)); |
116 } | 117 } |
117 if (current_.type == Event::MARK_COMPACTOR) | 118 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) |
118 previous_mark_compactor_event_ = current_; | 119 previous_incremental_mark_compactor_event_ = current_; |
119 | 120 |
120 if (collector == SCAVENGER) { | 121 if (collector == SCAVENGER) { |
121 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); | 122 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); |
122 } else { | 123 } else if (collector == MARK_COMPACTOR) { |
123 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); | 124 if (heap_->incremental_marking()->IsMarking()) { |
| 125 current_ = |
| 126 Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason); |
| 127 } else { |
| 128 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); |
| 129 } |
124 } | 130 } |
125 | 131 |
126 current_.start_time = start_time; | 132 current_.start_time = start_time; |
127 current_.start_object_size = heap_->SizeOfObjects(); | 133 current_.start_object_size = heap_->SizeOfObjects(); |
128 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); | 134 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); |
129 current_.start_holes_size = CountTotalHolesSize(heap_); | 135 current_.start_holes_size = CountTotalHolesSize(heap_); |
130 current_.new_space_object_size = | 136 current_.new_space_object_size = |
131 heap_->new_space()->top() - heap_->new_space()->bottom(); | 137 heap_->new_space()->top() - heap_->new_space()->bottom(); |
132 | 138 |
133 current_.cumulative_incremental_marking_steps = | 139 current_.cumulative_incremental_marking_steps = |
(...skipping 17 matching lines...) Expand all Loading... |
151 if (start_counter_ != 0) { | 157 if (start_counter_ != 0) { |
152 if (FLAG_trace_gc) { | 158 if (FLAG_trace_gc) { |
153 PrintF("[Finished reentrant %s during %s.]\n", | 159 PrintF("[Finished reentrant %s during %s.]\n", |
154 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", | 160 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", |
155 current_.TypeName(false)); | 161 current_.TypeName(false)); |
156 } | 162 } |
157 return; | 163 return; |
158 } | 164 } |
159 | 165 |
160 DCHECK(start_counter_ >= 0); | 166 DCHECK(start_counter_ >= 0); |
161 DCHECK( | 167 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || |
162 (collector == SCAVENGER && current_.type == Event::SCAVENGER) || | 168 (collector == MARK_COMPACTOR && |
163 (collector == MARK_COMPACTOR && current_.type == Event::MARK_COMPACTOR)); | 169 (current_.type == Event::MARK_COMPACTOR || |
| 170 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); |
164 | 171 |
165 current_.end_time = base::OS::TimeCurrentMillis(); | 172 current_.end_time = base::OS::TimeCurrentMillis(); |
166 current_.end_object_size = heap_->SizeOfObjects(); | 173 current_.end_object_size = heap_->SizeOfObjects(); |
167 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); | 174 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); |
168 current_.end_holes_size = CountTotalHolesSize(heap_); | 175 current_.end_holes_size = CountTotalHolesSize(heap_); |
169 new_space_top_after_gc_ = | 176 new_space_top_after_gc_ = |
170 reinterpret_cast<intptr_t>(heap_->new_space()->top()); | 177 reinterpret_cast<intptr_t>(heap_->new_space()->top()); |
171 | 178 |
172 if (current_.type == Event::SCAVENGER) { | 179 if (current_.type == Event::SCAVENGER) { |
173 current_.incremental_marking_steps = | 180 current_.incremental_marking_steps = |
174 current_.cumulative_incremental_marking_steps - | 181 current_.cumulative_incremental_marking_steps - |
175 previous_.cumulative_incremental_marking_steps; | 182 previous_.cumulative_incremental_marking_steps; |
176 current_.incremental_marking_bytes = | 183 current_.incremental_marking_bytes = |
177 current_.cumulative_incremental_marking_bytes - | 184 current_.cumulative_incremental_marking_bytes - |
178 previous_.cumulative_incremental_marking_bytes; | 185 previous_.cumulative_incremental_marking_bytes; |
179 current_.incremental_marking_duration = | 186 current_.incremental_marking_duration = |
180 current_.cumulative_incremental_marking_duration - | 187 current_.cumulative_incremental_marking_duration - |
181 previous_.cumulative_incremental_marking_duration; | 188 previous_.cumulative_incremental_marking_duration; |
182 current_.pure_incremental_marking_duration = | 189 current_.pure_incremental_marking_duration = |
183 current_.cumulative_pure_incremental_marking_duration - | 190 current_.cumulative_pure_incremental_marking_duration - |
184 previous_.cumulative_pure_incremental_marking_duration; | 191 previous_.cumulative_pure_incremental_marking_duration; |
185 scavenger_events_.push_front(current_); | 192 scavenger_events_.push_front(current_); |
186 } else { | 193 } else if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { |
187 current_.incremental_marking_steps = | 194 current_.incremental_marking_steps = |
188 current_.cumulative_incremental_marking_steps - | 195 current_.cumulative_incremental_marking_steps - |
189 previous_mark_compactor_event_.cumulative_incremental_marking_steps; | 196 previous_incremental_mark_compactor_event_ |
| 197 .cumulative_incremental_marking_steps; |
190 current_.incremental_marking_bytes = | 198 current_.incremental_marking_bytes = |
191 current_.cumulative_incremental_marking_bytes - | 199 current_.cumulative_incremental_marking_bytes - |
192 previous_mark_compactor_event_.cumulative_incremental_marking_bytes; | 200 previous_incremental_mark_compactor_event_ |
| 201 .cumulative_incremental_marking_bytes; |
193 current_.incremental_marking_duration = | 202 current_.incremental_marking_duration = |
194 current_.cumulative_incremental_marking_duration - | 203 current_.cumulative_incremental_marking_duration - |
195 previous_mark_compactor_event_.cumulative_incremental_marking_duration; | 204 previous_incremental_mark_compactor_event_ |
| 205 .cumulative_incremental_marking_duration; |
196 current_.pure_incremental_marking_duration = | 206 current_.pure_incremental_marking_duration = |
197 current_.cumulative_pure_incremental_marking_duration - | 207 current_.cumulative_pure_incremental_marking_duration - |
198 previous_mark_compactor_event_ | 208 previous_incremental_mark_compactor_event_ |
199 .cumulative_pure_incremental_marking_duration; | 209 .cumulative_pure_incremental_marking_duration; |
200 longest_incremental_marking_step_ = 0.0; | 210 longest_incremental_marking_step_ = 0.0; |
| 211 incremental_mark_compactor_events_.push_front(current_); |
| 212 } else { |
| 213 DCHECK(current_.incremental_marking_bytes == 0); |
| 214 DCHECK(current_.incremental_marking_duration == 0); |
| 215 DCHECK(current_.pure_incremental_marking_duration == 0); |
| 216 DCHECK(longest_incremental_marking_step_ == 0.0); |
201 mark_compactor_events_.push_front(current_); | 217 mark_compactor_events_.push_front(current_); |
202 } | 218 } |
203 | 219 |
204 // TODO(ernstm): move the code below out of GCTracer. | 220 // TODO(ernstm): move the code below out of GCTracer. |
205 | 221 |
206 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; | 222 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; |
207 | 223 |
208 double duration = current_.end_time - current_.start_time; | 224 double duration = current_.end_time - current_.start_time; |
209 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); | 225 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); |
210 | 226 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 | 409 |
394 return maximum; | 410 return maximum; |
395 } | 411 } |
396 | 412 |
397 | 413 |
398 double GCTracer::MeanIncrementalMarkingDuration() const { | 414 double GCTracer::MeanIncrementalMarkingDuration() const { |
399 if (cumulative_incremental_marking_steps_ == 0) return 0.0; | 415 if (cumulative_incremental_marking_steps_ == 0) return 0.0; |
400 | 416 |
401 // We haven't completed an entire round of incremental marking, yet. | 417 // We haven't completed an entire round of incremental marking, yet. |
402 // Use data from GCTracer instead of data from event buffers. | 418 // Use data from GCTracer instead of data from event buffers. |
403 if (mark_compactor_events_.empty()) { | 419 if (incremental_mark_compactor_events_.empty()) { |
404 return cumulative_incremental_marking_duration_ / | 420 return cumulative_incremental_marking_duration_ / |
405 cumulative_incremental_marking_steps_; | 421 cumulative_incremental_marking_steps_; |
406 } | 422 } |
407 | 423 |
408 int steps = 0; | 424 int steps = 0; |
409 double durations = 0.0; | 425 double durations = 0.0; |
410 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); | 426 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); |
411 while (iter != mark_compactor_events_.end()) { | 427 while (iter != incremental_mark_compactor_events_.end()) { |
412 steps += iter->incremental_marking_steps; | 428 steps += iter->incremental_marking_steps; |
413 durations += iter->incremental_marking_duration; | 429 durations += iter->incremental_marking_duration; |
414 ++iter; | 430 ++iter; |
415 } | 431 } |
416 | 432 |
417 if (steps == 0) return 0.0; | 433 if (steps == 0) return 0.0; |
418 | 434 |
419 return durations / steps; | 435 return durations / steps; |
420 } | 436 } |
421 | 437 |
422 | 438 |
423 double GCTracer::MaxIncrementalMarkingDuration() const { | 439 double GCTracer::MaxIncrementalMarkingDuration() const { |
424 // We haven't completed an entire round of incremental marking, yet. | 440 // We haven't completed an entire round of incremental marking, yet. |
425 // Use data from GCTracer instead of data from event buffers. | 441 // Use data from GCTracer instead of data from event buffers. |
426 if (mark_compactor_events_.empty()) return longest_incremental_marking_step_; | 442 if (incremental_mark_compactor_events_.empty()) |
| 443 return longest_incremental_marking_step_; |
427 | 444 |
428 double max_duration = 0.0; | 445 double max_duration = 0.0; |
429 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); | 446 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); |
430 while (iter != mark_compactor_events_.end()) | 447 while (iter != incremental_mark_compactor_events_.end()) |
431 max_duration = Max(iter->longest_incremental_marking_step, max_duration); | 448 max_duration = Max(iter->longest_incremental_marking_step, max_duration); |
432 | 449 |
433 return max_duration; | 450 return max_duration; |
434 } | 451 } |
435 | 452 |
436 | 453 |
437 intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { | 454 intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { |
438 if (cumulative_incremental_marking_duration_ == 0.0) return 0; | 455 if (cumulative_incremental_marking_duration_ == 0.0) return 0; |
439 | 456 |
440 // We haven't completed an entire round of incremental marking, yet. | 457 // We haven't completed an entire round of incremental marking, yet. |
441 // Use data from GCTracer instead of data from event buffers. | 458 // Use data from GCTracer instead of data from event buffers. |
442 if (mark_compactor_events_.empty()) { | 459 if (incremental_mark_compactor_events_.empty()) { |
443 return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ / | 460 return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ / |
444 cumulative_pure_incremental_marking_duration_); | 461 cumulative_pure_incremental_marking_duration_); |
445 } | 462 } |
446 | 463 |
447 intptr_t bytes = 0; | 464 intptr_t bytes = 0; |
448 double durations = 0.0; | 465 double durations = 0.0; |
449 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); | 466 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); |
450 while (iter != mark_compactor_events_.end()) { | 467 while (iter != incremental_mark_compactor_events_.end()) { |
451 bytes += iter->incremental_marking_bytes; | 468 bytes += iter->incremental_marking_bytes; |
452 durations += iter->pure_incremental_marking_duration; | 469 durations += iter->pure_incremental_marking_duration; |
453 ++iter; | 470 ++iter; |
454 } | 471 } |
455 | 472 |
456 if (durations == 0.0) return 0; | 473 if (durations == 0.0) return 0; |
457 | 474 |
458 return static_cast<intptr_t>(bytes / durations); | 475 return static_cast<intptr_t>(bytes / durations); |
459 } | 476 } |
460 | 477 |
(...skipping 13 matching lines...) Expand all Loading... |
474 return static_cast<intptr_t>(bytes / durations); | 491 return static_cast<intptr_t>(bytes / durations); |
475 } | 492 } |
476 | 493 |
477 | 494 |
478 intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { | 495 intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { |
479 intptr_t bytes = 0; | 496 intptr_t bytes = 0; |
480 double durations = 0.0; | 497 double durations = 0.0; |
481 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); | 498 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); |
482 while (iter != mark_compactor_events_.end()) { | 499 while (iter != mark_compactor_events_.end()) { |
483 bytes += iter->start_object_size; | 500 bytes += iter->start_object_size; |
484 durations += iter->end_time - iter->start_time + | 501 durations += iter->end_time - iter->start_time; |
485 iter->pure_incremental_marking_duration; | |
486 ++iter; | 502 ++iter; |
487 } | 503 } |
488 | 504 |
| 505 if (durations == 0.0) return 0; |
| 506 |
| 507 return static_cast<intptr_t>(bytes / durations); |
| 508 } |
| 509 |
| 510 |
| 511 intptr_t GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() |
| 512 const { |
| 513 intptr_t bytes = 0; |
| 514 double durations = 0.0; |
| 515 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); |
| 516 while (iter != incremental_mark_compactor_events_.end()) { |
| 517 bytes += iter->start_object_size; |
| 518 durations += iter->end_time - iter->start_time; |
| 519 ++iter; |
| 520 } |
| 521 |
489 if (durations == 0.0) return 0; | 522 if (durations == 0.0) return 0; |
490 | 523 |
491 return static_cast<intptr_t>(bytes / durations); | 524 return static_cast<intptr_t>(bytes / durations); |
492 } | 525 } |
493 | 526 |
494 | 527 |
495 intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { | 528 intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { |
496 intptr_t bytes = 0; | 529 intptr_t bytes = 0; |
497 double durations = 0.0; | 530 double durations = 0.0; |
498 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); | 531 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); |
(...skipping 18 matching lines...) Expand all Loading... |
517 context_disposal_events_.begin(); | 550 context_disposal_events_.begin(); |
518 while (iter != context_disposal_events_.end()) { | 551 while (iter != context_disposal_events_.end()) { |
519 end = iter->time_; | 552 end = iter->time_; |
520 ++iter; | 553 ++iter; |
521 } | 554 } |
522 | 555 |
523 return (begin - end) / context_disposal_events_.size(); | 556 return (begin - end) / context_disposal_events_.size(); |
524 } | 557 } |
525 } | 558 } |
526 } // namespace v8::internal | 559 } // namespace v8::internal |
OLD | NEW |