OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/heap/gc-tracer.h" | 7 #include "src/heap/gc-tracer.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample( | 157 heap_->isolate()->counters()->aggregated_memory_heap_committed()->AddSample( |
158 start_time, committed_memory); | 158 start_time, committed_memory); |
159 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample( | 159 heap_->isolate()->counters()->aggregated_memory_heap_used()->AddSample( |
160 start_time, used_memory); | 160 start_time, used_memory); |
161 } | 161 } |
162 | 162 |
163 | 163 |
164 void GCTracer::Stop(GarbageCollector collector) { | 164 void GCTracer::Stop(GarbageCollector collector) { |
165 start_counter_--; | 165 start_counter_--; |
166 if (start_counter_ != 0) { | 166 if (start_counter_ != 0) { |
167 if (FLAG_trace_gc) { | 167 Output("[Finished reentrant %s during %s.]\n", |
168 PrintF("[Finished reentrant %s during %s.]\n", | 168 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", |
169 collector == SCAVENGER ? "Scavenge" : "Mark-sweep", | 169 current_.TypeName(false)); |
170 current_.TypeName(false)); | |
171 } | |
172 return; | 170 return; |
173 } | 171 } |
174 | 172 |
175 DCHECK(start_counter_ >= 0); | 173 DCHECK(start_counter_ >= 0); |
176 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || | 174 DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) || |
177 (collector == MARK_COMPACTOR && | 175 (collector == MARK_COMPACTOR && |
178 (current_.type == Event::MARK_COMPACTOR || | 176 (current_.type == Event::MARK_COMPACTOR || |
179 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); | 177 current_.type == Event::INCREMENTAL_MARK_COMPACTOR))); |
180 | 178 |
181 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); | 179 current_.end_time = heap_->MonotonicallyIncreasingTimeInMs(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 } else { | 226 } else { |
229 DCHECK(current_.incremental_marking_bytes == 0); | 227 DCHECK(current_.incremental_marking_bytes == 0); |
230 DCHECK(current_.incremental_marking_duration == 0); | 228 DCHECK(current_.incremental_marking_duration == 0); |
231 DCHECK(current_.pure_incremental_marking_duration == 0); | 229 DCHECK(current_.pure_incremental_marking_duration == 0); |
232 longest_incremental_marking_step_ = 0.0; | 230 longest_incremental_marking_step_ = 0.0; |
233 mark_compactor_events_.push_front(current_); | 231 mark_compactor_events_.push_front(current_); |
234 } | 232 } |
235 | 233 |
236 // TODO(ernstm): move the code below out of GCTracer. | 234 // TODO(ernstm): move the code below out of GCTracer. |
237 | 235 |
238 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; | |
239 | |
240 double duration = current_.end_time - current_.start_time; | 236 double duration = current_.end_time - current_.start_time; |
241 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); | 237 double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0); |
242 | 238 |
243 heap_->UpdateCumulativeGCStatistics(duration, spent_in_mutator, | 239 heap_->UpdateCumulativeGCStatistics(duration, spent_in_mutator, |
244 current_.scopes[Scope::MC_MARK]); | 240 current_.scopes[Scope::MC_MARK]); |
245 | 241 |
246 if (current_.type == Event::SCAVENGER && FLAG_trace_gc_ignore_scavenger) | 242 if (current_.type == Event::SCAVENGER && FLAG_trace_gc_ignore_scavenger) |
247 return; | 243 return; |
248 | 244 |
| 245 if (FLAG_trace_gc_nvp) |
| 246 PrintNVP(); |
| 247 else |
| 248 Print(); |
| 249 |
249 if (FLAG_trace_gc) { | 250 if (FLAG_trace_gc) { |
250 if (FLAG_trace_gc_nvp) | |
251 PrintNVP(); | |
252 else | |
253 Print(); | |
254 | |
255 heap_->PrintShortHeapStatistics(); | 251 heap_->PrintShortHeapStatistics(); |
256 } | 252 } |
257 } | 253 } |
258 | 254 |
259 | 255 |
260 void GCTracer::SampleNewSpaceAllocation(double current_ms, | 256 void GCTracer::SampleNewSpaceAllocation(double current_ms, |
261 size_t counter_bytes) { | 257 size_t counter_bytes) { |
262 if (new_space_allocation_time_ms_ == 0) { | 258 if (new_space_allocation_time_ms_ == 0) { |
263 // It is the first sample. | 259 // It is the first sample. |
264 new_space_allocation_time_ms_ = current_ms; | 260 new_space_allocation_time_ms_ = current_ms; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 cumulative_incremental_marking_duration_ += duration; | 303 cumulative_incremental_marking_duration_ += duration; |
308 longest_incremental_marking_step_ = | 304 longest_incremental_marking_step_ = |
309 Max(longest_incremental_marking_step_, duration); | 305 Max(longest_incremental_marking_step_, duration); |
310 cumulative_marking_duration_ += duration; | 306 cumulative_marking_duration_ += duration; |
311 if (bytes > 0) { | 307 if (bytes > 0) { |
312 cumulative_pure_incremental_marking_duration_ += duration; | 308 cumulative_pure_incremental_marking_duration_ += duration; |
313 } | 309 } |
314 } | 310 } |
315 | 311 |
316 | 312 |
| 313 void GCTracer::Output(const char* format, ...) const { |
| 314 if (FLAG_trace_gc) { |
| 315 va_list arguments; |
| 316 va_start(arguments, format); |
| 317 base::OS::VPrint(format, arguments); |
| 318 va_end(arguments); |
| 319 } |
| 320 |
| 321 const int kBufferSize = 256; |
| 322 char raw_buffer[kBufferSize]; |
| 323 Vector<char> buffer(raw_buffer, kBufferSize); |
| 324 va_list arguments2; |
| 325 va_start(arguments2, format); |
| 326 VSNPrintF(buffer, format, arguments2); |
| 327 va_end(arguments2); |
| 328 |
| 329 heap_->AddToRingBuffer(buffer.start()); |
| 330 } |
| 331 |
| 332 |
317 void GCTracer::Print() const { | 333 void GCTracer::Print() const { |
318 PrintIsolate(heap_->isolate(), "%8.0f ms: ", | 334 if (FLAG_trace_gc) { |
319 heap_->isolate()->time_millis_since_init()); | 335 PrintIsolate(heap_->isolate(), ""); |
| 336 } |
| 337 Output("%8.0f ms: ", heap_->isolate()->time_millis_since_init()); |
320 | 338 |
321 PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", current_.TypeName(false), | 339 Output("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", current_.TypeName(false), |
322 static_cast<double>(current_.start_object_size) / MB, | 340 static_cast<double>(current_.start_object_size) / MB, |
323 static_cast<double>(current_.start_memory_size) / MB, | 341 static_cast<double>(current_.start_memory_size) / MB, |
324 static_cast<double>(current_.end_object_size) / MB, | 342 static_cast<double>(current_.end_object_size) / MB, |
325 static_cast<double>(current_.end_memory_size) / MB); | 343 static_cast<double>(current_.end_memory_size) / MB); |
326 | 344 |
327 int external_time = static_cast<int>(current_.scopes[Scope::EXTERNAL]); | 345 int external_time = static_cast<int>(current_.scopes[Scope::EXTERNAL]); |
328 if (external_time > 0) PrintF("%d / ", external_time); | 346 if (external_time > 0) PrintF("%d / ", external_time); |
329 | 347 |
330 double duration = current_.end_time - current_.start_time; | 348 double duration = current_.end_time - current_.start_time; |
331 PrintF("%.1f ms", duration); | 349 Output("%.1f ms", duration); |
332 if (current_.type == Event::SCAVENGER) { | 350 if (current_.type == Event::SCAVENGER) { |
333 if (current_.incremental_marking_steps > 0) { | 351 if (current_.incremental_marking_steps > 0) { |
334 PrintF(" (+ %.1f ms in %d steps since last GC)", | 352 Output(" (+ %.1f ms in %d steps since last GC)", |
335 current_.incremental_marking_duration, | 353 current_.incremental_marking_duration, |
336 current_.incremental_marking_steps); | 354 current_.incremental_marking_steps); |
337 } | 355 } |
338 } else { | 356 } else { |
339 if (current_.incremental_marking_steps > 0) { | 357 if (current_.incremental_marking_steps > 0) { |
340 PrintF( | 358 Output( |
341 " (+ %.1f ms in %d steps since start of marking, " | 359 " (+ %.1f ms in %d steps since start of marking, " |
342 "biggest step %.1f ms)", | 360 "biggest step %.1f ms)", |
343 current_.incremental_marking_duration, | 361 current_.incremental_marking_duration, |
344 current_.incremental_marking_steps, | 362 current_.incremental_marking_steps, |
345 current_.longest_incremental_marking_step); | 363 current_.longest_incremental_marking_step); |
346 } | 364 } |
347 } | 365 } |
348 | 366 |
349 if (current_.gc_reason != NULL) { | 367 if (current_.gc_reason != NULL) { |
350 PrintF(" [%s]", current_.gc_reason); | 368 Output(" [%s]", current_.gc_reason); |
351 } | 369 } |
352 | 370 |
353 if (current_.collector_reason != NULL) { | 371 if (current_.collector_reason != NULL) { |
354 PrintF(" [%s]", current_.collector_reason); | 372 Output(" [%s]", current_.collector_reason); |
355 } | 373 } |
356 | 374 |
357 PrintF(".\n"); | 375 Output(".\n"); |
358 } | 376 } |
359 | 377 |
360 | 378 |
361 void GCTracer::PrintNVP() const { | 379 void GCTracer::PrintNVP() const { |
362 PrintIsolate(heap_->isolate(), "[I:%p] %8.0f ms: ", heap_->isolate(), | 380 PrintIsolate(heap_->isolate(), "[I:%p] %8.0f ms: ", heap_->isolate(), |
363 heap_->isolate()->time_millis_since_init()); | 381 heap_->isolate()->time_millis_since_init()); |
364 | 382 |
365 double duration = current_.end_time - current_.start_time; | 383 double duration = current_.end_time - current_.start_time; |
366 double spent_in_mutator = current_.start_time - previous_.end_time; | 384 double spent_in_mutator = current_.start_time - previous_.end_time; |
367 | 385 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 | 676 |
659 | 677 |
660 bool GCTracer::SurvivalEventsRecorded() const { | 678 bool GCTracer::SurvivalEventsRecorded() const { |
661 return survival_events_.size() > 0; | 679 return survival_events_.size() > 0; |
662 } | 680 } |
663 | 681 |
664 | 682 |
665 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); } | 683 void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); } |
666 } | 684 } |
667 } // namespace v8::internal | 685 } // namespace v8::internal |
OLD | NEW |