| 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 |