Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(706)

Side by Side Diff: src/heap/gc-tracer.cc

Issue 1154873003: Add old generation allocation throughput computation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix CE Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/gc-tracer.h ('k') | src/heap/heap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 GCTracer::GCTracer(Heap* heap) 93 GCTracer::GCTracer(Heap* heap)
94 : heap_(heap), 94 : heap_(heap),
95 cumulative_incremental_marking_steps_(0), 95 cumulative_incremental_marking_steps_(0),
96 cumulative_incremental_marking_bytes_(0), 96 cumulative_incremental_marking_bytes_(0),
97 cumulative_incremental_marking_duration_(0.0), 97 cumulative_incremental_marking_duration_(0.0),
98 cumulative_pure_incremental_marking_duration_(0.0), 98 cumulative_pure_incremental_marking_duration_(0.0),
99 longest_incremental_marking_step_(0.0), 99 longest_incremental_marking_step_(0.0),
100 cumulative_marking_duration_(0.0), 100 cumulative_marking_duration_(0.0),
101 cumulative_sweeping_duration_(0.0), 101 cumulative_sweeping_duration_(0.0),
102 new_space_allocation_time_ms_(0.0), 102 allocation_time_ms_(0.0),
103 new_space_allocation_counter_bytes_(0), 103 new_space_allocation_counter_bytes_(0),
104 new_space_allocation_duration_since_gc_(0.0), 104 old_generation_allocation_counter_bytes_(0),
105 allocation_duration_since_gc_(0.0),
105 new_space_allocation_in_bytes_since_gc_(0), 106 new_space_allocation_in_bytes_since_gc_(0),
107 old_generation_allocation_in_bytes_since_gc_(0),
106 start_counter_(0) { 108 start_counter_(0) {
107 current_ = Event(Event::START, NULL, NULL); 109 current_ = Event(Event::START, NULL, NULL);
108 current_.end_time = base::OS::TimeCurrentMillis(); 110 current_.end_time = base::OS::TimeCurrentMillis();
109 previous_ = previous_incremental_mark_compactor_event_ = current_; 111 previous_ = previous_incremental_mark_compactor_event_ = current_;
110 } 112 }
111 113
112 114
113 void GCTracer::Start(GarbageCollector collector, const char* gc_reason, 115 void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
114 const char* collector_reason) { 116 const char* collector_reason) {
115 start_counter_++; 117 start_counter_++;
116 if (start_counter_ != 1) return; 118 if (start_counter_ != 1) return;
117 119
118 previous_ = current_; 120 previous_ = current_;
119 double start_time = heap_->MonotonicallyIncreasingTimeInMs(); 121 double start_time = heap_->MonotonicallyIncreasingTimeInMs();
120 SampleNewSpaceAllocation(start_time, heap_->NewSpaceAllocationCounter()); 122 SampleAllocation(start_time, heap_->NewSpaceAllocationCounter(),
123 heap_->OldGenerationAllocationCounter());
121 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) 124 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR)
122 previous_incremental_mark_compactor_event_ = current_; 125 previous_incremental_mark_compactor_event_ = current_;
123 126
124 if (collector == SCAVENGER) { 127 if (collector == SCAVENGER) {
125 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason); 128 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
126 } else if (collector == MARK_COMPACTOR) { 129 } else if (collector == MARK_COMPACTOR) {
127 if (heap_->incremental_marking()->WasActivated()) { 130 if (heap_->incremental_marking()->WasActivated()) {
128 current_ = 131 current_ =
129 Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason); 132 Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason);
130 } else { 133 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || 179 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) ||
177 (collector == MARK_COMPACTOR && 180 (collector == MARK_COMPACTOR &&
178 (current_.type == Event::MARK_COMPACTOR || 181 (current_.type == Event::MARK_COMPACTOR ||
179 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); 182 current_.type == Event::INCREMENTAL_MARK_COMPACTOR)));
180 183
181 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); 184 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs();
182 current_.end_object_size = heap_->SizeOfObjects(); 185 current_.end_object_size = heap_->SizeOfObjects();
183 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size(); 186 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size();
184 current_.end_holes_size = CountTotalHolesSize(heap_); 187 current_.end_holes_size = CountTotalHolesSize(heap_);
185 188
186 AddNewSpaceAllocation(current_.end_time); 189 AddAllocation(current_.end_time);
187 190
188 int committed_memory = static_cast<int>(heap_->CommittedMemory() / KB); 191 int committed_memory = static_cast<int>(heap_->CommittedMemory() / KB);
189 int used_memory = static_cast<int>(current_.end_object_size / KB); 192 int used_memory = static_cast<int>(current_.end_object_size / KB);
190 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample( 193 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample(
191 current_.end_time, committed_memory); 194 current_.end_time, committed_memory);
192 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample( 195 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample(
193 current_.end_time, used_memory); 196 current_.end_time, used_memory);
194 197
195 if (current_.type == Event::SCAVENGER) { 198 if (current_.type == Event::SCAVENGER) {
196 current_.incremental_marking_steps = 199 current_.incremental_marking_steps =
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 if (FLAG_trace_gc_nvp) 253 if (FLAG_trace_gc_nvp)
251 PrintNVP(); 254 PrintNVP();
252 else 255 else
253 Print(); 256 Print();
254 257
255 heap_->PrintShortHeapStatistics(); 258 heap_->PrintShortHeapStatistics();
256 } 259 }
257 } 260 }
258 261
259 262
260 void GCTracer::SampleNewSpaceAllocation(double current_ms, 263 void GCTracer::SampleAllocation(double current_ms,
261 size_t counter_bytes) { 264 size_t new_space_counter_bytes,
262 if (new_space_allocation_time_ms_ == 0) { 265 size_t old_generation_counter_bytes) {
266 if (allocation_time_ms_ == 0) {
263 // It is the first sample. 267 // It is the first sample.
264 new_space_allocation_time_ms_ = current_ms; 268 allocation_time_ms_ = current_ms;
265 new_space_allocation_counter_bytes_ = counter_bytes; 269 new_space_allocation_counter_bytes_ = new_space_counter_bytes;
270 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes;
266 return; 271 return;
267 } 272 }
268 // This assumes that counters are unsigned integers so that the subtraction 273 // This assumes that counters are unsigned integers so that the subtraction
269 // below works even if the new counter is less then the old counter. 274 // below works even if the new counter is less then the old counter.
270 size_t allocated_bytes = counter_bytes - new_space_allocation_counter_bytes_; 275 size_t new_space_allocated_bytes =
271 double duration = current_ms - new_space_allocation_time_ms_; 276 new_space_counter_bytes - new_space_allocation_counter_bytes_;
277 size_t old_generation_allocated_bytes =
278 old_generation_counter_bytes - old_generation_allocation_counter_bytes_;
279 double duration = current_ms - allocation_time_ms_;
272 const double kMinDurationMs = 1; 280 const double kMinDurationMs = 1;
273 if (duration < kMinDurationMs) { 281 if (duration < kMinDurationMs) {
274 // Do not sample small durations to avoid precision errors. 282 // Do not sample small durations to avoid precision errors.
275 return; 283 return;
276 } 284 }
277 new_space_allocation_time_ms_ = current_ms; 285 allocation_time_ms_ = current_ms;
278 new_space_allocation_counter_bytes_ = counter_bytes; 286 new_space_allocation_counter_bytes_ = new_space_counter_bytes;
279 new_space_allocation_duration_since_gc_ += duration; 287 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes;
280 new_space_allocation_in_bytes_since_gc_ += allocated_bytes; 288 allocation_duration_since_gc_ += duration;
289 new_space_allocation_in_bytes_since_gc_ += new_space_allocated_bytes;
290 old_generation_allocation_in_bytes_since_gc_ +=
291 old_generation_allocated_bytes;
281 } 292 }
282 293
283 294
284 void GCTracer::AddNewSpaceAllocation(double current_ms) { 295 void GCTracer::AddAllocation(double current_ms) {
285 new_space_allocation_time_ms_ = current_ms; 296 allocation_time_ms_ = current_ms;
297 new_space_allocation_events_.push_front(AllocationEvent(
298 allocation_duration_since_gc_, new_space_allocation_in_bytes_since_gc_));
286 allocation_events_.push_front( 299 allocation_events_.push_front(
287 AllocationEvent(new_space_allocation_duration_since_gc_, 300 AllocationEvent(allocation_duration_since_gc_,
288 new_space_allocation_in_bytes_since_gc_)); 301 new_space_allocation_in_bytes_since_gc_ +
289 new_space_allocation_duration_since_gc_ = 0; 302 old_generation_allocation_in_bytes_since_gc_));
303 allocation_duration_since_gc_ = 0;
290 new_space_allocation_in_bytes_since_gc_ = 0; 304 new_space_allocation_in_bytes_since_gc_ = 0;
305 old_generation_allocation_in_bytes_since_gc_ = 0;
291 } 306 }
292 307
293 308
294 void GCTracer::AddContextDisposalTime(double time) { 309 void GCTracer::AddContextDisposalTime(double time) {
295 context_disposal_events_.push_front(ContextDisposalEvent(time)); 310 context_disposal_events_.push_front(ContextDisposalEvent(time));
296 } 311 }
297 312
298 313
299 void GCTracer::AddSurvivalRatio(double promotion_ratio) { 314 void GCTracer::AddSurvivalRatio(double promotion_ratio) {
300 survival_events_.push_front(SurvivalEvent(promotion_ratio)); 315 survival_events_.push_front(SurvivalEvent(promotion_ratio));
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 } 591 }
577 592
578 if (durations == 0.0) return 0; 593 if (durations == 0.0) return 0;
579 594
580 return static_cast<intptr_t>(bytes / durations); 595 return static_cast<intptr_t>(bytes / durations);
581 } 596 }
582 597
583 598
584 size_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const { 599 size_t GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond() const {
585 size_t bytes = new_space_allocation_in_bytes_since_gc_; 600 size_t bytes = new_space_allocation_in_bytes_since_gc_;
586 double durations = new_space_allocation_duration_since_gc_; 601 double durations = allocation_duration_since_gc_;
587 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); 602 AllocationEventBuffer::const_iterator iter =
603 new_space_allocation_events_.begin();
588 const size_t max_bytes = static_cast<size_t>(-1); 604 const size_t max_bytes = static_cast<size_t>(-1);
589 while (iter != allocation_events_.end() && bytes < max_bytes - bytes) { 605 while (iter != new_space_allocation_events_.end() &&
606 bytes < max_bytes - bytes) {
590 bytes += iter->allocation_in_bytes_; 607 bytes += iter->allocation_in_bytes_;
591 durations += iter->duration_; 608 durations += iter->duration_;
592 ++iter; 609 ++iter;
593 } 610 }
594 611
595 if (durations == 0.0) return 0; 612 if (durations == 0.0) return 0;
596 613
597 return static_cast<size_t>(bytes / durations + 0.5); 614 return static_cast<size_t>(bytes / durations + 0.5);
598 } 615 }
599 616
600 617
601 size_t GCTracer::NewSpaceAllocatedBytesInLast(double time_ms) const { 618 size_t GCTracer::AllocatedBytesInLast(double time_ms) const {
602 size_t bytes = new_space_allocation_in_bytes_since_gc_; 619 size_t bytes = new_space_allocation_in_bytes_since_gc_ +
603 double durations = new_space_allocation_duration_since_gc_; 620 old_generation_allocation_in_bytes_since_gc_;
621 double durations = allocation_duration_since_gc_;
604 AllocationEventBuffer::const_iterator iter = allocation_events_.begin(); 622 AllocationEventBuffer::const_iterator iter = allocation_events_.begin();
605 const size_t max_bytes = static_cast<size_t>(-1); 623 const size_t max_bytes = static_cast<size_t>(-1);
606 while (iter != allocation_events_.end() && bytes < max_bytes - bytes && 624 while (iter != allocation_events_.end() && bytes < max_bytes - bytes &&
607 durations < time_ms) { 625 durations < time_ms) {
608 bytes += iter->allocation_in_bytes_; 626 bytes += iter->allocation_in_bytes_;
609 durations += iter->duration_; 627 durations += iter->duration_;
610 ++iter; 628 ++iter;
611 } 629 }
612 630
613 if (durations == 0.0) return 0; 631 if (durations == 0.0) return 0;
614 632
615 bytes = static_cast<size_t>(bytes * (time_ms / durations) + 0.5); 633 bytes = static_cast<size_t>(bytes * (time_ms / durations) + 0.5);
616 // Return at least 1 since 0 means "no data". 634 // Return at least 1 since 0 means "no data".
617 return std::max<size_t>(bytes, 1); 635 return std::max<size_t>(bytes, 1);
618 } 636 }
619 637
620 638
621 size_t GCTracer::CurrentNewSpaceAllocationThroughputInBytesPerMillisecond() 639 size_t GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const {
622 const {
623 static const double kThroughputTimeFrame = 5000; 640 static const double kThroughputTimeFrame = 5000;
624 size_t allocated_bytes = NewSpaceAllocatedBytesInLast(kThroughputTimeFrame); 641 size_t allocated_bytes = AllocatedBytesInLast(kThroughputTimeFrame);
625 if (allocated_bytes == 0) return 0; 642 if (allocated_bytes == 0) return 0;
626 return static_cast<size_t>((allocated_bytes / kThroughputTimeFrame) + 1); 643 return static_cast<size_t>((allocated_bytes / kThroughputTimeFrame) + 1);
627 } 644 }
628 645
629 646
630 double GCTracer::ContextDisposalRateInMilliseconds() const { 647 double GCTracer::ContextDisposalRateInMilliseconds() const {
631 if (context_disposal_events_.size() < kRingBufferMaxSize) return 0.0; 648 if (context_disposal_events_.size() < kRingBufferMaxSize) return 0.0;
632 649
633 double begin = base::OS::TimeCurrentMillis(); 650 double begin = base::OS::TimeCurrentMillis();
634 double end = 0.0; 651 double end = 0.0;
(...skipping 23 matching lines...) Expand all
658 675
659 676
660 bool GCTracer::SurvivalEventsRecorded() const { 677 bool GCTracer::SurvivalEventsRecorded() const {
661 return survival_events_.size() > 0; 678 return survival_events_.size() > 0;
662 } 679 }
663 680
664 681
665 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); } 682 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); }
666 } 683 }
667 } // namespace v8::internal 684 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/gc-tracer.h ('k') | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698