1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HEAP_GC_TRACER_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_GC_TRACER_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A simple ring buffer class with maximum size known at compile time.
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The class only implements the functionality required in GCTracer.
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename T, size_t MAX_SIZE>
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RingBuffer {
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class const_iterator {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const_iterator() : index_(0), elements_(NULL) {}
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const_iterator(size_t index, const T* elements)
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        : index_(index), elements_(elements) {}
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool operator==(const const_iterator& rhs) const {
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return elements_ == rhs.elements_ && index_ == rhs.index_;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool operator!=(const const_iterator& rhs) const {
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return elements_ != rhs.elements_ || index_ != rhs.index_;
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operator const T*() const { return elements_ + index_; }
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const T* operator->() const { return elements_ + index_; }
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const T& operator*() const { return elements_[index_]; }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const_iterator& operator++() {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      index_ = (index_ + 1) % (MAX_SIZE + 1);
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return *this;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const_iterator& operator--() {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1);
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return *this;
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t index_;
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const T* elements_;
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RingBuffer() : begin_(0), end_(0) {}
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool empty() const { return begin_ == end_; }
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size() const {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1);
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const_iterator begin() const { return const_iterator(begin_, elements_); }
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const_iterator end() const { return const_iterator(end_, elements_); }
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const_iterator back() const { return --end(); }
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void push_back(const T& element) {
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    elements_[end_] = element;
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    end_ = (end_ + 1) % (MAX_SIZE + 1);
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1);
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void push_front(const T& element) {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    elements_[begin_] = element;
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  T elements_[MAX_SIZE + 1];
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t begin_;
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t end_;
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(RingBuffer);
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// GCTracer collects and prints ONE line after each garbage collector
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// invocation IFF --trace_gc is used.
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(ernstm): Unit tests.
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass GCTracer {
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Scope {
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enum ScopeId {
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXTERNAL,
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_MARK,
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP,
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP_NEWSPACE,
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP_OLDSPACE,
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP_CODE,
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP_CELL,
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_SWEEP_MAP,
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_EVACUATE_PAGES,
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_NEW_TO_NEW_POINTERS,
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_ROOT_TO_NEW_POINTERS,
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_OLD_TO_NEW_POINTERS,
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_POINTERS_TO_EVACUATED,
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_UPDATE_MISC_POINTERS,
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_WEAKCOLLECTION_PROCESS,
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_WEAKCOLLECTION_CLEAR,
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_WEAKCOLLECTION_ABORT,
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MC_FLUSH_CODE,
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NUMBER_OF_SCOPES
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    };
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Scope(GCTracer* tracer, ScopeId scope) : tracer_(tracer), scope_(scope) {
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      start_time_ = base::OS::TimeCurrentMillis();
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ~Scope() {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(scope_ < NUMBER_OF_SCOPES);  // scope_ is unsigned.
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      tracer_->current_.scopes[scope_] +=
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          base::OS::TimeCurrentMillis() - start_time_;
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCTracer* tracer_;
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ScopeId scope_;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double start_time_;
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Scope);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class AllocationEvent {
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Default constructor leaves the event uninitialized.
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationEvent() {}
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AllocationEvent(double duration, intptr_t allocation_in_bytes);
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Time spent in the mutator during the end of the last garbage collection
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to the beginning of the next garbage collection.
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double duration_;
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Memory allocated in the new space during the end of the last garbage
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // collection to the beginning of the next garbage collection.
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t allocation_in_bytes_;
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Event {
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 };
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Default constructor leaves the event uninitialized.
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Event() {}
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Event(Type type, const char* gc_reason, const char* collector_reason);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Returns a string describing the event type.
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* TypeName(bool short_name) const;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Type of event
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Type type;
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* gc_reason;
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* collector_reason;
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Timestamp set in the constructor.
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double start_time;
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Timestamp set in the destructor.
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double end_time;
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Size of objects in heap set in constructor.
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t start_object_size;
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Size of objects in heap set in destructor.
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t end_object_size;
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Size of memory allocated from OS set in constructor.
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t start_memory_size;
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Size of memory allocated from OS set in destructor.
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t end_memory_size;
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Total amount of space either wasted or contained in one of free lists
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // before the current GC.
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t start_holes_size;
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Total amount of space either wasted or contained in one of free lists
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // after the current GC.
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t end_holes_size;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Size of new space objects in constructor.
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t new_space_object_size;
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Number of incremental marking steps since creation of tracer.
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (value at start of event)
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cumulative_incremental_marking_steps;
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Incremental marking steps since
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last event for SCAVENGER events
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int incremental_marking_steps;
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bytes marked since creation of tracer (value at start of event).
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t cumulative_incremental_marking_bytes;
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bytes marked since
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last event for SCAVENGER events
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    intptr_t incremental_marking_bytes;
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Cumulative duration of incremental marking steps since creation of
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // tracer. (value at start of event)
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double cumulative_incremental_marking_duration;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Duration of incremental marking steps since
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last event for SCAVENGER events
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double incremental_marking_duration;
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Cumulative pure duration of incremental marking steps since creation of
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // tracer. (value at start of event)
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double cumulative_pure_incremental_marking_duration;
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Duration of pure incremental marking steps since
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last event for SCAVENGER events
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double pure_incremental_marking_duration;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Longest incremental marking step since start of marking.
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // (value at start of event)
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double longest_incremental_marking_step;
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Amounts of time spent in different scopes during GC.
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    double scopes[Scope::NUMBER_OF_SCOPES];
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kRingBufferMaxSize = 10;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer;
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef RingBuffer<AllocationEvent, kRingBufferMaxSize> AllocationEventBuffer;
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit GCTracer(Heap* heap);
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Start collecting data.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Start(GarbageCollector collector, const char* gc_reason,
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             const char* collector_reason);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stop collecting data and print results.
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Stop();
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Log an allocation throughput event.
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Log an incremental marking step.
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddIncrementalMarkingStep(double duration, intptr_t bytes);
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Log time spent in marking.
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddMarkingTime(double duration) {
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cumulative_marking_duration_ += duration;
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Time spent in marking.
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_marking_duration() const {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return cumulative_marking_duration_;
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Log time spent in sweeping on main thread.
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddSweepingTime(double duration) {
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cumulative_sweeping_duration_ += duration;
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Time spent in sweeping on main thread.
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_sweeping_duration() const {
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return cumulative_sweeping_duration_;
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the mean duration of the last scavenger events. Returns 0 if no
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // events have been recorded.
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MeanScavengerDuration() const {
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MeanDuration(scavenger_events_);
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the max duration of the last scavenger events. Returns 0 if no
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // events have been recorded.
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MaxScavengerDuration() const { return MaxDuration(scavenger_events_); }
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the mean duration of the last mark compactor events. Returns 0 if
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // no events have been recorded.
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MeanMarkCompactorDuration() const {
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MeanDuration(mark_compactor_events_);
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the max duration of the last mark compactor events. Return 0 if no
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // events have been recorded.
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MaxMarkCompactorDuration() const {
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MaxDuration(mark_compactor_events_);
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the mean step duration of the last incremental marking round.
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no incremental marking round has been completed.
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MeanIncrementalMarkingDuration() const;
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the max step duration of the last incremental marking round.
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no incremental marking round has been completed.
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MaxIncrementalMarkingDuration() const;
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the average incremental marking speed in bytes/millisecond.
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no events have been recorded.
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t IncrementalMarkingSpeedInBytesPerMillisecond() const;
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the average scavenge speed in bytes/millisecond.
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no events have been recorded.
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t ScavengeSpeedInBytesPerMillisecond() const;
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the max mark-sweep speed in bytes/millisecond.
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no events have been recorded.
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t MarkCompactSpeedInBytesPerMillisecond() const;
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocation throughput in the new space in bytes/millisecond.
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns 0 if no events have been recorded.
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const;
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Print one detailed trace line in name=value format.
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(ernstm): Move to Heap.
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PrintNVP() const;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Print one trace line.
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(ernstm): Move to Heap.
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Print() const;
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the mean duration of the events in the given ring buffer.
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MeanDuration(const EventBuffer& events) const;
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the max duration of the events in the given ring buffer.
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double MaxDuration(const EventBuffer& events) const;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Pointer to the heap that owns this tracer.
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap* heap_;
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has returned.
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Event current_;
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Previous tracer event.
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Event previous_;
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Previous MARK_COMPACTOR event.
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Event previous_mark_compactor_event_;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // RingBuffers for SCAVENGER events.
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EventBuffer scavenger_events_;
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // RingBuffers for MARK_COMPACTOR events.
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EventBuffer mark_compactor_events_;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // RingBuffer for allocation events.
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationEventBuffer allocation_events_;
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Cumulative number of incremental marking steps since creation of tracer.
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int cumulative_incremental_marking_steps_;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Cumulative size of incremental marking steps (in bytes) since creation of
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // tracer.
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t cumulative_incremental_marking_bytes_;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Cumulative duration of incremental marking steps since creation of tracer.
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_incremental_marking_duration_;
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Cumulative duration of pure incremental marking steps since creation of
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // tracer.
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_pure_incremental_marking_duration_;
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Longest incremental marking step since start of marking.
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double longest_incremental_marking_step_;
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Total marking time.
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This timer is precise when run with --print-cumulative-gc-stat
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_marking_duration_;
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Total sweeping time on the main thread.
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This timer is precise when run with --print-cumulative-gc-stat
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): Account for sweeping time on sweeper threads. Add a
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // different field for that.
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(hpayer): This timer right now just holds the sweeping time
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the initial atomic sweeping pause. Make sure that it accumulates
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // all sweeping operations performed on the main thread.
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double cumulative_sweeping_duration_;
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Holds the new space top pointer recorded at the end of the last garbage
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // collection.
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t new_space_top_after_gc_;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(GCTracer);
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8::internal
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_HEAP_GC_TRACER_H_
402