cppgc: Add composite object tracing to Visitor
This allows embedding objects in each other and recursively trace through them. Bug: chromium:1056170 Change-Id: I4e4ae4c1669109c01003cb6b69797cf271a74033 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2198977 Reviewed-by: Omer Katz <omerkatz@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#67841}
This commit is contained in:
parent
99e4ef48e1
commit
1d26770085
1
BUILD.gn
1
BUILD.gn
@ -4107,6 +4107,7 @@ v8_source_set("cppgc_base") {
|
||||
"src/heap/cppgc/stack.h",
|
||||
"src/heap/cppgc/sweeper.cc",
|
||||
"src/heap/cppgc/sweeper.h",
|
||||
"src/heap/cppgc/visitor.cc",
|
||||
"src/heap/cppgc/worklist.h",
|
||||
]
|
||||
|
||||
|
@ -35,7 +35,7 @@ class Visitor {
|
||||
|
||||
template <typename T>
|
||||
void Trace(const WeakMember<T>& weak_member) {
|
||||
static_assert(sizeof(T), "T must be fully defined");
|
||||
static_assert(sizeof(T), "Pointee type must be fully defined.");
|
||||
static_assert(internal::IsGarbageCollectedType<T>::value,
|
||||
"T must be GarabgeCollected or GarbageCollectedMixin type");
|
||||
|
||||
@ -81,6 +81,18 @@ class Visitor {
|
||||
&HandleWeak<WeakPersistent>, &p);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Trace(const T& object) {
|
||||
#if V8_ENABLE_CHECKS
|
||||
// This object is embedded in potentially multiple nested objects. The
|
||||
// outermost object must not be in construction as such objects are (a) not
|
||||
// processed immediately, and (b) only processed conservatively if not
|
||||
// otherwise possible.
|
||||
CheckObjectNotInConstruction(&object);
|
||||
#endif // V8_ENABLE_CHECKS
|
||||
TraceTrait<T>::Trace(this, &object);
|
||||
}
|
||||
|
||||
template <typename T, void (T::*method)(const LivenessBroker&)>
|
||||
void RegisterWeakCallbackMethod(const T* obj) {
|
||||
RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>, obj);
|
||||
@ -121,7 +133,7 @@ class Visitor {
|
||||
|
||||
template <typename T>
|
||||
void Trace(const T* t) {
|
||||
static_assert(sizeof(T), "T must be fully defined");
|
||||
static_assert(sizeof(T), "Pointee type must be fully defined.");
|
||||
static_assert(internal::IsGarbageCollectedType<T>::value,
|
||||
"T must be GarabgeCollected or GarbageCollectedMixin type");
|
||||
if (!t) {
|
||||
@ -130,6 +142,10 @@ class Visitor {
|
||||
Visit(t, TraceTrait<T>::GetTraceDescriptor(t));
|
||||
}
|
||||
|
||||
#if V8_ENABLE_CHECKS
|
||||
V8_EXPORT void CheckObjectNotInConstruction(const void* address);
|
||||
#endif // V8_ENABLE_CHECKS
|
||||
|
||||
friend class internal::VisitorBase;
|
||||
};
|
||||
|
||||
|
16
src/heap/cppgc/visitor.cc
Normal file
16
src/heap/cppgc/visitor.cc
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/heap/cppgc/visitor.h"
|
||||
|
||||
namespace cppgc {
|
||||
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
void Visitor::CheckObjectNotInConstruction(const void* address) {
|
||||
// TODO(chromium:1056170): |address| is an inner pointer of an object. Check
|
||||
// that the object is not in construction.
|
||||
}
|
||||
#endif // V8_ENABLE_CHECKS
|
||||
|
||||
} // namespace cppgc
|
@ -228,5 +228,34 @@ TEST_F(VisitorTest, DispatchRegisterWeakCallbackMethod) {
|
||||
EXPECT_EQ(1u, WeakCallbackDispatcher::callback_callcount);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class Composite final {
|
||||
public:
|
||||
static size_t callback_callcount;
|
||||
Composite() { callback_callcount = 0; }
|
||||
void Trace(Visitor* visitor) const { callback_callcount++; }
|
||||
};
|
||||
|
||||
size_t Composite::callback_callcount;
|
||||
|
||||
class GCedWithComposite final : public GarbageCollected<GCedWithComposite> {
|
||||
public:
|
||||
void Trace(Visitor* visitor) const { visitor->Trace(composite); }
|
||||
|
||||
Composite composite;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(VisitorTest, DispatchToCompositeObject) {
|
||||
Member<GCedWithComposite> ref =
|
||||
MakeGarbageCollected<GCedWithComposite>(GetHeap());
|
||||
DispatchingVisitor visitor(ref, ref);
|
||||
EXPECT_EQ(0u, Composite::callback_callcount);
|
||||
visitor.Trace(ref);
|
||||
EXPECT_EQ(1u, Composite::callback_callcount);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace cppgc
|
||||
|
Loading…
Reference in New Issue
Block a user