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 {
int64_t cpp_wall_clock_duration_in_us = -1;
};
struct GarbageCollectionFullMainThreadBatchedIncrementalMark {
std::vector<GarbageCollectionFullMainThreadIncrementalMark> events;
};
struct GarbageCollectionFullMainThreadIncrementalSweep {
int64_t wall_clock_duration_in_us = -1;
int64_t cpp_wall_clock_duration_in_us = -1;
};
struct GarbageCollectionFullMainThreadBatchedIncrementalSweep {
std::vector<GarbageCollectionFullMainThreadIncrementalSweep> events;
template <typename EventType>
struct GarbageCollectionBatchedEvents {
std::vector<EventType> events;
};
using GarbageCollectionFullMainThreadBatchedIncrementalMark =
GarbageCollectionBatchedEvents<
GarbageCollectionFullMainThreadIncrementalMark>;
using GarbageCollectionFullMainThreadBatchedIncrementalSweep =
GarbageCollectionBatchedEvents<
GarbageCollectionFullMainThreadIncrementalSweep>;
struct GarbageCollectionYoungCycle {
int reason = -1;
int64_t total_wall_clock_duration_in_us = -1;
......
......@@ -317,7 +317,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
incremental_mark_batched_events_.events.emplace_back();
incremental_mark_batched_events_.events.back().cpp_wall_clock_duration_in_us =
cppgc_event.duration_us;
// TODO(chromium:1154636): Populate event.wall_clock_duration_in_us.
if (incremental_mark_batched_events_.events.size() == kMaxBatchedEvents) {
recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_),
GetContextId());
......@@ -336,7 +335,6 @@ void CppHeap::MetricRecorderAdapter::AddMainThreadEvent(
incremental_sweep_batched_events_.events.emplace_back();
incremental_sweep_batched_events_.events.back()
.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) {
recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_),
GetContextId());
......
......@@ -666,7 +666,11 @@ void GCTracer::AddIncrementalMarkingStep(double duration, size_t bytes) {
incremental_marking_bytes_ += bytes;
incremental_marking_duration_ += duration;
}
ReportIncrementalMarkingStepToRecorder();
ReportIncrementalMarkingStepToRecorder(duration);
}
void GCTracer::AddIncrementalSweepingStep(double duration) {
ReportIncrementalSweepingStepToRecorder(duration);
}
void GCTracer::Output(const char* format, ...) const {
......@@ -1491,9 +1495,9 @@ void CopySizeMetrics(
return isolate->GetOrRegisterRecorderContextId(isolate->native_context());
}
void FlushBatchedIncrementalEvents(
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark&
batched_events,
template <typename EventType>
void FlushBatchedEvents(
v8::metrics::GarbageCollectionBatchedEvents<EventType>& batched_events,
Isolate* isolate) {
DCHECK_NOT_NULL(isolate->metrics_recorder());
DCHECK(!batched_events.events.empty());
......@@ -1515,14 +1519,17 @@ void GCTracer::ReportFullCycleToRecorder() {
DCHECK_NOT_NULL(recorder);
if (!recorder->HasEmbedderRecorder()) {
incremental_mark_batched_events_ = {};
incremental_sweep_batched_events_ = {};
if (cpp_heap) {
cpp_heap->GetMetricRecorder()->ClearCachedEvents();
}
return;
}
if (!incremental_mark_batched_events_.events.empty()) {
FlushBatchedIncrementalEvents(incremental_mark_batched_events_,
heap_->isolate());
FlushBatchedEvents(incremental_mark_batched_events_, heap_->isolate());
}
if (!incremental_sweep_batched_events_.events.empty()) {
FlushBatchedEvents(incremental_sweep_batched_events_, heap_->isolate());
}
v8::metrics::GarbageCollectionFullCycle event;
......@@ -1640,7 +1647,7 @@ void GCTracer::ReportFullCycleToRecorder() {
recorder->AddMainThreadEvent(event, GetContextId(heap_->isolate()));
}
void GCTracer::ReportIncrementalMarkingStepToRecorder() {
void GCTracer::ReportIncrementalMarkingStepToRecorder(double v8_duration) {
DCHECK_EQ(Event::Type::INCREMENTAL_MARK_COMPACTOR, current_.type);
static constexpr int kMaxBatchedEvents =
CppHeap::MetricRecorderAdapter::kMaxBatchedEvents;
......@@ -1661,10 +1668,27 @@ void GCTracer::ReportIncrementalMarkingStepToRecorder() {
.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) {
FlushBatchedIncrementalEvents(incremental_mark_batched_events_,
heap_->isolate());
FlushBatchedEvents(incremental_mark_batched_events_, 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 {
// Log an incremental marking step.
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.
// Returns a conservative value if no events have been recorded.
double IncrementalMarkingSpeedInBytesPerMillisecond() const;
......@@ -502,7 +505,8 @@ class V8_EXPORT_PRIVATE GCTracer {
void FetchBackgroundGeneralCounters();
void ReportFullCycleToRecorder();
void ReportIncrementalMarkingStepToRecorder();
void ReportIncrementalMarkingStepToRecorder(double v8_duration);
void ReportIncrementalSweepingStepToRecorder(double v8_duration);
void ReportYoungCycleToRecorder();
// Pointer to the heap that owns this tracer.
......@@ -589,6 +593,8 @@ class V8_EXPORT_PRIVATE GCTracer {
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalMark
incremental_mark_batched_events_;
v8::metrics::GarbageCollectionFullMainThreadBatchedIncrementalSweep
incremental_sweep_batched_events_;
base::Mutex background_counter_mutex_;
BackgroundCounter background_counter_[Scope::NUMBER_OF_SCOPES];
......
......@@ -138,10 +138,8 @@ class IncrementalMarkingRootMarkingVisitor : public RootVisitor {
Heap* heap_;
};
bool IncrementalMarking::WasActivated() { return was_activated_; }
bool IncrementalMarking::CanBeActivated() {
// Only start incremental marking in a safe state:
// 1) when incremental marking is turned on
......@@ -360,7 +358,6 @@ bool IncrementalMarking::ShouldRetainMap(Map map, int age) {
return true;
}
void IncrementalMarking::RetainMaps() {
// Do not retain dead maps if flag disables it or there is
// - memory pressure (reduce_memory_footprint_),
......
......@@ -455,9 +455,12 @@ bool Sweeper::ConcurrentSweepSpace(AllocationSpace identity,
bool Sweeper::IncrementalSweepSpace(AllocationSpace identity) {
TRACE_GC_EPOCH(heap_->tracer(), GCTracer::Scope::MC_INCREMENTAL_SWEEPING,
ThreadKind::kMain);
const double start = heap_->MonotonicallyIncreasingTimeInMs();
if (Page* page = GetSweepingPageSafe(identity)) {
ParallelSweepPage(page, identity);
}
const double duration = heap_->MonotonicallyIncreasingTimeInMs() - start;
heap_->tracer()->AddIncrementalSweepingStep(duration);
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