Commit 74d0c0aa authored by Omer Katz's avatar Omer Katz Committed by V8 LUCI CQ

cppgc: CppHeap no longer inherits from EmbedderHeapTracer api

This CL removes registration of CppHeap as a remote tracer, and
revises LocalEmbedderHeapTracer as a switching point between CppHeap
and a remote tracer. Currently it is assumed that CppHeap and a remote
tracer are mutually exclusive and only one can be used at any given
time.

Bug: v8:12407
Change-Id: I53513d181ab63f56a88f05c3b76b47ac4dffe86f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3289167
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78132}
parent 95645bd3
...@@ -914,11 +914,13 @@ class V8_EXPORT Isolate { ...@@ -914,11 +914,13 @@ class V8_EXPORT Isolate {
/** /**
* Sets the embedder heap tracer for the isolate. * Sets the embedder heap tracer for the isolate.
* SetEmbedderHeapTracer cannot be used simultaneously with AttachCppHeap.
*/ */
void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer); void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
/* /*
* Gets the currently active heap tracer for the isolate. * Gets the currently active heap tracer for the isolate that was set with
* SetEmbedderHeapTracer.
*/ */
EmbedderHeapTracer* GetEmbedderHeapTracer(); EmbedderHeapTracer* GetEmbedderHeapTracer();
...@@ -938,6 +940,7 @@ class V8_EXPORT Isolate { ...@@ -938,6 +940,7 @@ class V8_EXPORT Isolate {
* Attaches a managed C++ heap as an extension to the JavaScript heap. The * Attaches a managed C++ heap as an extension to the JavaScript heap. The
* embedder maintains ownership of the CppHeap. At most one C++ heap can be * embedder maintains ownership of the CppHeap. At most one C++ heap can be
* attached to V8. * attached to V8.
* AttachCppHeap cannot be used simultaneously with SetEmbedderHeapTracer.
* *
* This is an experimental feature and may still change significantly. * This is an experimental feature and may still change significantly.
*/ */
......
...@@ -8481,6 +8481,7 @@ void Isolate::RemoveGCEpilogueCallback(GCCallback callback) { ...@@ -8481,6 +8481,7 @@ void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
CHECK_NULL(isolate->heap()->cpp_heap());
isolate->heap()->SetEmbedderHeapTracer(tracer); isolate->heap()->SetEmbedderHeapTracer(tracer);
} }
...@@ -8496,6 +8497,7 @@ void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) { ...@@ -8496,6 +8497,7 @@ void Isolate::SetEmbedderRootsHandler(EmbedderRootsHandler* handler) {
void Isolate::AttachCppHeap(CppHeap* cpp_heap) { void Isolate::AttachCppHeap(CppHeap* cpp_heap) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
CHECK_NULL(GetEmbedderHeapTracer());
isolate->heap()->AttachCppHeap(cpp_heap); isolate->heap()->AttachCppHeap(cpp_heap);
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/execution/isolate-inl.h" #include "src/execution/isolate-inl.h"
#include "src/flags/flags.h" #include "src/flags/flags.h"
#include "src/handles/global-handles.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/heap/base/stack.h" #include "src/heap/base/stack.h"
#include "src/heap/cppgc-js/cpp-snapshot.h" #include "src/heap/cppgc-js/cpp-snapshot.h"
...@@ -221,10 +222,8 @@ void UnifiedHeapMarker::AddObject(void* object) { ...@@ -221,10 +222,8 @@ void UnifiedHeapMarker::AddObject(void* object) {
void FatalOutOfMemoryHandlerImpl(const std::string& reason, void FatalOutOfMemoryHandlerImpl(const std::string& reason,
const SourceLocation&, HeapBase* heap) { const SourceLocation&, HeapBase* heap) {
FatalProcessOutOfMemory( FatalProcessOutOfMemory(static_cast<v8::internal::CppHeap*>(heap)->isolate(),
reinterpret_cast<v8::internal::Isolate*>( reason.c_str());
static_cast<v8::internal::CppHeap*>(heap)->isolate()),
reason.c_str());
} }
} // namespace } // namespace
...@@ -366,11 +365,8 @@ void CppHeap::AttachIsolate(Isolate* isolate) { ...@@ -366,11 +365,8 @@ void CppHeap::AttachIsolate(Isolate* isolate) {
isolate_->heap_profiler()->AddBuildEmbedderGraphCallback( isolate_->heap_profiler()->AddBuildEmbedderGraphCallback(
&CppGraphBuilder::Run, this); &CppGraphBuilder::Run, this);
} }
isolate_->heap()->SetEmbedderHeapTracer(this);
isolate_->heap()->local_embedder_heap_tracer()->SetWrapperDescriptor(
wrapper_descriptor_);
SetMetricRecorder(std::make_unique<MetricRecorderAdapter>(*this)); SetMetricRecorder(std::make_unique<MetricRecorderAdapter>(*this));
SetStackStart(base::Stack::GetStackStart()); isolate_->global_handles()->SetStackStart(base::Stack::GetStackStart());
oom_handler().SetCustomHandler(&FatalOutOfMemoryHandlerImpl); oom_handler().SetCustomHandler(&FatalOutOfMemoryHandlerImpl);
no_gc_scope_--; no_gc_scope_--;
} }
...@@ -382,17 +378,20 @@ void CppHeap::DetachIsolate() { ...@@ -382,17 +378,20 @@ void CppHeap::DetachIsolate() {
// Delegate to existing EmbedderHeapTracer API to finish any ongoing garbage // Delegate to existing EmbedderHeapTracer API to finish any ongoing garbage
// collection. // collection.
FinalizeTracing(); if (isolate_->heap()->incremental_marking()->IsMarking()) {
isolate_->heap()->FinalizeIncrementalMarkingAtomically(
i::GarbageCollectionReason::kExternalFinalize);
}
sweeper_.FinishIfRunning(); sweeper_.FinishIfRunning();
if (isolate_->heap_profiler()) { auto* heap_profiler = isolate_->heap_profiler();
isolate_->heap_profiler()->RemoveBuildEmbedderGraphCallback( if (heap_profiler) {
&CppGraphBuilder::Run, this); heap_profiler->RemoveBuildEmbedderGraphCallback(&CppGraphBuilder::Run,
this);
} }
SetMetricRecorder(nullptr); SetMetricRecorder(nullptr);
isolate_ = nullptr; isolate_ = nullptr;
// Any future garbage collections will ignore the V8->C++ references. // Any future garbage collections will ignore the V8->C++ references.
isolate()->SetEmbedderHeapTracer(nullptr);
oom_handler().SetCustomHandler(nullptr); oom_handler().SetCustomHandler(nullptr);
// Enter no GC scope. // Enter no GC scope.
no_gc_scope_++; no_gc_scope_++;
...@@ -411,36 +410,42 @@ void CppHeap::RegisterV8References( ...@@ -411,36 +410,42 @@ void CppHeap::RegisterV8References(
namespace { namespace {
bool ShouldReduceMemory(CppHeap::TraceFlags flags) { bool IsMemoryReducingGC(CppHeap::GarbageCollectionFlags flags) {
return (flags == CppHeap::TraceFlags::kReduceMemory) || return flags & CppHeap::GarbageCollectionFlagValues::kReduceMemory;
(flags == CppHeap::TraceFlags::kForced);
} }
} // namespace bool IsForceGC(CppHeap::GarbageCollectionFlags flags) {
return flags & CppHeap::GarbageCollectionFlagValues::kForced;
}
void CppHeap::TracePrologue(TraceFlags flags) { bool ShouldReduceMemory(CppHeap::GarbageCollectionFlags flags) {
return IsMemoryReducingGC(flags) || IsForceGC(flags);
}
} // namespace
void CppHeap::TracePrologue(GarbageCollectionFlags gc_flags) {
CHECK(!sweeper_.IsSweepingInProgress()); CHECK(!sweeper_.IsSweepingInProgress());
#if defined(CPPGC_YOUNG_GENERATION) #if defined(CPPGC_YOUNG_GENERATION)
cppgc::internal::SequentialUnmarker unmarker(raw_heap()); cppgc::internal::SequentialUnmarker unmarker(raw_heap());
#endif // defined(CPPGC_YOUNG_GENERATION) #endif // defined(CPPGC_YOUNG_GENERATION)
current_flags_ = flags; current_gc_flags_ = gc_flags;
const UnifiedHeapMarker::MarkingConfig marking_config{ const UnifiedHeapMarker::MarkingConfig marking_config{
UnifiedHeapMarker::MarkingConfig::CollectionType::kMajor, UnifiedHeapMarker::MarkingConfig::CollectionType::kMajor,
cppgc::Heap::StackState::kNoHeapPointers, cppgc::Heap::StackState::kNoHeapPointers,
((current_flags_ & TraceFlags::kForced) && (IsForceGC(current_gc_flags_) && !force_incremental_marking_for_testing_)
!force_incremental_marking_for_testing_)
? UnifiedHeapMarker::MarkingConfig::MarkingType::kAtomic ? UnifiedHeapMarker::MarkingConfig::MarkingType::kAtomic
: UnifiedHeapMarker::MarkingConfig::MarkingType:: : UnifiedHeapMarker::MarkingConfig::MarkingType::
kIncrementalAndConcurrent, kIncrementalAndConcurrent,
flags & TraceFlags::kForced IsForceGC(current_gc_flags_)
? UnifiedHeapMarker::MarkingConfig::IsForcedGC::kForced ? UnifiedHeapMarker::MarkingConfig::IsForcedGC::kForced
: UnifiedHeapMarker::MarkingConfig::IsForcedGC::kNotForced}; : UnifiedHeapMarker::MarkingConfig::IsForcedGC::kNotForced};
DCHECK_IMPLIES(!isolate_, (cppgc::Heap::MarkingType::kAtomic == DCHECK_IMPLIES(!isolate_, (cppgc::Heap::MarkingType::kAtomic ==
marking_config.marking_type) || marking_config.marking_type) ||
force_incremental_marking_for_testing_); force_incremental_marking_for_testing_);
if (ShouldReduceMemory(flags)) { if (ShouldReduceMemory(current_gc_flags_)) {
// Only enable compaction when in a memory reduction garbage collection as // Only enable compaction when in a memory reduction garbage collection as
// it may significantly increase the final garbage collection pause. // it may significantly increase the final garbage collection pause.
compactor_.InitializeIfShouldCompact(marking_config.marking_type, compactor_.InitializeIfShouldCompact(marking_config.marking_type,
...@@ -453,7 +458,7 @@ void CppHeap::TracePrologue(TraceFlags flags) { ...@@ -453,7 +458,7 @@ void CppHeap::TracePrologue(TraceFlags flags) {
marking_done_ = false; marking_done_ = false;
} }
bool CppHeap::AdvanceTracing(double deadline_in_ms) { bool CppHeap::AdvanceTracing(double max_duration) {
is_in_v8_marking_step_ = true; is_in_v8_marking_step_ = true;
cppgc::internal::StatsCollector::EnabledScope stats_scope( cppgc::internal::StatsCollector::EnabledScope stats_scope(
stats_collector(), stats_collector(),
...@@ -461,7 +466,7 @@ bool CppHeap::AdvanceTracing(double deadline_in_ms) { ...@@ -461,7 +466,7 @@ bool CppHeap::AdvanceTracing(double deadline_in_ms) {
: cppgc::internal::StatsCollector::kIncrementalMark); : cppgc::internal::StatsCollector::kIncrementalMark);
const v8::base::TimeDelta deadline = const v8::base::TimeDelta deadline =
in_atomic_pause_ ? v8::base::TimeDelta::Max() in_atomic_pause_ ? v8::base::TimeDelta::Max()
: v8::base::TimeDelta::FromMillisecondsD(deadline_in_ms); : v8::base::TimeDelta::FromMillisecondsD(max_duration);
const size_t marked_bytes_limit = in_atomic_pause_ ? SIZE_MAX : 0; const size_t marked_bytes_limit = in_atomic_pause_ ? SIZE_MAX : 0;
DCHECK_NOT_NULL(marker_); DCHECK_NOT_NULL(marker_);
// TODO(chromium:1056170): Replace when unified heap transitions to // TODO(chromium:1056170): Replace when unified heap transitions to
...@@ -475,7 +480,7 @@ bool CppHeap::AdvanceTracing(double deadline_in_ms) { ...@@ -475,7 +480,7 @@ bool CppHeap::AdvanceTracing(double deadline_in_ms) {
bool CppHeap::IsTracingDone() { return marking_done_; } bool CppHeap::IsTracingDone() { return marking_done_; }
void CppHeap::EnterFinalPause(EmbedderStackState stack_state) { void CppHeap::EnterFinalPause(cppgc::EmbedderStackState stack_state) {
CHECK(!in_disallow_gc_scope()); CHECK(!in_disallow_gc_scope());
in_atomic_pause_ = true; in_atomic_pause_ = true;
if (override_stack_state_) { if (override_stack_state_) {
...@@ -486,7 +491,7 @@ void CppHeap::EnterFinalPause(EmbedderStackState stack_state) { ...@@ -486,7 +491,7 @@ void CppHeap::EnterFinalPause(EmbedderStackState stack_state) {
stack_state); stack_state);
} }
void CppHeap::TraceEpilogue(TraceSummary* trace_summary) { void CppHeap::TraceEpilogue() {
CHECK(in_atomic_pause_); CHECK(in_atomic_pause_);
CHECK(marking_done_); CHECK(marking_done_);
{ {
...@@ -524,12 +529,12 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) { ...@@ -524,12 +529,12 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
compactable_space_handling = compactor_.CompactSpacesIfEnabled(); compactable_space_handling = compactor_.CompactSpacesIfEnabled();
const cppgc::internal::Sweeper::SweepingConfig sweeping_config{ const cppgc::internal::Sweeper::SweepingConfig sweeping_config{
// In case the GC was forced, also finalize sweeping right away. // In case the GC was forced, also finalize sweeping right away.
current_flags_ & TraceFlags::kForced IsForceGC(current_gc_flags_)
? cppgc::internal::Sweeper::SweepingConfig::SweepingType::kAtomic ? cppgc::internal::Sweeper::SweepingConfig::SweepingType::kAtomic
: cppgc::internal::Sweeper::SweepingConfig::SweepingType:: : cppgc::internal::Sweeper::SweepingConfig::SweepingType::
kIncrementalAndConcurrent, kIncrementalAndConcurrent,
compactable_space_handling, compactable_space_handling,
ShouldReduceMemory(current_flags_) ShouldReduceMemory(current_gc_flags_)
? cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: ? cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling::
kDiscardWherePossible kDiscardWherePossible
: cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling:: : cppgc::internal::Sweeper::SweepingConfig::FreeMemoryHandling::
...@@ -540,9 +545,6 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) { ...@@ -540,9 +545,6 @@ void CppHeap::TraceEpilogue(TraceSummary* trace_summary) {
sweeping_config.sweeping_type); sweeping_config.sweeping_type);
sweeper().Start(sweeping_config); sweeper().Start(sweeping_config);
} }
DCHECK_NOT_NULL(trace_summary);
trace_summary->allocated_size = SIZE_MAX;
trace_summary->time = 0;
in_atomic_pause_ = false; in_atomic_pause_ = false;
sweeper().NotifyDoneIfNeeded(); sweeper().NotifyDoneIfNeeded();
} }
...@@ -562,7 +564,7 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() { ...@@ -562,7 +564,7 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() {
// finalizations where not allowed. // finalizations where not allowed.
// - Recursive sweeping. // - Recursive sweeping.
// - GC forbidden scope. // - GC forbidden scope.
if (sweeper().IsSweepingOnMutatorThread() || in_no_gc_scope()) { if (sweeper().IsSweepingOnMutatorThread() || in_no_gc_scope() || !isolate_) {
return; return;
} }
...@@ -572,10 +574,12 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() { ...@@ -572,10 +574,12 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() {
const int64_t bytes_to_report = buffered_allocated_bytes_; const int64_t bytes_to_report = buffered_allocated_bytes_;
buffered_allocated_bytes_ = 0; buffered_allocated_bytes_ = 0;
auto* const tracer = isolate_->heap()->local_embedder_heap_tracer();
DCHECK_NOT_NULL(tracer);
if (bytes_to_report < 0) { if (bytes_to_report < 0) {
DecreaseAllocatedSize(static_cast<size_t>(-bytes_to_report)); tracer->DecreaseAllocatedSize(static_cast<size_t>(-bytes_to_report));
} else { } else {
IncreaseAllocatedSize(static_cast<size_t>(bytes_to_report)); tracer->IncreaseAllocatedSize(static_cast<size_t>(bytes_to_report));
} }
} }
...@@ -595,12 +599,10 @@ void CppHeap::CollectGarbageForTesting( ...@@ -595,12 +599,10 @@ void CppHeap::CollectGarbageForTesting(
} else { } else {
// Perform an atomic GC, with starting incremental/concurrent marking and // Perform an atomic GC, with starting incremental/concurrent marking and
// immediately finalizing the garbage collection. // immediately finalizing the garbage collection.
if (!IsMarking()) TracePrologue(TraceFlags::kForced); if (!IsMarking()) TracePrologue(GarbageCollectionFlagValues::kForced);
EnterFinalPause(stack_state); EnterFinalPause(stack_state);
AdvanceTracing(std::numeric_limits<double>::infinity()); AdvanceTracing(std::numeric_limits<double>::infinity());
TraceSummary trace_summary; TraceEpilogue();
TraceEpilogue(&trace_summary);
DCHECK_EQ(SIZE_MAX, trace_summary.allocated_size);
} }
} }
...@@ -618,12 +620,12 @@ void CppHeap::StartIncrementalGarbageCollectionForTesting() { ...@@ -618,12 +620,12 @@ void CppHeap::StartIncrementalGarbageCollectionForTesting() {
DCHECK_NULL(isolate_); DCHECK_NULL(isolate_);
if (IsMarking()) return; if (IsMarking()) return;
force_incremental_marking_for_testing_ = true; force_incremental_marking_for_testing_ = true;
TracePrologue(TraceFlags::kForced); TracePrologue(GarbageCollectionFlagValues::kForced);
force_incremental_marking_for_testing_ = false; force_incremental_marking_for_testing_ = false;
} }
void CppHeap::FinalizeIncrementalGarbageCollectionForTesting( void CppHeap::FinalizeIncrementalGarbageCollectionForTesting(
EmbedderStackState stack_state) { cppgc::EmbedderStackState stack_state) {
DCHECK(!in_no_gc_scope()); DCHECK(!in_no_gc_scope());
DCHECK_NULL(isolate_); DCHECK_NULL(isolate_);
DCHECK(IsMarking()); DCHECK(IsMarking());
......
...@@ -12,8 +12,8 @@ static_assert( ...@@ -12,8 +12,8 @@ static_assert(
#include "include/v8-callbacks.h" #include "include/v8-callbacks.h"
#include "include/v8-cppgc.h" #include "include/v8-cppgc.h"
#include "include/v8-embedder-heap.h"
#include "include/v8-metrics.h" #include "include/v8-metrics.h"
#include "src/base/flags.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/heap/cppgc/heap-base.h" #include "src/heap/cppgc/heap-base.h"
#include "src/heap/cppgc/stats-collector.h" #include "src/heap/cppgc/stats-collector.h"
...@@ -29,9 +29,15 @@ namespace internal { ...@@ -29,9 +29,15 @@ namespace internal {
class V8_EXPORT_PRIVATE CppHeap final class V8_EXPORT_PRIVATE CppHeap final
: public cppgc::internal::HeapBase, : public cppgc::internal::HeapBase,
public v8::CppHeap, public v8::CppHeap,
public v8::EmbedderHeapTracer,
public cppgc::internal::StatsCollector::AllocationObserver { public cppgc::internal::StatsCollector::AllocationObserver {
public: public:
enum GarbageCollectionFlagValues {
kReduceMemory,
kForced,
};
using GarbageCollectionFlags = base::Flags<GarbageCollectionFlagValues>;
class MetricRecorderAdapter final : public cppgc::internal::MetricRecorder { class MetricRecorderAdapter final : public cppgc::internal::MetricRecorder {
public: public:
static constexpr int kMaxBatchedEvents = 16; static constexpr int kMaxBatchedEvents = 16;
...@@ -106,14 +112,13 @@ class V8_EXPORT_PRIVATE CppHeap final ...@@ -106,14 +112,13 @@ class V8_EXPORT_PRIVATE CppHeap final
void FinishSweepingIfRunning(); void FinishSweepingIfRunning();
// v8::EmbedderHeapTracer interface.
void RegisterV8References( void RegisterV8References(
const std::vector<std::pair<void*, void*> >& embedder_fields) final; const std::vector<std::pair<void*, void*>>& embedder_fields);
void TracePrologue(TraceFlags flags) final; void TracePrologue(GarbageCollectionFlags);
bool AdvanceTracing(double deadline_in_ms) final; bool AdvanceTracing(double max_duration);
bool IsTracingDone() final; bool IsTracingDone();
void TraceEpilogue(TraceSummary* trace_summary) final; void TraceEpilogue();
void EnterFinalPause(EmbedderStackState stack_state) final; void EnterFinalPause(cppgc::EmbedderStackState stack_state);
// StatsCollector::AllocationObserver interface. // StatsCollector::AllocationObserver interface.
void AllocatedObjectSizeIncreased(size_t) final; void AllocatedObjectSizeIncreased(size_t) final;
...@@ -122,6 +127,12 @@ class V8_EXPORT_PRIVATE CppHeap final ...@@ -122,6 +127,12 @@ class V8_EXPORT_PRIVATE CppHeap final
MetricRecorderAdapter* GetMetricRecorder() const; MetricRecorderAdapter* GetMetricRecorder() const;
v8::WrapperDescriptor wrapper_descriptor() const {
return wrapper_descriptor_;
}
Isolate* isolate() const { return isolate_; }
private: private:
void FinalizeIncrementalGarbageCollectionIfNeeded( void FinalizeIncrementalGarbageCollectionIfNeeded(
cppgc::Heap::StackState) final { cppgc::Heap::StackState) final {
...@@ -132,11 +143,12 @@ class V8_EXPORT_PRIVATE CppHeap final ...@@ -132,11 +143,12 @@ class V8_EXPORT_PRIVATE CppHeap final
void ReportBufferedAllocationSizeIfPossible(); void ReportBufferedAllocationSizeIfPossible();
void StartIncrementalGarbageCollectionForTesting() final; void StartIncrementalGarbageCollectionForTesting() final;
void FinalizeIncrementalGarbageCollectionForTesting(EmbedderStackState) final; void FinalizeIncrementalGarbageCollectionForTesting(
cppgc::EmbedderStackState) final;
Isolate* isolate_ = nullptr; Isolate* isolate_ = nullptr;
bool marking_done_ = false; bool marking_done_ = false;
TraceFlags current_flags_ = TraceFlags::kNoFlags; GarbageCollectionFlags current_gc_flags_;
// Buffered allocated bytes. Reporting allocated bytes to V8 can trigger a GC // Buffered allocated bytes. Reporting allocated bytes to V8 can trigger a GC
// atomic pause. Allocated bytes are buffer in case this is temporarily // atomic pause. Allocated bytes are buffer in case this is temporarily
......
...@@ -463,7 +463,8 @@ class CppGraphBuilderImpl final { ...@@ -463,7 +463,8 @@ class CppGraphBuilderImpl final {
void AddEdge(State& parent, const TracedReferenceBase& ref, void AddEdge(State& parent, const TracedReferenceBase& ref,
const std::string& edge_name) { const std::string& edge_name) {
DCHECK(parent.IsVisibleNotDependent()); DCHECK(parent.IsVisibleNotDependent());
v8::Local<v8::Value> v8_value = ref.Get(cpp_heap_.isolate()); v8::Local<v8::Value> v8_value =
ref.Get(reinterpret_cast<v8::Isolate*>(cpp_heap_.isolate()));
if (!v8_value.IsEmpty()) { if (!v8_value.IsEmpty()) {
if (!parent.get_node()) { if (!parent.get_node()) {
parent.set_node(AddNode(*parent.header())); parent.set_node(AddNode(*parent.header()));
...@@ -836,7 +837,8 @@ void CppGraphBuilderImpl::VisitWeakContainerForVisibility( ...@@ -836,7 +837,8 @@ void CppGraphBuilderImpl::VisitWeakContainerForVisibility(
void CppGraphBuilderImpl::VisitForVisibility(State& parent, void CppGraphBuilderImpl::VisitForVisibility(State& parent,
const TracedReferenceBase& ref) { const TracedReferenceBase& ref) {
v8::Local<v8::Value> v8_value = ref.Get(cpp_heap_.isolate()); v8::Local<v8::Value> v8_value =
ref.Get(reinterpret_cast<v8::Isolate*>(cpp_heap_.isolate()));
if (!v8_value.IsEmpty()) { if (!v8_value.IsEmpty()) {
parent.MarkVisible(); parent.MarkVisible();
} }
......
...@@ -15,6 +15,7 @@ namespace v8 { ...@@ -15,6 +15,7 @@ namespace v8 {
namespace internal { namespace internal {
void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) { void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) {
CHECK_NULL(cpp_heap_);
if (remote_tracer_) remote_tracer_->isolate_ = nullptr; if (remote_tracer_) remote_tracer_->isolate_ = nullptr;
remote_tracer_ = tracer; remote_tracer_ = tracer;
...@@ -23,12 +24,32 @@ void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) { ...@@ -23,12 +24,32 @@ void LocalEmbedderHeapTracer::SetRemoteTracer(EmbedderHeapTracer* tracer) {
remote_tracer_->isolate_ = reinterpret_cast<v8::Isolate*>(isolate_); remote_tracer_->isolate_ = reinterpret_cast<v8::Isolate*>(isolate_);
} }
void LocalEmbedderHeapTracer::SetCppHeap(CppHeap* cpp_heap) {
CHECK_NULL(remote_tracer_);
cpp_heap_ = cpp_heap;
}
namespace {
CppHeap::GarbageCollectionFlags ConvertTraceFlags(
EmbedderHeapTracer::TraceFlags flags) {
CppHeap::GarbageCollectionFlags result;
if (flags & EmbedderHeapTracer::TraceFlags::kForced)
result |= CppHeap::GarbageCollectionFlagValues::kForced;
if (flags & EmbedderHeapTracer::TraceFlags::kReduceMemory)
result |= CppHeap::GarbageCollectionFlagValues::kReduceMemory;
return result;
}
} // namespace
void LocalEmbedderHeapTracer::TracePrologue( void LocalEmbedderHeapTracer::TracePrologue(
EmbedderHeapTracer::TraceFlags flags) { EmbedderHeapTracer::TraceFlags flags) {
if (!InUse()) return; if (!InUse()) return;
embedder_worklist_empty_ = false; embedder_worklist_empty_ = false;
remote_tracer_->TracePrologue(flags); if (cpp_heap_)
cpp_heap()->TracePrologue(ConvertTraceFlags(flags));
else
remote_tracer_->TracePrologue(flags);
} }
void LocalEmbedderHeapTracer::TraceEpilogue() { void LocalEmbedderHeapTracer::TraceEpilogue() {
...@@ -39,10 +60,13 @@ void LocalEmbedderHeapTracer::TraceEpilogue() { ...@@ -39,10 +60,13 @@ void LocalEmbedderHeapTracer::TraceEpilogue() {
embedder_stack_state_ = embedder_stack_state_ =
EmbedderHeapTracer::EmbedderStackState::kMayContainHeapPointers; EmbedderHeapTracer::EmbedderStackState::kMayContainHeapPointers;
EmbedderHeapTracer::TraceSummary summary; if (cpp_heap_) {
remote_tracer_->TraceEpilogue(&summary); cpp_heap()->TraceEpilogue();
if (summary.allocated_size == SIZE_MAX) return; } else {
UpdateRemoteStats(summary.allocated_size, summary.time); EmbedderHeapTracer::TraceSummary summary;
remote_tracer_->TraceEpilogue(&summary);
UpdateRemoteStats(summary.allocated_size, summary.time);
}
} }
void LocalEmbedderHeapTracer::UpdateRemoteStats(size_t allocated_size, void LocalEmbedderHeapTracer::UpdateRemoteStats(size_t allocated_size,
...@@ -60,17 +84,24 @@ void LocalEmbedderHeapTracer::UpdateRemoteStats(size_t allocated_size, ...@@ -60,17 +84,24 @@ void LocalEmbedderHeapTracer::UpdateRemoteStats(size_t allocated_size,
void LocalEmbedderHeapTracer::EnterFinalPause() { void LocalEmbedderHeapTracer::EnterFinalPause() {
if (!InUse()) return; if (!InUse()) return;
remote_tracer_->EnterFinalPause(embedder_stack_state_); if (cpp_heap_)
cpp_heap()->EnterFinalPause(embedder_stack_state_);
else
remote_tracer_->EnterFinalPause(embedder_stack_state_);
} }
bool LocalEmbedderHeapTracer::Trace(double deadline) { bool LocalEmbedderHeapTracer::Trace(double max_duration) {
if (!InUse()) return true; if (!InUse()) return true;
return remote_tracer_->AdvanceTracing(deadline); if (cpp_heap_)
return cpp_heap()->AdvanceTracing(max_duration);
else
return remote_tracer_->AdvanceTracing(max_duration);
} }
bool LocalEmbedderHeapTracer::IsRemoteTracingDone() { bool LocalEmbedderHeapTracer::IsRemoteTracingDone() {
return !InUse() || remote_tracer_->IsTracingDone(); return !InUse() || (cpp_heap_ ? cpp_heap()->IsTracingDone()
: remote_tracer_->IsTracingDone());
} }
void LocalEmbedderHeapTracer::SetEmbedderStackStateForNextFinalization( void LocalEmbedderHeapTracer::SetEmbedderStackStateForNextFinalization(
...@@ -108,13 +139,16 @@ bool ExtractWrappableInfo(Isolate* isolate, JSObject js_object, ...@@ -108,13 +139,16 @@ bool ExtractWrappableInfo(Isolate* isolate, JSObject js_object,
LocalEmbedderHeapTracer::ProcessingScope::ProcessingScope( LocalEmbedderHeapTracer::ProcessingScope::ProcessingScope(
LocalEmbedderHeapTracer* tracer) LocalEmbedderHeapTracer* tracer)
: tracer_(tracer), wrapper_descriptor_(tracer->wrapper_descriptor_) { : tracer_(tracer), wrapper_descriptor_(tracer->wrapper_descriptor()) {
wrapper_cache_.reserve(kWrapperCacheSize); wrapper_cache_.reserve(kWrapperCacheSize);
} }
LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope() { LocalEmbedderHeapTracer::ProcessingScope::~ProcessingScope() {
if (!wrapper_cache_.empty()) { if (!wrapper_cache_.empty()) {
tracer_->remote_tracer()->RegisterV8References(std::move(wrapper_cache_)); if (tracer_->cpp_heap_)
tracer_->cpp_heap()->RegisterV8References(std::move(wrapper_cache_));
else
tracer_->remote_tracer_->RegisterV8References(std::move(wrapper_cache_));
} }
} }
...@@ -122,7 +156,7 @@ LocalEmbedderHeapTracer::WrapperInfo ...@@ -122,7 +156,7 @@ LocalEmbedderHeapTracer::WrapperInfo
LocalEmbedderHeapTracer::ExtractWrapperInfo(Isolate* isolate, LocalEmbedderHeapTracer::ExtractWrapperInfo(Isolate* isolate,
JSObject js_object) { JSObject js_object) {
WrapperInfo info; WrapperInfo info;
if (ExtractWrappableInfo(isolate, js_object, wrapper_descriptor_, &info)) { if (ExtractWrappableInfo(isolate, js_object, wrapper_descriptor(), &info)) {
return info; return info;
} }
return {nullptr, nullptr}; return {nullptr, nullptr};
...@@ -141,7 +175,10 @@ void LocalEmbedderHeapTracer::ProcessingScope::TracePossibleWrapper( ...@@ -141,7 +175,10 @@ void LocalEmbedderHeapTracer::ProcessingScope::TracePossibleWrapper(
void LocalEmbedderHeapTracer::ProcessingScope::FlushWrapperCacheIfFull() { void LocalEmbedderHeapTracer::ProcessingScope::FlushWrapperCacheIfFull() {
if (wrapper_cache_.size() == wrapper_cache_.capacity()) { if (wrapper_cache_.size() == wrapper_cache_.capacity()) {
tracer_->remote_tracer()->RegisterV8References(std::move(wrapper_cache_)); if (tracer_->cpp_heap_)
tracer_->cpp_heap()->RegisterV8References(std::move(wrapper_cache_));
else
tracer_->remote_tracer_->RegisterV8References(std::move(wrapper_cache_));
wrapper_cache_.clear(); wrapper_cache_.clear();
wrapper_cache_.reserve(kWrapperCacheSize); wrapper_cache_.reserve(kWrapperCacheSize);
} }
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include "include/v8-embedder-heap.h" #include "include/v8-embedder-heap.h"
#include "include/v8-traced-handle.h" #include "include/v8-traced-handle.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/execution/isolate.h"
#include "src/flags/flags.h" #include "src/flags/flags.h"
#include "src/heap/cppgc-js/cpp-heap.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -76,12 +78,19 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final { ...@@ -76,12 +78,19 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final {
~LocalEmbedderHeapTracer() { ~LocalEmbedderHeapTracer() {
if (remote_tracer_) remote_tracer_->isolate_ = nullptr; if (remote_tracer_) remote_tracer_->isolate_ = nullptr;
// CppHeap is not detached from Isolate here. Detaching is done explciitly
// on Isolate/Heap/CppHeap destruction.
} }
bool InUse() const { return remote_tracer_ != nullptr; } bool InUse() const { return cpp_heap_ || (remote_tracer_ != nullptr); }
EmbedderHeapTracer* remote_tracer() const { return remote_tracer_; } // This method doesn't take CppHeap into account.
EmbedderHeapTracer* remote_tracer() const {
DCHECK_NULL(cpp_heap_);
return remote_tracer_;
}
void SetRemoteTracer(EmbedderHeapTracer* tracer); void SetRemoteTracer(EmbedderHeapTracer* tracer);
void SetCppHeap(CppHeap* cpp_heap);
void TracePrologue(EmbedderHeapTracer::TraceFlags flags); void TracePrologue(EmbedderHeapTracer::TraceFlags flags);
void TraceEpilogue(); void TraceEpilogue();
void EnterFinalPause(); void EnterFinalPause();
...@@ -124,6 +133,7 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final { ...@@ -124,6 +133,7 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final {
WrapperInfo ExtractWrapperInfo(Isolate* isolate, JSObject js_object); WrapperInfo ExtractWrapperInfo(Isolate* isolate, JSObject js_object);
void SetWrapperDescriptor(const WrapperDescriptor& wrapper_descriptor) { void SetWrapperDescriptor(const WrapperDescriptor& wrapper_descriptor) {
DCHECK_NULL(cpp_heap_);
wrapper_descriptor_ = wrapper_descriptor; wrapper_descriptor_ = wrapper_descriptor;
} }
...@@ -154,8 +164,23 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final { ...@@ -154,8 +164,23 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final {
WrapperDescriptor::kUnknownEmbedderId); WrapperDescriptor::kUnknownEmbedderId);
} }
CppHeap* cpp_heap() {
DCHECK_NOT_NULL(cpp_heap_);
DCHECK_NULL(remote_tracer_);
DCHECK_IMPLIES(isolate_, cpp_heap_ == isolate_->heap()->cpp_heap());
return cpp_heap_;
}
WrapperDescriptor wrapper_descriptor() {
if (cpp_heap_)
return cpp_heap()->wrapper_descriptor();
else
return wrapper_descriptor_;
}
Isolate* const isolate_; Isolate* const isolate_;
EmbedderHeapTracer* remote_tracer_ = nullptr; EmbedderHeapTracer* remote_tracer_ = nullptr;
CppHeap* cpp_heap_ = nullptr;
DefaultEmbedderRootsHandler default_embedder_roots_handler_; DefaultEmbedderRootsHandler default_embedder_roots_handler_;
EmbedderHeapTracer::EmbedderStackState embedder_stack_state_ = EmbedderHeapTracer::EmbedderStackState embedder_stack_state_ =
......
...@@ -5896,11 +5896,13 @@ EmbedderHeapTracer* Heap::GetEmbedderHeapTracer() const { ...@@ -5896,11 +5896,13 @@ EmbedderHeapTracer* Heap::GetEmbedderHeapTracer() const {
void Heap::AttachCppHeap(v8::CppHeap* cpp_heap) { void Heap::AttachCppHeap(v8::CppHeap* cpp_heap) {
CppHeap::From(cpp_heap)->AttachIsolate(isolate()); CppHeap::From(cpp_heap)->AttachIsolate(isolate());
cpp_heap_ = cpp_heap; cpp_heap_ = cpp_heap;
local_embedder_heap_tracer()->SetCppHeap(CppHeap::From(cpp_heap));
} }
void Heap::DetachCppHeap() { void Heap::DetachCppHeap() {
CppHeap::From(cpp_heap_)->DetachIsolate(); CppHeap::From(cpp_heap_)->DetachIsolate();
cpp_heap_ = nullptr; cpp_heap_ = nullptr;
local_embedder_heap_tracer()->SetCppHeap(nullptr);
} }
EmbedderHeapTracer::TraceFlags Heap::flags_for_embedder_tracer() const { EmbedderHeapTracer::TraceFlags Heap::flags_for_embedder_tracer() const {
......
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