V8 Project
gc-tracer.h
Go to the documentation of this file.
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_HEAP_GC_TRACER_H_
6 #define V8_HEAP_GC_TRACER_H_
7 
9 
10 namespace v8 {
11 namespace internal {
12 
13 // A simple ring buffer class with maximum size known at compile time.
14 // The class only implements the functionality required in GCTracer.
15 template <typename T, size_t MAX_SIZE>
16 class RingBuffer {
17  public:
19  public:
21 
22  const_iterator(size_t index, const T* elements)
23  : index_(index), elements_(elements) {}
24 
25  bool operator==(const const_iterator& rhs) const {
26  return elements_ == rhs.elements_ && index_ == rhs.index_;
27  }
28 
29  bool operator!=(const const_iterator& rhs) const {
30  return elements_ != rhs.elements_ || index_ != rhs.index_;
31  }
32 
33  operator const T*() const { return elements_ + index_; }
34 
35  const T* operator->() const { return elements_ + index_; }
36 
37  const T& operator*() const { return elements_[index_]; }
38 
40  index_ = (index_ + 1) % (MAX_SIZE + 1);
41  return *this;
42  }
43 
45  index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1);
46  return *this;
47  }
48 
49  private:
50  size_t index_;
51  const T* elements_;
52  };
53 
54  RingBuffer() : begin_(0), end_(0) {}
55 
56  bool empty() const { return begin_ == end_; }
57  size_t size() const {
58  return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1);
59  }
62  const_iterator back() const { return --end(); }
63  void push_back(const T& element) {
64  elements_[end_] = element;
65  end_ = (end_ + 1) % (MAX_SIZE + 1);
66  if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1);
67  }
68  void push_front(const T& element) {
69  begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1);
70  if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1);
71  elements_[begin_] = element;
72  }
73 
74  private:
75  T elements_[MAX_SIZE + 1];
76  size_t begin_;
77  size_t end_;
78 
80 };
81 
82 
83 // GCTracer collects and prints ONE line after each garbage collector
84 // invocation IFF --trace_gc is used.
85 // TODO(ernstm): Unit tests.
86 class GCTracer {
87  public:
88  class Scope {
89  public:
90  enum ScopeId {
111  };
112 
113  Scope(GCTracer* tracer, ScopeId scope) : tracer_(tracer), scope_(scope) {
115  }
116 
117  ~Scope() {
118  DCHECK(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned.
121  }
122 
123  private:
126  double start_time_;
127 
129  };
130 
131 
133  public:
134  // Default constructor leaves the event uninitialized.
136 
137  AllocationEvent(double duration, intptr_t allocation_in_bytes);
138 
139  // Time spent in the mutator during the end of the last garbage collection
140  // to the beginning of the next garbage collection.
141  double duration_;
142 
143  // Memory allocated in the new space during the end of the last garbage
144  // collection to the beginning of the next garbage collection.
146  };
147 
148  class Event {
149  public:
150  enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 };
151 
152  // Default constructor leaves the event uninitialized.
153  Event() {}
154 
155  Event(Type type, const char* gc_reason, const char* collector_reason);
156 
157  // Returns a string describing the event type.
158  const char* TypeName(bool short_name) const;
159 
160  // Type of event
162 
163  const char* gc_reason;
164  const char* collector_reason;
165 
166  // Timestamp set in the constructor.
167  double start_time;
168 
169  // Timestamp set in the destructor.
170  double end_time;
171 
172  // Size of objects in heap set in constructor.
174 
175  // Size of objects in heap set in destructor.
176  intptr_t end_object_size;
177 
178  // Size of memory allocated from OS set in constructor.
180 
181  // Size of memory allocated from OS set in destructor.
182  intptr_t end_memory_size;
183 
184  // Total amount of space either wasted or contained in one of free lists
185  // before the current GC.
187 
188  // Total amount of space either wasted or contained in one of free lists
189  // after the current GC.
190  intptr_t end_holes_size;
191 
192  // Size of new space objects in constructor.
194 
195  // Number of incremental marking steps since creation of tracer.
196  // (value at start of event)
198 
199  // Incremental marking steps since
200  // - last event for SCAVENGER events
201  // - last MARK_COMPACTOR event for MARK_COMPACTOR events
203 
204  // Bytes marked since creation of tracer (value at start of event).
206 
207  // Bytes marked since
208  // - last event for SCAVENGER events
209  // - last MARK_COMPACTOR event for MARK_COMPACTOR events
211 
212  // Cumulative duration of incremental marking steps since creation of
213  // tracer. (value at start of event)
215 
216  // Duration of incremental marking steps since
217  // - last event for SCAVENGER events
218  // - last MARK_COMPACTOR event for MARK_COMPACTOR events
220 
221  // Cumulative pure duration of incremental marking steps since creation of
222  // tracer. (value at start of event)
224 
225  // Duration of pure incremental marking steps since
226  // - last event for SCAVENGER events
227  // - last MARK_COMPACTOR event for MARK_COMPACTOR events
229 
230  // Longest incremental marking step since start of marking.
231  // (value at start of event)
233 
234  // Amounts of time spent in different scopes during GC.
236  };
237 
238  static const int kRingBufferMaxSize = 10;
239 
241 
243 
244  explicit GCTracer(Heap* heap);
245 
246  // Start collecting data.
247  void Start(GarbageCollector collector, const char* gc_reason,
248  const char* collector_reason);
249 
250  // Stop collecting data and print results.
251  void Stop();
252 
253  // Log an allocation throughput event.
254  void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes);
255 
256  // Log an incremental marking step.
257  void AddIncrementalMarkingStep(double duration, intptr_t bytes);
258 
259  // Log time spent in marking.
260  void AddMarkingTime(double duration) {
261  cumulative_marking_duration_ += duration;
262  }
263 
264  // Time spent in marking.
267  }
268 
269  // Log time spent in sweeping on main thread.
270  void AddSweepingTime(double duration) {
271  cumulative_sweeping_duration_ += duration;
272  }
273 
274  // Time spent in sweeping on main thread.
277  }
278 
279  // Compute the mean duration of the last scavenger events. Returns 0 if no
280  // events have been recorded.
281  double MeanScavengerDuration() const {
283  }
284 
285  // Compute the max duration of the last scavenger events. Returns 0 if no
286  // events have been recorded.
288 
289  // Compute the mean duration of the last mark compactor events. Returns 0 if
290  // no events have been recorded.
291  double MeanMarkCompactorDuration() const {
293  }
294 
295  // Compute the max duration of the last mark compactor events. Return 0 if no
296  // events have been recorded.
297  double MaxMarkCompactorDuration() const {
299  }
300 
301  // Compute the mean step duration of the last incremental marking round.
302  // Returns 0 if no incremental marking round has been completed.
303  double MeanIncrementalMarkingDuration() const;
304 
305  // Compute the max step duration of the last incremental marking round.
306  // Returns 0 if no incremental marking round has been completed.
307  double MaxIncrementalMarkingDuration() const;
308 
309  // Compute the average incremental marking speed in bytes/millisecond.
310  // Returns 0 if no events have been recorded.
312 
313  // Compute the average scavenge speed in bytes/millisecond.
314  // Returns 0 if no events have been recorded.
315  intptr_t ScavengeSpeedInBytesPerMillisecond() const;
316 
317  // Compute the max mark-sweep speed in bytes/millisecond.
318  // Returns 0 if no events have been recorded.
319  intptr_t MarkCompactSpeedInBytesPerMillisecond() const;
320 
321  // Allocation throughput in the new space in bytes/millisecond.
322  // Returns 0 if no events have been recorded.
324 
325  private:
326  // Print one detailed trace line in name=value format.
327  // TODO(ernstm): Move to Heap.
328  void PrintNVP() const;
329 
330  // Print one trace line.
331  // TODO(ernstm): Move to Heap.
332  void Print() const;
333 
334  // Compute the mean duration of the events in the given ring buffer.
335  double MeanDuration(const EventBuffer& events) const;
336 
337  // Compute the max duration of the events in the given ring buffer.
338  double MaxDuration(const EventBuffer& events) const;
339 
340  // Pointer to the heap that owns this tracer.
342 
343  // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
344  // has returned.
346 
347  // Previous tracer event.
349 
350  // Previous MARK_COMPACTOR event.
352 
353  // RingBuffers for SCAVENGER events.
355 
356  // RingBuffers for MARK_COMPACTOR events.
358 
359  // RingBuffer for allocation events.
361 
362  // Cumulative number of incremental marking steps since creation of tracer.
364 
365  // Cumulative size of incremental marking steps (in bytes) since creation of
366  // tracer.
368 
369  // Cumulative duration of incremental marking steps since creation of tracer.
371 
372  // Cumulative duration of pure incremental marking steps since creation of
373  // tracer.
375 
376  // Longest incremental marking step since start of marking.
378 
379  // Total marking time.
380  // This timer is precise when run with --print-cumulative-gc-stat
382 
383  // Total sweeping time on the main thread.
384  // This timer is precise when run with --print-cumulative-gc-stat
385  // TODO(hpayer): Account for sweeping time on sweeper threads. Add a
386  // different field for that.
387  // TODO(hpayer): This timer right now just holds the sweeping time
388  // of the initial atomic sweeping pause. Make sure that it accumulates
389  // all sweeping operations performed on the main thread.
391 
392  // Holds the new space top pointer recorded at the end of the last garbage
393  // collection.
395 
397 };
398 }
399 } // namespace v8::internal
400 
401 #endif // V8_HEAP_GC_TRACER_H_
static double TimeCurrentMillis()
double cumulative_pure_incremental_marking_duration
Definition: gc-tracer.h:223
double cumulative_incremental_marking_duration
Definition: gc-tracer.h:214
const char * TypeName(bool short_name) const
Definition: gc-tracer.cc:57
intptr_t cumulative_incremental_marking_bytes
Definition: gc-tracer.h:205
double scopes[Scope::NUMBER_OF_SCOPES]
Definition: gc-tracer.h:235
Scope(GCTracer *tracer, ScopeId scope)
Definition: gc-tracer.h:113
void Print() const
Definition: gc-tracer.cc:223
double MeanMarkCompactorDuration() const
Definition: gc-tracer.h:291
double cumulative_sweeping_duration() const
Definition: gc-tracer.h:275
double longest_incremental_marking_step_
Definition: gc-tracer.h:377
intptr_t MarkCompactSpeedInBytesPerMillisecond() const
Definition: gc-tracer.cc:448
int cumulative_incremental_marking_steps_
Definition: gc-tracer.h:363
double MaxMarkCompactorDuration() const
Definition: gc-tracer.h:297
double MaxDuration(const EventBuffer &events) const
Definition: gc-tracer.cc:354
void AddSweepingTime(double duration)
Definition: gc-tracer.h:270
DISALLOW_COPY_AND_ASSIGN(GCTracer)
double cumulative_marking_duration() const
Definition: gc-tracer.h:265
void AddIncrementalMarkingStep(double duration, intptr_t bytes)
Definition: gc-tracer.cc:210
static const int kRingBufferMaxSize
Definition: gc-tracer.h:238
intptr_t IncrementalMarkingSpeedInBytesPerMillisecond() const
Definition: gc-tracer.cc:407
double MeanDuration(const EventBuffer &events) const
Definition: gc-tracer.cc:340
double cumulative_pure_incremental_marking_duration_
Definition: gc-tracer.h:374
double MeanScavengerDuration() const
Definition: gc-tracer.h:281
GCTracer(Heap *heap)
Definition: gc-tracer.cc:82
double MaxIncrementalMarkingDuration() const
Definition: gc-tracer.cc:393
double MaxScavengerDuration() const
Definition: gc-tracer.h:287
intptr_t ScavengeSpeedInBytesPerMillisecond() const
Definition: gc-tracer.cc:432
double cumulative_incremental_marking_duration_
Definition: gc-tracer.h:370
double MeanIncrementalMarkingDuration() const
Definition: gc-tracer.cc:368
Event previous_mark_compactor_event_
Definition: gc-tracer.h:351
void AddMarkingTime(double duration)
Definition: gc-tracer.h:260
RingBuffer< Event, kRingBufferMaxSize > EventBuffer
Definition: gc-tracer.h:240
void Start(GarbageCollector collector, const char *gc_reason, const char *collector_reason)
Definition: gc-tracer.cc:98
double cumulative_sweeping_duration_
Definition: gc-tracer.h:390
intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const
Definition: gc-tracer.cc:465
void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes)
Definition: gc-tracer.cc:204
intptr_t new_space_top_after_gc_
Definition: gc-tracer.h:394
AllocationEventBuffer allocation_events_
Definition: gc-tracer.h:360
void PrintNVP() const
Definition: gc-tracer.cc:266
EventBuffer mark_compactor_events_
Definition: gc-tracer.h:357
RingBuffer< AllocationEvent, kRingBufferMaxSize > AllocationEventBuffer
Definition: gc-tracer.h:242
intptr_t cumulative_incremental_marking_bytes_
Definition: gc-tracer.h:367
EventBuffer scavenger_events_
Definition: gc-tracer.h:354
double cumulative_marking_duration_
Definition: gc-tracer.h:381
bool operator==(const const_iterator &rhs) const
Definition: gc-tracer.h:25
bool operator!=(const const_iterator &rhs) const
Definition: gc-tracer.h:29
const_iterator(size_t index, const T *elements)
Definition: gc-tracer.h:22
void push_front(const T &element)
Definition: gc-tracer.h:68
bool empty() const
Definition: gc-tracer.h:56
T elements_[MAX_SIZE+1]
Definition: gc-tracer.h:75
const_iterator begin() const
Definition: gc-tracer.h:60
DISALLOW_COPY_AND_ASSIGN(RingBuffer)
size_t size() const
Definition: gc-tracer.h:57
const_iterator end() const
Definition: gc-tracer.h:61
void push_back(const T &element)
Definition: gc-tracer.h:63
const_iterator back() const
Definition: gc-tracer.h:62
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25