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 |