| 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 { |
| 11 | 11 |
| 12 static intptr_t CountTotalHolesSize(Heap* heap) { | 12 static intptr_t CountTotalHolesSize(Heap* heap) { |
| 13 intptr_t holes_size = 0; | 13 intptr_t holes_size = 0; |
| 14 OldSpaces spaces(heap); | 14 OldSpaces spaces(heap); |
| 15 for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) { | 15 for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) { |
| 16 holes_size += space->Waste() + space->Available(); | 16 holes_size += space->Waste() + space->Available(); |
| 17 } | 17 } |
| 18 return holes_size; | 18 return holes_size; |
| 19 } | 19 } |
| 20 | 20 |
| 21 | 21 |
| 22 GCTracer::AllocationEvent::AllocationEvent(double duration, |
| 23 intptr_t allocation_in_bytes) { |
| 24 duration_ = duration; |
| 25 allocation_in_bytes_ = allocation_in_bytes; |
| 26 } |
| 27 |
| 28 |
| 22 GCTracer::Event::Event(Type type, const char* gc_reason, | 29 GCTracer::Event::Event(Type type, const char* gc_reason, |
| 23 const char* collector_reason) | 30 const char* collector_reason) |
| 24 : type(type), | 31 : type(type), |
| 25 gc_reason(gc_reason), | 32 gc_reason(gc_reason), |
| 26 collector_reason(collector_reason), | 33 collector_reason(collector_reason), |
| 27 start_time(0.0), | 34 start_time(0.0), |
| 28 end_time(0.0), | 35 end_time(0.0), |
| 29 start_object_size(0), | 36 start_object_size(0), |
| 30 end_object_size(0), | 37 end_object_size(0), |
| 31 start_memory_size(0), | 38 start_memory_size(0), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 | 80 |
| 74 | 81 |
| 75 GCTracer::GCTracer(Heap* heap) | 82 GCTracer::GCTracer(Heap* heap) |
| 76 : heap_(heap), | 83 : heap_(heap), |
| 77 cumulative_incremental_marking_steps_(0), | 84 cumulative_incremental_marking_steps_(0), |
| 78 cumulative_incremental_marking_bytes_(0), | 85 cumulative_incremental_marking_bytes_(0), |
| 79 cumulative_incremental_marking_duration_(0.0), | 86 cumulative_incremental_marking_duration_(0.0), |
| 80 cumulative_pure_incremental_marking_duration_(0.0), | 87 cumulative_pure_incremental_marking_duration_(0.0), |
| 81 longest_incremental_marking_step_(0.0), | 88 longest_incremental_marking_step_(0.0), |
| 82 cumulative_marking_duration_(0.0), | 89 cumulative_marking_duration_(0.0), |
| 83 cumulative_sweeping_duration_(0.0) { | 90 cumulative_sweeping_duration_(0.0), |
| 91 new_space_top_after_gc_(0) { |
| 84 current_ = Event(Event::START, NULL, NULL); | 92 current_ = Event(Event::START, NULL, NULL); |
| 85 current_.end_time = base::OS::TimeCurrentMillis(); | 93 current_.end_time = base::OS::TimeCurrentMillis(); |
| 86 previous_ = previous_mark_compactor_event_ = current_; | 94 previous_ = previous_mark_compactor_event_ = current_; |
| 87 } | 95 } |
| 88 | 96 |
| 89 | 97 |
| 90 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, | 98 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, |
| 91 const char* collector_reason) { | 99 const char* collector_reason) { |
| 92 previous_ = current_; | 100 previous_ = current_; |
| 101 double start_time = base::OS::TimeCurrentMillis(); |
| 102 if (new_space_top_after_gc_ != 0) { |
| 103 AddNewSpaceAllocationTime( |
| 104 start_time - previous_.end_time, |
| 105 reinterpret_cast<intptr_t>((heap_->new_space()->top()) - |
| 106 new_space_top_after_gc_)); |
| 107 } |
| 93 if (current_.type == Event::MARK_COMPACTOR) | 108 if (current_.type == Event::MARK_COMPACTOR) |
| 94 previous_mark_compactor_event_ = current_; | 109 previous_mark_compactor_event_ = current_; |
| 95 | 110 |
| 96 if (collector == SCAVENGER) { | 111 if (collector == SCAVENGER) { |
| 97 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); | 112 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); |
| 98 } else { | 113 } else { |
| 99 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); | 114 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason); |
| 100 } | 115 } |
| 101 | 116 |
| 102 current_.start_time = base::OS::TimeCurrentMillis(); | 117 current_.start_time = start_time; |
| 103 current_.start_object_size = heap_->SizeOfObjects(); | 118 current_.start_object_size = heap_->SizeOfObjects(); |
| 104 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); | 119 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size(); |
| 105 current_.start_holes_size = CountTotalHolesSize(heap_); | 120 current_.start_holes_size = CountTotalHolesSize(heap_); |
| 106 current_.new_space_object_size = | 121 current_.new_space_object_size = |
| 107 heap_->new_space()->top() - heap_->new_space()->bottom(); | 122 heap_->new_space()->top() - heap_->new_space()->bottom(); |
| 108 | 123 |
| 109 current_.cumulative_incremental_marking_steps = | 124 current_.cumulative_incremental_marking_steps = |
| 110 cumulative_incremental_marking_steps_; | 125 cumulative_incremental_marking_steps_; |
| 111 current_.cumulative_incremental_marking_bytes = | 126 current_.cumulative_incremental_marking_bytes = |
| 112 cumulative_incremental_marking_bytes_; | 127 cumulative_incremental_marking_bytes_; |
| 113 current_.cumulative_incremental_marking_duration = | 128 current_.cumulative_incremental_marking_duration = |
| 114 cumulative_incremental_marking_duration_; | 129 cumulative_incremental_marking_duration_; |
| 115 current_.cumulative_pure_incremental_marking_duration = | 130 current_.cumulative_pure_incremental_marking_duration = |
| 116 cumulative_pure_incremental_marking_duration_; | 131 cumulative_pure_incremental_marking_duration_; |
| 117 current_.longest_incremental_marking_step = longest_incremental_marking_step_; | 132 current_.longest_incremental_marking_step = longest_incremental_marking_step_; |
| 118 | 133 |
| 119 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) { | 134 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) { |
| 120 current_.scopes[i] = 0; | 135 current_.scopes[i] = 0; |
| 121 } | 136 } |
| 122 } | 137 } |
| 123 | 138 |
| 124 | 139 |
| 125 void GCTracer::Stop() { | 140 void GCTracer::Stop() { |
| 126 current_.end_time = base::OS::TimeCurrentMillis(); | 141 current_.end_time = base::OS::TimeCurrentMillis(); |
| 127 current_.end_object_size = heap_->SizeOfObjects(); | 142 current_.end_object_size = heap_->SizeOfObjects(); |
| 128 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); | 143 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); |
| 129 current_.end_holes_size = CountTotalHolesSize(heap_); | 144 current_.end_holes_size = CountTotalHolesSize(heap_); |
| 145 new_space_top_after_gc_ = |
| 146 reinterpret_cast<intptr_t>(heap_->new_space()->top()); |
| 130 | 147 |
| 131 if (current_.type == Event::SCAVENGER) { | 148 if (current_.type == Event::SCAVENGER) { |
| 132 current_.incremental_marking_steps = | 149 current_.incremental_marking_steps = |
| 133 current_.cumulative_incremental_marking_steps - | 150 current_.cumulative_incremental_marking_steps - |
| 134 previous_.cumulative_incremental_marking_steps; | 151 previous_.cumulative_incremental_marking_steps; |
| 135 current_.incremental_marking_bytes = | 152 current_.incremental_marking_bytes = |
| 136 current_.cumulative_incremental_marking_bytes - | 153 current_.cumulative_incremental_marking_bytes - |
| 137 previous_.cumulative_incremental_marking_bytes; | 154 previous_.cumulative_incremental_marking_bytes; |
| 138 current_.incremental_marking_duration = | 155 current_.incremental_marking_duration = |
| 139 current_.cumulative_incremental_marking_duration - | 156 current_.cumulative_incremental_marking_duration - |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 if (FLAG_trace_gc_nvp) | 194 if (FLAG_trace_gc_nvp) |
| 178 PrintNVP(); | 195 PrintNVP(); |
| 179 else | 196 else |
| 180 Print(); | 197 Print(); |
| 181 | 198 |
| 182 heap_->PrintShortHeapStatistics(); | 199 heap_->PrintShortHeapStatistics(); |
| 183 } | 200 } |
| 184 } | 201 } |
| 185 | 202 |
| 186 | 203 |
| 204 void GCTracer::AddNewSpaceAllocationTime(double duration, |
| 205 intptr_t allocation_in_bytes) { |
| 206 allocation_events_.push_front(AllocationEvent(duration, allocation_in_bytes)); |
| 207 } |
| 208 |
| 209 |
| 187 void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) { | 210 void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) { |
| 188 cumulative_incremental_marking_steps_++; | 211 cumulative_incremental_marking_steps_++; |
| 189 cumulative_incremental_marking_bytes_ += bytes; | 212 cumulative_incremental_marking_bytes_ += bytes; |
| 190 cumulative_incremental_marking_duration_ += duration; | 213 cumulative_incremental_marking_duration_ += duration; |
| 191 longest_incremental_marking_step_ = | 214 longest_incremental_marking_step_ = |
| 192 Max(longest_incremental_marking_step_, duration); | 215 Max(longest_incremental_marking_step_, duration); |
| 193 cumulative_marking_duration_ += duration; | 216 cumulative_marking_duration_ += duration; |
| 194 if (bytes > 0) { | 217 if (bytes > 0) { |
| 195 cumulative_pure_incremental_marking_duration_ += duration; | 218 cumulative_pure_incremental_marking_duration_ += duration; |
| 196 } | 219 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 current_.start_object_size - previous_.end_object_size; | 310 current_.start_object_size - previous_.end_object_size; |
| 288 PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc); | 311 PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc); |
| 289 PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_); | 312 PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_); |
| 290 PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ", | 313 PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ", |
| 291 heap_->semi_space_copied_object_size_); | 314 heap_->semi_space_copied_object_size_); |
| 292 PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_); | 315 PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_); |
| 293 PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_); | 316 PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_); |
| 294 PrintF("nodes_promoted=%d ", heap_->nodes_promoted_); | 317 PrintF("nodes_promoted=%d ", heap_->nodes_promoted_); |
| 295 PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_); | 318 PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_); |
| 296 PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_); | 319 PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_); |
| 320 PrintF("new_space_allocation_throughput=%d ", |
| 321 NewSpaceAllocationThroughputInBytesPerMillisecond()); |
| 297 | 322 |
| 298 if (current_.type == Event::SCAVENGER) { | 323 if (current_.type == Event::SCAVENGER) { |
| 299 PrintF("steps_count=%d ", current_.incremental_marking_steps); | 324 PrintF("steps_count=%d ", current_.incremental_marking_steps); |
| 300 PrintF("steps_took=%.1f ", current_.incremental_marking_duration); | 325 PrintF("steps_took=%.1f ", current_.incremental_marking_duration); |
| 301 PrintF("scavenge_throughput=%" V8_PTR_PREFIX "d ", | 326 PrintF("scavenge_throughput=%" V8_PTR_PREFIX "d ", |
| 302 ScavengeSpeedInBytesPerMillisecond()); | 327 ScavengeSpeedInBytesPerMillisecond()); |
| 303 } else { | 328 } else { |
| 304 PrintF("steps_count=%d ", current_.incremental_marking_steps); | 329 PrintF("steps_count=%d ", current_.incremental_marking_steps); |
| 305 PrintF("steps_took=%.1f ", current_.incremental_marking_duration); | 330 PrintF("steps_took=%.1f ", current_.incremental_marking_duration); |
| 306 PrintF("longest_step=%.1f ", current_.longest_incremental_marking_step); | 331 PrintF("longest_step=%.1f ", current_.longest_incremental_marking_step); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 bytes += iter->start_object_size; | 453 bytes += iter->start_object_size; |
| 429 durations += iter->end_time - iter->start_time + | 454 durations += iter->end_time - iter->start_time + |
| 430 iter->pure_incremental_marking_duration; | 455 iter->pure_incremental_marking_duration; |
| 431 ++iter; | 456 ++iter; |
| 432 } | 457 } |
| 433 | 458 |
| 434 if (durations == 0.0) return 0; | 459 if (durations == 0.0) return 0; |
| 435 | 460 |
| 436 return static_cast<intptr_t>(bytes / durations); | 461 return static_cast<intptr_t>(bytes / durations); |
| 437 } | 462 } |
| 463 |
| 464 |
| 465 intptr_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { |
| 466 intptr_t bytes = 0; |
| 467 double durations = 0.0; |
| 468 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); |
| 469 while (iter != allocation_events_.end()) { |
| 470 bytes += iter->allocation_in_bytes_; |
| 471 durations += iter->duration_; |
| 472 ++iter; |
| 473 } |
| 474 |
| 475 if (durations == 0.0) return 0; |
| 476 |
| 477 return static_cast<intptr_t>(bytes / durations); |
| 478 } |
| 438 } | 479 } |
| 439 } // namespace v8::internal | 480 } // namespace v8::internal |
| OLD | NEW |