Commit 7ff07f6e authored by Nikolaos Papaspyrou's avatar Nikolaos Papaspyrou Committed by V8 LUCI CQ

heap: Add incremental mark/sweep step events

Report fine-grain incremental mark/sweep statistics to the Recorder API.
These will be used by Blink to populate UMA histograms such as
V8.GC.Event.MainThread.Full.Incremental.(Mark|Sweep).

Bug: chromium:1154636
Change-Id: I1cbdcb2ffa49bd01d04a2e1d43921cebf956ac84
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3545070Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Nikolaos Papaspyrou <nikolaos@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79596}
parent ec6117ed
...@@ -61,19 +61,23 @@ struct GarbageCollectionFullMainThreadIncrementalMark { ...@@ -61,19 +61,23 @@ struct GarbageCollectionFullMainThreadIncrementalMark {
int64_t cpp_wall_clock_duration_in_us = -1; int64_t cpp_wall_clock_duration_in_us = -1;
}; };
struct GarbageCollectionFullMainThreadBatchedIncrementalMark {
std::vector<GarbageCollectionFullMainThreadIncrementalMark> events;
};
struct GarbageCollectionFullMainThreadIncrementalSweep { struct GarbageCollectionFullMainThreadIncrementalSweep {
int64_t wall_clock_duration_in_us = -1; int64_t wall_clock_duration_in_us = -1;
int64_t cpp_wall_clock_duration_in_us = -1; int64_t cpp_wall_clock_duration_in_us = -1;
}; };
struct GarbageCollectionFullMainThreadBatchedIncrementalSweep { template <typename EventType>
std::vector<GarbageCollectionFullMainThreadIncrementalSweep> events; struct GarbageCollectionBatchedEvents {
std::vector<EventType> events;
}; };
using GarbageCollectionFullMainThreadBatchedIncrementalMark =
GarbageCollectionBatchedEvents<
GarbageCollectionFullMainThreadIncrementalMark>;
using GarbageCollectionFullMainThreadBatchedIncrementalSweep =
GarbageCollectionBatchedEvents<
GarbageCollectionFullMainThreadIncrementalSweep>;
struct GarbageCollectionYoungCycle { struct GarbageCollectionYoungCycle {
int reason = -1; int reason = -1;
int64_t total_wall_clock_duration_in_us = -1; int64_t total_wall_clock_duration_in_us = -1;
......
...@@ -317,7 +317,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent( ...@@ -317,7 +317,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
incremental_mark_batched_events_.events.emplace_back(); incremental_mark_batched_events_.events.emplace_back();
incremental_mark_batched_events_.events.back().cpp_wall_clock_duration_in_us = incremental_mark_batched_events_.events.back().cpp_wall_clock_duration_in_us =
cppgc_event.duration_us; cppgc_event.duration_us;
// TODO(chromium:1154636): Populate event.wall_clock_duration_in_us.
if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) { if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) {
recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_), recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_),
GetContextId()); GetContextId());
...@@ -336,7 +335,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent( ...@@ -336,7 +335,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
incremental_sweep_batched_events_.events.emplace_back(); incremental_sweep_batched_events_.events.emplace_back();
incremental_sweep_batched_events_.events.back() incremental_sweep_batched_events_.events.back()
.cpp_wall_clock_duration_in_us = cppgc_event.duration_us; .cpp_wall_clock_duration_in_us = cppgc_event.duration_us;
// TODO(chromium:1154636): Populate event.wall_clock_duration_in_us.
if (incremental_sweep_batched_events_.events.size() == kMaxBatchedEvents) { if (incremental_sweep_batched_events_.events.size() == kMaxBatchedEvents) {
recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_), recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_),
GetContextId()); GetContextId());
......
...@@ -666,7 +666,11 @@ void GCTracer::AddIncrementalMarkingStep(double duration, size_t bytes) { ...@@ -666,7 +666,11 @@ void GCTracer::AddIncrementalMarkingStep(double duration, size_t bytes) {
incremental_marking_bytes_ += bytes; incremental_marking_bytes_ += bytes;
incremental_marking_duration_ += duration; incremental_marking_duration_ += duration;
} }
ReportIncrementalMarkingStepToRecorder(); ReportIncrementalMarkingStepToRecorder(duration);
}
void GCTracer::AddIncrementalSweepingStep(double duration) {
ReportIncrementalSweepingStepToRecorder(duration);
} }
void GCTracer::Output(const char* format, ...) const { void GCTracer::Output(const char* format, ...) const {
...@@ -1491,9 +1495,9 @@ void CopySizeMetrics( ...@@ -1491,9 +1495,9 @@ void CopySizeMetrics(
return isolate->GetOrRegisterRecorderContextId(isolate->native_context()); return isolate->GetOrRegisterRecorderContextId(isolate->native_context());
} }
void FlushBatchedIncrementalEvents( template <typename EventType>
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark& void FlushBatchedEvents(
batched_events, v8::metrics::GarbageCollectionBatchedEvents<EventType>& batched_events,
Isolate* isolate) { Isolate* isolate) {
DCHECK_NOT_NULL(isolate->metrics_recorder()); DCHECK_NOT_NULL(isolate->metrics_recorder());
DCHECK(!batched_events.events.empty()); DCHECK(!batched_events.events.empty());
...@@ -1515,14 +1519,17 @@ void GCTracer::ReportFullCycleToRecorder() { ...@@ -1515,14 +1519,17 @@ void GCTracer::ReportFullCycleToRecorder() {
DCHECK_NOT_NULL(recorder); DCHECK_NOT_NULL(recorder);
if (!recorder->HasEmbedderRecorder()) { if (!recorder->HasEmbedderRecorder()) {
incremental_mark_batched_events_ = {}; incremental_mark_batched_events_ = {};
incremental_sweep_batched_events_ = {};
if (cpp_heap) { if (cpp_heap) {
cpp_heap->GetMetricRecorder()->ClearCachedEvents(); cpp_heap->GetMetricRecorder()->ClearCachedEvents();
} }
return; return;
} }
if (!incremental_mark_batched_events_.events.empty()) { if (!incremental_mark_batched_events_.events.empty()) {
FlushBatchedIncrementalEvents(incremental_mark_batched_events_, FlushBatchedEvents(incremental_mark_batched_events_, heap_->isolate());
heap_->isolate()); }
if (!incremental_sweep_batched_events_.events.empty()) {
FlushBatchedEvents(incremental_sweep_batched_events_, heap_->isolate());
} }
v8::metrics::GarbageCollectionFullCycle event; v8::metrics::GarbageCollectionFullCycle event;
...@@ -1640,7 +1647,7 @@ void GCTracer::ReportFullCycleToRecorder() { ...@@ -1640,7 +1647,7 @@ void GCTracer::ReportFullCycleToRecorder() {
recorder->AddMainThreadEvent(event, GetContextId(heap_->isolate())); recorder->AddMainThreadEvent(event, GetContextId(heap_->isolate()));
} }
void GCTracer::ReportIncrementalMarkingStepToRecorder() { void GCTracer::ReportIncrementalMarkingStepToRecorder(double v8_duration) {
DCHECK_EQ(Event::Type::INCREMENTAL_MARK_COMPACTOR, current_.type); DCHECK_EQ(Event::Type::INCREMENTAL_MARK_COMPACTOR, current_.type);
static constexpr int kMaxBatchedEvents = static constexpr int kMaxBatchedEvents =
CppHeap::MetricRecorderAdapter::kMaxBatchedEvents; CppHeap::MetricRecorderAdapter::kMaxBatchedEvents;
...@@ -1661,10 +1668,27 @@ void GCTracer::ReportIncrementalMarkingStepToRecorder() { ...@@ -1661,10 +1668,27 @@ void GCTracer::ReportIncrementalMarkingStepToRecorder() {
.cpp_wall_clock_duration_in_us = cppgc_event.value().duration_us; .cpp_wall_clock_duration_in_us = cppgc_event.value().duration_us;
} }
} }
// TODO(chromium:1154636): Populate event.wall_clock_duration_in_us. incremental_mark_batched_events_.events.back().wall_clock_duration_in_us =
static_cast<int64_t>(v8_duration *
base::Time::kMicrosecondsPerMillisecond);
if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) { if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) {
FlushBatchedIncrementalEvents(incremental_mark_batched_events_, FlushBatchedEvents(incremental_mark_batched_events_, heap_->isolate());
heap_->isolate()); }
}
void GCTracer::ReportIncrementalSweepingStepToRecorder(double v8_duration) {
static constexpr int kMaxBatchedEvents =
CppHeap::MetricRecorderAdapter::kMaxBatchedEvents;
const std::shared_ptr<metrics::Recorder>& recorder =
heap_->isolate()->metrics_recorder();
DCHECK_NOT_NULL(recorder);
if (!recorder->HasEmbedderRecorder()) return;
incremental_sweep_batched_events_.events.emplace_back();
incremental_sweep_batched_events_.events.back().wall_clock_duration_in_us =
static_cast<int64_t>(v8_duration *
base::Time::kMicrosecondsPerMillisecond);
if (incremental_sweep_batched_events_.events.size() == kMaxBatchedEvents) {
FlushBatchedEvents(incremental_sweep_batched_events_, heap_->isolate());
} }
} }
......
...@@ -322,6 +322,9 @@ class V8_EXPORT_PRIVATE GCTracer { ...@@ -322,6 +322,9 @@ class V8_EXPORT_PRIVATE GCTracer {
// Log an incremental marking step. // Log an incremental marking step.
void AddIncrementalMarkingStep(double duration, size_t bytes); void AddIncrementalMarkingStep(double duration, size_t bytes);
// Log an incremental marking step.
void AddIncrementalSweepingStep(double duration);
// Compute the average incremental marking speed in bytes/millisecond. // Compute the average incremental marking speed in bytes/millisecond.
// Returns a conservative value if no events have been recorded. // Returns a conservative value if no events have been recorded.
double IncrementalMarkingSpeedInBytesPerMillisecond() const; double IncrementalMarkingSpeedInBytesPerMillisecond() const;
...@@ -502,7 +505,8 @@ class V8_EXPORT_PRIVATE GCTracer { ...@@ -502,7 +505,8 @@ class V8_EXPORT_PRIVATE GCTracer {
void FetchBackgroundGeneralCounters(); void FetchBackgroundGeneralCounters();
void ReportFullCycleToRecorder(); void ReportFullCycleToRecorder();
void ReportIncrementalMarkingStepToRecorder(); void ReportIncrementalMarkingStepToRecorder(double v8_duration);
void ReportIncrementalSweepingStepToRecorder(double v8_duration);
void ReportYoungCycleToRecorder(); void ReportYoungCycleToRecorder();
// Pointer to the heap that owns this tracer. // Pointer to the heap that owns this tracer.
...@@ -589,6 +593,8 @@ class V8_EXPORT_PRIVATE GCTracer { ...@@ -589,6 +593,8 @@ class V8_EXPORT_PRIVATE GCTracer {
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark
incremental_mark_batched_events_; incremental_mark_batched_events_;
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalSweep
incremental_sweep_batched_events_;
base::Mutex background_counter_mutex_; base::Mutex background_counter_mutex_;
BackgroundCounter background_counter_[Scope::NUMBER_OF_SCOPES]; BackgroundCounter background_counter_[Scope::NUMBER_OF_SCOPES];
......
...@@ -138,10 +138,8 @@ class IncrementalMarkingRootMarkingVisitor : public RootVisitor { ...@@ -138,10 +138,8 @@ class IncrementalMarkingRootMarkingVisitor : public RootVisitor {
Heap* heap_; Heap* heap_;
}; };
bool IncrementalMarking::WasActivated() { return was_activated_; } bool IncrementalMarking::WasActivated() { return was_activated_; }
bool IncrementalMarking::CanBeActivated() { bool IncrementalMarking::CanBeActivated() {
// Only start incremental marking in a safe state: // Only start incremental marking in a safe state:
// 1) when incremental marking is turned on // 1) when incremental marking is turned on
...@@ -360,7 +358,6 @@ bool IncrementalMarking::ShouldRetainMap(Map map, int age) { ...@@ -360,7 +358,6 @@ bool IncrementalMarking::ShouldRetainMap(Map map, int age) {
return true; return true;
} }
void IncrementalMarking::RetainMaps() { void IncrementalMarking::RetainMaps() {
// Do not retain dead maps if flag disables it or there is // Do not retain dead maps if flag disables it or there is
// - memory pressure (reduce_memory_footprint_), // - memory pressure (reduce_memory_footprint_),
......
...@@ -455,9 +455,12 @@ bool Sweeper::ConcurrentSweepSpace(AllocationSpace identity, ...@@ -455,9 +455,12 @@ bool Sweeper::ConcurrentSweepSpace(AllocationSpace identity,
bool Sweeper::IncrementalSweepSpace(AllocationSpace identity) { bool Sweeper::IncrementalSweepSpace(AllocationSpace identity) {
TRACE_GC_EPOCH(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_SWEEPING, TRACE_GC_EPOCH(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_SWEEPING,
ThreadKind::kMain); ThreadKind::kMain);
const double start = heap_->MonotonicallyIncreasingTimeInMs();
if (Page* page = GetSweepingPageSafe(identity)) { if (Page* page = GetSweepingPageSafe(identity)) {
ParallelSweepPage(page, identity); ParallelSweepPage(page, identity);
} }
const double duration = heap_->MonotonicallyIncreasingTimeInMs() - start;
heap_->tracer()->AddIncrementalSweepingStep(duration);
return sweeping_list_[GetSweepSpaceIndex(identity)].empty(); return sweeping_list_[GetSweepSpaceIndex(identity)].empty();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment