cppgc: Add TraceTrait<Member<T>>
Embedders forward the Value in TraceEphemeron as Member reference (as depicted in the API docs). Add TraceTrait<Member<T>> that forwards to TraceTrait<T> accordingly, supporting the intended use case. Bug: chromium:1056170 Change-Id: I3b247cb3553ae34d9ff5393aefeaec24068e78c2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2656255 Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/master@{#72412}
This commit is contained in:
parent
6f973ba8de
commit
677a9ad9cd
@ -203,6 +203,8 @@ class BasicMember final : private MemberBase, private CheckingPolicy {
|
||||
void ClearFromGC() const { MemberBase::ClearFromGC(); }
|
||||
|
||||
friend class cppgc::Visitor;
|
||||
template <typename U>
|
||||
friend struct cppgc::TraceTrait;
|
||||
};
|
||||
|
||||
template <typename T1, typename WeaknessTag1, typename WriteBarrierPolicy1,
|
||||
|
@ -151,7 +151,7 @@ class V8_EXPORT Visitor {
|
||||
*/
|
||||
template <typename K, typename V>
|
||||
void Trace(const EphemeronPair<K, V>& ephemeron_pair) {
|
||||
TraceEphemeron(ephemeron_pair.key, ephemeron_pair.value.GetRawAtomic());
|
||||
TraceEphemeron(ephemeron_pair.key, &ephemeron_pair.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,6 +164,7 @@ class V8_EXPORT Visitor {
|
||||
template <typename K, typename V>
|
||||
void TraceEphemeron(const WeakMember<K>& key, const V* value) {
|
||||
TraceDescriptor value_desc = TraceTrait<V>::GetTraceDescriptor(value);
|
||||
if (!value_desc.base_object_payload) return;
|
||||
VisitEphemeron(key, value_desc);
|
||||
}
|
||||
|
||||
@ -317,6 +318,14 @@ class V8_EXPORT Visitor {
|
||||
friend class internal::VisitorBase;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TraceTrait<Member<T>> {
|
||||
static TraceDescriptor GetTraceDescriptor(const void* self) {
|
||||
return TraceTrait<T>::GetTraceDescriptor(
|
||||
static_cast<const Member<T>*>(self)->GetRawAtomic());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace cppgc
|
||||
|
||||
#endif // INCLUDE_CPPGC_VISITOR_H_
|
||||
|
@ -30,7 +30,20 @@ class EphemeronHolder : public GarbageCollected<GCed> {
|
||||
EphemeronPair<GCed, GCed> ephemeron_pair_;
|
||||
};
|
||||
|
||||
class EhpemeronPairTest : public testing::TestWithHeap {
|
||||
class EphemeronHolderTraceEphemeron
|
||||
: public GarbageCollected<EphemeronHolderTraceEphemeron> {
|
||||
public:
|
||||
EphemeronHolderTraceEphemeron(GCed* key, GCed* value)
|
||||
: ephemeron_pair_(key, value) {}
|
||||
void Trace(cppgc::Visitor* visitor) const {
|
||||
visitor->TraceEphemeron(ephemeron_pair_.key, &ephemeron_pair_.value);
|
||||
}
|
||||
|
||||
private:
|
||||
EphemeronPair<GCed, GCed> ephemeron_pair_;
|
||||
};
|
||||
|
||||
class EphemeronPairTest : public testing::TestWithHeap {
|
||||
using MarkingConfig = Marker::MarkingConfig;
|
||||
|
||||
static constexpr Marker::MarkingConfig IncrementalPreciseMarkingConfig = {
|
||||
@ -69,11 +82,11 @@ class EhpemeronPairTest : public testing::TestWithHeap {
|
||||
|
||||
// static
|
||||
constexpr Marker::MarkingConfig
|
||||
EhpemeronPairTest::IncrementalPreciseMarkingConfig;
|
||||
EphemeronPairTest::IncrementalPreciseMarkingConfig;
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_F(EhpemeronPairTest, ValueMarkedWhenKeyIsMarked) {
|
||||
TEST_F(EphemeronPairTest, ValueMarkedWhenKeyIsMarked) {
|
||||
GCed* key = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
Persistent<EphemeronHolder> holder =
|
||||
@ -84,7 +97,7 @@ TEST_F(EhpemeronPairTest, ValueMarkedWhenKeyIsMarked) {
|
||||
EXPECT_TRUE(HeapObjectHeader::FromPayload(value).IsMarked());
|
||||
}
|
||||
|
||||
TEST_F(EhpemeronPairTest, ValueNotMarkedWhenKeyIsNotMarked) {
|
||||
TEST_F(EphemeronPairTest, ValueNotMarkedWhenKeyIsNotMarked) {
|
||||
GCed* key = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
Persistent<EphemeronHolder> holder =
|
||||
@ -95,7 +108,7 @@ TEST_F(EhpemeronPairTest, ValueNotMarkedWhenKeyIsNotMarked) {
|
||||
EXPECT_FALSE(HeapObjectHeader::FromPayload(value).IsMarked());
|
||||
}
|
||||
|
||||
TEST_F(EhpemeronPairTest, ValueNotMarkedBeforeKey) {
|
||||
TEST_F(EphemeronPairTest, ValueNotMarkedBeforeKey) {
|
||||
GCed* key = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
Persistent<EphemeronHolder> holder =
|
||||
@ -108,5 +121,27 @@ TEST_F(EhpemeronPairTest, ValueNotMarkedBeforeKey) {
|
||||
EXPECT_TRUE(HeapObjectHeader::FromPayload(value).IsMarked());
|
||||
}
|
||||
|
||||
TEST_F(EphemeronPairTest, TraceEphemeronDispatch) {
|
||||
GCed* key = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
GCed* value = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
Persistent<EphemeronHolderTraceEphemeron> holder =
|
||||
MakeGarbageCollected<EphemeronHolderTraceEphemeron>(GetAllocationHandle(),
|
||||
key, value);
|
||||
HeapObjectHeader::FromPayload(key).TryMarkAtomic();
|
||||
InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get());
|
||||
FinishMarking();
|
||||
EXPECT_TRUE(HeapObjectHeader::FromPayload(value).IsMarked());
|
||||
}
|
||||
|
||||
TEST_F(EphemeronPairTest, EmptyValue) {
|
||||
GCed* key = MakeGarbageCollected<GCed>(GetAllocationHandle());
|
||||
Persistent<EphemeronHolderTraceEphemeron> holder =
|
||||
MakeGarbageCollected<EphemeronHolderTraceEphemeron>(GetAllocationHandle(),
|
||||
key, nullptr);
|
||||
HeapObjectHeader::FromPayload(key).TryMarkAtomic();
|
||||
InitializeMarker(*Heap::From(GetHeap()), GetPlatformHandle().get());
|
||||
FinishMarking();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace cppgc
|
||||
|
Loading…
Reference in New Issue
Block a user