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

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

Issue 1830723004: Refactor the ring buffer in GCTracer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix cast Created 4 years, 8 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 | « no previous file | src/heap/gc-tracer.cc » ('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 #ifndef V8_HEAP_GC_TRACER_H_ 5 #ifndef V8_HEAP_GC_TRACER_H_
6 #define V8_HEAP_GC_TRACER_H_ 6 #define V8_HEAP_GC_TRACER_H_
7 7
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/counters.h" 9 #include "src/counters.h"
10 #include "src/globals.h" 10 #include "src/globals.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 // A simple ring buffer class with maximum size known at compile time. 15 template <typename T>
16 // The class only implements the functionality required in GCTracer.
17 template <typename T, size_t MAX_SIZE>
18 class RingBuffer { 16 class RingBuffer {
19 public: 17 public:
20 class const_iterator { 18 RingBuffer() { Reset(); }
21 public: 19 static const int kSize = 10;
22 const_iterator() : index_(0), elements_(NULL) {} 20 void Push(const T& value) {
23 21 if (count_ == kSize) {
24 const_iterator(size_t index, const T* elements) 22 elements_[start_++] = value;
25 : index_(index), elements_(elements) {} 23 if (start_ == kSize) start_ = 0;
26 24 } else {
27 bool operator==(const const_iterator& rhs) const { 25 DCHECK_EQ(start_, 0);
28 return elements_ == rhs.elements_ && index_ == rhs.index_; 26 elements_[count_++] = value;
29 } 27 }
30
31 bool operator!=(const const_iterator& rhs) const {
32 return elements_ != rhs.elements_ || index_ != rhs.index_;
33 }
34
35 operator const T*() const { return elements_ + index_; }
36
37 const T* operator->() const { return elements_ + index_; }
38
39 const T& operator*() const { return elements_[index_]; }
40
41 const_iterator& operator++() {
42 index_ = (index_ + 1) % (MAX_SIZE + 1);
43 return *this;
44 }
45
46 const_iterator& operator--() {
47 index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1);
48 return *this;
49 }
50
51 private:
52 size_t index_;
53 const T* elements_;
54 };
55
56 RingBuffer() : begin_(0), end_(0) {}
57
58 bool empty() const { return begin_ == end_; }
59 size_t size() const {
60 return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1);
61 }
62 const_iterator begin() const { return const_iterator(begin_, elements_); }
63 const_iterator end() const { return const_iterator(end_, elements_); }
64 const_iterator back() const { return --end(); }
65 void push_back(const T& element) {
66 elements_[end_] = element;
67 end_ = (end_ + 1) % (MAX_SIZE + 1);
68 if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1);
69 }
70 void push_front(const T& element) {
71 begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1);
72 if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1);
73 elements_[begin_] = element;
74 } 28 }
75 29
76 void reset() { 30 int Count() const { return count_; }
77 begin_ = 0; 31
78 end_ = 0; 32 template <typename Callback>
33 T Sum(Callback callback, const T& initial) const {
34 int j = start_ + count_ - 1;
35 if (j >= kSize) j -= kSize;
36 T result = initial;
37 for (int i = 0; i < count_; i++) {
38 result = callback(result, elements_[j]);
39 if (--j == -1) j += kSize;
40 }
41 return result;
79 } 42 }
80 43
44 void Reset() { start_ = count_ = 0; }
45
81 private: 46 private:
82 T elements_[MAX_SIZE + 1]; 47 T elements_[kSize];
83 size_t begin_; 48 int start_;
84 size_t end_; 49 int count_;
85
86 DISALLOW_COPY_AND_ASSIGN(RingBuffer); 50 DISALLOW_COPY_AND_ASSIGN(RingBuffer);
87 }; 51 };
88 52
53 typedef std::pair<uint64_t, double> BytesAndDuration;
54
55 inline BytesAndDuration MakeBytesAndDuration(uint64_t bytes, double duration) {
56 return std::make_pair(bytes, duration);
57 }
89 58
90 enum ScavengeSpeedMode { kForAllObjects, kForSurvivedObjects }; 59 enum ScavengeSpeedMode { kForAllObjects, kForSurvivedObjects };
91 60
92 // GCTracer collects and prints ONE line after each garbage collector 61 // GCTracer collects and prints ONE line after each garbage collector
93 // invocation IFF --trace_gc is used. 62 // invocation IFF --trace_gc is used.
94 // TODO(ernstm): Unit tests. 63 // TODO(ernstm): Unit tests.
95 class GCTracer { 64 class GCTracer {
96 public: 65 public:
97 class Scope { 66 class Scope {
98 public: 67 public:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 private: 120 private:
152 GCTracer* tracer_; 121 GCTracer* tracer_;
153 ScopeId scope_; 122 ScopeId scope_;
154 double start_time_; 123 double start_time_;
155 RuntimeCallTimer timer_; 124 RuntimeCallTimer timer_;
156 125
157 DISALLOW_COPY_AND_ASSIGN(Scope); 126 DISALLOW_COPY_AND_ASSIGN(Scope);
158 }; 127 };
159 128
160 129
161 class AllocationEvent {
162 public:
163 // Default constructor leaves the event uninitialized.
164 AllocationEvent() {}
165
166 AllocationEvent(double duration, size_t allocation_in_bytes);
167
168 // Time spent in the mutator during the end of the last sample to the
169 // beginning of the next sample.
170 double duration_;
171
172 // Memory allocated in the new space during the end of the last sample
173 // to the beginning of the next sample
174 size_t allocation_in_bytes_;
175 };
176
177
178 class CompactionEvent {
179 public:
180 CompactionEvent() : duration(0), live_bytes_compacted(0) {}
181
182 CompactionEvent(double duration, intptr_t live_bytes_compacted)
183 : duration(duration), live_bytes_compacted(live_bytes_compacted) {}
184
185 double duration;
186 intptr_t live_bytes_compacted;
187 };
188
189
190 class ContextDisposalEvent {
191 public:
192 // Default constructor leaves the event uninitialized.
193 ContextDisposalEvent() {}
194
195 explicit ContextDisposalEvent(double time);
196
197 // Time when context disposal event happened.
198 double time_;
199 };
200
201
202 class SurvivalEvent {
203 public:
204 // Default constructor leaves the event uninitialized.
205 SurvivalEvent() {}
206
207 explicit SurvivalEvent(double survival_ratio);
208
209 double promotion_ratio_;
210 };
211
212
213 class Event { 130 class Event {
214 public: 131 public:
215 enum Type { 132 enum Type {
216 SCAVENGER = 0, 133 SCAVENGER = 0,
217 MARK_COMPACTOR = 1, 134 MARK_COMPACTOR = 1,
218 INCREMENTAL_MARK_COMPACTOR = 2, 135 INCREMENTAL_MARK_COMPACTOR = 2,
219 START = 3 136 START = 3
220 }; 137 };
221 138
222 // Default constructor leaves the event uninitialized. 139 // Default constructor leaves the event uninitialized.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 double pure_incremental_marking_duration; 224 double pure_incremental_marking_duration;
308 225
309 // Longest incremental marking step since start of marking. 226 // Longest incremental marking step since start of marking.
310 // (value at start of event) 227 // (value at start of event)
311 double longest_incremental_marking_step; 228 double longest_incremental_marking_step;
312 229
313 // Amounts of time spent in different scopes during GC. 230 // Amounts of time spent in different scopes during GC.
314 double scopes[Scope::NUMBER_OF_SCOPES]; 231 double scopes[Scope::NUMBER_OF_SCOPES];
315 }; 232 };
316 233
317 static const size_t kRingBufferMaxSize = 10;
318
319 typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer;
320
321 typedef RingBuffer<AllocationEvent, kRingBufferMaxSize> AllocationEventBuffer;
322
323 typedef RingBuffer<ContextDisposalEvent, kRingBufferMaxSize>
324 ContextDisposalEventBuffer;
325
326 typedef RingBuffer<CompactionEvent, kRingBufferMaxSize> CompactionEventBuffer;
327
328 typedef RingBuffer<SurvivalEvent, kRingBufferMaxSize> SurvivalEventBuffer;
329
330 static const int kThroughputTimeFrameMs = 5000; 234 static const int kThroughputTimeFrameMs = 5000;
331 235
332 explicit GCTracer(Heap* heap); 236 explicit GCTracer(Heap* heap);
333 237
334 // Start collecting data. 238 // Start collecting data.
335 void Start(GarbageCollector collector, const char* gc_reason, 239 void Start(GarbageCollector collector, const char* gc_reason,
336 const char* collector_reason); 240 const char* collector_reason);
337 241
338 // Stop collecting data and print results. 242 // Stop collecting data and print results.
339 void Stop(GarbageCollector collector); 243 void Stop(GarbageCollector collector);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 // events. 342 // events.
439 // Returns 0 if no events have been recorded. 343 // Returns 0 if no events have been recorded.
440 double AverageSurvivalRatio() const; 344 double AverageSurvivalRatio() const;
441 345
442 // Returns true if at least one survival event was recorded. 346 // Returns true if at least one survival event was recorded.
443 bool SurvivalEventsRecorded() const; 347 bool SurvivalEventsRecorded() const;
444 348
445 // Discard all recorded survival events. 349 // Discard all recorded survival events.
446 void ResetSurvivalEvents(); 350 void ResetSurvivalEvents();
447 351
352 // Returns the average speed of the events in the buffer.
353 // If the buffer is empty, the result is 0.
354 // Otherwise, the result is between 1 byte/ms and 1 GB/ms.
355 static int AverageSpeed(const RingBuffer<BytesAndDuration>& buffer);
356 static int AverageSpeed(const RingBuffer<BytesAndDuration>& buffer,
357 const BytesAndDuration& initial, double time_ms);
358
448 private: 359 private:
449 // Print one detailed trace line in name=value format. 360 // Print one detailed trace line in name=value format.
450 // TODO(ernstm): Move to Heap. 361 // TODO(ernstm): Move to Heap.
451 void PrintNVP() const; 362 void PrintNVP() const;
452 363
453 // Print one trace line. 364 // Print one trace line.
454 // TODO(ernstm): Move to Heap. 365 // TODO(ernstm): Move to Heap.
455 void Print() const; 366 void Print() const;
456 367
457 // Prints a line and also adds it to the heap's ring buffer so that 368 // Prints a line and also adds it to the heap's ring buffer so that
458 // it can be included in later crash dumps. 369 // it can be included in later crash dumps.
459 void Output(const char* format, ...) const; 370 void Output(const char* format, ...) const;
460 371
461 // Compute the mean duration of the events in the given ring buffer.
462 double MeanDuration(const EventBuffer& events) const;
463
464 // Compute the max duration of the events in the given ring buffer.
465 double MaxDuration(const EventBuffer& events) const;
466
467 void ClearMarkCompactStatistics() { 372 void ClearMarkCompactStatistics() {
468 cumulative_incremental_marking_steps_ = 0; 373 cumulative_incremental_marking_steps_ = 0;
469 cumulative_incremental_marking_bytes_ = 0; 374 cumulative_incremental_marking_bytes_ = 0;
470 cumulative_incremental_marking_duration_ = 0; 375 cumulative_incremental_marking_duration_ = 0;
471 cumulative_pure_incremental_marking_duration_ = 0; 376 cumulative_pure_incremental_marking_duration_ = 0;
472 longest_incremental_marking_step_ = 0; 377 longest_incremental_marking_step_ = 0;
473 cumulative_incremental_marking_finalization_steps_ = 0; 378 cumulative_incremental_marking_finalization_steps_ = 0;
474 cumulative_incremental_marking_finalization_duration_ = 0; 379 cumulative_incremental_marking_finalization_duration_ = 0;
475 longest_incremental_marking_finalization_step_ = 0; 380 longest_incremental_marking_finalization_step_ = 0;
476 cumulative_marking_duration_ = 0; 381 cumulative_marking_duration_ = 0;
(...skipping 16 matching lines...) Expand all
493 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() 398 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
494 // has returned. 399 // has returned.
495 Event current_; 400 Event current_;
496 401
497 // Previous tracer event. 402 // Previous tracer event.
498 Event previous_; 403 Event previous_;
499 404
500 // Previous INCREMENTAL_MARK_COMPACTOR event. 405 // Previous INCREMENTAL_MARK_COMPACTOR event.
501 Event previous_incremental_mark_compactor_event_; 406 Event previous_incremental_mark_compactor_event_;
502 407
503 // RingBuffers for SCAVENGER events.
504 EventBuffer scavenger_events_;
505
506 // RingBuffers for MARK_COMPACTOR events.
507 EventBuffer mark_compactor_events_;
508
509 // RingBuffers for INCREMENTAL_MARK_COMPACTOR events.
510 EventBuffer incremental_mark_compactor_events_;
511
512 // RingBuffer for allocation events.
513 AllocationEventBuffer new_space_allocation_events_;
514 AllocationEventBuffer old_generation_allocation_events_;
515
516 // RingBuffer for context disposal events.
517 ContextDisposalEventBuffer context_disposal_events_;
518
519 // RingBuffer for compaction events.
520 CompactionEventBuffer compaction_events_;
521
522 // RingBuffer for survival events.
523 SurvivalEventBuffer survival_events_;
524
525 // Cumulative number of incremental marking steps since creation of tracer. 408 // Cumulative number of incremental marking steps since creation of tracer.
526 int cumulative_incremental_marking_steps_; 409 int cumulative_incremental_marking_steps_;
527 410
528 // Cumulative size of incremental marking steps (in bytes) since creation of 411 // Cumulative size of incremental marking steps (in bytes) since creation of
529 // tracer. 412 // tracer.
530 intptr_t cumulative_incremental_marking_bytes_; 413 intptr_t cumulative_incremental_marking_bytes_;
531 414
532 // Cumulative duration of incremental marking steps since creation of tracer. 415 // Cumulative duration of incremental marking steps since creation of tracer.
533 double cumulative_incremental_marking_duration_; 416 double cumulative_incremental_marking_duration_;
534 417
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 size_t old_generation_allocation_in_bytes_since_gc_; 457 size_t old_generation_allocation_in_bytes_since_gc_;
575 458
576 double combined_mark_compact_speed_cache_; 459 double combined_mark_compact_speed_cache_;
577 460
578 // Counts how many tracers were started without stopping. 461 // Counts how many tracers were started without stopping.
579 int start_counter_; 462 int start_counter_;
580 463
581 // Separate timer used for --runtime_call_stats 464 // Separate timer used for --runtime_call_stats
582 RuntimeCallTimer timer_; 465 RuntimeCallTimer timer_;
583 466
467 RingBuffer<BytesAndDuration> recorded_incremental_marking_steps_;
468 RingBuffer<BytesAndDuration> recorded_scavenges_total_;
469 RingBuffer<BytesAndDuration> recorded_scavenges_survived_;
470 RingBuffer<BytesAndDuration> recorded_compactions_;
471 RingBuffer<BytesAndDuration> recorded_mark_compacts_;
472 RingBuffer<BytesAndDuration> recorded_incremental_mark_compacts_;
473 RingBuffer<BytesAndDuration> recorded_new_generation_allocations_;
474 RingBuffer<BytesAndDuration> recorded_old_generation_allocations_;
475 RingBuffer<double> recorded_context_disposal_times_;
476 RingBuffer<double> recorded_survival_ratios_;
477
584 DISALLOW_COPY_AND_ASSIGN(GCTracer); 478 DISALLOW_COPY_AND_ASSIGN(GCTracer);
585 }; 479 };
586 } // namespace internal 480 } // namespace internal
587 } // namespace v8 481 } // namespace v8
588 482
589 #endif // V8_HEAP_GC_TRACER_H_ 483 #endif // V8_HEAP_GC_TRACER_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/gc-tracer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698