Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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_GC_TRACER_H_ | |
| 6 #define V8_GC_TRACER_H_ | |
| 7 | |
| 8 namespace v8 { | |
| 9 namespace internal { | |
| 10 | |
| 11 // TODO(ernstm): Move into GCTracer. | |
|
Hannes Payer (out of office)
2014/07/24 09:03:33
remove todo
ernstm
2014/07/24 11:49:49
Done.
| |
| 12 // A simple ring buffer class with maximum size known at compile time. | |
| 13 // The class only implements the functionality required in GCTracer. | |
| 14 template<typename T, size_t MAX_SIZE> | |
| 15 class RingBuffer { | |
| 16 public: | |
| 17 class const_iterator { | |
| 18 public: | |
| 19 const_iterator() : index_(0), elements_(NULL) {} | |
| 20 | |
| 21 const_iterator(size_t index, const T* elements) : | |
| 22 index_(index), elements_(elements) {} | |
| 23 | |
| 24 bool operator==(const const_iterator& rhs) const { | |
| 25 return elements_ == rhs.elements_ && | |
| 26 index_ == rhs.index_; | |
| 27 } | |
| 28 | |
| 29 bool operator!=(const const_iterator& rhs) const { | |
| 30 return elements_ != rhs.elements_ || | |
| 31 index_ != rhs.index_; | |
| 32 } | |
| 33 | |
| 34 operator const T*() const { | |
| 35 return elements_ + index_; | |
| 36 } | |
| 37 | |
| 38 const T* operator->() const { | |
| 39 return elements_ + index_; | |
| 40 } | |
| 41 | |
| 42 const T& operator*() const { | |
| 43 return elements_[index_]; | |
| 44 } | |
| 45 | |
| 46 const_iterator& operator++() { | |
| 47 index_ = (index_ + 1) % (MAX_SIZE + 1); | |
| 48 return *this; | |
| 49 } | |
| 50 | |
| 51 const_iterator& operator--() { | |
| 52 index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); | |
| 53 return *this; | |
| 54 } | |
| 55 | |
| 56 private: | |
| 57 size_t index_; | |
| 58 const T* elements_; | |
| 59 }; | |
| 60 | |
| 61 RingBuffer() : begin_(0), end_(0) {} | |
| 62 | |
| 63 bool empty() const { return begin_ == end_; } | |
| 64 size_t size() const { | |
| 65 return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); | |
| 66 } | |
| 67 const_iterator begin() const { return const_iterator(begin_, elements_); } | |
| 68 const_iterator end() const { return const_iterator(end_, elements_); } | |
| 69 const_iterator back() const { return --end(); } | |
| 70 void push_back(const T& element) { | |
| 71 elements_[end_] = element; | |
| 72 end_ = (end_ + 1) % (MAX_SIZE + 1); | |
| 73 if (end_ == begin_) | |
| 74 begin_ = (begin_ + 1) % (MAX_SIZE + 1); | |
| 75 } | |
| 76 void push_front(const T& element) { | |
| 77 begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1); | |
| 78 if (begin_ == end_) | |
| 79 end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1); | |
| 80 elements_[begin_] = element; | |
| 81 } | |
| 82 | |
| 83 private: | |
| 84 T elements_[MAX_SIZE + 1]; | |
| 85 size_t begin_; | |
| 86 size_t end_; | |
| 87 | |
| 88 DISALLOW_COPY_AND_ASSIGN(RingBuffer); | |
| 89 }; | |
| 90 | |
| 91 | |
| 92 // GCTracer collects and prints ONE line after each garbage collector | |
| 93 // invocation IFF --trace_gc is used. | |
| 94 | |
|
Hannes Payer (out of office)
2014/07/24 09:03:33
remove newline
ernstm
2014/07/24 11:49:49
Done.
| |
| 95 // TODO(ernstm): Unit tests. | |
| 96 class GCTracer BASE_EMBEDDED { | |
| 97 public: | |
| 98 class Scope BASE_EMBEDDED { | |
| 99 public: | |
| 100 enum ScopeId { | |
| 101 EXTERNAL, | |
| 102 MC_MARK, | |
| 103 MC_SWEEP, | |
| 104 MC_SWEEP_NEWSPACE, | |
| 105 MC_SWEEP_OLDSPACE, | |
| 106 MC_SWEEP_CODE, | |
| 107 MC_SWEEP_CELL, | |
| 108 MC_SWEEP_MAP, | |
| 109 MC_EVACUATE_PAGES, | |
| 110 MC_UPDATE_NEW_TO_NEW_POINTERS, | |
| 111 MC_UPDATE_ROOT_TO_NEW_POINTERS, | |
| 112 MC_UPDATE_OLD_TO_NEW_POINTERS, | |
| 113 MC_UPDATE_POINTERS_TO_EVACUATED, | |
| 114 MC_UPDATE_POINTERS_BETWEEN_EVACUATED, | |
| 115 MC_UPDATE_MISC_POINTERS, | |
| 116 MC_WEAKCOLLECTION_PROCESS, | |
| 117 MC_WEAKCOLLECTION_CLEAR, | |
| 118 MC_FLUSH_CODE, | |
| 119 NUMBER_OF_SCOPES | |
| 120 }; | |
| 121 | |
| 122 Scope(GCTracer* tracer, ScopeId scope) | |
| 123 : tracer_(tracer), | |
| 124 scope_(scope) { | |
| 125 start_time_ = base::OS::TimeCurrentMillis(); | |
| 126 } | |
| 127 | |
| 128 ~Scope() { | |
| 129 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | |
| 130 tracer_->current_.scopes[scope_] += | |
| 131 base::OS::TimeCurrentMillis() - start_time_; | |
| 132 } | |
| 133 | |
| 134 private: | |
| 135 GCTracer* tracer_; | |
| 136 ScopeId scope_; | |
| 137 double start_time_; | |
| 138 | |
| 139 DISALLOW_COPY_AND_ASSIGN(Scope); | |
| 140 }; | |
| 141 | |
| 142 | |
| 143 class Event { | |
| 144 public: | |
| 145 enum Type { | |
| 146 SCAVENGER = 0, | |
| 147 MARK_COMPACTOR = 1, | |
| 148 START = 2 | |
| 149 }; | |
| 150 | |
| 151 // Default constructor leaves the event uninitialized. | |
| 152 Event() {} | |
| 153 | |
| 154 Event(Type type, | |
| 155 const char* gc_reason, | |
| 156 const char* collector_reason); | |
| 157 | |
| 158 // Returns a string describing the event type. | |
| 159 const char* TypeName(bool short_name) const; | |
| 160 | |
| 161 // Type of event | |
| 162 Type type; | |
| 163 | |
| 164 const char* gc_reason; | |
| 165 const char* collector_reason; | |
| 166 | |
| 167 // Timestamp set in the constructor. | |
| 168 double start_time; | |
| 169 | |
| 170 // Timestamp set in the destructor. | |
| 171 double end_time; | |
| 172 | |
| 173 // Size of objects in heap set in constructor. | |
| 174 intptr_t start_object_size; | |
| 175 | |
| 176 // Size of objects in heap set in destructor. | |
| 177 intptr_t end_object_size; | |
| 178 | |
| 179 // Size of memory allocated from OS set in constructor. | |
| 180 intptr_t start_memory_size; | |
| 181 | |
| 182 // Size of memory allocated from OS set in destructor. | |
| 183 intptr_t end_memory_size; | |
| 184 | |
| 185 // Total amount of space either wasted or contained in one of free lists | |
| 186 // before the current GC. | |
| 187 intptr_t start_holes_size; | |
| 188 | |
| 189 // Total amount of space either wasted or contained in one of free lists | |
| 190 // after the current GC. | |
| 191 intptr_t end_holes_size; | |
| 192 | |
| 193 // Number of incremental marking steps since creation of tracer. | |
| 194 // (value at start of event) | |
| 195 int incremental_marking_steps; | |
| 196 | |
| 197 // Cumulative duration of incremental marking steps since creation of | |
| 198 // tracer. (value at start of event) | |
| 199 double incremental_marking_duration; | |
| 200 | |
| 201 // Longest incremental marking step since start of marking. | |
| 202 // (value at start of event) | |
| 203 double longest_incremental_marking_step; | |
| 204 | |
| 205 // Amounts of time spent in different scopes during GC. | |
| 206 double scopes[Scope::NUMBER_OF_SCOPES]; | |
| 207 }; | |
| 208 | |
| 209 static const int kRingBufferMaxSize = 10; | |
| 210 | |
| 211 typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer; | |
| 212 | |
| 213 explicit GCTracer(Heap* heap); | |
| 214 | |
| 215 // Start collecting data. | |
| 216 void Start(GarbageCollector collector, | |
| 217 const char* gc_reason, | |
| 218 const char* collector_reason); | |
| 219 | |
| 220 // Stop collecting data and print results. | |
| 221 void Stop(); | |
| 222 | |
| 223 // Log an incremental marking step. | |
| 224 void AddIncrementalMarkingStep(double duration); | |
| 225 | |
| 226 private: | |
| 227 // Print one detailed trace line in name=value format. | |
| 228 // TODO(ernstm): Move to Heap. | |
| 229 void PrintNVP() const; | |
| 230 | |
| 231 // Print one trace line. | |
| 232 // TODO(ernstm): Move to Heap. | |
| 233 void Print() const; | |
| 234 | |
| 235 // Pointer to the heap that owns this tracer. | |
| 236 Heap* heap_; | |
| 237 | |
| 238 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() | |
| 239 // has returned. | |
| 240 Event current_; | |
| 241 | |
| 242 // Previous tracer event. | |
| 243 Event previous_; | |
| 244 | |
| 245 // Previous MARK_COMPACTOR event. | |
| 246 Event previous_mark_compactor_event_; | |
| 247 | |
| 248 // RingBuffers for SCAVENGER events. | |
| 249 EventBuffer scavenger_events_; | |
| 250 | |
| 251 // RingBuffers for MARK_COMPACTOR events. | |
| 252 EventBuffer mark_compactor_events_; | |
| 253 | |
| 254 // Cumulative number of incremental marking steps since creation of tracer. | |
| 255 int incremental_marking_steps_; | |
| 256 | |
| 257 // Cumulative duration of incremental marking steps since creation of tracer. | |
| 258 double incremental_marking_duration_; | |
| 259 | |
| 260 // Longest incremental marking step since start of marking. | |
| 261 double longest_incremental_marking_step_; | |
| 262 | |
| 263 DISALLOW_COPY_AND_ASSIGN(GCTracer); | |
| 264 }; | |
| 265 | |
| 266 } } // namespace v8::internal | |
| 267 | |
| 268 #endif // V8_GC_TRACER_H_ | |
| OLD | NEW |