Commit bfaca03f authored by Michael Lippautz's avatar Michael Lippautz Committed by V8 LUCI CQ

cppgc: Improve marking verifier

- Reset parent object and signal stack with nullptr sentinel
- Adjust FATAL messaging
- Fix dispatch for in-construction objects on stack

Bug: v8:11709
Change-Id: I4da0f0f373699aa1fa09745231911c7056978a4f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2856837Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74275}
parent 15610ebb
...@@ -35,7 +35,7 @@ class UnifiedHeapVerificationVisitor final : public JSVisitor { ...@@ -35,7 +35,7 @@ class UnifiedHeapVerificationVisitor final : public JSVisitor {
void VisitWeakContainer(const void* object, cppgc::TraceDescriptor, void VisitWeakContainer(const void* object, cppgc::TraceDescriptor,
cppgc::TraceDescriptor weak_desc, cppgc::WeakCallback, cppgc::TraceDescriptor weak_desc, cppgc::WeakCallback,
const void*) { const void*) final {
if (!object) return; if (!object) return;
// Contents of weak containers are found themselves through page iteration // Contents of weak containers are found themselves through page iteration
...@@ -58,13 +58,8 @@ class UnifiedHeapVerificationVisitor final : public JSVisitor { ...@@ -58,13 +58,8 @@ class UnifiedHeapVerificationVisitor final : public JSVisitor {
UnifiedHeapMarkingVerifier::UnifiedHeapMarkingVerifier( UnifiedHeapMarkingVerifier::UnifiedHeapMarkingVerifier(
cppgc::internal::HeapBase& heap_base) cppgc::internal::HeapBase& heap_base)
: MarkingVerifierBase( : MarkingVerifierBase(
heap_base, std::make_unique<UnifiedHeapVerificationVisitor>(state_)) { heap_base, state_,
} std::make_unique<UnifiedHeapVerificationVisitor>(state_)) {}
void UnifiedHeapMarkingVerifier::SetCurrentParent(
const cppgc::internal::HeapObjectHeader* parent) {
state_.SetCurrentParent(parent);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -16,8 +16,6 @@ class V8_EXPORT_PRIVATE UnifiedHeapMarkingVerifier final ...@@ -16,8 +16,6 @@ class V8_EXPORT_PRIVATE UnifiedHeapMarkingVerifier final
explicit UnifiedHeapMarkingVerifier(cppgc::internal::HeapBase&); explicit UnifiedHeapMarkingVerifier(cppgc::internal::HeapBase&);
~UnifiedHeapMarkingVerifier() final = default; ~UnifiedHeapMarkingVerifier() final = default;
void SetCurrentParent(const cppgc::internal::HeapObjectHeader*) final;
private: private:
// TODO(chromium:1056170): Use a verification state that can handle JS // TODO(chromium:1056170): Use a verification state that can handle JS
// references. // references.
......
...@@ -14,8 +14,10 @@ namespace cppgc { ...@@ -14,8 +14,10 @@ namespace cppgc {
namespace internal { namespace internal {
MarkingVerifierBase::MarkingVerifierBase( MarkingVerifierBase::MarkingVerifierBase(
HeapBase& heap, std::unique_ptr<cppgc::Visitor> visitor) HeapBase& heap, VerificationState& verification_state,
std::unique_ptr<cppgc::Visitor> visitor)
: ConservativeTracingVisitor(heap, *heap.page_backend(), *visitor.get()), : ConservativeTracingVisitor(heap, *heap.page_backend(), *visitor.get()),
verification_state_(verification_state),
visitor_(std::move(visitor)) {} visitor_(std::move(visitor)) {}
void MarkingVerifierBase::Run(Heap::Config::StackState stack_state) { void MarkingVerifierBase::Run(Heap::Config::StackState stack_state) {
...@@ -36,23 +38,38 @@ void VerificationState::VerifyMarked(const void* base_object_payload) const { ...@@ -36,23 +38,38 @@ void VerificationState::VerifyMarked(const void* base_object_payload) const {
"MarkingVerifier: Encountered unmarked object.\n" "MarkingVerifier: Encountered unmarked object.\n"
"#\n" "#\n"
"# Hint:\n" "# Hint:\n"
"# %s\n" "# %s (%p)\n"
"# \\-> %s", "# \\-> %s (%p)",
parent_->GetName().value, child_header.GetName().value); parent_ ? parent_->GetName().value : "Stack",
parent_ ? parent_->Payload() : nullptr, child_header.GetName().value,
child_header.Payload());
} }
} }
void MarkingVerifierBase::VisitInConstructionConservatively( void MarkingVerifierBase::VisitInConstructionConservatively(
HeapObjectHeader& header, TraceConservativelyCallback callback) { HeapObjectHeader& header, TraceConservativelyCallback callback) {
CHECK(header.IsMarked());
if (in_construction_objects_->find(&header) != if (in_construction_objects_->find(&header) !=
in_construction_objects_->end()) in_construction_objects_->end())
return; return;
in_construction_objects_->insert(&header); in_construction_objects_->insert(&header);
// Stack case: Parent is stack and this is merely ensuring that the object
// itself is marked. If the object is marked, then it is being processed by
// the on-heap phase.
if (verification_state_.IsParentOnStack()) {
verification_state_.VerifyMarked(header.Payload());
return;
}
// Heap case: Dispatching parent object that must be marked (pre-condition).
CHECK(header.IsMarked());
callback(this, header); callback(this, header);
} }
void MarkingVerifierBase::VisitPointer(const void* address) { void MarkingVerifierBase::VisitPointer(const void* address) {
// Entry point for stack walk. The conservative visitor dispatches as follows:
// - Fully constructed objects: Visit()
// - Objects in construction: VisitInConstructionConservatively()
TraceConservativelyIfNeeded(address); TraceConservativelyIfNeeded(address);
} }
...@@ -62,7 +79,7 @@ bool MarkingVerifierBase::VisitHeapObjectHeader(HeapObjectHeader* header) { ...@@ -62,7 +79,7 @@ bool MarkingVerifierBase::VisitHeapObjectHeader(HeapObjectHeader* header) {
DCHECK(!header->IsFree()); DCHECK(!header->IsFree());
SetCurrentParent(header); verification_state_.SetCurrentParent(header);
if (!header->IsInConstruction()) { if (!header->IsInConstruction()) {
header->Trace(visitor_.get()); header->Trace(visitor_.get());
...@@ -71,6 +88,8 @@ bool MarkingVerifierBase::VisitHeapObjectHeader(HeapObjectHeader* header) { ...@@ -71,6 +88,8 @@ bool MarkingVerifierBase::VisitHeapObjectHeader(HeapObjectHeader* header) {
TraceConservativelyIfNeeded(*header); TraceConservativelyIfNeeded(*header);
} }
verification_state_.SetCurrentParent(nullptr);
return true; return true;
} }
...@@ -112,12 +131,8 @@ class VerificationVisitor final : public cppgc::Visitor { ...@@ -112,12 +131,8 @@ class VerificationVisitor final : public cppgc::Visitor {
} // namespace } // namespace
MarkingVerifier::MarkingVerifier(HeapBase& heap_base) MarkingVerifier::MarkingVerifier(HeapBase& heap_base)
: MarkingVerifierBase(heap_base, : MarkingVerifierBase(heap_base, state_,
std::make_unique<VerificationVisitor>(state_)) {} std::make_unique<VerificationVisitor>(state_)) {}
void MarkingVerifier::SetCurrentParent(const HeapObjectHeader* parent) {
state_.SetCurrentParent(parent);
}
} // namespace internal } // namespace internal
} // namespace cppgc } // namespace cppgc
...@@ -21,6 +21,9 @@ class VerificationState { ...@@ -21,6 +21,9 @@ class VerificationState {
void VerifyMarked(const void*) const; void VerifyMarked(const void*) const;
void SetCurrentParent(const HeapObjectHeader* header) { parent_ = header; } void SetCurrentParent(const HeapObjectHeader* header) { parent_ = header; }
// No parent means parent was on stack.
bool IsParentOnStack() const { return !parent_; }
private: private:
const HeapObjectHeader* parent_ = nullptr; const HeapObjectHeader* parent_ = nullptr;
}; };
...@@ -40,9 +43,8 @@ class V8_EXPORT_PRIVATE MarkingVerifierBase ...@@ -40,9 +43,8 @@ class V8_EXPORT_PRIVATE MarkingVerifierBase
void Run(Heap::Config::StackState); void Run(Heap::Config::StackState);
protected: protected:
MarkingVerifierBase(HeapBase&, std::unique_ptr<cppgc::Visitor>); MarkingVerifierBase(HeapBase&, VerificationState&,
std::unique_ptr<cppgc::Visitor>);
virtual void SetCurrentParent(const HeapObjectHeader*) = 0;
private: private:
void VisitInConstructionConservatively(HeapObjectHeader&, void VisitInConstructionConservatively(HeapObjectHeader&,
...@@ -51,6 +53,7 @@ class V8_EXPORT_PRIVATE MarkingVerifierBase ...@@ -51,6 +53,7 @@ class V8_EXPORT_PRIVATE MarkingVerifierBase
bool VisitHeapObjectHeader(HeapObjectHeader*); bool VisitHeapObjectHeader(HeapObjectHeader*);
VerificationState& verification_state_;
std::unique_ptr<cppgc::Visitor> visitor_; std::unique_ptr<cppgc::Visitor> visitor_;
std::unordered_set<const HeapObjectHeader*> in_construction_objects_heap_; std::unordered_set<const HeapObjectHeader*> in_construction_objects_heap_;
...@@ -64,8 +67,6 @@ class V8_EXPORT_PRIVATE MarkingVerifier final : public MarkingVerifierBase { ...@@ -64,8 +67,6 @@ class V8_EXPORT_PRIVATE MarkingVerifier final : public MarkingVerifierBase {
explicit MarkingVerifier(HeapBase&); explicit MarkingVerifier(HeapBase&);
~MarkingVerifier() final = default; ~MarkingVerifier() final = default;
void SetCurrentParent(const HeapObjectHeader*) final;
private: private:
VerificationState state_; VerificationState state_;
}; };
......
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