#include "src/heap/gc-tracer.h"
#include <cstdarg>
#include <limits>
#include <optional>
#include "include/v8-metrics.h"
#include "src/base/atomic-utils.h"
#include "src/base/logging.h"
#include "src/base/platform/time.h"
#include "src/base/strings.h"
#include "src/common/globals.h"
#include "src/execution/thread-id.h"
#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/cppgc/metric-recorder.h"
#include "src/heap/gc-tracer-inl.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/heap/incremental-marking.h"
#include "src/heap/memory-balancer.h"
#include "src/heap/spaces.h"
#include "src/logging/counters.h"
#include "src/logging/metrics.h"
#include "src/logging/tracing-flags.h"
#include "src/tracing/tracing-category-observer.h"
namespace v8 {
namespace internal {
static size_t CountTotalHolesSize(Heap* heap) { … }
namespace {
std::atomic<CollectionEpoch> global_epoch{ … };
CollectionEpoch next_epoch() { … }
BytesAndDuration;
double BoundedAverageSpeed(
const base::RingBuffer<BytesAndDuration>& buffer,
std::optional<v8::base::TimeDelta> selected_duration) { … }
double BoundedAverageSpeed(const base::RingBuffer<BytesAndDuration>& buffer) { … }
}
GCTracer::Event::Event(Type type, State state,
GarbageCollectionReason gc_reason,
const char* collector_reason)
: … { … }
const char* ToString(GCTracer::Event::Type type, bool short_name) { … }
GCTracer::RecordGCPhasesInfo::RecordGCPhasesInfo(
Heap* heap, GarbageCollector collector, GarbageCollectionReason reason) { … }
GCTracer::GCTracer(Heap* heap, base::TimeTicks startup_time,
GarbageCollectionReason initial_gc_reason)
: … { … }
void GCTracer::ResetForTesting() { … }
void GCTracer::StartObservablePause(base::TimeTicks time) { … }
void GCTracer::UpdateCurrentEvent(GarbageCollectionReason gc_reason,
const char* collector_reason) { … }
void GCTracer::StartCycle(GarbageCollector collector,
GarbageCollectionReason gc_reason,
const char* collector_reason, MarkingType marking) { … }
void GCTracer::StartAtomicPause() { … }
void GCTracer::StartInSafepoint(base::TimeTicks time) { … }
void GCTracer::StopInSafepoint(base::TimeTicks time) { … }
void GCTracer::StopObservablePause(GarbageCollector collector,
base::TimeTicks time) { … }
void GCTracer::UpdateMemoryBalancerGCSpeed() { … }
void GCTracer::StopAtomicPause() { … }
namespace {
constexpr v8::base::TimeDelta YoungGenerationWallTime(
const GCTracer::Event& event) { … }
}
void GCTracer::StopCycle(GarbageCollector collector) { … }
void GCTracer::StopFullCycleIfNeeded() { … }
void GCTracer::StopYoungCycleIfNeeded() { … }
void GCTracer::NotifyFullSweepingCompleted() { … }
void GCTracer::NotifyYoungSweepingCompleted() { … }
void GCTracer::NotifyFullCppGCCompleted() { … }
void GCTracer::NotifyYoungCppGCCompleted() { … }
void GCTracer::NotifyYoungCppGCRunning() { … }
void GCTracer::SampleAllocation(base::TimeTicks current,
size_t new_space_counter_bytes,
size_t old_generation_counter_bytes,
size_t embedder_counter_bytes) { … }
void GCTracer::SampleConcurrencyEsimate(size_t concurrency) { … }
void GCTracer::NotifyMarkingStart() { … }
uint16_t GCTracer::CodeFlushingIncrease() const { … }
void GCTracer::AddCompactionEvent(double duration,
size_t live_bytes_compacted) { … }
void GCTracer::AddSurvivalRatio(double promotion_ratio) { … }
void GCTracer::AddIncrementalMarkingStep(double duration, size_t bytes) { … }
void GCTracer::AddIncrementalSweepingStep(double duration) { … }
void GCTracer::Output(const char* format, ...) const { … }
void GCTracer::Print() const { … }
void GCTracer::PrintNVP() const { … }
void GCTracer::RecordIncrementalMarkingSpeed(size_t bytes,
base::TimeDelta duration) { … }
void GCTracer::RecordTimeToIncrementalMarkingTask(
base::TimeDelta time_to_task) { … }
std::optional<base::TimeDelta> GCTracer::AverageTimeToIncrementalMarkingTask()
const { … }
void GCTracer::RecordEmbedderSpeed(size_t bytes, double duration) { … }
void GCTracer::RecordMutatorUtilization(base::TimeTicks mark_compact_end_time,
base::TimeDelta mark_compact_duration) { … }
double GCTracer::AverageMarkCompactMutatorUtilization() const { … }
double GCTracer::CurrentMarkCompactMutatorUtilization() const { … }
double GCTracer::IncrementalMarkingSpeedInBytesPerMillisecond() const { … }
double GCTracer::EmbedderSpeedInBytesPerMillisecond() const { … }
double GCTracer::YoungGenerationSpeedInBytesPerMillisecond(
YoungGenerationSpeedMode mode) const { … }
double GCTracer::CompactionSpeedInBytesPerMillisecond() const { … }
double GCTracer::MarkCompactSpeedInBytesPerMillisecond() const { … }
double GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() const { … }
double GCTracer::CombinedMarkCompactSpeedInBytesPerMillisecond() { … }
double GCTracer::CombineSpeedsInBytesPerMillisecond(double default_speed,
double optional_speed) { … }
double GCTracer::NewSpaceAllocationThroughputInBytesPerMillisecond(
std::optional<base::TimeDelta> selected_duration) const { … }
double GCTracer::OldGenerationAllocationThroughputInBytesPerMillisecond(
std::optional<base::TimeDelta> selected_duration) const { … }
double GCTracer::EmbedderAllocationThroughputInBytesPerMillisecond(
std::optional<base::TimeDelta> selected_duration) const { … }
double GCTracer::AllocationThroughputInBytesPerMillisecond(
std::optional<base::TimeDelta> selected_duration) const { … }
double GCTracer::CurrentAllocationThroughputInBytesPerMillisecond() const { … }
double GCTracer::CurrentOldGenerationAllocationThroughputInBytesPerMillisecond()
const { … }
double GCTracer::CurrentEmbedderAllocationThroughputInBytesPerMillisecond()
const { … }
double GCTracer::AverageSurvivalRatio() const { … }
bool GCTracer::SurvivalEventsRecorded() const { … }
void GCTracer::ResetSurvivalEvents() { … }
void GCTracer::NotifyIncrementalMarkingStart() { … }
void GCTracer::FetchBackgroundCounters() { … }
namespace {
V8_INLINE int TruncateToMs(base::TimeDelta delta) { … }
}
void GCTracer::RecordGCPhasesHistograms(RecordGCPhasesInfo::Mode mode) { … }
void GCTracer::RecordGCSumCounters() { … }
namespace {
void CopyTimeMetrics(
::v8::metrics::GarbageCollectionPhases& metrics,
const cppgc::internal::MetricRecorder::GCCycle::IncrementalPhases&
cppgc_metrics) { … }
void CopyTimeMetrics(
::v8::metrics::GarbageCollectionPhases& metrics,
const cppgc::internal::MetricRecorder::GCCycle::Phases& cppgc_metrics) { … }
void CopySizeMetrics(
::v8::metrics::GarbageCollectionSizes& metrics,
const cppgc::internal::MetricRecorder::GCCycle::Sizes& cppgc_metrics) { … }
::v8::metrics::Recorder::ContextId GetContextId(
v8::internal::Isolate* isolate) { … }
template <typename EventType>
void FlushBatchedEvents(
v8::metrics::GarbageCollectionBatchedEvents<EventType>& batched_events,
Isolate* isolate) { … }
}
void GCTracer::ReportFullCycleToRecorder() { … }
void GCTracer::ReportIncrementalMarkingStepToRecorder(double v8_duration) { … }
void GCTracer::ReportIncrementalSweepingStepToRecorder(double v8_duration) { … }
void GCTracer::ReportYoungCycleToRecorder() { … }
GarbageCollector GCTracer::GetCurrentCollector() const { … }
#ifdef DEBUG
bool GCTracer::IsInObservablePause() const { … }
bool GCTracer::IsInAtomicPause() const { … }
bool GCTracer::IsConsistentWithCollector(GarbageCollector collector) const { … }
bool GCTracer::IsSweepingInProgress() const { … }
#endif
}
}