Commit 95f7b1a3 authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: young-gen: Visit TracedReferences to find V8->Blink refs

The CL uses GlobalHandles::IterateTraceNodes() to find back references
from V8 to cppgc.

Bug: chromium:1029379
Change-Id: I6e959ae5d591247b817386cafe26b6cd74161b63
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3467874Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79183}
parent d5eb2335
......@@ -41,6 +41,7 @@
#include "src/heap/cppgc/stats-collector.h"
#include "src/heap/cppgc/sweeper.h"
#include "src/heap/cppgc/unmarker.h"
#include "src/heap/embedder-tracing-inl.h"
#include "src/heap/embedder-tracing.h"
#include "src/heap/gc-tracer.h"
#include "src/heap/marking-worklist.h"
......@@ -50,6 +51,62 @@
namespace v8 {
namespace {
class V8ToCppGCReferencesVisitor final
: public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
public:
V8ToCppGCReferencesVisitor(
cppgc::internal::MutatorMarkingState& marking_state,
v8::internal::Isolate* isolate,
const v8::WrapperDescriptor& wrapper_descriptor)
: marking_state_(marking_state),
isolate_(isolate),
wrapper_descriptor_(wrapper_descriptor) {}
void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) final {
UNREACHABLE();
}
void VisitTracedReference(const v8::TracedReference<v8::Value>& value) final {
VisitHandle(value, value.WrapperClassId());
}
private:
void VisitHandle(const v8::TracedReference<v8::Value>& value,
uint16_t class_id) {
DCHECK(value.IsEmpty());
const internal::JSObject js_object =
*reinterpret_cast<const internal::JSObject* const&>(value);
if (!js_object.ptr() || !js_object.IsApiWrapper()) return;
internal::LocalEmbedderHeapTracer::WrapperInfo info;
if (!internal::LocalEmbedderHeapTracer::ExtractWrappableInfo(
isolate_, js_object, wrapper_descriptor_, &info))
return;
marking_state_.MarkAndPush(
cppgc::internal::HeapObjectHeader::FromObject(info.second));
}
cppgc::internal::MutatorMarkingState& marking_state_;
v8::internal::Isolate* isolate_;
const v8::WrapperDescriptor& wrapper_descriptor_;
};
void TraceV8ToCppGCReferences(
v8::internal::Isolate* isolate,
cppgc::internal::MutatorMarkingState& marking_state,
const v8::WrapperDescriptor& wrapper_descriptor) {
DCHECK(isolate);
V8ToCppGCReferencesVisitor forwarding_visitor(marking_state, isolate,
wrapper_descriptor);
isolate->global_handles()->IterateTracedNodes(&forwarding_visitor);
}
} // namespace
// static
constexpr uint16_t WrapperDescriptor::kUnknownEmbedderId;
......@@ -195,8 +252,9 @@ class UnifiedHeapMarker final : public cppgc::internal::MarkerBase {
return marking_worklists_;
}
cppgc::internal::MarkingStateBase& GetMutatorMarkingState() {
return marking_visitor_->marking_state_;
cppgc::internal::MutatorMarkingState& GetMutatorMarkingState() {
return static_cast<cppgc::internal::MutatorMarkingState&>(
marking_visitor_->marking_state_);
}
protected:
......@@ -444,8 +502,11 @@ void CppHeap::InitializeTracing(
DCHECK_IMPLIES(GetMetricRecorder(),
!GetMetricRecorder()->MetricsReportPending());
DCHECK(!collection_type_);
collection_type_ = collection_type;
#if defined(CPPGC_YOUNG_GENERATION)
if (collection_type ==
if (*collection_type_ ==
cppgc::internal::GarbageCollector::Config::CollectionType::kMajor)
cppgc::internal::SequentialUnmarker unmarker(raw_heap());
#endif // defined(CPPGC_YOUNG_GENERATION)
......@@ -453,7 +514,7 @@ void CppHeap::InitializeTracing(
current_gc_flags_ = gc_flags;
const UnifiedHeapMarker::MarkingConfig marking_config{
collection_type, cppgc::Heap::StackState::kNoHeapPointers,
*collection_type_, cppgc::Heap::StackState::kNoHeapPointers,
(IsForceGC(current_gc_flags_) && !force_incremental_marking_for_testing_)
? UnifiedHeapMarker::MarkingConfig::MarkingType::kAtomic
: UnifiedHeapMarker::MarkingConfig::MarkingType::
......@@ -509,12 +570,20 @@ void CppHeap::EnterFinalPause(cppgc::EmbedderStackState stack_state) {
stack_state = *override_stack_state_;
}
marker_->EnterAtomicPause(stack_state);
if (isolate_ &&
*collection_type_ ==
cppgc::internal::GarbageCollector::Config::CollectionType::kMinor) {
// Visit V8 -> cppgc references.
TraceV8ToCppGCReferences(isolate_,
static_cast<UnifiedHeapMarker*>(marker_.get())
->GetMutatorMarkingState(),
wrapper_descriptor_);
}
compactor_.CancelIfShouldNotCompact(cppgc::Heap::MarkingType::kAtomic,
stack_state);
}
void CppHeap::TraceEpilogue(
cppgc::internal::GarbageCollector::Config::CollectionType collection_type) {
void CppHeap::TraceEpilogue() {
CHECK(in_atomic_pause_);
CHECK(marking_done_);
{
......@@ -534,7 +603,7 @@ void CppHeap::TraceEpilogue(
buffered_allocated_bytes_ = 0;
const size_t bytes_allocated_in_prefinalizers = ExecutePreFinalizers();
#if CPPGC_VERIFY_HEAP
UnifiedHeapMarkingVerifier verifier(*this, collection_type);
UnifiedHeapMarkingVerifier verifier(*this, *collection_type_);
verifier.Run(
stack_state_of_prev_gc(), stack_end_of_current_gc(),
stats_collector()->marked_bytes() + bytes_allocated_in_prefinalizers);
......@@ -568,6 +637,7 @@ void CppHeap::TraceEpilogue(
sweeper().Start(sweeping_config);
}
in_atomic_pause_ = false;
collection_type_.reset();
sweeper().NotifyDoneIfNeeded();
}
......@@ -628,7 +698,7 @@ void CppHeap::CollectGarbageForTesting(
}
EnterFinalPause(stack_state);
AdvanceTracing(std::numeric_limits<double>::infinity());
TraceEpilogue(collection_type);
TraceEpilogue();
}
}
......
......@@ -15,6 +15,7 @@ static_assert(
#include "include/v8-metrics.h"
#include "src/base/flags.h"
#include "src/base/macros.h"
#include "src/base/optional.h"
#include "src/heap/cppgc/heap-base.h"
#include "src/heap/cppgc/stats-collector.h"
#include "src/logging/metrics.h"
......@@ -124,7 +125,7 @@ class V8_EXPORT_PRIVATE CppHeap final
void StartTracing();
bool AdvanceTracing(double max_duration);
bool IsTracingDone();
void TraceEpilogue(cppgc::internal::GarbageCollector::Config::CollectionType);
void TraceEpilogue();
void EnterFinalPause(cppgc::EmbedderStackState stack_state);
// StatsCollector::AllocationObserver interface.
......@@ -158,6 +159,9 @@ class V8_EXPORT_PRIVATE CppHeap final
Isolate* isolate_ = nullptr;
bool marking_done_ = false;
// |collection_type_| is initialized when marking is in progress.
base::Optional<cppgc::internal::GarbageCollector::Config::CollectionType>
collection_type_;
GarbageCollectionFlags current_gc_flags_;
// Buffered allocated bytes. Reporting allocated bytes to V8 can trigger a GC
......
......@@ -70,8 +70,7 @@ void LocalEmbedderHeapTracer::TraceEpilogue() {
EmbedderHeapTracer::EmbedderStackState::kMayContainHeapPointers;
if (cpp_heap_) {
cpp_heap()->TraceEpilogue(
cppgc::internal::GarbageCollector::Config::CollectionType::kMajor);
cpp_heap()->TraceEpilogue();
} else {
EmbedderHeapTracer::TraceSummary summary;
remote_tracer_->TraceEpilogue(&summary);
......
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