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: | |
72 if (short_name) { | 71 if (short_name) { |
73 return "ms"; | 72 return "ms"; |
74 } else { | 73 } else { |
75 return "Mark-sweep"; | 74 return "Mark-sweep"; |
76 } | 75 } |
77 case START: | 76 case START: |
78 if (short_name) { | 77 if (short_name) { |
79 return "st"; | 78 return "st"; |
80 } else { | 79 } else { |
81 return "Start"; | 80 return "Start"; |
82 } | 81 } |
83 } | 82 } |
84 return "Unknown Event Type"; | 83 return "Unknown Event Type"; |
85 } | 84 } |
86 | 85 |
87 | 86 |
88 GCTracer::GCTracer(Heap* heap) | 87 GCTracer::GCTracer(Heap* heap) |
89 : heap_(heap), | 88 : heap_(heap), |
90 cumulative_incremental_marking_steps_(0), | 89 cumulative_incremental_marking_steps_(0), |
91 cumulative_incremental_marking_bytes_(0), | 90 cumulative_incremental_marking_bytes_(0), |
92 cumulative_incremental_marking_duration_(0.0), | 91 cumulative_incremental_marking_duration_(0.0), |
93 cumulative_pure_incremental_marking_duration_(0.0), | 92 cumulative_pure_incremental_marking_duration_(0.0), |
94 longest_incremental_marking_step_(0.0), | 93 longest_incremental_marking_step_(0.0), |
95 cumulative_marking_duration_(0.0), | 94 cumulative_marking_duration_(0.0), |
96 cumulative_sweeping_duration_(0.0), | 95 cumulative_sweeping_duration_(0.0), |
97 new_space_top_after_gc_(0) { | 96 new_space_top_after_gc_(0) { |
98 current_ = Event(Event::START, NULL, NULL); | 97 current_ = Event(Event::START, NULL, NULL); |
99 current_.end_time = base::OS::TimeCurrentMillis(); | 98 current_.end_time = base::OS::TimeCurrentMillis(); |
100 previous_ = previous_incremental_mark_compactor_event_ = current_; | 99 previous_ = previous_mark_compactor_event_ = current_; |
101 } | 100 } |
102 | 101 |
103 | 102 |
104 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, | 103 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, |
105 const char* collector_reason) { | 104 const char* collector_reason) { |
106 previous_ = current_; | 105 previous_ = current_; |
107 double start_time = base::OS::TimeCurrentMillis(); | 106 double start_time = base::OS::TimeCurrentMillis(); |
108 if (new_space_top_after_gc_ != 0) { | 107 if (new_space_top_after_gc_ != 0) { |
109 AddNewSpaceAllocationTime( | 108 AddNewSpaceAllocationTime( |
110 start_time - previous_.end_time, | 109 start_time - previous_.end_time, |
111 reinterpret_cast<intptr_t>((heap_->new_space()->top()) - | 110 reinterpret_cast<intptr_t>((heap_->new_space()->top()) - |
112 new_space_top_after_gc_)); | 111 new_space_top_after_gc_)); |
113 } | 112 } |
114 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) | 113 if (current_.type == Event::MARK_COMPACTOR) |
115 previous_incremental_mark_compactor_event_ = current_; | 114 previous_mark_compactor_event_ = current_; |
116 | 115 |
117 if (collector == SCAVENGER) { | 116 if (collector == SCAVENGER) { |
118 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); | 117 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); |
119 } else if (collector == MARK_COMPACTOR) { | 118 } else { |
120 if (heap_->incremental_marking()->IsMarking()) { | 119 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); |
121 current_ = | |
122 Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason); | |
123 } else { | |
124 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); | |
125 } | |
126 } | 120 } |
127 | 121 |
128 current_.start_time = start_time; | 122 current_.start_time = start_time; |
129 current_.start_object_size = heap_->SizeOfObjects(); | 123 current_.start_object_size = heap_->SizeOfObjects(); |
130 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); | 124 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); |
131 current_.start_holes_size = CountTotalHolesSize(heap_); | 125 current_.start_holes_size = CountTotalHolesSize(heap_); |
132 current_.new_space_object_size = | 126 current_.new_space_object_size = |
133 heap_->new_space()->top() - heap_->new_space()->bottom(); | 127 heap_->new_space()->top() - heap_->new_space()->bottom(); |
134 | 128 |
135 current_.cumulative_incremental_marking_steps = | 129 current_.cumulative_incremental_marking_steps = |
(...skipping 27 matching lines...) Expand all Loading... |
163 current_.incremental_marking_bytes = | 157 current_.incremental_marking_bytes = |
164 current_.cumulative_incremental_marking_bytes - | 158 current_.cumulative_incremental_marking_bytes - |
165 previous_.cumulative_incremental_marking_bytes; | 159 previous_.cumulative_incremental_marking_bytes; |
166 current_.incremental_marking_duration = | 160 current_.incremental_marking_duration = |
167 current_.cumulative_incremental_marking_duration - | 161 current_.cumulative_incremental_marking_duration - |
168 previous_.cumulative_incremental_marking_duration; | 162 previous_.cumulative_incremental_marking_duration; |
169 current_.pure_incremental_marking_duration = | 163 current_.pure_incremental_marking_duration = |
170 current_.cumulative_pure_incremental_marking_duration - | 164 current_.cumulative_pure_incremental_marking_duration - |
171 previous_.cumulative_pure_incremental_marking_duration; | 165 previous_.cumulative_pure_incremental_marking_duration; |
172 scavenger_events_.push_front(current_); | 166 scavenger_events_.push_front(current_); |
173 } else if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) { | 167 } else { |
174 current_.incremental_marking_steps = | 168 current_.incremental_marking_steps = |
175 current_.cumulative_incremental_marking_steps - | 169 current_.cumulative_incremental_marking_steps - |
176 previous_incremental_mark_compactor_event_ | 170 previous_mark_compactor_event_.cumulative_incremental_marking_steps; |
177 .cumulative_incremental_marking_steps; | |
178 current_.incremental_marking_bytes = | 171 current_.incremental_marking_bytes = |
179 current_.cumulative_incremental_marking_bytes - | 172 current_.cumulative_incremental_marking_bytes - |
180 previous_incremental_mark_compactor_event_ | 173 previous_mark_compactor_event_.cumulative_incremental_marking_bytes; |
181 .cumulative_incremental_marking_bytes; | |
182 current_.incremental_marking_duration = | 174 current_.incremental_marking_duration = |
183 current_.cumulative_incremental_marking_duration - | 175 current_.cumulative_incremental_marking_duration - |
184 previous_incremental_mark_compactor_event_ | 176 previous_mark_compactor_event_.cumulative_incremental_marking_duration; |
185 .cumulative_incremental_marking_duration; | |
186 current_.pure_incremental_marking_duration = | 177 current_.pure_incremental_marking_duration = |
187 current_.cumulative_pure_incremental_marking_duration - | 178 current_.cumulative_pure_incremental_marking_duration - |
188 previous_incremental_mark_compactor_event_ | 179 previous_mark_compactor_event_ |
189 .cumulative_pure_incremental_marking_duration; | 180 .cumulative_pure_incremental_marking_duration; |
190 longest_incremental_marking_step_ = 0.0; | 181 longest_incremental_marking_step_ = 0.0; |
191 incremental_mark_compactor_events_.push_front(current_); | |
192 } else { | |
193 DCHECK(current_.incremental_marking_bytes == 0); | |
194 DCHECK(current_.incremental_marking_duration == 0); | |
195 DCHECK(current_.pure_incremental_marking_duration == 0); | |
196 DCHECK(longest_incremental_marking_step_ == 0.0); | |
197 mark_compactor_events_.push_front(current_); | 182 mark_compactor_events_.push_front(current_); |
198 } | 183 } |
199 | 184 |
200 // TODO(ernstm): move the code below out of GCTracer. | 185 // TODO(ernstm): move the code below out of GCTracer. |
201 | 186 |
202 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; | 187 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; |
203 | 188 |
204 double duration = current_.end_time - current_.start_time; | 189 double duration = current_.end_time - current_.start_time; |
205 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); | 190 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); |
206 | 191 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 374 |
390 return maximum; | 375 return maximum; |
391 } | 376 } |
392 | 377 |
393 | 378 |
394 double GCTracer::MeanIncrementalMarkingDuration() const { | 379 double GCTracer::MeanIncrementalMarkingDuration() const { |
395 if (cumulative_incremental_marking_steps_ == 0) return 0.0; | 380 if (cumulative_incremental_marking_steps_ == 0) return 0.0; |
396 | 381 |
397 // We haven't completed an entire round of incremental marking, yet. | 382 // We haven't completed an entire round of incremental marking, yet. |
398 // Use data from GCTracer instead of data from event buffers. | 383 // Use data from GCTracer instead of data from event buffers. |
399 if (incremental_mark_compactor_events_.empty()) { | 384 if (mark_compactor_events_.empty()) { |
400 return cumulative_incremental_marking_duration_ / | 385 return cumulative_incremental_marking_duration_ / |
401 cumulative_incremental_marking_steps_; | 386 cumulative_incremental_marking_steps_; |
402 } | 387 } |
403 | 388 |
404 int steps = 0; | 389 int steps = 0; |
405 double durations = 0.0; | 390 double durations = 0.0; |
406 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); | 391 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); |
407 while (iter != incremental_mark_compactor_events_.end()) { | 392 while (iter != mark_compactor_events_.end()) { |
408 steps += iter->incremental_marking_steps; | 393 steps += iter->incremental_marking_steps; |
409 durations += iter->incremental_marking_duration; | 394 durations += iter->incremental_marking_duration; |
410 ++iter; | 395 ++iter; |
411 } | 396 } |
412 | 397 |
413 if (steps == 0) return 0.0; | 398 if (steps == 0) return 0.0; |
414 | 399 |
415 return durations / steps; | 400 return durations / steps; |
416 } | 401 } |
417 | 402 |
418 | 403 |
419 double GCTracer::MaxIncrementalMarkingDuration() const { | 404 double GCTracer::MaxIncrementalMarkingDuration() const { |
420 // We haven't completed an entire round of incremental marking, yet. | 405 // We haven't completed an entire round of incremental marking, yet. |
421 // Use data from GCTracer instead of data from event buffers. | 406 // Use data from GCTracer instead of data from event buffers. |
422 if (incremental_mark_compactor_events_.empty()) | 407 if (mark_compactor_events_.empty()) return longest_incremental_marking_step_; |
423 return longest_incremental_marking_step_; | |
424 | 408 |
425 double max_duration = 0.0; | 409 double max_duration = 0.0; |
426 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); | 410 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); |
427 while (iter != incremental_mark_compactor_events_.end()) | 411 while (iter != mark_compactor_events_.end()) |
428 max_duration = Max(iter->longest_incremental_marking_step, max_duration); | 412 max_duration = Max(iter->longest_incremental_marking_step, max_duration); |
429 | 413 |
430 return max_duration; | 414 return max_duration; |
431 } | 415 } |
432 | 416 |
433 | 417 |
434 intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { | 418 intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { |
435 if (cumulative_incremental_marking_duration_ == 0.0) return 0; | 419 if (cumulative_incremental_marking_duration_ == 0.0) return 0; |
436 | 420 |
437 // We haven't completed an entire round of incremental marking, yet. | 421 // We haven't completed an entire round of incremental marking, yet. |
438 // Use data from GCTracer instead of data from event buffers. | 422 // Use data from GCTracer instead of data from event buffers. |
439 if (incremental_mark_compactor_events_.empty()) { | 423 if (mark_compactor_events_.empty()) { |
440 return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ / | 424 return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ / |
441 cumulative_pure_incremental_marking_duration_); | 425 cumulative_pure_incremental_marking_duration_); |
442 } | 426 } |
443 | 427 |
444 intptr_t bytes = 0; | 428 intptr_t bytes = 0; |
445 double durations = 0.0; | 429 double durations = 0.0; |
446 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); | 430 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); |
447 while (iter != incremental_mark_compactor_events_.end()) { | 431 while (iter != mark_compactor_events_.end()) { |
448 bytes += iter->incremental_marking_bytes; | 432 bytes += iter->incremental_marking_bytes; |
449 durations += iter->pure_incremental_marking_duration; | 433 durations += iter->pure_incremental_marking_duration; |
450 ++iter; | 434 ++iter; |
451 } | 435 } |
452 | 436 |
453 if (durations == 0.0) return 0; | 437 if (durations == 0.0) return 0; |
454 | 438 |
455 return static_cast<intptr_t>(bytes / durations); | 439 return static_cast<intptr_t>(bytes / durations); |
456 } | 440 } |
457 | 441 |
(...skipping 13 matching lines...) Expand all Loading... |
471 return static_cast<intptr_t>(bytes / durations); | 455 return static_cast<intptr_t>(bytes / durations); |
472 } | 456 } |
473 | 457 |
474 | 458 |
475 intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { | 459 intptr_t GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { |
476 intptr_t bytes = 0; | 460 intptr_t bytes = 0; |
477 double durations = 0.0; | 461 double durations = 0.0; |
478 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); | 462 EventBuffer::const_iterator iter = mark_compactor_events_.begin(); |
479 while (iter != mark_compactor_events_.end()) { | 463 while (iter != mark_compactor_events_.end()) { |
480 bytes += iter->start_object_size; | 464 bytes += iter->start_object_size; |
481 durations += iter->end_time - iter->start_time; | 465 durations += iter->end_time - iter->start_time + |
| 466 iter->pure_incremental_marking_duration; |
482 ++iter; | 467 ++iter; |
483 } | 468 } |
484 | 469 |
485 if (durations == 0.0) return 0; | |
486 | |
487 return static_cast<intptr_t>(bytes / durations); | |
488 } | |
489 | |
490 | |
491 intptr_t GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() | |
492 const { | |
493 intptr_t bytes = 0; | |
494 double durations = 0.0; | |
495 EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin(); | |
496 while (iter != incremental_mark_compactor_events_.end()) { | |
497 bytes += iter->start_object_size; | |
498 durations += iter->end_time - iter->start_time; | |
499 ++iter; | |
500 } | |
501 | |
502 if (durations == 0.0) return 0; | 470 if (durations == 0.0) return 0; |
503 | 471 |
504 return static_cast<intptr_t>(bytes / durations); | 472 return static_cast<intptr_t>(bytes / durations); |
505 } | 473 } |
506 | 474 |
507 | 475 |
508 intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { | 476 intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { |
509 intptr_t bytes = 0; | 477 intptr_t bytes = 0; |
510 double durations = 0.0; | 478 double durations = 0.0; |
511 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); | 479 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); |
(...skipping 18 matching lines...) Expand all Loading... |
530 context_disposal_events_.begin(); | 498 context_disposal_events_.begin(); |
531 while (iter != context_disposal_events_.end()) { | 499 while (iter != context_disposal_events_.end()) { |
532 end = iter->time_; | 500 end = iter->time_; |
533 ++iter; | 501 ++iter; |
534 } | 502 } |
535 | 503 |
536 return (begin - end) / context_disposal_events_.size(); | 504 return (begin - end) / context_disposal_events_.size(); |
537 } | 505 } |
538 } | 506 } |
539 } // namespace v8::internal | 507 } // namespace v8::internal |
OLD | NEW |