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

Side by Side Diff: src/gc-tracer.cc

Issue 437993003: Move a bunch of GC related files to heap/ subdirectory (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: make presubmit happy Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/gc-tracer.h ('k') | src/handles-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #include "src/v8.h"
6
7 #include "src/gc-tracer.h"
8
9 namespace v8 {
10 namespace internal {
11
12 static intptr_t CountTotalHolesSize(Heap* heap) {
13 intptr_t holes_size = 0;
14 OldSpaces spaces(heap);
15 for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) {
16 holes_size += space->Waste() + space->Available();
17 }
18 return holes_size;
19 }
20
21
22 GCTracer::Event::Event(Type type, const char* gc_reason,
23 const char* collector_reason)
24 : type(type),
25 gc_reason(gc_reason),
26 collector_reason(collector_reason),
27 start_time(0.0),
28 end_time(0.0),
29 start_object_size(0),
30 end_object_size(0),
31 start_memory_size(0),
32 end_memory_size(0),
33 start_holes_size(0),
34 end_holes_size(0),
35 cumulative_incremental_marking_steps(0),
36 incremental_marking_steps(0),
37 cumulative_incremental_marking_bytes(0),
38 incremental_marking_bytes(0),
39 cumulative_incremental_marking_duration(0.0),
40 incremental_marking_duration(0.0),
41 longest_incremental_marking_step(0.0) {
42 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
43 scopes[i] = 0;
44 }
45 }
46
47
48 const char* GCTracer::Event::TypeName(bool short_name) const {
49 switch (type) {
50 case SCAVENGER:
51 if (short_name) {
52 return "s";
53 } else {
54 return "Scavenge";
55 }
56 case MARK_COMPACTOR:
57 if (short_name) {
58 return "ms";
59 } else {
60 return "Mark-sweep";
61 }
62 case START:
63 if (short_name) {
64 return "st";
65 } else {
66 return "Start";
67 }
68 }
69 return "Unknown Event Type";
70 }
71
72
73 GCTracer::GCTracer(Heap* heap)
74 : heap_(heap),
75 cumulative_incremental_marking_steps_(0),
76 cumulative_incremental_marking_bytes_(0),
77 cumulative_incremental_marking_duration_(0.0),
78 longest_incremental_marking_step_(0.0),
79 cumulative_marking_duration_(0.0),
80 cumulative_sweeping_duration_(0.0) {
81 current_ = Event(Event::START, NULL, NULL);
82 current_.end_time = base::OS::TimeCurrentMillis();
83 previous_ = previous_mark_compactor_event_ = current_;
84 }
85
86
87 void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
88 const char* collector_reason) {
89 previous_ = current_;
90 if (current_.type == Event::MARK_COMPACTOR)
91 previous_mark_compactor_event_ = current_;
92
93 if (collector == SCAVENGER) {
94 current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
95 } else {
96 current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
97 }
98
99 current_.start_time = base::OS::TimeCurrentMillis();
100 current_.start_object_size = heap_->SizeOfObjects();
101 current_.start_memory_size = heap_->isolate()->memory_allocator()->Size();
102 current_.start_holes_size = CountTotalHolesSize(heap_);
103
104 current_.cumulative_incremental_marking_steps =
105 cumulative_incremental_marking_steps_;
106 current_.cumulative_incremental_marking_bytes =
107 cumulative_incremental_marking_bytes_;
108 current_.cumulative_incremental_marking_duration =
109 cumulative_incremental_marking_duration_;
110 current_.longest_incremental_marking_step = longest_incremental_marking_step_;
111
112 for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
113 current_.scopes[i] = 0;
114 }
115 }
116
117
118 void GCTracer::Stop() {
119 current_.end_time = base::OS::TimeCurrentMillis();
120 current_.end_object_size = heap_->SizeOfObjects();
121 current_.end_memory_size = heap_->isolate()->memory_allocator()->Size();
122 current_.end_holes_size = CountTotalHolesSize(heap_);
123
124 if (current_.type == Event::SCAVENGER) {
125 current_.incremental_marking_steps =
126 current_.cumulative_incremental_marking_steps -
127 previous_.cumulative_incremental_marking_steps;
128 current_.incremental_marking_bytes =
129 current_.cumulative_incremental_marking_bytes -
130 previous_.cumulative_incremental_marking_bytes;
131 current_.incremental_marking_duration =
132 current_.cumulative_incremental_marking_duration -
133 previous_.cumulative_incremental_marking_duration;
134 scavenger_events_.push_front(current_);
135 } else {
136 current_.incremental_marking_steps =
137 current_.cumulative_incremental_marking_steps -
138 previous_mark_compactor_event_.cumulative_incremental_marking_steps;
139 current_.incremental_marking_bytes =
140 current_.cumulative_incremental_marking_bytes -
141 previous_mark_compactor_event_.cumulative_incremental_marking_bytes;
142 current_.incremental_marking_duration =
143 current_.cumulative_incremental_marking_duration -
144 previous_mark_compactor_event_.cumulative_incremental_marking_duration;
145 longest_incremental_marking_step_ = 0.0;
146 mark_compactor_events_.push_front(current_);
147 }
148
149 // TODO(ernstm): move the code below out of GCTracer.
150
151 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
152
153 double duration = current_.end_time - current_.start_time;
154 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0);
155
156 heap_->UpdateCumulativeGCStatistics(duration, spent_in_mutator,
157 current_.scopes[Scope::MC_MARK]);
158
159 if (current_.type == Event::SCAVENGER && FLAG_trace_gc_ignore_scavenger)
160 return;
161
162 if (FLAG_trace_gc) {
163 if (FLAG_trace_gc_nvp)
164 PrintNVP();
165 else
166 Print();
167
168 heap_->PrintShortHeapStatistics();
169 }
170 }
171
172
173 void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) {
174 cumulative_incremental_marking_steps_++;
175 cumulative_incremental_marking_bytes_ += bytes;
176 cumulative_incremental_marking_duration_ += duration;
177 longest_incremental_marking_step_ =
178 Max(longest_incremental_marking_step_, duration);
179 cumulative_marking_duration_ += duration;
180 }
181
182
183 void GCTracer::Print() const {
184 PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
185
186 PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", current_.TypeName(false),
187 static_cast<double>(current_.start_object_size) / MB,
188 static_cast<double>(current_.start_memory_size) / MB,
189 static_cast<double>(current_.end_object_size) / MB,
190 static_cast<double>(current_.end_memory_size) / MB);
191
192 int external_time = static_cast<int>(current_.scopes[Scope::EXTERNAL]);
193 if (external_time > 0) PrintF("%d / ", external_time);
194
195 double duration = current_.end_time - current_.start_time;
196 PrintF("%.1f ms", duration);
197 if (current_.type == Event::SCAVENGER) {
198 if (current_.incremental_marking_steps > 0) {
199 PrintF(" (+ %.1f ms in %d steps since last GC)",
200 current_.incremental_marking_duration,
201 current_.incremental_marking_steps);
202 }
203 } else {
204 if (current_.incremental_marking_steps > 0) {
205 PrintF(
206 " (+ %.1f ms in %d steps since start of marking, "
207 "biggest step %.1f ms)",
208 current_.incremental_marking_duration,
209 current_.incremental_marking_steps,
210 current_.longest_incremental_marking_step);
211 }
212 }
213
214 if (current_.gc_reason != NULL) {
215 PrintF(" [%s]", current_.gc_reason);
216 }
217
218 if (current_.collector_reason != NULL) {
219 PrintF(" [%s]", current_.collector_reason);
220 }
221
222 PrintF(".\n");
223 }
224
225
226 void GCTracer::PrintNVP() const {
227 PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
228
229 double duration = current_.end_time - current_.start_time;
230 double spent_in_mutator = current_.start_time - previous_.end_time;
231
232 PrintF("pause=%.1f ", duration);
233 PrintF("mutator=%.1f ", spent_in_mutator);
234 PrintF("gc=%s ", current_.TypeName(true));
235
236 PrintF("external=%.1f ", current_.scopes[Scope::EXTERNAL]);
237 PrintF("mark=%.1f ", current_.scopes[Scope::MC_MARK]);
238 PrintF("sweep=%.2f ", current_.scopes[Scope::MC_SWEEP]);
239 PrintF("sweepns=%.2f ", current_.scopes[Scope::MC_SWEEP_NEWSPACE]);
240 PrintF("sweepos=%.2f ", current_.scopes[Scope::MC_SWEEP_OLDSPACE]);
241 PrintF("sweepcode=%.2f ", current_.scopes[Scope::MC_SWEEP_CODE]);
242 PrintF("sweepcell=%.2f ", current_.scopes[Scope::MC_SWEEP_CELL]);
243 PrintF("sweepmap=%.2f ", current_.scopes[Scope::MC_SWEEP_MAP]);
244 PrintF("evacuate=%.1f ", current_.scopes[Scope::MC_EVACUATE_PAGES]);
245 PrintF("new_new=%.1f ",
246 current_.scopes[Scope::MC_UPDATE_NEW_TO_NEW_POINTERS]);
247 PrintF("root_new=%.1f ",
248 current_.scopes[Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS]);
249 PrintF("old_new=%.1f ",
250 current_.scopes[Scope::MC_UPDATE_OLD_TO_NEW_POINTERS]);
251 PrintF("compaction_ptrs=%.1f ",
252 current_.scopes[Scope::MC_UPDATE_POINTERS_TO_EVACUATED]);
253 PrintF("intracompaction_ptrs=%.1f ",
254 current_.scopes[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
255 PrintF("misc_compaction=%.1f ",
256 current_.scopes[Scope::MC_UPDATE_MISC_POINTERS]);
257 PrintF("weakcollection_process=%.1f ",
258 current_.scopes[Scope::MC_WEAKCOLLECTION_PROCESS]);
259 PrintF("weakcollection_clear=%.1f ",
260 current_.scopes[Scope::MC_WEAKCOLLECTION_CLEAR]);
261
262 PrintF("total_size_before=%" V8_PTR_PREFIX "d ", current_.start_object_size);
263 PrintF("total_size_after=%" V8_PTR_PREFIX "d ", current_.end_object_size);
264 PrintF("holes_size_before=%" V8_PTR_PREFIX "d ", current_.start_holes_size);
265 PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", current_.end_holes_size);
266
267 intptr_t allocated_since_last_gc =
268 current_.start_object_size - previous_.end_object_size;
269 PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc);
270 PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_);
271 PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ",
272 heap_->semi_space_copied_object_size_);
273 PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_);
274 PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_);
275 PrintF("nodes_promoted=%d ", heap_->nodes_promoted_);
276 PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_);
277 PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_);
278
279 if (current_.type == Event::SCAVENGER) {
280 PrintF("steps_count=%d ", current_.incremental_marking_steps);
281 PrintF("steps_took=%.1f ", current_.incremental_marking_duration);
282 } else {
283 PrintF("steps_count=%d ", current_.incremental_marking_steps);
284 PrintF("steps_took=%.1f ", current_.incremental_marking_duration);
285 PrintF("longest_step=%.1f ", current_.longest_incremental_marking_step);
286 PrintF("incremental_marking_throughput=%" V8_PTR_PREFIX "d ",
287 IncrementalMarkingSpeedInBytesPerMillisecond());
288 }
289
290 PrintF("\n");
291 }
292
293
294 double GCTracer::MeanDuration(const EventBuffer& events) const {
295 if (events.empty()) return 0.0;
296
297 double mean = 0.0;
298 EventBuffer::const_iterator iter = events.begin();
299 while (iter != events.end()) {
300 mean += iter->end_time - iter->start_time;
301 ++iter;
302 }
303
304 return mean / events.size();
305 }
306
307
308 double GCTracer::MaxDuration(const EventBuffer& events) const {
309 if (events.empty()) return 0.0;
310
311 double maximum = 0.0f;
312 EventBuffer::const_iterator iter = events.begin();
313 while (iter != events.end()) {
314 maximum = Max(iter->end_time - iter->start_time, maximum);
315 ++iter;
316 }
317
318 return maximum;
319 }
320
321
322 double GCTracer::MeanIncrementalMarkingDuration() const {
323 if (cumulative_incremental_marking_steps_ == 0) return 0.0;
324
325 // We haven't completed an entire round of incremental marking, yet.
326 // Use data from GCTracer instead of data from event buffers.
327 if (mark_compactor_events_.empty()) {
328 return cumulative_incremental_marking_duration_ /
329 cumulative_incremental_marking_steps_;
330 }
331
332 int steps = 0;
333 double durations = 0.0;
334 EventBuffer::const_iterator iter = mark_compactor_events_.begin();
335 while (iter != mark_compactor_events_.end()) {
336 steps += iter->incremental_marking_steps;
337 durations += iter->incremental_marking_duration;
338 ++iter;
339 }
340
341 if (steps == 0) return 0.0;
342
343 return durations / steps;
344 }
345
346
347 double GCTracer::MaxIncrementalMarkingDuration() const {
348 // We haven't completed an entire round of incremental marking, yet.
349 // Use data from GCTracer instead of data from event buffers.
350 if (mark_compactor_events_.empty()) return longest_incremental_marking_step_;
351
352 double max_duration = 0.0;
353 EventBuffer::const_iterator iter = mark_compactor_events_.begin();
354 while (iter != mark_compactor_events_.end())
355 max_duration = Max(iter->longest_incremental_marking_step, max_duration);
356
357 return max_duration;
358 }
359
360
361 intptr_t GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const {
362 if (cumulative_incremental_marking_duration_ == 0.0) return 0;
363
364 // We haven't completed an entire round of incremental marking, yet.
365 // Use data from GCTracer instead of data from event buffers.
366 if (mark_compactor_events_.empty()) {
367 return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ /
368 cumulative_incremental_marking_duration_);
369 }
370
371 intptr_t bytes = 0;
372 double durations = 0.0;
373 EventBuffer::const_iterator iter = mark_compactor_events_.begin();
374 while (iter != mark_compactor_events_.end()) {
375 bytes += iter->incremental_marking_bytes;
376 durations += iter->incremental_marking_duration;
377 ++iter;
378 }
379
380 if (durations == 0.0) return 0;
381
382 return static_cast<intptr_t>(bytes / durations);
383 }
384 }
385 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/gc-tracer.h ('k') | src/handles-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698