v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
gc-tracer.h
Go to the documentation of this file.
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_HEAP_GC_TRACER_H_
6#define V8_HEAP_GC_TRACER_H_
7
8#include <optional>
9
10#include "include/v8-metrics.h"
12#include "src/base/macros.h"
14#include "src/common/globals.h"
15#include "src/heap/base/bytes.h"
19#include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck
20
21namespace v8 {
22namespace internal {
23
28
29#define TRACE_GC_CATEGORIES \
30 "devtools.timeline," TRACE_DISABLED_BY_DEFAULT("v8.gc")
31
32// Sweeping for full GC may be interleaved with sweeping for minor
33// gc. The below scopes should use TRACE_GC_EPOCH to associate them
34// with the right cycle.
35#define TRACE_GC(tracer, scope_id) \
36 DCHECK_NE(GCTracer::Scope::MC_SWEEP, scope_id); \
37 DCHECK_NE(GCTracer::Scope::MC_BACKGROUND_SWEEPING, scope_id); \
38 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
39 tracer, GCTracer::Scope::ScopeId(scope_id), ThreadKind::kMain); \
40 TRACE_EVENT0(TRACE_GC_CATEGORIES, \
41 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)))
42
43#define TRACE_GC_ARG1(tracer, scope_id, arg0_name, arg0_value) \
44 DCHECK_NE(GCTracer::Scope::MC_SWEEP, scope_id); \
45 DCHECK_NE(GCTracer::Scope::MC_BACKGROUND_SWEEPING, scope_id); \
46 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
47 tracer, GCTracer::Scope::ScopeId(scope_id), ThreadKind::kMain); \
48 TRACE_EVENT1(TRACE_GC_CATEGORIES, \
49 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)), \
50 arg0_name, arg0_value)
51
52#define TRACE_GC_WITH_FLOW(tracer, scope_id, bind_id, flow_flags) \
53 DCHECK_NE(GCTracer::Scope::MC_SWEEP, scope_id); \
54 DCHECK_NE(GCTracer::Scope::MC_BACKGROUND_SWEEPING, scope_id); \
55 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
56 tracer, GCTracer::Scope::ScopeId(scope_id), ThreadKind::kMain); \
57 TRACE_EVENT_WITH_FLOW0( \
58 TRACE_GC_CATEGORIES, \
59 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)), bind_id, \
60 flow_flags)
61
62#define TRACE_GC1(tracer, scope_id, thread_kind) \
63 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
64 tracer, GCTracer::Scope::ScopeId(scope_id), thread_kind); \
65 TRACE_EVENT0(TRACE_GC_CATEGORIES, \
66 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)))
67
68#define TRACE_GC1_WITH_FLOW(tracer, scope_id, thread_kind, bind_id, \
69 flow_flags) \
70 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
71 tracer, GCTracer::Scope::ScopeId(scope_id), thread_kind); \
72 TRACE_EVENT_WITH_FLOW0( \
73 TRACE_GC_CATEGORIES, \
74 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)), bind_id, \
75 flow_flags)
76
77#define TRACE_GC_EPOCH(tracer, scope_id, thread_kind) \
78 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
79 tracer, GCTracer::Scope::ScopeId(scope_id), thread_kind); \
80 TRACE_EVENT1(TRACE_GC_CATEGORIES, \
81 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)), \
82 "epoch", tracer->CurrentEpoch(scope_id))
83
84#define TRACE_GC_EPOCH_WITH_FLOW(tracer, scope_id, thread_kind, bind_id, \
85 flow_flags) \
86 GCTracer::Scope UNIQUE_IDENTIFIER(gc_tracer_scope)( \
87 tracer, GCTracer::Scope::ScopeId(scope_id), thread_kind); \
88 TRACE_EVENT_WITH_FLOW1( \
89 TRACE_GC_CATEGORIES, \
90 GCTracer::Scope::Name(GCTracer::Scope::ScopeId(scope_id)), bind_id, \
91 flow_flags, "epoch", tracer->CurrentEpoch(scope_id))
92
93#define TRACE_GC_NOTE(note) \
94 do { \
95 TRACE_EVENT0(TRACE_GC_CATEGORIES, note); \
96 } while (0)
97
98#define TRACE_GC_NOTE_WITH_FLOW(note, bind_id, flow_flags) \
99 do { \
100 TRACE_EVENT_WITH_FLOW0(TRACE_GC_CATEGORIES, note, bind_id, flow_flags); \
101 } while (0)
102
103using CollectionEpoch = uint32_t;
104
105// GCTracer collects and prints ONE line after each garbage collector
106// invocation IFF --trace_gc is used.
109
110 public:
111 struct IncrementalInfos final {
112 constexpr V8_INLINE IncrementalInfos& operator+=(base::TimeDelta delta);
113
116 int steps = 0;
117 };
118
120 public:
121 enum ScopeId {
122#define DEFINE_SCOPE(scope) scope,
124#undef DEFINE_SCOPE
125 NUMBER_OF_SCOPES,
126
127 FIRST_INCREMENTAL_SCOPE = MC_INCREMENTAL,
128 LAST_INCREMENTAL_SCOPE = MC_INCREMENTAL_SWEEPING,
129 FIRST_SCOPE = MC_INCREMENTAL,
130 NUMBER_OF_INCREMENTAL_SCOPES =
131 LAST_INCREMENTAL_SCOPE - FIRST_INCREMENTAL_SCOPE + 1,
132 FIRST_TOP_MC_SCOPE = MC_CLEAR,
133 LAST_TOP_MC_SCOPE = MC_SWEEP,
134 FIRST_BACKGROUND_SCOPE = BACKGROUND_YOUNG_ARRAY_BUFFER_SWEEP,
135 LAST_BACKGROUND_SCOPE =
136 SCAVENGER_BACKGROUND_TRACED_HANDLES_COMPUTE_WEAKNESS_PARALLEL
137 };
138
139 V8_INLINE Scope(GCTracer* tracer, ScopeId scope, ThreadKind thread_kind);
141 Scope(const Scope&) = delete;
142 Scope& operator=(const Scope&) = delete;
143 static constexpr const char* Name(ScopeId id);
144 static constexpr bool NeedsYoungEpoch(ScopeId id);
145 static constexpr int IncrementalOffset(ScopeId id);
146
147 private:
152#ifdef V8_RUNTIME_CALL_STATS
153 RuntimeCallTimer timer_;
154 RuntimeCallStats* runtime_stats_ = nullptr;
155 std::optional<WorkerThreadRuntimeCallStatsScope> runtime_call_stats_scope_;
156#endif // defined(V8_RUNTIME_CALL_STATS)
157 };
158
159 class Event {
160 public:
161 enum class Type {
162 SCAVENGER = 0,
163 MARK_COMPACTOR = 1,
164 INCREMENTAL_MARK_COMPACTOR = 2,
166 INCREMENTAL_MINOR_MARK_SWEEPER = 4,
167 START = 5,
168 };
169
170 // Returns true if the event corresponds to a young generation GC.
171 V8_INLINE static constexpr bool IsYoungGenerationEvent(Type type);
172
173 // The state diagram for a GC cycle:
174 // (NOT_RUNNING) -----(StartCycle)----->
175 // MARKING --(StartAtomicPause)-->
176 // ATOMIC ---(StopAtomicPause)-->
177 // SWEEPING ------(StopCycle)-----> NOT_RUNNING
178 enum class State { NOT_RUNNING, MARKING, ATOMIC, SWEEPING };
179
180 Event(Type type, State state, GarbageCollectionReason gc_reason,
181 const char* collector_reason, Priority priority);
182
183 // Type of the event.
185
186 // State of the cycle corresponding to the event.
188
190 const char* collector_reason;
191
192 // The Isolate's priority during the current GC cycle. The priority is set
193 // when the cycle starts. If the priority changes before the cycle is
194 // finished, the priority will be reset to denote a mixed priority.
195 std::optional<Priority> priority;
196
197 // Timestamp set in the constructor.
199
200 // Timestamp set in the destructor.
202
203 // Memory reduction flag set.
204 bool reduce_memory = false;
205
206 // Size of objects in heap set in constructor.
207 size_t start_object_size = 0;
208
209 // Size of objects in heap set in destructor.
210 size_t end_object_size = 0;
211
212 // Size of memory allocated from OS set in constructor.
213 size_t start_memory_size = 0;
214
215 // Size of memory allocated from OS set in destructor.
216 size_t end_memory_size = 0;
217
218 // Total amount of space either wasted or contained in one of free lists
219 // before the current GC.
220 size_t start_holes_size = 0;
221
222 // Total amount of space either wasted or contained in one of free lists
223 // after the current GC.
224 size_t end_holes_size = 0;
225
226 // Size of young objects in constructor.
227 size_t young_object_size = 0;
228
229 // Size of survived young objects in destructor.
230 size_t survived_young_object_size = 0;
231
232 // Bytes marked incrementally for INCREMENTAL_MARK_COMPACTOR
233 size_t incremental_marking_bytes = 0;
234
235 // Approximate number of threads that contributed in garbage collection.
236 size_t concurrency_estimate = 1;
237
238 // Duration (in ms) of incremental marking steps for
239 // INCREMENTAL_MARK_COMPACTOR.
241
243
244 // Start/end of atomic/safepoint pause.
247
248 // Amounts of time spent in different scopes during GC.
249 base::TimeDelta scopes[Scope::NUMBER_OF_SCOPES];
250
251 // Holds details for incremental marking scopes.
252 IncrementalInfos incremental_scopes[Scope::NUMBER_OF_INCREMENTAL_SCOPES];
253 };
254
255 class RecordGCPhasesInfo final {
256 public:
259
260 enum class Mode { None, Scavenger, Finalize };
261
262 Mode mode() const { return mode_; }
263 const char* trace_event_name() const { return trace_event_name_; }
264
265 // The timers are based on Gc types and the kinds of GC being invoked.
266 TimedHistogram* type_timer() const { return type_timer_; }
267 TimedHistogram* type_priority_timer() const { return type_priority_timer_; }
268
269 private:
271 const char* trace_event_name_;
274 };
275
276 static constexpr base::TimeDelta kThroughputTimeFrame =
277 base::TimeDelta::FromSeconds(5);
278 static constexpr double kConservativeSpeedInBytesPerMillisecond = 128 * KB;
279
280#ifdef V8_RUNTIME_CALL_STATS
281 V8_INLINE static RuntimeCallCounterId RCSCounterFromScope(Scope::ScopeId id);
282#endif // defined(V8_RUNTIME_CALL_STATS)
283
284 GCTracer(Heap* heap, base::TimeTicks startup_time,
285 GarbageCollectionReason initial_gc_reason =
286 GarbageCollectionReason::kUnknown);
287
288 GCTracer(const GCTracer&) = delete;
289 GCTracer& operator=(const GCTracer&) = delete;
290
291 V8_INLINE CollectionEpoch CurrentEpoch(Scope::ScopeId id) const;
292
293 // Start and stop an observable pause.
294 void StartObservablePause(base::TimeTicks time);
295 void StopObservablePause(GarbageCollector collector, base::TimeTicks time);
296
297 // Update the current event if it precedes the start of the observable pause.
298 void UpdateCurrentEvent(GarbageCollectionReason gc_reason,
299 const char* collector_reason);
300
301 enum class MarkingType { kAtomic, kIncremental };
302
303 // Start and stop a GC cycle (collecting data and reporting results).
304 void StartCycle(GarbageCollector collector, GarbageCollectionReason gc_reason,
305 const char* collector_reason, MarkingType marking);
306 void StopYoungCycleIfFinished();
307 void StopFullCycleIfFinished();
308
309 void UpdateMemoryBalancerGCSpeed();
310
311 // Start and stop a cycle's atomic pause.
312 void StartAtomicPause();
313 void StopAtomicPause();
314
315 void StartInSafepoint(base::TimeTicks time);
316 void StopInSafepoint(base::TimeTicks time);
317
318 // Notify the GC tracer that full/young sweeping is completed. A cycle cannot
319 // be stopped until sweeping is completed and `StopCycle` would bail out if
320 // `Notify*SweepingCompleted` is not called before. These methods also call
321 // `StopCycle` if all other conditions are also met (e.g. Oilpan sweeping is
322 // also completed).
323 void NotifyFullSweepingCompletedAndStopCycleIfFinished();
324 void NotifyYoungSweepingCompletedAndStopCycleIfFinished();
325 // Marks young sweeping as complete but doesn't try to call `StopCycle` even
326 // if possible.
327 void NotifyYoungSweepingCompleted();
328
329 void NotifyFullCppGCCompleted();
330 void NotifyYoungCppGCRunning();
331 void NotifyYoungCppGCCompleted();
332
333#ifdef DEBUG
334 bool IsInObservablePause() const;
335 bool IsInAtomicPause() const;
336
337 // Checks if the current event is consistent with a collector.
338 bool IsConsistentWithCollector(GarbageCollector collector) const;
339
340 // Checks if the current event corresponds to a full GC cycle whose sweeping
341 // has not finalized yet.
342 bool IsSweepingInProgress() const;
343#endif
344
345 // Sample and accumulate bytes allocated since the last GC.
346 void SampleAllocation(base::TimeTicks current, size_t new_space_counter_bytes,
347 size_t old_generation_counter_bytes,
348 size_t embedder_counter_bytes);
349
350 void AddCompactionEvent(double duration, size_t live_bytes_compacted);
351
352 void AddSurvivalRatio(double survival_ratio);
353
354 void SampleConcurrencyEsimate(size_t concurrency);
355
356 // Log an incremental marking step.
357 void AddIncrementalMarkingStep(double duration, size_t bytes);
358
359 // Log an incremental marking step.
360 void AddIncrementalSweepingStep(double duration);
361
362 // Compute the average incremental marking speed in bytes/millisecond.
363 // Returns a conservative value if no events have been recorded.
364 double IncrementalMarkingSpeedInBytesPerMillisecond() const;
365
366 // Compute the average embedder speed in bytes/millisecond.
367 // Returns nullopt if no events have been recorded.
368 std::optional<double> EmbedderSpeedInBytesPerMillisecond() const;
369
370 // Average estimaged young generation speed in bytes/millisecond. This factors
371 // in concurrency and assumes that the level of concurrency provided by the
372 // embedder is stable. E.g., receiving lower concurrency than previously
373 // recorded events will yield in lower current speed.
374 //
375 // Returns nullopt if no events have been recorded.
376 std::optional<double> YoungGenerationSpeedInBytesPerMillisecond(
377 YoungGenerationSpeedMode mode) const;
378
379 // Compute the average compaction speed in bytes/millisecond.
380 // Returns nullopt if not enough events have been recorded.
381 std::optional<double> CompactionSpeedInBytesPerMillisecond() const;
382
383 // Compute the average mark-sweep speed in bytes/millisecond.
384 // Returns nullopt if no events have been recorded.
385 std::optional<double> MarkCompactSpeedInBytesPerMillisecond() const;
386
387 // Compute the average incremental mark-sweep finalize speed in
388 // bytes/millisecond.
389 // Returns nullopt if no events have been recorded.
390 std::optional<double> FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()
391 const;
392
393 // Compute the overall old generation mark compact speed including incremental
394 // steps and the final mark-compact step.
395 std::optional<double> OldGenerationSpeedInBytesPerMillisecond();
396
397 // Allocation throughput in the new space in bytes/millisecond.
398 // Returns 0 if no allocation events have been recorded.
399 double NewSpaceAllocationThroughputInBytesPerMillisecond() const;
400
401 // Allocation throughput in the old generation in bytes/millisecond in the
402 // last time_ms milliseconds.
403 // Returns 0 if no allocation events have been recorded.
404 double OldGenerationAllocationThroughputInBytesPerMillisecond() const;
405
406 // Allocation throughput in the embedder in bytes/millisecond in the
407 // last time_ms milliseconds.
408 // Returns 0 if no allocation events have been recorded.
409 double EmbedderAllocationThroughputInBytesPerMillisecond() const;
410
411 // Allocation throughput in heap in bytes/millisecond in the last time_ms
412 // milliseconds.
413 // Returns 0 if no allocation events have been recorded.
414 double AllocationThroughputInBytesPerMillisecond() const;
415
416 // Computes the average survival ratio based on the last recorded survival
417 // events.
418 // Returns 0 if no events have been recorded.
419 double AverageSurvivalRatio() const;
420
421 // Returns true if at least one survival event was recorded.
422 bool SurvivalEventsRecorded() const;
423
424 // Discard all recorded survival events.
425 void ResetSurvivalEvents();
426
427 void NotifyIncrementalMarkingStart();
428
429 // Invoked when starting marking - either incremental or as part of the atomic
430 // pause. Used for computing/updating code flushing increase.
431 void NotifyMarkingStart();
432
433 // Returns the current cycle's code flushing increase in seconds.
434 uint16_t CodeFlushingIncrease() const;
435
436 // Returns average mutator utilization with respect to mark-compact
437 // garbage collections. This ignores scavenger.
438 double AverageMarkCompactMutatorUtilization() const;
439 double CurrentMarkCompactMutatorUtilization() const;
440
441 V8_INLINE void AddScopeSample(Scope::ScopeId id, base::TimeDelta duration);
442
443 void RecordGCPhasesHistograms(RecordGCPhasesInfo::Mode mode);
444
445 void RecordGCSizeCounters() const;
446
447 void RecordEmbedderMarkingSpeed(size_t bytes, base::TimeDelta duration);
448
449 // Returns the average time between scheduling and invocation of an
450 // incremental marking task.
451 std::optional<base::TimeDelta> AverageTimeToIncrementalMarkingTask() const;
452 void RecordTimeToIncrementalMarkingTask(base::TimeDelta time_to_task);
453
454#ifdef V8_RUNTIME_CALL_STATS
455 V8_INLINE WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats();
456#endif // defined(V8_RUNTIME_CALL_STATS)
457
458 GarbageCollector GetCurrentCollector() const;
459
460 void UpdateCurrentEventPriority(Priority priority);
461
462 private:
465
469
470 void StopCycle(GarbageCollector collector);
471
472 // Statistics for background scopes are kept out of the current event and only
473 // copied there via FetchBackgroundCounters(). This method here is thread-safe
474 // but may return out-of-date numbers as it only considers data from the
475 // current Event.
476 V8_INLINE double current_scope(Scope::ScopeId id) const;
477
478 V8_INLINE constexpr const IncrementalInfos& incremental_scope(
479 Scope::ScopeId id) const;
480
481 void ResetForTesting();
482 void RecordIncrementalMarkingSpeed(size_t bytes, base::TimeDelta duration);
483 void RecordMutatorUtilization(base::TimeTicks mark_compactor_end_time,
484 base::TimeDelta mark_compactor_duration);
485
486 // Update counters for an entire full GC cycle. Exact accounting of events
487 // within a GC is not necessary which is why the recording takes place at the
488 // end of the atomic pause.
489 void RecordGCSumCounters();
490
491 // Print one detailed trace line in name=value format.
492 // TODO(ernstm): Move to Heap.
493 void PrintNVP() const;
494
495 // Print one trace line.
496 // TODO(ernstm): Move to Heap.
497 void Print() const;
498
499 // Prints a line and also adds it to the heap's ring buffer so that
500 // it can be included in later crash dumps.
501 void PRINTF_FORMAT(2, 3) Output(const char* format, ...) const;
502
503 void FetchBackgroundCounters();
504
505 void ReportFullCycleToRecorder();
506 void ReportIncrementalMarkingStepToRecorder(double v8_duration);
507 void ReportIncrementalSweepingStepToRecorder(double v8_duration);
508 void ReportYoungCycleToRecorder();
509
510 // Pointer to the heap that owns this tracer.
512
513 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
514 // has returned.
516
517 // Previous tracer event.
518 Event previous_;
519
520 // The starting time of the observable pause if set.
521 std::optional<base::TimeTicks> start_of_observable_pause_;
522
523 // We need two epochs, since there can be scavenges during sweeping.
524 CollectionEpoch epoch_young_ = 0;
525 CollectionEpoch epoch_full_ = 0;
526
527 // Incremental marking speed for major GCs. Marking for minor GCs is ignored.
528 double recorded_major_incremental_marking_speed_ = 0.0;
529
530 std::optional<base::TimeDelta> average_time_to_incremental_marking_task_;
531
532 // This is not the general last marking start time as it's only updated when
533 // we reach the minimum threshold for code flushing which is 1 sec.
534 std::optional<base::TimeTicks> last_marking_start_time_for_code_flushing_;
535 uint16_t code_flushing_increase_s_ = 0;
536
537 // Incremental scopes carry more information than just the duration. The infos
538 // here are merged back upon starting/stopping the GC tracer.
539 IncrementalInfos incremental_scopes_[Scope::NUMBER_OF_INCREMENTAL_SCOPES];
540
541 // Timestamp and allocation counter at the last sampled allocation event.
542 base::TimeTicks allocation_time_;
543 size_t new_space_allocation_counter_bytes_ = 0;
544 size_t old_generation_allocation_counter_bytes_ = 0;
545 size_t embedder_allocation_counter_bytes_ = 0;
546
547 std::optional<double> combined_mark_compact_speed_cache_;
548
549 // Used for computing average mutator utilization.
550 double average_mutator_duration_ = 0.0;
551 double average_mark_compact_duration_ = 0.0;
552 double current_mark_compact_mutator_utilization_ = 1.0;
553
554 // The end of the last mark-compact GC. Is set to isolate/heap setup time
555 // before the first one.
556 base::TimeTicks previous_mark_compact_end_time_;
557 base::TimeDelta total_duration_since_last_mark_compact_;
558
559 BytesAndDurationBuffer recorded_compactions_;
560 BytesAndDurationBuffer recorded_incremental_mark_compacts_;
561 BytesAndDurationBuffer recorded_mark_compacts_;
562 BytesAndDurationBuffer recorded_major_totals_;
563 BytesAndDurationBuffer recorded_embedder_marking_;
564
565 static constexpr base::TimeDelta kSmoothedAllocationSpeedDecayRate =
566 v8::base::TimeDelta::FromMilliseconds(100);
567
568 SmoothedBytesAndDuration new_generation_allocations_{
569 kSmoothedAllocationSpeedDecayRate};
570 SmoothedBytesAndDuration old_generation_allocations_{
571 kSmoothedAllocationSpeedDecayRate};
572 SmoothedBytesAndDuration embedder_generation_allocations_{
573 kSmoothedAllocationSpeedDecayRate};
574
575 // Estimate for young generation speed. Based on walltime and concurrency
576 // estimates.
580
581 // A full GC cycle stops only when both v8 and cppgc (if available) GCs have
582 // finished sweeping.
583 bool notified_full_sweeping_completed_ = false;
584 bool notified_full_cppgc_completed_ = false;
585 bool full_cppgc_completed_during_minor_gc_ = false;
586
587 bool notified_young_sweeping_completed_ = false;
588 // Similar to full GCs, a young GC cycle stops only when both v8 and cppgc GCs
589 // have finished sweeping.
590 bool notified_young_cppgc_completed_ = false;
591 // Keep track whether the young cppgc GC was scheduled (as opposed to full
592 // cycles, for young cycles cppgc is not always scheduled).
593 bool notified_young_cppgc_running_ = false;
594
595 // When a full GC cycle is interrupted by a young generation GC cycle, the
596 // |previous_| event is used as temporary storage for the |current_| event
597 // that corresponded to the full GC cycle, and this field is set to true.
598 bool young_gc_while_full_gc_ = false;
599
604
606 base::TimeDelta background_scopes_[Scope::NUMBER_OF_SCOPES];
607
608#if defined(V8_USE_PERFETTO)
609 perfetto::ThreadTrack parent_track_;
610#endif
611
612 FRIEND_TEST(GCTracerTest, AllocationThroughput);
613 FRIEND_TEST(GCTracerTest, BackgroundScavengerScope);
614 FRIEND_TEST(GCTracerTest, BackgroundMinorMSScope);
615 FRIEND_TEST(GCTracerTest, BackgroundMajorMCScope);
616 FRIEND_TEST(GCTracerTest, CyclePriorities);
617 FRIEND_TEST(GCTracerTest, EmbedderAllocationThroughput);
618 FRIEND_TEST(GCTracerTest, MultithreadedBackgroundScope);
619 FRIEND_TEST(GCTracerTest, NewSpaceAllocationThroughput);
620 FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughput);
621 FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughputWithProvidedTime);
622 FRIEND_TEST(GCTracerTest, RegularScope);
623 FRIEND_TEST(GCTracerTest, IncrementalMarkingDetails);
624 FRIEND_TEST(GCTracerTest, IncrementalScope);
625 FRIEND_TEST(GCTracerTest, IncrementalMarkingSpeed);
626 FRIEND_TEST(GCTracerTest, MutatorUtilization);
627 FRIEND_TEST(GCTracerTest, RecordMarkCompactHistograms);
628 FRIEND_TEST(GCTracerTest, RecordScavengerHistograms);
629};
630
631const char* ToString(GCTracer::Event::Type type, bool short_name);
632
633} // namespace internal
634} // namespace v8
635
636#endif // V8_HEAP_GC_TRACER_H_
base::TimeTicks incremental_marking_start_time
Definition gc-tracer.h:242
base::TimeTicks end_atomic_pause_time
Definition gc-tracer.h:246
base::TimeTicks start_atomic_pause_time
Definition gc-tracer.h:245
GarbageCollectionReason gc_reason
Definition gc-tracer.h:189
std::optional< Priority > priority
Definition gc-tracer.h:195
base::TimeDelta incremental_marking_duration
Definition gc-tracer.h:240
TimedHistogram * type_timer() const
Definition gc-tracer.h:266
TimedHistogram * type_priority_timer() const
Definition gc-tracer.h:267
const base::TimeTicks start_time_
Definition gc-tracer.h:151
const ThreadKind thread_kind_
Definition gc-tracer.h:150
Scope & operator=(const Scope &)=delete
Scope(const Scope &)=delete
FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughput)
FRIEND_TEST(GCTracerTest, MultithreadedBackgroundScope)
FRIEND_TEST(GCTracerTest, BackgroundScavengerScope)
FRIEND_TEST(GCTracerTest, IncrementalMarkingDetails)
FRIEND_TEST(GCTracerTest, IncrementalMarkingSpeed)
FRIEND_TEST(GCTracerTest, IncrementalScope)
FRIEND_TEST(GCTracerTest, RecordMarkCompactHistograms)
base::RingBuffer< double > recorded_survival_ratios_
Definition gc-tracer.h:579
BytesAndDurationBuffer recorded_minor_gc_atomic_pause_
Definition gc-tracer.h:578
FRIEND_TEST(GCTracerTest, CyclePriorities)
FRIEND_TEST(GCTracerTest, BackgroundMajorMCScope)
BytesAndDurationBuffer recorded_minor_gc_per_thread_
Definition gc-tracer.h:577
FRIEND_TEST(GCTracerTest, NewSpaceAllocationThroughput)
GCTracer & operator=(const GCTracer &)=delete
FRIEND_TEST(GCTracerTest, BackgroundMinorMSScope)
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark incremental_mark_batched_events_
Definition gc-tracer.h:601
FRIEND_TEST(GCTracerTest, PerGenerationAllocationThroughputWithProvidedTime)
base::Mutex background_scopes_mutex_
Definition gc-tracer.h:605
FRIEND_TEST(GCTracerTest, EmbedderAllocationThroughput)
FRIEND_TEST(GCTracerTest, RegularScope)
GCTracer(const GCTracer &)=delete
FRIEND_TEST(GCTracerTest, RecordScavengerHistograms)
FRIEND_TEST(GCTracerTest, MutatorUtilization)
FRIEND_TEST(GCTracerTest, AllocationThroughput)
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalSweep incremental_sweep_batched_events_
Definition gc-tracer.h:603
RecordWriteMode const mode_
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation trace turbo cfg trace TurboFan s graph trimmer trace TurboFan s control equivalence trace TurboFan s register allocator trace stack load store counters for optimized code in run fuzzing &&concurrent_recompilation trace_turbo trace_turbo_scheduled trace_turbo_stack_accesses verify TurboFan machine graph of code stubs enable FixedArray bounds checks print TurboFan statistics of wasm compilations maximum cumulative size of bytecode considered for inlining scale factor of bytecode size used to calculate the inlining budget * KB
use conservative stack scanning use direct handles with conservative stack scanning Treat some precise references as conservative references to stress test object pinning in Scavenger minor_gc_task Enables random stressing of object pinning in Scavenger
#define DEFINE_SCOPE(scope)
Definition gc-tracer.h:122
#define TRACER_SCOPES(F)
#define TRACER_BACKGROUND_SCOPES(F)
base::ElapsedTimer timer_
size_t priority
v8::base::RingBuffer< BytesAndDuration > BytesAndDurationBuffer
Definition bytes.h:27
STL namespace.
GarbageCollectionReason
Definition globals.h:1428
constexpr const char * ToString(DeoptimizeKind kind)
Definition globals.h:880
YoungGenerationSpeedMode
Definition gc-tracer.h:24
@ kUpToAndIncludingAtomicPause
Definition gc-tracer.h:25
uint32_t CollectionEpoch
Definition gc-tracer.h:103
base::uc32 current_
#define PRINTF_FORMAT(format_param, dots_param)
#define V8_EXPORT_PRIVATE
Definition macros.h:460
Heap * heap_
#define V8_INLINE
Definition v8config.h:500
#define V8_NODISCARD
Definition v8config.h:693