diff options
Diffstat (limited to 'deps/v8/src/heap/cppgc-js/cpp-heap.cc')
-rw-r--r-- | deps/v8/src/heap/cppgc-js/cpp-heap.cc | 131 |
1 files changed, 124 insertions, 7 deletions
diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.cc b/deps/v8/src/heap/cppgc-js/cpp-heap.cc index 006c35808f..c91dac2697 100644 --- a/deps/v8/src/heap/cppgc-js/cpp-heap.cc +++ b/deps/v8/src/heap/cppgc-js/cpp-heap.cc @@ -14,9 +14,11 @@ #include "include/v8.h" #include "src/base/logging.h" #include "src/base/macros.h" +#include "src/base/platform/platform.h" #include "src/base/platform/time.h" -#include "src/execution/isolate.h" +#include "src/execution/isolate-inl.h" #include "src/flags/flags.h" +#include "src/handles/handles.h" #include "src/heap/base/stack.h" #include "src/heap/cppgc-js/cpp-snapshot.h" #include "src/heap/cppgc-js/unified-heap-marking-state.h" @@ -29,12 +31,14 @@ #include "src/heap/cppgc/marker.h" #include "src/heap/cppgc/marking-state.h" #include "src/heap/cppgc/marking-visitor.h" +#include "src/heap/cppgc/metric-recorder.h" #include "src/heap/cppgc/object-allocator.h" #include "src/heap/cppgc/prefinalizer-handler.h" #include "src/heap/cppgc/raw-heap.h" #include "src/heap/cppgc/stats-collector.h" #include "src/heap/cppgc/sweeper.h" #include "src/heap/embedder-tracing.h" +#include "src/heap/gc-tracer.h" #include "src/heap/marking-worklist.h" #include "src/heap/sweeper.h" #include "src/init/v8.h" @@ -215,16 +219,105 @@ void UnifiedHeapMarker::AddObject(void* object) { } // namespace +void CppHeap::MetricRecorderAdapter::AddMainThreadEvent( + const FullCycle& cppgc_event) { + last_full_gc_event_ = cppgc_event; + GetIsolate()->heap()->tracer()->NotifyGCCompleted(); +} + +void CppHeap::MetricRecorderAdapter::AddMainThreadEvent( + const MainThreadIncrementalMark& cppgc_event) { + // Incremental marking steps might be nested in V8 marking steps. In such + // cases, stash the relevant values and delegate to V8 to report them. For + // non-nested steps, report to the Recorder directly. + if (cpp_heap_.is_in_v8_marking_step_) { + last_incremental_mark_event_ = cppgc_event; + return; + } + // This is a standalone incremental marking step. + const std::shared_ptr<metrics::Recorder>& recorder = + GetIsolate()->metrics_recorder(); + DCHECK_NOT_NULL(recorder); + if (!recorder->HasEmbedderRecorder()) return; + 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()); + } +} + +void CppHeap::MetricRecorderAdapter::AddMainThreadEvent( + const MainThreadIncrementalSweep& cppgc_event) { + // Incremental sweeping steps are never nested inside V8 sweeping steps, so + // report to the Recorder directly. + const std::shared_ptr<metrics::Recorder>& recorder = + GetIsolate()->metrics_recorder(); + DCHECK_NOT_NULL(recorder); + if (!recorder->HasEmbedderRecorder()) return; + 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()); + } +} + +void CppHeap::MetricRecorderAdapter::FlushBatchedIncrementalEvents() { + const std::shared_ptr<metrics::Recorder>& recorder = + GetIsolate()->metrics_recorder(); + DCHECK_NOT_NULL(recorder); + if (!incremental_mark_batched_events_.events.empty()) { + recorder->AddMainThreadEvent(std::move(incremental_mark_batched_events_), + GetContextId()); + } + if (!incremental_sweep_batched_events_.events.empty()) { + recorder->AddMainThreadEvent(std::move(incremental_sweep_batched_events_), + GetContextId()); + } +} + +bool CppHeap::MetricRecorderAdapter::MetricsReportPending() const { + return last_full_gc_event_.has_value(); +} + +const base::Optional<cppgc::internal::MetricRecorder::FullCycle> +CppHeap::MetricRecorderAdapter::ExtractLastFullGcEvent() { + return std::move(last_full_gc_event_); +} + +const base::Optional<cppgc::internal::MetricRecorder::MainThreadIncrementalMark> +CppHeap::MetricRecorderAdapter::ExtractLastIncrementalMarkEvent() { + return std::move(last_incremental_mark_event_); +} + +Isolate* CppHeap::MetricRecorderAdapter::GetIsolate() const { + DCHECK_NOT_NULL(cpp_heap_.isolate()); + return reinterpret_cast<Isolate*>(cpp_heap_.isolate()); +} + +v8::metrics::Recorder::ContextId CppHeap::MetricRecorderAdapter::GetContextId() + const { + DCHECK_NOT_NULL(GetIsolate()); + if (GetIsolate()->context().is_null()) + return v8::metrics::Recorder::ContextId::Empty(); + HandleScope scope(GetIsolate()); + return GetIsolate()->GetOrRegisterRecorderContextId( + GetIsolate()->native_context()); +} + CppHeap::CppHeap( v8::Platform* platform, const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>& custom_spaces, - const v8::WrapperDescriptor& wrapper_descriptor, - std::unique_ptr<cppgc::internal::MetricRecorder> metric_recorder) + const v8::WrapperDescriptor& wrapper_descriptor) : cppgc::internal::HeapBase( std::make_shared<CppgcPlatformAdapter>(platform), custom_spaces, cppgc::internal::HeapBase::StackSupport:: - kSupportsConservativeStackScan, - std::move(metric_recorder)), + kSupportsConservativeStackScan), wrapper_descriptor_(wrapper_descriptor) { CHECK_NE(WrapperDescriptor::kUnknownEmbedderId, wrapper_descriptor_.embedder_id_for_garbage_collected); @@ -260,6 +353,8 @@ void CppHeap::AttachIsolate(Isolate* isolate) { isolate_->heap()->SetEmbedderHeapTracer(this); isolate_->heap()->local_embedder_heap_tracer()->SetWrapperDescriptor( wrapper_descriptor_); + SetMetricRecorder(std::make_unique<MetricRecorderAdapter>(*this)); + SetStackStart(base::Stack::GetStackStart()); no_gc_scope_--; } @@ -277,6 +372,7 @@ void CppHeap::DetachIsolate() { isolate_->heap_profiler()->RemoveBuildEmbedderGraphCallback( &CppGraphBuilder::Run, this); } + SetMetricRecorder(nullptr); isolate_ = nullptr; // Any future garbage collections will ignore the V8->C++ references. isolate()->SetEmbedderHeapTracer(nullptr); @@ -295,6 +391,15 @@ void CppHeap::RegisterV8References( marking_done_ = false; } +namespace { + +bool ShouldReduceMemory(CppHeap::TraceFlags flags) { + return (flags == CppHeap::TraceFlags::kReduceMemory) || + (flags == CppHeap::TraceFlags::kForced); +} + +} // namespace + void CppHeap::TracePrologue(TraceFlags flags) { // Finish sweeping in case it is still running. sweeper_.FinishIfRunning(); @@ -314,7 +419,7 @@ void CppHeap::TracePrologue(TraceFlags flags) { DCHECK_IMPLIES(!isolate_, (cppgc::Heap::MarkingType::kAtomic == marking_config.marking_type) || force_incremental_marking_for_testing_); - if ((flags == TraceFlags::kReduceMemory) || (flags == TraceFlags::kForced)) { + if (ShouldReduceMemory(flags)) { // Only enable compaction when in a memory reduction garbage collection as // it may significantly increase the final garbage collection pause. compactor_.InitializeIfShouldCompact(marking_config.marking_type, @@ -328,6 +433,7 @@ void CppHeap::TracePrologue(TraceFlags flags) { } bool CppHeap::AdvanceTracing(double deadline_in_ms) { + is_in_v8_marking_step_ = true; cppgc::internal::StatsCollector::EnabledScope stats_scope( stats_collector(), in_atomic_pause_ ? cppgc::internal::StatsCollector::kAtomicMark @@ -341,6 +447,7 @@ bool CppHeap::AdvanceTracing(double deadline_in_ms) { marking_done_ = marker_->AdvanceMarkingWithLimits(deadline, marked_bytes_limit); DCHECK_IMPLIES(in_atomic_pause_, marking_done_); + is_in_v8_marking_step_ = false; return marking_done_; } @@ -392,7 +499,12 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) { ? cppgc::internal::Sweeper::SweepingConfig::SweepingType::kAtomic : cppgc::internal::Sweeper::SweepingConfig::SweepingType:: kIncrementalAndConcurrent, - compactable_space_handling}; + compactable_space_handling, + ShouldReduceMemory(current_flags_) + ? cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: + kDiscardWherePossible + : cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: + kDoNotDiscard}; DCHECK_IMPLIES( !isolate_, cppgc::internal::Sweeper::SweepingConfig::SweepingType::kAtomic == @@ -568,5 +680,10 @@ void CppHeap::CollectCustomSpaceStatisticsAtLastGC( std::move(receiver)); } +CppHeap::MetricRecorderAdapter* CppHeap::GetMetricRecorder() const { + return static_cast<MetricRecorderAdapter*>( + stats_collector_->GetMetricRecorder()); +} + } // namespace internal } // namespace v8 |