blob: 2b1f06acd7dbf1d54f8a2ca0bb96240e467a9adc [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/heap/gc-tracer.h"
6
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/counters.h"
8#include "src/heap/heap-inl.h"
9#include "src/isolate.h"
10
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011namespace v8 {
12namespace internal {
13
14static intptr_t CountTotalHolesSize(Heap* heap) {
15 intptr_t holes_size = 0;
16 OldSpaces spaces(heap);
17 for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) {
18 holes_size += space->Waste() + space->Available();
19 }
20 return holes_size;
21}
22
23
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024GCTracer::Scope::Scope(GCTracer* tracer, ScopeId scope)
25 : tracer_(tracer), scope_(scope) {
26 start_time_ = tracer_->heap_->MonotonicallyIncreasingTimeInMs();
Ben Murdochda12d292016-06-02 14:46:10 +010027 // TODO(cbruni): remove once we fully moved to a trace-based system.
28 if (FLAG_runtime_call_stats) {
Ben Murdochc5610432016-08-08 18:44:38 +010029 RuntimeCallStats::Enter(tracer_->heap_->isolate(), &timer_,
30 &RuntimeCallStats::GC);
Ben Murdochda12d292016-06-02 14:46:10 +010031 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032}
33
34
35GCTracer::Scope::~Scope() {
36 DCHECK(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned.
37 tracer_->current_.scopes[scope_] +=
38 tracer_->heap_->MonotonicallyIncreasingTimeInMs() - start_time_;
Ben Murdochda12d292016-06-02 14:46:10 +010039 // TODO(cbruni): remove once we fully moved to a trace-based system.
40 if (FLAG_runtime_call_stats) {
Ben Murdochc5610432016-08-08 18:44:38 +010041 RuntimeCallStats::Leave(tracer_->heap_->isolate(), &timer_);
Ben Murdochda12d292016-06-02 14:46:10 +010042 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043}
44
Ben Murdochda12d292016-06-02 14:46:10 +010045const char* GCTracer::Scope::Name(ScopeId id) {
46#define CASE(scope) \
47 case Scope::scope: \
48 return "V8.GC_" #scope;
49 switch (id) {
50 TRACER_SCOPES(CASE)
51 case Scope::NUMBER_OF_SCOPES:
52 break;
53 }
54#undef CASE
55 return "(unknown)";
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056}
57
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058GCTracer::Event::Event(Type type, const char* gc_reason,
59 const char* collector_reason)
60 : type(type),
61 gc_reason(gc_reason),
62 collector_reason(collector_reason),
63 start_time(0.0),
64 end_time(0.0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000065 reduce_memory(false),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 start_object_size(0),
67 end_object_size(0),
68 start_memory_size(0),
69 end_memory_size(0),
70 start_holes_size(0),
71 end_holes_size(0),
72 cumulative_incremental_marking_steps(0),
73 incremental_marking_steps(0),
74 cumulative_incremental_marking_bytes(0),
75 incremental_marking_bytes(0),
76 cumulative_incremental_marking_duration(0.0),
77 incremental_marking_duration(0.0),
78 cumulative_pure_incremental_marking_duration(0.0),
79 pure_incremental_marking_duration(0.0),
80 longest_incremental_marking_step(0.0) {
81 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
82 scopes[i] = 0;
83 }
84}
85
86
87const char* GCTracer::Event::TypeName(bool short_name) const {
88 switch (type) {
89 case SCAVENGER:
90 if (short_name) {
91 return "s";
92 } else {
93 return "Scavenge";
94 }
95 case MARK_COMPACTOR:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096 case INCREMENTAL_MARK_COMPACTOR:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097 if (short_name) {
98 return "ms";
99 } else {
100 return "Mark-sweep";
101 }
102 case START:
103 if (short_name) {
104 return "st";
105 } else {
106 return "Start";
107 }
108 }
109 return "Unknown Event Type";
110}
111
112
113GCTracer::GCTracer(Heap* heap)
114 : heap_(heap),
115 cumulative_incremental_marking_steps_(0),
116 cumulative_incremental_marking_bytes_(0),
117 cumulative_incremental_marking_duration_(0.0),
118 cumulative_pure_incremental_marking_duration_(0.0),
119 longest_incremental_marking_step_(0.0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 cumulative_incremental_marking_finalization_steps_(0),
121 cumulative_incremental_marking_finalization_duration_(0.0),
122 longest_incremental_marking_finalization_step_(0.0),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 cumulative_marking_duration_(0.0),
124 cumulative_sweeping_duration_(0.0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 allocation_time_ms_(0.0),
126 new_space_allocation_counter_bytes_(0),
127 old_generation_allocation_counter_bytes_(0),
128 allocation_duration_since_gc_(0.0),
129 new_space_allocation_in_bytes_since_gc_(0),
130 old_generation_allocation_in_bytes_since_gc_(0),
131 combined_mark_compact_speed_cache_(0.0),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 start_counter_(0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133 current_ = Event(Event::START, NULL, NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400135 previous_ = previous_incremental_mark_compactor_event_ = current_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136}
137
Ben Murdoch61f157c2016-09-16 13:49:30 +0100138void GCTracer::ResetForTesting() {
139 cumulative_incremental_marking_steps_ = 0.0;
140 cumulative_incremental_marking_bytes_ = 0.0;
141 cumulative_incremental_marking_duration_ = 0.0;
142 cumulative_pure_incremental_marking_duration_ = 0.0;
143 longest_incremental_marking_step_ = 0.0;
144 cumulative_incremental_marking_finalization_steps_ = 0.0;
145 cumulative_incremental_marking_finalization_duration_ = 0.0;
146 longest_incremental_marking_finalization_step_ = 0.0;
147 cumulative_marking_duration_ = 0.0;
148 cumulative_sweeping_duration_ = 0.0;
149 allocation_time_ms_ = 0.0;
150 new_space_allocation_counter_bytes_ = 0.0;
151 old_generation_allocation_counter_bytes_ = 0.0;
152 allocation_duration_since_gc_ = 0.0;
153 new_space_allocation_in_bytes_since_gc_ = 0.0;
154 old_generation_allocation_in_bytes_since_gc_ = 0.0;
155 combined_mark_compact_speed_cache_ = 0.0;
156 start_counter_ = 0;
157}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158
159void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
160 const char* collector_reason) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400161 start_counter_++;
162 if (start_counter_ != 1) return;
163
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164 previous_ = current_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000165 double start_time = heap_->MonotonicallyIncreasingTimeInMs();
166 SampleAllocation(start_time, heap_->NewSpaceAllocationCounter(),
167 heap_->OldGenerationAllocationCounter());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168 if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR)
169 previous_incremental_mark_compactor_event_ = current_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170
171 if (collector == SCAVENGER) {
172 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 } else if (collector == MARK_COMPACTOR) {
174 if (heap_->incremental_marking()->WasActivated()) {
175 current_ =
176 Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason);
177 } else {
178 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
179 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 }
181
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 current_.reduce_memory = heap_->ShouldReduceMemory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183 current_.start_time = start_time;
184 current_.start_object_size = heap_->SizeOfObjects();
Ben Murdochc5610432016-08-08 18:44:38 +0100185 current_.start_memory_size = heap_->memory_allocator()->Size();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186 current_.start_holes_size = CountTotalHolesSize(heap_);
187 current_.new_space_object_size =
188 heap_->new_space()->top() - heap_->new_space()->bottom();
189
190 current_.cumulative_incremental_marking_steps =
191 cumulative_incremental_marking_steps_;
192 current_.cumulative_incremental_marking_bytes =
193 cumulative_incremental_marking_bytes_;
194 current_.cumulative_incremental_marking_duration =
195 cumulative_incremental_marking_duration_;
196 current_.cumulative_pure_incremental_marking_duration =
197 cumulative_pure_incremental_marking_duration_;
198 current_.longest_incremental_marking_step = longest_incremental_marking_step_;
199
200 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
201 current_.scopes[i] = 0;
202 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 int committed_memory = static_cast<int>(heap_->CommittedMemory() / KB);
204 int used_memory = static_cast<int>(current_.start_object_size / KB);
205 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample(
206 start_time, committed_memory);
207 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample(
208 start_time, used_memory);
Ben Murdochda12d292016-06-02 14:46:10 +0100209 // TODO(cbruni): remove once we fully moved to a trace-based system.
210 if (FLAG_runtime_call_stats) {
Ben Murdochc5610432016-08-08 18:44:38 +0100211 RuntimeCallStats::Enter(heap_->isolate(), &timer_, &RuntimeCallStats::GC);
Ben Murdochda12d292016-06-02 14:46:10 +0100212 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213}
214
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215void GCTracer::Stop(GarbageCollector collector) {
216 start_counter_--;
217 if (start_counter_ != 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000218 Output("[Finished reentrant %s during %s.]\n",
219 collector == SCAVENGER ? "Scavenge" : "Mark-sweep",
220 current_.TypeName(false));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400221 return;
222 }
223
224 DCHECK(start_counter_ >= 0);
225 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) ||
226 (collector == MARK_COMPACTOR &&
227 (current_.type == Event::MARK_COMPACTOR ||
228 current_.type == Event::INCREMENTAL_MARK_COMPACTOR)));
229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 current_.end_object_size = heap_->SizeOfObjects();
Ben Murdochc5610432016-08-08 18:44:38 +0100232 current_.end_memory_size = heap_->memory_allocator()->Size();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 current_.end_holes_size = CountTotalHolesSize(heap_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 current_.survived_new_space_object_size = heap_->SurvivedNewSpaceObjectSize();
235
236 AddAllocation(current_.end_time);
237
238 int committed_memory = static_cast<int>(heap_->CommittedMemory() / KB);
239 int used_memory = static_cast<int>(current_.end_object_size / KB);
240 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample(
241 current_.end_time, committed_memory);
242 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample(
243 current_.end_time, used_memory);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244
Ben Murdochda12d292016-06-02 14:46:10 +0100245 double duration = current_.end_time - current_.start_time;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000246 if (current_.type == Event::SCAVENGER) {
247 current_.incremental_marking_steps =
248 current_.cumulative_incremental_marking_steps -
249 previous_.cumulative_incremental_marking_steps;
250 current_.incremental_marking_bytes =
251 current_.cumulative_incremental_marking_bytes -
252 previous_.cumulative_incremental_marking_bytes;
253 current_.incremental_marking_duration =
254 current_.cumulative_incremental_marking_duration -
255 previous_.cumulative_incremental_marking_duration;
256 current_.pure_incremental_marking_duration =
257 current_.cumulative_pure_incremental_marking_duration -
258 previous_.cumulative_pure_incremental_marking_duration;
Ben Murdochda12d292016-06-02 14:46:10 +0100259 recorded_scavenges_total_.Push(
260 MakeBytesAndDuration(current_.new_space_object_size, duration));
261 recorded_scavenges_survived_.Push(MakeBytesAndDuration(
262 current_.survived_new_space_object_size, duration));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400263 } else if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264 current_.incremental_marking_steps =
265 current_.cumulative_incremental_marking_steps -
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400266 previous_incremental_mark_compactor_event_
267 .cumulative_incremental_marking_steps;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000268 current_.incremental_marking_bytes =
269 current_.cumulative_incremental_marking_bytes -
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400270 previous_incremental_mark_compactor_event_
271 .cumulative_incremental_marking_bytes;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000272 current_.incremental_marking_duration =
273 current_.cumulative_incremental_marking_duration -
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400274 previous_incremental_mark_compactor_event_
275 .cumulative_incremental_marking_duration;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000276 current_.pure_incremental_marking_duration =
277 current_.cumulative_pure_incremental_marking_duration -
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400278 previous_incremental_mark_compactor_event_
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 .cumulative_pure_incremental_marking_duration;
280 longest_incremental_marking_step_ = 0.0;
Ben Murdochda12d292016-06-02 14:46:10 +0100281 recorded_incremental_marking_steps_.Push(
282 MakeBytesAndDuration(current_.incremental_marking_bytes,
283 current_.pure_incremental_marking_duration));
284 recorded_incremental_mark_compacts_.Push(
285 MakeBytesAndDuration(current_.start_object_size, duration));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000286 combined_mark_compact_speed_cache_ = 0.0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400287 } else {
288 DCHECK(current_.incremental_marking_bytes == 0);
289 DCHECK(current_.incremental_marking_duration == 0);
290 DCHECK(current_.pure_incremental_marking_duration == 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000291 longest_incremental_marking_step_ = 0.0;
Ben Murdochda12d292016-06-02 14:46:10 +0100292 recorded_mark_compacts_.Push(
293 MakeBytesAndDuration(current_.start_object_size, duration));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000294 combined_mark_compact_speed_cache_ = 0.0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295 }
296
297 // TODO(ernstm): move the code below out of GCTracer.
298
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0);
300
301 heap_->UpdateCumulativeGCStatistics(duration, spent_in_mutator,
302 current_.scopes[Scope::MC_MARK]);
303
304 if (current_.type == Event::SCAVENGER && FLAG_trace_gc_ignore_scavenger)
305 return;
306
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000307 if (FLAG_trace_gc_nvp)
308 PrintNVP();
309 else
310 Print();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000311
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 if (FLAG_trace_gc) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000313 heap_->PrintShortHeapStatistics();
314 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315
316 longest_incremental_marking_finalization_step_ = 0.0;
317 cumulative_incremental_marking_finalization_steps_ = 0;
318 cumulative_incremental_marking_finalization_duration_ = 0.0;
Ben Murdochda12d292016-06-02 14:46:10 +0100319 // TODO(cbruni): remove once we fully moved to a trace-based system.
320 if (FLAG_runtime_call_stats) {
Ben Murdochc5610432016-08-08 18:44:38 +0100321 RuntimeCallStats::Leave(heap_->isolate(), &timer_);
Ben Murdochda12d292016-06-02 14:46:10 +0100322 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323}
324
325
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326void GCTracer::SampleAllocation(double current_ms,
327 size_t new_space_counter_bytes,
328 size_t old_generation_counter_bytes) {
329 if (allocation_time_ms_ == 0) {
330 // It is the first sample.
331 allocation_time_ms_ = current_ms;
332 new_space_allocation_counter_bytes_ = new_space_counter_bytes;
333 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes;
334 return;
335 }
336 // This assumes that counters are unsigned integers so that the subtraction
337 // below works even if the new counter is less then the old counter.
338 size_t new_space_allocated_bytes =
339 new_space_counter_bytes - new_space_allocation_counter_bytes_;
340 size_t old_generation_allocated_bytes =
341 old_generation_counter_bytes - old_generation_allocation_counter_bytes_;
342 double duration = current_ms - allocation_time_ms_;
343 allocation_time_ms_ = current_ms;
344 new_space_allocation_counter_bytes_ = new_space_counter_bytes;
345 old_generation_allocation_counter_bytes_ = old_generation_counter_bytes;
346 allocation_duration_since_gc_ += duration;
347 new_space_allocation_in_bytes_since_gc_ += new_space_allocated_bytes;
348 old_generation_allocation_in_bytes_since_gc_ +=
349 old_generation_allocated_bytes;
350}
351
352
353void GCTracer::AddAllocation(double current_ms) {
354 allocation_time_ms_ = current_ms;
Ben Murdochda12d292016-06-02 14:46:10 +0100355 if (allocation_duration_since_gc_ > 0) {
356 recorded_new_generation_allocations_.Push(
357 MakeBytesAndDuration(new_space_allocation_in_bytes_since_gc_,
358 allocation_duration_since_gc_));
359 recorded_old_generation_allocations_.Push(
360 MakeBytesAndDuration(old_generation_allocation_in_bytes_since_gc_,
361 allocation_duration_since_gc_));
362 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000363 allocation_duration_since_gc_ = 0;
364 new_space_allocation_in_bytes_since_gc_ = 0;
365 old_generation_allocation_in_bytes_since_gc_ = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366}
367
368
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400369void GCTracer::AddContextDisposalTime(double time) {
Ben Murdochda12d292016-06-02 14:46:10 +0100370 recorded_context_disposal_times_.Push(time);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400371}
372
373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374void GCTracer::AddCompactionEvent(double duration,
375 intptr_t live_bytes_compacted) {
Ben Murdochda12d292016-06-02 14:46:10 +0100376 recorded_compactions_.Push(
377 MakeBytesAndDuration(live_bytes_compacted, duration));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378}
379
380
381void GCTracer::AddSurvivalRatio(double promotion_ratio) {
Ben Murdochda12d292016-06-02 14:46:10 +0100382 recorded_survival_ratios_.Push(promotion_ratio);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400383}
384
385
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000386void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) {
387 cumulative_incremental_marking_steps_++;
388 cumulative_incremental_marking_bytes_ += bytes;
389 cumulative_incremental_marking_duration_ += duration;
390 longest_incremental_marking_step_ =
391 Max(longest_incremental_marking_step_, duration);
392 cumulative_marking_duration_ += duration;
393 if (bytes > 0) {
394 cumulative_pure_incremental_marking_duration_ += duration;
395 }
396}
397
398
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399void GCTracer::AddIncrementalMarkingFinalizationStep(double duration) {
400 cumulative_incremental_marking_finalization_steps_++;
401 cumulative_incremental_marking_finalization_duration_ += duration;
402 longest_incremental_marking_finalization_step_ =
403 Max(longest_incremental_marking_finalization_step_, duration);
404}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000405
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000406
407void GCTracer::Output(const char* format, ...) const {
408 if (FLAG_trace_gc) {
409 va_list arguments;
410 va_start(arguments, format);
411 base::OS::VPrint(format, arguments);
412 va_end(arguments);
413 }
414
415 const int kBufferSize = 256;
416 char raw_buffer[kBufferSize];
417 Vector<char> buffer(raw_buffer, kBufferSize);
418 va_list arguments2;
419 va_start(arguments2, format);
420 VSNPrintF(buffer, format, arguments2);
421 va_end(arguments2);
422
423 heap_->AddToRingBuffer(buffer.start());
424}
425
426
427void GCTracer::Print() const {
428 if (FLAG_trace_gc) {
Ben Murdochc5610432016-08-08 18:44:38 +0100429 PrintIsolate(heap_->isolate(), "%s", "");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000430 }
431 Output("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
432
433 Output("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", current_.TypeName(false),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 static_cast<double>(current_.start_object_size) / MB,
435 static_cast<double>(current_.start_memory_size) / MB,
436 static_cast<double>(current_.end_object_size) / MB,
437 static_cast<double>(current_.end_memory_size) / MB);
438
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000439 double duration = current_.end_time - current_.start_time;
Ben Murdochda12d292016-06-02 14:46:10 +0100440 Output("%.1f / %.1f ms", duration, TotalExternalTime());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 if (current_.type == Event::SCAVENGER) {
443 if (current_.incremental_marking_steps > 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000444 Output(" (+ %.1f ms in %d steps since last GC)",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000445 current_.incremental_marking_duration,
446 current_.incremental_marking_steps);
447 }
448 } else {
449 if (current_.incremental_marking_steps > 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 Output(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451 " (+ %.1f ms in %d steps since start of marking, "
452 "biggest step %.1f ms)",
453 current_.incremental_marking_duration,
454 current_.incremental_marking_steps,
455 current_.longest_incremental_marking_step);
456 }
457 }
458
459 if (current_.gc_reason != NULL) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460 Output(" [%s]", current_.gc_reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461 }
462
463 if (current_.collector_reason != NULL) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 Output(" [%s]", current_.collector_reason);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465 }
466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467 Output(".\n");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468}
469
470
471void GCTracer::PrintNVP() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 double duration = current_.end_time - current_.start_time;
473 double spent_in_mutator = current_.start_time - previous_.end_time;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 intptr_t allocated_since_last_gc =
475 current_.start_object_size - previous_.end_object_size;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000476
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000477 switch (current_.type) {
478 case Event::SCAVENGER:
479 PrintIsolate(heap_->isolate(),
480 "%8.0f ms: "
481 "pause=%.1f "
482 "mutator=%.1f "
483 "gc=%s "
484 "reduce_memory=%d "
485 "scavenge=%.2f "
486 "old_new=%.2f "
487 "weak=%.2f "
488 "roots=%.2f "
489 "code=%.2f "
490 "semispace=%.2f "
491 "object_groups=%.2f "
Ben Murdochda12d292016-06-02 14:46:10 +0100492 "external_prologue=%.2f "
493 "external_epilogue=%.2f "
494 "external_weak_global_handles=%.2f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 "steps_count=%d "
496 "steps_took=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100497 "scavenge_throughput=%.f "
Ben Murdochc5610432016-08-08 18:44:38 +0100498 "total_size_before=%" V8PRIdPTR
499 " "
500 "total_size_after=%" V8PRIdPTR
501 " "
502 "holes_size_before=%" V8PRIdPTR
503 " "
504 "holes_size_after=%" V8PRIdPTR
505 " "
506 "allocated=%" V8PRIdPTR
507 " "
508 "promoted=%" V8PRIdPTR
509 " "
510 "semi_space_copied=%" V8PRIdPTR
511 " "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512 "nodes_died_in_new=%d "
513 "nodes_copied_in_new=%d "
514 "nodes_promoted=%d "
515 "promotion_ratio=%.1f%% "
516 "average_survival_ratio=%.1f%% "
517 "promotion_rate=%.1f%% "
518 "semi_space_copy_rate=%.1f%% "
Ben Murdochda12d292016-06-02 14:46:10 +0100519 "new_space_allocation_throughput=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000520 "context_disposal_rate=%.1f\n",
521 heap_->isolate()->time_millis_since_init(), duration,
522 spent_in_mutator, current_.TypeName(true),
523 current_.reduce_memory,
524 current_.scopes[Scope::SCAVENGER_SCAVENGE],
525 current_.scopes[Scope::SCAVENGER_OLD_TO_NEW_POINTERS],
526 current_.scopes[Scope::SCAVENGER_WEAK],
527 current_.scopes[Scope::SCAVENGER_ROOTS],
528 current_.scopes[Scope::SCAVENGER_CODE_FLUSH_CANDIDATES],
529 current_.scopes[Scope::SCAVENGER_SEMISPACE],
530 current_.scopes[Scope::SCAVENGER_OBJECT_GROUPS],
Ben Murdochda12d292016-06-02 14:46:10 +0100531 current_.scopes[Scope::SCAVENGER_EXTERNAL_PROLOGUE],
532 current_.scopes[Scope::SCAVENGER_EXTERNAL_EPILOGUE],
533 current_.scopes[Scope::EXTERNAL_WEAK_GLOBAL_HANDLES],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000534 current_.incremental_marking_steps,
535 current_.incremental_marking_duration,
536 ScavengeSpeedInBytesPerMillisecond(),
537 current_.start_object_size, current_.end_object_size,
538 current_.start_holes_size, current_.end_holes_size,
539 allocated_since_last_gc, heap_->promoted_objects_size(),
540 heap_->semi_space_copied_object_size(),
541 heap_->nodes_died_in_new_space_,
542 heap_->nodes_copied_in_new_space_, heap_->nodes_promoted_,
543 heap_->promotion_ratio_, AverageSurvivalRatio(),
544 heap_->promotion_rate_, heap_->semi_space_copied_rate_,
545 NewSpaceAllocationThroughputInBytesPerMillisecond(),
546 ContextDisposalRateInMilliseconds());
547 break;
548 case Event::MARK_COMPACTOR:
549 case Event::INCREMENTAL_MARK_COMPACTOR:
550 PrintIsolate(
551 heap_->isolate(),
552 "%8.0f ms: "
553 "pause=%.1f "
554 "mutator=%.1f "
555 "gc=%s "
556 "reduce_memory=%d "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000557 "clear=%1.f "
558 "clear.code_flush=%.1f "
559 "clear.dependent_code=%.1f "
560 "clear.global_handles=%.1f "
561 "clear.maps=%.1f "
562 "clear.slots_buffer=%.1f "
563 "clear.store_buffer=%.1f "
564 "clear.string_table=%.1f "
565 "clear.weak_cells=%.1f "
566 "clear.weak_collections=%.1f "
567 "clear.weak_lists=%.1f "
568 "evacuate=%.1f "
569 "evacuate.candidates=%.1f "
570 "evacuate.clean_up=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100571 "evacuate.copy=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 "evacuate.update_pointers=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000573 "evacuate.update_pointers.to_evacuated=%.1f "
574 "evacuate.update_pointers.to_new=%.1f "
575 "evacuate.update_pointers.weak=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100576 "external.mc_prologue=%.1f "
577 "external.mc_epilogue=%.1f "
578 "external.mc_incremental_prologue=%.1f "
579 "external.mc_incremental_epilogue=%.1f "
580 "external.weak_global_handles=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 "finish=%.1f "
582 "mark=%.1f "
583 "mark.finish_incremental=%.1f "
584 "mark.prepare_code_flush=%.1f "
585 "mark.roots=%.1f "
586 "mark.weak_closure=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100587 "mark.weak_closure.ephemeral=%.1f "
588 "mark.weak_closure.weak_handles=%.1f "
589 "mark.weak_closure.weak_roots=%.1f "
590 "mark.weak_closure.harmony=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000591 "sweep=%.1f "
592 "sweep.code=%.1f "
593 "sweep.map=%.1f "
594 "sweep.old=%.1f "
595 "incremental_finalize=%.1f "
596 "steps_count=%d "
597 "steps_took=%.1f "
598 "longest_step=%.1f "
599 "finalization_steps_count=%d "
600 "finalization_steps_took=%.1f "
601 "finalization_longest_step=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100602 "incremental_marking_throughput=%.f "
Ben Murdochc5610432016-08-08 18:44:38 +0100603 "total_size_before=%" V8PRIdPTR
604 " "
605 "total_size_after=%" V8PRIdPTR
606 " "
607 "holes_size_before=%" V8PRIdPTR
608 " "
609 "holes_size_after=%" V8PRIdPTR
610 " "
611 "allocated=%" V8PRIdPTR
612 " "
613 "promoted=%" V8PRIdPTR
614 " "
615 "semi_space_copied=%" V8PRIdPTR
616 " "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000617 "nodes_died_in_new=%d "
618 "nodes_copied_in_new=%d "
619 "nodes_promoted=%d "
620 "promotion_ratio=%.1f%% "
621 "average_survival_ratio=%.1f%% "
622 "promotion_rate=%.1f%% "
623 "semi_space_copy_rate=%.1f%% "
Ben Murdochda12d292016-06-02 14:46:10 +0100624 "new_space_allocation_throughput=%.1f "
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000625 "context_disposal_rate=%.1f "
Ben Murdochda12d292016-06-02 14:46:10 +0100626 "compaction_speed=%.f\n",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000627 heap_->isolate()->time_millis_since_init(), duration,
628 spent_in_mutator, current_.TypeName(true), current_.reduce_memory,
Ben Murdochda12d292016-06-02 14:46:10 +0100629 current_.scopes[Scope::MC_CLEAR],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000630 current_.scopes[Scope::MC_CLEAR_CODE_FLUSH],
631 current_.scopes[Scope::MC_CLEAR_DEPENDENT_CODE],
632 current_.scopes[Scope::MC_CLEAR_GLOBAL_HANDLES],
633 current_.scopes[Scope::MC_CLEAR_MAPS],
634 current_.scopes[Scope::MC_CLEAR_SLOTS_BUFFER],
635 current_.scopes[Scope::MC_CLEAR_STORE_BUFFER],
636 current_.scopes[Scope::MC_CLEAR_STRING_TABLE],
637 current_.scopes[Scope::MC_CLEAR_WEAK_CELLS],
638 current_.scopes[Scope::MC_CLEAR_WEAK_COLLECTIONS],
639 current_.scopes[Scope::MC_CLEAR_WEAK_LISTS],
640 current_.scopes[Scope::MC_EVACUATE],
641 current_.scopes[Scope::MC_EVACUATE_CANDIDATES],
642 current_.scopes[Scope::MC_EVACUATE_CLEAN_UP],
Ben Murdochda12d292016-06-02 14:46:10 +0100643 current_.scopes[Scope::MC_EVACUATE_COPY],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645 current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_TO_EVACUATED],
646 current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW],
647 current_.scopes[Scope::MC_EVACUATE_UPDATE_POINTERS_WEAK],
Ben Murdochda12d292016-06-02 14:46:10 +0100648 current_.scopes[Scope::MC_EXTERNAL_PROLOGUE],
649 current_.scopes[Scope::MC_EXTERNAL_EPILOGUE],
650 current_.scopes[Scope::MC_INCREMENTAL_EXTERNAL_PROLOGUE],
651 current_.scopes[Scope::MC_INCREMENTAL_EXTERNAL_EPILOGUE],
652 current_.scopes[Scope::EXTERNAL_WEAK_GLOBAL_HANDLES],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000653 current_.scopes[Scope::MC_FINISH], current_.scopes[Scope::MC_MARK],
654 current_.scopes[Scope::MC_MARK_FINISH_INCREMENTAL],
655 current_.scopes[Scope::MC_MARK_PREPARE_CODE_FLUSH],
656 current_.scopes[Scope::MC_MARK_ROOTS],
657 current_.scopes[Scope::MC_MARK_WEAK_CLOSURE],
Ben Murdochda12d292016-06-02 14:46:10 +0100658 current_.scopes[Scope::MC_MARK_WEAK_CLOSURE_EPHEMERAL],
659 current_.scopes[Scope::MC_MARK_WEAK_CLOSURE_WEAK_HANDLES],
660 current_.scopes[Scope::MC_MARK_WEAK_CLOSURE_WEAK_ROOTS],
661 current_.scopes[Scope::MC_MARK_WEAK_CLOSURE_HARMONY],
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000662 current_.scopes[Scope::MC_SWEEP],
663 current_.scopes[Scope::MC_SWEEP_CODE],
664 current_.scopes[Scope::MC_SWEEP_MAP],
665 current_.scopes[Scope::MC_SWEEP_OLD],
666 current_.scopes[Scope::MC_INCREMENTAL_FINALIZE],
667 current_.incremental_marking_steps,
668 current_.incremental_marking_duration,
669 current_.longest_incremental_marking_step,
670 cumulative_incremental_marking_finalization_steps_,
671 cumulative_incremental_marking_finalization_duration_,
672 longest_incremental_marking_finalization_step_,
673 IncrementalMarkingSpeedInBytesPerMillisecond(),
674 current_.start_object_size, current_.end_object_size,
675 current_.start_holes_size, current_.end_holes_size,
676 allocated_since_last_gc, heap_->promoted_objects_size(),
677 heap_->semi_space_copied_object_size(),
678 heap_->nodes_died_in_new_space_, heap_->nodes_copied_in_new_space_,
679 heap_->nodes_promoted_, heap_->promotion_ratio_,
680 AverageSurvivalRatio(), heap_->promotion_rate_,
681 heap_->semi_space_copied_rate_,
682 NewSpaceAllocationThroughputInBytesPerMillisecond(),
683 ContextDisposalRateInMilliseconds(),
684 CompactionSpeedInBytesPerMillisecond());
685 break;
686 case Event::START:
687 break;
688 default:
689 UNREACHABLE();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000691}
692
Ben Murdochda12d292016-06-02 14:46:10 +0100693double GCTracer::AverageSpeed(const RingBuffer<BytesAndDuration>& buffer,
694 const BytesAndDuration& initial, double time_ms) {
695 BytesAndDuration sum = buffer.Sum(
696 [time_ms](BytesAndDuration a, BytesAndDuration b) {
697 if (time_ms != 0 && a.second >= time_ms) return a;
698 return std::make_pair(a.first + b.first, a.second + b.second);
699 },
700 initial);
701 uint64_t bytes = sum.first;
702 double durations = sum.second;
703 if (durations == 0.0) return 0;
704 double speed = bytes / durations;
705 const int max_speed = 1024 * MB;
706 const int min_speed = 1;
707 if (speed >= max_speed) return max_speed;
708 if (speed <= min_speed) return min_speed;
709 return speed;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000710}
711
Ben Murdochda12d292016-06-02 14:46:10 +0100712double GCTracer::AverageSpeed(const RingBuffer<BytesAndDuration>& buffer) {
713 return AverageSpeed(buffer, MakeBytesAndDuration(0, 0), 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000714}
715
Ben Murdochda12d292016-06-02 14:46:10 +0100716double GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 if (cumulative_incremental_marking_duration_ == 0.0) return 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718 // We haven't completed an entire round of incremental marking, yet.
719 // Use data from GCTracer instead of data from event buffers.
Ben Murdochda12d292016-06-02 14:46:10 +0100720 if (recorded_incremental_marking_steps_.Count() == 0) {
721 return cumulative_incremental_marking_bytes_ /
722 cumulative_pure_incremental_marking_duration_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000723 }
Ben Murdochda12d292016-06-02 14:46:10 +0100724 return AverageSpeed(recorded_incremental_marking_steps_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000725}
726
Ben Murdochda12d292016-06-02 14:46:10 +0100727double GCTracer::ScavengeSpeedInBytesPerMillisecond(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 ScavengeSpeedMode mode) const {
Ben Murdochda12d292016-06-02 14:46:10 +0100729 if (mode == kForAllObjects) {
730 return AverageSpeed(recorded_scavenges_total_);
731 } else {
732 return AverageSpeed(recorded_scavenges_survived_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000733 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735
Ben Murdochda12d292016-06-02 14:46:10 +0100736double GCTracer::CompactionSpeedInBytesPerMillisecond() const {
737 return AverageSpeed(recorded_compactions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000738}
739
Ben Murdochda12d292016-06-02 14:46:10 +0100740double GCTracer::MarkCompactSpeedInBytesPerMillisecond() const {
741 return AverageSpeed(recorded_mark_compacts_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400742}
743
Ben Murdochda12d292016-06-02 14:46:10 +0100744double GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() const {
745 return AverageSpeed(recorded_incremental_mark_compacts_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746}
747
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748double GCTracer::CombinedMarkCompactSpeedInBytesPerMillisecond() {
749 if (combined_mark_compact_speed_cache_ > 0)
750 return combined_mark_compact_speed_cache_;
751 const double kMinimumMarkingSpeed = 0.5;
Ben Murdochda12d292016-06-02 14:46:10 +0100752 double speed1 = IncrementalMarkingSpeedInBytesPerMillisecond();
753 double speed2 = FinalIncrementalMarkCompactSpeedInBytesPerMillisecond();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754 if (speed1 < kMinimumMarkingSpeed || speed2 < kMinimumMarkingSpeed) {
755 // No data for the incremental marking speed.
756 // Return the non-incremental mark-compact speed.
757 combined_mark_compact_speed_cache_ =
Ben Murdochda12d292016-06-02 14:46:10 +0100758 MarkCompactSpeedInBytesPerMillisecond();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759 } else {
760 // Combine the speed of incremental step and the speed of the final step.
761 // 1 / (1 / speed1 + 1 / speed2) = speed1 * speed2 / (speed1 + speed2).
762 combined_mark_compact_speed_cache_ = speed1 * speed2 / (speed1 + speed2);
763 }
764 return combined_mark_compact_speed_cache_;
765}
766
Ben Murdochda12d292016-06-02 14:46:10 +0100767double GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 double time_ms) const {
769 size_t bytes = new_space_allocation_in_bytes_since_gc_;
770 double durations = allocation_duration_since_gc_;
Ben Murdochda12d292016-06-02 14:46:10 +0100771 return AverageSpeed(recorded_new_generation_allocations_,
772 MakeBytesAndDuration(bytes, durations), time_ms);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000773}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000774
Ben Murdochda12d292016-06-02 14:46:10 +0100775double GCTracer::OldGenerationAllocationThroughputInBytesPerMillisecond(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000776 double time_ms) const {
777 size_t bytes = old_generation_allocation_in_bytes_since_gc_;
778 double durations = allocation_duration_since_gc_;
Ben Murdochda12d292016-06-02 14:46:10 +0100779 return AverageSpeed(recorded_old_generation_allocations_,
780 MakeBytesAndDuration(bytes, durations), time_ms);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000781}
782
Ben Murdochda12d292016-06-02 14:46:10 +0100783double GCTracer::AllocationThroughputInBytesPerMillisecond(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000784 double time_ms) const {
785 return NewSpaceAllocationThroughputInBytesPerMillisecond(time_ms) +
786 OldGenerationAllocationThroughputInBytesPerMillisecond(time_ms);
787}
788
Ben Murdochda12d292016-06-02 14:46:10 +0100789double GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 return AllocationThroughputInBytesPerMillisecond(kThroughputTimeFrameMs);
791}
792
Ben Murdochda12d292016-06-02 14:46:10 +0100793double GCTracer::CurrentOldGenerationAllocationThroughputInBytesPerMillisecond()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794 const {
795 return OldGenerationAllocationThroughputInBytesPerMillisecond(
796 kThroughputTimeFrameMs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400798
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400799double GCTracer::ContextDisposalRateInMilliseconds() const {
Ben Murdochda12d292016-06-02 14:46:10 +0100800 if (recorded_context_disposal_times_.Count() <
801 recorded_context_disposal_times_.kSize)
802 return 0.0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000803 double begin = heap_->MonotonicallyIncreasingTimeInMs();
Ben Murdochda12d292016-06-02 14:46:10 +0100804 double end = recorded_context_disposal_times_.Sum(
805 [](double a, double b) { return b; }, 0.0);
806 return (begin - end) / recorded_context_disposal_times_.Count();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400807}
808
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000809double GCTracer::AverageSurvivalRatio() const {
Ben Murdochda12d292016-06-02 14:46:10 +0100810 if (recorded_survival_ratios_.Count() == 0) return 0.0;
811 double sum = recorded_survival_ratios_.Sum(
812 [](double a, double b) { return a + b; }, 0.0);
813 return sum / recorded_survival_ratios_.Count();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400814}
815
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400816bool GCTracer::SurvivalEventsRecorded() const {
Ben Murdochda12d292016-06-02 14:46:10 +0100817 return recorded_survival_ratios_.Count() > 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400818}
819
Ben Murdochda12d292016-06-02 14:46:10 +0100820void GCTracer::ResetSurvivalEvents() { recorded_survival_ratios_.Reset(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000821} // namespace internal
822} // namespace v8