Revert "unified-young-gen: Trace cross-heap references"
This reverts commit 43f03448d3
.
Reason for revert: Data race caught by TSAN:
https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux64%20TSAN%20-%20isolates/22640/overview
Original change's description:
> unified-young-gen: Trace cross-heap references
>
> The CL enables the marking visitor in CppGC to trace
> v8::TracedReferences (by just reusing the unified heap visitor from the
> full GC). In addition, it specifies VisitJSApiObject for
> NewSpaceVisitors to be able to trace wrappers from Minor MC in case
> --cppgc-young-generation is enabled.
>
> Bug: v8:13475
> Change-Id: I04ba1f2a22e05caebf53dc8d64f2488c42ab8579
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4026896
> Commit-Queue: Anton Bikineev <bikineev@chromium.org>
> Reviewed-by: Omer Katz <omerkatz@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#84313}
Bug: v8:13475
Change-Id: I8b8351774a121ca2296efa3c8d3a588fa7380d86
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4032053
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84314}
This commit is contained in:
parent
43f03448d3
commit
bdf634f851
@ -220,8 +220,12 @@ class UnifiedHeapConcurrentMarker
|
|||||||
std::unique_ptr<cppgc::Visitor>
|
std::unique_ptr<cppgc::Visitor>
|
||||||
UnifiedHeapConcurrentMarker::CreateConcurrentMarkingVisitor(
|
UnifiedHeapConcurrentMarker::CreateConcurrentMarkingVisitor(
|
||||||
cppgc::internal::ConcurrentMarkingState& marking_state) const {
|
cppgc::internal::ConcurrentMarkingState& marking_state) const {
|
||||||
|
if (collection_type_ == CppHeap::CollectionType::kMajor)
|
||||||
return std::make_unique<ConcurrentUnifiedHeapMarkingVisitor>(
|
return std::make_unique<ConcurrentUnifiedHeapMarkingVisitor>(
|
||||||
heap(), v8_heap_, marking_state, collection_type_);
|
heap(), v8_heap_, marking_state);
|
||||||
|
else
|
||||||
|
return std::make_unique<ConcurrentMinorGCMarkingVisitor>(heap(), v8_heap_,
|
||||||
|
marking_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FatalOutOfMemoryHandlerImpl(const std::string& reason,
|
void FatalOutOfMemoryHandlerImpl(const std::string& reason,
|
||||||
@ -308,8 +312,13 @@ UnifiedHeapMarker::UnifiedHeapMarker(Heap* v8_heap,
|
|||||||
cppgc::internal::MarkingConfig config)
|
cppgc::internal::MarkingConfig config)
|
||||||
: cppgc::internal::MarkerBase(heap, platform, config),
|
: cppgc::internal::MarkerBase(heap, platform, config),
|
||||||
mutator_unified_heap_marking_state_(v8_heap, nullptr),
|
mutator_unified_heap_marking_state_(v8_heap, nullptr),
|
||||||
marking_visitor_(std::make_unique<MutatorUnifiedHeapMarkingVisitor>(
|
marking_visitor_(config.collection_type == CppHeap::CollectionType::kMajor
|
||||||
heap, mutator_marking_state_, mutator_unified_heap_marking_state_)),
|
? std::make_unique<MutatorUnifiedHeapMarkingVisitor>(
|
||||||
|
heap, mutator_marking_state_,
|
||||||
|
mutator_unified_heap_marking_state_)
|
||||||
|
: std::make_unique<MutatorMinorGCMarkingVisitor>(
|
||||||
|
heap, mutator_marking_state_,
|
||||||
|
mutator_unified_heap_marking_state_)),
|
||||||
conservative_marking_visitor_(heap, mutator_marking_state_,
|
conservative_marking_visitor_(heap, mutator_marking_state_,
|
||||||
*marking_visitor_) {
|
*marking_visitor_) {
|
||||||
concurrent_marker_ = std::make_unique<UnifiedHeapConcurrentMarker>(
|
concurrent_marker_ = std::make_unique<UnifiedHeapConcurrentMarker>(
|
||||||
@ -677,18 +686,6 @@ void CppHeap::InitializeTracing(CollectionType collection_type,
|
|||||||
marking_config);
|
marking_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
MarkingWorklists::Local* GetV8MarkingWorklists(
|
|
||||||
Isolate* isolate, cppgc::internal::CollectionType collection_type) {
|
|
||||||
auto* heap = isolate->heap();
|
|
||||||
if (collection_type == cppgc::internal::CollectionType::kMajor) {
|
|
||||||
return heap->mark_compact_collector()->local_marking_worklists();
|
|
||||||
} else {
|
|
||||||
return heap->minor_mark_compact_collector()->local_marking_worklists();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void CppHeap::StartTracing() {
|
void CppHeap::StartTracing() {
|
||||||
if (!TracingInitialized()) return;
|
if (!TracingInitialized()) return;
|
||||||
if (isolate_) {
|
if (isolate_) {
|
||||||
@ -698,7 +695,9 @@ void CppHeap::StartTracing() {
|
|||||||
marker_.get()
|
marker_.get()
|
||||||
->To<UnifiedHeapMarker>()
|
->To<UnifiedHeapMarker>()
|
||||||
.GetMutatorUnifiedHeapMarkingState()
|
.GetMutatorUnifiedHeapMarkingState()
|
||||||
.Update(GetV8MarkingWorklists(isolate_, *collection_type_));
|
.Update(isolate_->heap()
|
||||||
|
->mark_compact_collector()
|
||||||
|
->local_marking_worklists());
|
||||||
}
|
}
|
||||||
marker_->StartMarking();
|
marker_->StartMarking();
|
||||||
marking_done_ = false;
|
marking_done_ = false;
|
||||||
@ -743,11 +742,11 @@ void CppHeap::EnterFinalPause(cppgc::EmbedderStackState stack_state) {
|
|||||||
auto& marker = marker_.get()->To<UnifiedHeapMarker>();
|
auto& marker = marker_.get()->To<UnifiedHeapMarker>();
|
||||||
// Scan global handles conservatively in case we are attached to an Isolate.
|
// Scan global handles conservatively in case we are attached to an Isolate.
|
||||||
// TODO(1029379): Support global handle marking visitors with minor GC.
|
// TODO(1029379): Support global handle marking visitors with minor GC.
|
||||||
if (isolate_) {
|
if (isolate_ && !generational_gc_supported()) {
|
||||||
auto& heap = *isolate()->heap();
|
auto& heap = *isolate()->heap();
|
||||||
marker.conservative_visitor().SetConservativeTracedHandlesMarkingVisitor(
|
marker.conservative_visitor().SetConservativeTracedHandlesMarkingVisitor(
|
||||||
std::make_unique<ConservativeTracedHandlesMarkingVisitor>(
|
std::make_unique<ConservativeTracedHandlesMarkingVisitor>(
|
||||||
heap, *GetV8MarkingWorklists(isolate_, *collection_type_)));
|
heap, *heap.mark_compact_collector()->local_marking_worklists()));
|
||||||
}
|
}
|
||||||
marker.EnterAtomicPause(stack_state);
|
marker.EnterAtomicPause(stack_state);
|
||||||
compactor_.CancelIfShouldNotCompact(MarkingType::kAtomic, stack_state);
|
compactor_.CancelIfShouldNotCompact(MarkingType::kAtomic, stack_state);
|
||||||
|
@ -14,18 +14,6 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::unique_ptr<MarkingWorklists::Local> GetV8MarkingWorklists(
|
|
||||||
Heap* heap, cppgc::internal::CollectionType collection_type) {
|
|
||||||
if (!heap) return {};
|
|
||||||
auto* worklist =
|
|
||||||
(collection_type == cppgc::internal::CollectionType::kMajor)
|
|
||||||
? heap->mark_compact_collector()->marking_worklists()
|
|
||||||
: heap->minor_mark_compact_collector()->marking_worklists();
|
|
||||||
return std::make_unique<MarkingWorklists::Local>(worklist);
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
UnifiedHeapMarkingVisitorBase::UnifiedHeapMarkingVisitorBase(
|
UnifiedHeapMarkingVisitorBase::UnifiedHeapMarkingVisitorBase(
|
||||||
HeapBase& heap, cppgc::internal::BasicMarkingState& marking_state,
|
HeapBase& heap, cppgc::internal::BasicMarkingState& marking_state,
|
||||||
UnifiedHeapMarkingState& unified_heap_marking_state)
|
UnifiedHeapMarkingState& unified_heap_marking_state)
|
||||||
@ -79,11 +67,13 @@ MutatorUnifiedHeapMarkingVisitor::MutatorUnifiedHeapMarkingVisitor(
|
|||||||
|
|
||||||
ConcurrentUnifiedHeapMarkingVisitor::ConcurrentUnifiedHeapMarkingVisitor(
|
ConcurrentUnifiedHeapMarkingVisitor::ConcurrentUnifiedHeapMarkingVisitor(
|
||||||
HeapBase& heap, Heap* v8_heap,
|
HeapBase& heap, Heap* v8_heap,
|
||||||
cppgc::internal::ConcurrentMarkingState& marking_state,
|
cppgc::internal::ConcurrentMarkingState& marking_state)
|
||||||
CppHeap::CollectionType collectione_type)
|
|
||||||
: UnifiedHeapMarkingVisitorBase(heap, marking_state,
|
: UnifiedHeapMarkingVisitorBase(heap, marking_state,
|
||||||
concurrent_unified_heap_marking_state_),
|
concurrent_unified_heap_marking_state_),
|
||||||
local_marking_worklist_(GetV8MarkingWorklists(v8_heap, collectione_type)),
|
local_marking_worklist_(
|
||||||
|
v8_heap ? std::make_unique<MarkingWorklists::Local>(
|
||||||
|
v8_heap->mark_compact_collector()->marking_worklists())
|
||||||
|
: nullptr),
|
||||||
concurrent_unified_heap_marking_state_(v8_heap,
|
concurrent_unified_heap_marking_state_(v8_heap,
|
||||||
local_marking_worklist_.get()) {}
|
local_marking_worklist_.get()) {}
|
||||||
|
|
||||||
|
@ -67,12 +67,23 @@ class V8_EXPORT_PRIVATE MutatorUnifiedHeapMarkingVisitor
|
|||||||
~MutatorUnifiedHeapMarkingVisitor() override = default;
|
~MutatorUnifiedHeapMarkingVisitor() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class V8_EXPORT_PRIVATE MutatorMinorGCMarkingVisitor final
|
||||||
|
: public MutatorUnifiedHeapMarkingVisitor {
|
||||||
|
public:
|
||||||
|
using MutatorUnifiedHeapMarkingVisitor::MutatorUnifiedHeapMarkingVisitor;
|
||||||
|
~MutatorMinorGCMarkingVisitor() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Override and make the function empty, since we don't want to trace V8
|
||||||
|
// reference during cppgc's minor GC.
|
||||||
|
void Visit(const TracedReferenceBase&) final {}
|
||||||
|
};
|
||||||
|
|
||||||
class V8_EXPORT_PRIVATE ConcurrentUnifiedHeapMarkingVisitor
|
class V8_EXPORT_PRIVATE ConcurrentUnifiedHeapMarkingVisitor
|
||||||
: public UnifiedHeapMarkingVisitorBase {
|
: public UnifiedHeapMarkingVisitorBase {
|
||||||
public:
|
public:
|
||||||
ConcurrentUnifiedHeapMarkingVisitor(HeapBase&, Heap*,
|
ConcurrentUnifiedHeapMarkingVisitor(HeapBase&, Heap*,
|
||||||
cppgc::internal::ConcurrentMarkingState&,
|
cppgc::internal::ConcurrentMarkingState&);
|
||||||
CppHeap::CollectionType);
|
|
||||||
~ConcurrentUnifiedHeapMarkingVisitor() override;
|
~ConcurrentUnifiedHeapMarkingVisitor() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -89,6 +100,20 @@ class V8_EXPORT_PRIVATE ConcurrentUnifiedHeapMarkingVisitor
|
|||||||
UnifiedHeapMarkingState concurrent_unified_heap_marking_state_;
|
UnifiedHeapMarkingState concurrent_unified_heap_marking_state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Same visitor as for full GCs unified heap, but avoids visiting
|
||||||
|
// TracedReferences.
|
||||||
|
class V8_EXPORT_PRIVATE ConcurrentMinorGCMarkingVisitor final
|
||||||
|
: public ConcurrentUnifiedHeapMarkingVisitor {
|
||||||
|
public:
|
||||||
|
using ConcurrentUnifiedHeapMarkingVisitor::
|
||||||
|
ConcurrentUnifiedHeapMarkingVisitor;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Override and make the function empty, since we don't want to trace V8
|
||||||
|
// reference during cppgc's minor GC.
|
||||||
|
void Visit(const TracedReferenceBase&) final {}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
@ -592,23 +592,6 @@ int YoungGenerationMarkingVisitorBase<
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConcreteVisitor, typename MarkingState>
|
|
||||||
int YoungGenerationMarkingVisitorBase<
|
|
||||||
ConcreteVisitor, MarkingState>::VisitJSApiObject(Map map, JSObject object) {
|
|
||||||
if (!worklists_local_->SupportsExtractWrapper())
|
|
||||||
return this->VisitJSObject(map, object);
|
|
||||||
if (!concrete_visitor()->ShouldVisit(object)) return 0;
|
|
||||||
MarkingWorklists::Local::WrapperSnapshot wrapper_snapshot;
|
|
||||||
const bool valid_snapshot =
|
|
||||||
worklists_local_->ExtractWrapper(map, object, wrapper_snapshot);
|
|
||||||
const int size = concrete_visitor()->VisitJSObjectSubclass(map, object);
|
|
||||||
if (size && valid_snapshot) {
|
|
||||||
// Success: The object needs to be processed for embedder references.
|
|
||||||
worklists_local_->PushExtractedWrapper(wrapper_snapshot);
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ConcreteVisitor, typename MarkingState>
|
template <typename ConcreteVisitor, typename MarkingState>
|
||||||
void YoungGenerationMarkingVisitorBase<ConcreteVisitor, MarkingState>::
|
void YoungGenerationMarkingVisitorBase<ConcreteVisitor, MarkingState>::
|
||||||
MarkObjectViaMarkingWorklist(HeapObject object) {
|
MarkObjectViaMarkingWorklist(HeapObject object) {
|
||||||
|
@ -244,8 +244,6 @@ class YoungGenerationMarkingVisitorBase
|
|||||||
|
|
||||||
V8_INLINE int VisitJSArrayBuffer(Map map, JSArrayBuffer object);
|
V8_INLINE int VisitJSArrayBuffer(Map map, JSArrayBuffer object);
|
||||||
|
|
||||||
V8_INLINE int VisitJSApiObject(Map map, JSObject object);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ConcreteVisitor* concrete_visitor() {
|
ConcreteVisitor* concrete_visitor() {
|
||||||
return static_cast<ConcreteVisitor*>(this);
|
return static_cast<ConcreteVisitor*>(this);
|
||||||
|
@ -216,7 +216,7 @@ template <typename ConcreteVisitor>
|
|||||||
int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map map,
|
int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map map,
|
||||||
JSObject object) {
|
JSObject object) {
|
||||||
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
|
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
|
||||||
return visitor->VisitJSApiObject(map, object);
|
return visitor->VisitJSObject(map, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConcreteVisitor>
|
template <typename ConcreteVisitor>
|
||||||
@ -233,16 +233,6 @@ int NewSpaceVisitor<ConcreteVisitor>::VisitWeakCell(Map map,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ConcreteVisitor>
|
|
||||||
template <typename T, typename TBodyDescriptor>
|
|
||||||
int NewSpaceVisitor<ConcreteVisitor>::VisitJSObjectSubclass(Map map, T object) {
|
|
||||||
if (!this->ShouldVisit(object)) return 0;
|
|
||||||
this->VisitMapPointer(object);
|
|
||||||
int size = TBodyDescriptor::SizeOf(map, object);
|
|
||||||
TBodyDescriptor::IterateBody(map, object, size, this);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
@ -148,9 +148,6 @@ class NewSpaceVisitor : public HeapVisitor<int, ConcreteVisitor> {
|
|||||||
|
|
||||||
int VisitSharedFunctionInfo(Map map, SharedFunctionInfo object);
|
int VisitSharedFunctionInfo(Map map, SharedFunctionInfo object);
|
||||||
int VisitWeakCell(Map map, WeakCell weak_cell);
|
int VisitWeakCell(Map map, WeakCell weak_cell);
|
||||||
|
|
||||||
template <typename T, typename TBodyDescriptor = typename T::BodyDescriptor>
|
|
||||||
int VisitJSObjectSubclass(Map map, T object);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class WeakObjectRetainer;
|
class WeakObjectRetainer;
|
||||||
|
@ -479,7 +479,6 @@ class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> {
|
|||||||
V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
|
V8_INLINE void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) final;
|
||||||
V8_INLINE int VisitEphemeronHashTable(Map map, EphemeronHashTable object);
|
V8_INLINE int VisitEphemeronHashTable(Map map, EphemeronHashTable object);
|
||||||
V8_INLINE int VisitJSArrayBuffer(Map map, JSArrayBuffer object);
|
V8_INLINE int VisitJSArrayBuffer(Map map, JSArrayBuffer object);
|
||||||
V8_INLINE int VisitJSApiObject(Map map, JSObject object);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename TSlot>
|
template <typename TSlot>
|
||||||
@ -560,10 +559,6 @@ int ScavengeVisitor::VisitJSArrayBuffer(Map map, JSArrayBuffer object) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScavengeVisitor::VisitJSApiObject(Map map, JSObject object) {
|
|
||||||
return VisitJSObject(map, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScavengeVisitor::VisitEphemeronHashTable(Map map,
|
int ScavengeVisitor::VisitEphemeronHashTable(Map map,
|
||||||
EphemeronHashTable table) {
|
EphemeronHashTable table) {
|
||||||
// Register table with the scavenger, so it can take care of the weak keys
|
// Register table with the scavenger, so it can take care of the weak keys
|
||||||
|
@ -87,47 +87,6 @@ TEST_F(YoungUnifiedHeapTest, CollectUnreachableCppGCObject) {
|
|||||||
EXPECT_EQ(1u, Wrappable::destructor_callcount);
|
EXPECT_EQ(1u, Wrappable::destructor_callcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(YoungUnifiedHeapTest, FindingV8ToCppGCReference) {
|
|
||||||
v8::HandleScope scope(v8_isolate());
|
|
||||||
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
|
|
||||||
v8::Context::Scope context_scope(context);
|
|
||||||
|
|
||||||
uint16_t wrappable_type = WrapperHelper::kTracedEmbedderId;
|
|
||||||
auto* wrappable_object =
|
|
||||||
cppgc::MakeGarbageCollected<Wrappable>(allocation_handle());
|
|
||||||
v8::Local<v8::Object> api_object =
|
|
||||||
WrapperHelper::CreateWrapper(context, &wrappable_type, wrappable_object);
|
|
||||||
EXPECT_FALSE(api_object.IsEmpty());
|
|
||||||
|
|
||||||
Wrappable::destructor_callcount = 0;
|
|
||||||
CollectYoungGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
|
|
||||||
EXPECT_EQ(0u, Wrappable::destructor_callcount);
|
|
||||||
|
|
||||||
WrapperHelper::ResetWrappableConnection(api_object);
|
|
||||||
CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
|
|
||||||
EXPECT_EQ(1u, Wrappable::destructor_callcount);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(YoungUnifiedHeapTest, FindingCppGCToV8Reference) {
|
|
||||||
v8::HandleScope handle_scope(v8_isolate());
|
|
||||||
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
|
|
||||||
v8::Context::Scope context_scope(context);
|
|
||||||
|
|
||||||
auto* wrappable_object =
|
|
||||||
cppgc::MakeGarbageCollected<Wrappable>(allocation_handle());
|
|
||||||
|
|
||||||
{
|
|
||||||
v8::HandleScope inner_handle_scope(v8_isolate());
|
|
||||||
auto local = v8::Object::New(v8_isolate());
|
|
||||||
EXPECT_TRUE(local->IsObject());
|
|
||||||
wrappable_object->SetWrapper(v8_isolate(), local);
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectYoungGarbageWithEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
|
|
||||||
auto local = wrappable_object->wrapper().Get(v8_isolate());
|
|
||||||
EXPECT_TRUE(local->IsObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user