Commit 8b3e66d5 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

cppgc: Make member_unittests use idiomatic allocation

Bug: chromium:1056170
Change-Id: I98bbff8d2938c6b34fe2c358d504ba6211ec8b54
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2140931Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67054}
parent 3d098174
......@@ -2,17 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <array>
#include <algorithm>
#include <vector>
#include "include/cppgc/allocation.h"
#include "include/cppgc/garbage-collected.h"
#include "include/cppgc/member.h"
#include "include/cppgc/type-traits.h"
#include "test/unittests/heap/cppgc/tests.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cppgc {
namespace internal {
namespace {
struct GCed : GarbageCollected<GCed> {};
struct DerivedGCed : GCed {};
......@@ -37,21 +42,24 @@ using MemberWithCustomBarrier =
BasicStrongMember<GCed, CustomWriteBarrierPolicy>;
struct CustomCheckingPolicy {
static std::array<GCed, 10> Array;
static std::vector<GCed*> Cached;
static size_t ChecksTriggered;
void CheckPointer(const void* ptr) {
EXPECT_LE(Array.data(), ptr);
EXPECT_GT(Array.data() + Array.size(), ptr);
EXPECT_NE(Cached.cend(), std::find(Cached.cbegin(), Cached.cend(), ptr));
++ChecksTriggered;
}
};
std::array<GCed, 10> CustomCheckingPolicy::Array;
std::vector<GCed*> CustomCheckingPolicy::Cached;
size_t CustomCheckingPolicy::ChecksTriggered = 0;
using MemberWithCustomChecking =
internal::BasicMember<GCed, class StrongMemberTag,
DijkstraWriteBarrierPolicy, CustomCheckingPolicy>;
class MemberTest : public testing::TestSupportingAllocationOnly {};
} // namespace
template <template <typename> class Member>
void EmptyTest() {
{
......@@ -66,115 +74,115 @@ void EmptyTest() {
}
}
TEST(MemberTest, Empty) {
TEST_F(MemberTest, Empty) {
EmptyTest<Member>();
EmptyTest<WeakMember>();
EmptyTest<UntracedMember>();
}
template <template <typename> class Member>
void ClearTest() {
GCed gced;
Member<GCed> member = &gced;
void ClearTest(cppgc::Heap* heap) {
Member<GCed> member = MakeGarbageCollected<GCed>(heap);
EXPECT_NE(nullptr, member.Get());
member.Clear();
EXPECT_EQ(nullptr, member.Get());
}
TEST(MemberTest, Clear) {
ClearTest<Member>();
ClearTest<WeakMember>();
ClearTest<UntracedMember>();
TEST_F(MemberTest, Clear) {
cppgc::Heap* heap = GetHeap();
ClearTest<Member>(heap);
ClearTest<WeakMember>(heap);
ClearTest<UntracedMember>(heap);
}
template <template <typename> class Member>
void ReleaseTest() {
GCed gced;
Member<GCed> member = &gced;
void ReleaseTest(cppgc::Heap* heap) {
GCed* gced = MakeGarbageCollected<GCed>(heap);
Member<GCed> member = gced;
EXPECT_NE(nullptr, member.Get());
GCed* raw = member.Release();
EXPECT_EQ(&gced, raw);
EXPECT_EQ(gced, raw);
EXPECT_EQ(nullptr, member.Get());
}
TEST(MemberTest, Release) {
ReleaseTest<Member>();
ReleaseTest<WeakMember>();
ReleaseTest<UntracedMember>();
TEST_F(MemberTest, Release) {
cppgc::Heap* heap = GetHeap();
ReleaseTest<Member>(heap);
ReleaseTest<WeakMember>(heap);
ReleaseTest<UntracedMember>(heap);
}
template <template <typename> class Member1, template <typename> class Member2>
void SwapTest() {
GCed gced1, gced2;
Member1<GCed> member1 = &gced1;
Member2<GCed> member2 = &gced2;
EXPECT_EQ(&gced1, member1.Get());
EXPECT_EQ(&gced2, member2.Get());
void SwapTest(cppgc::Heap* heap) {
GCed* gced1 = MakeGarbageCollected<GCed>(heap);
GCed* gced2 = MakeGarbageCollected<GCed>(heap);
Member1<GCed> member1 = gced1;
Member2<GCed> member2 = gced2;
EXPECT_EQ(gced1, member1.Get());
EXPECT_EQ(gced2, member2.Get());
member1.Swap(member2);
EXPECT_EQ(&gced2, member1.Get());
EXPECT_EQ(&gced1, member2.Get());
EXPECT_EQ(gced2, member1.Get());
EXPECT_EQ(gced1, member2.Get());
}
TEST(MemberTest, Swap) {
SwapTest<Member, Member>();
SwapTest<Member, WeakMember>();
SwapTest<Member, UntracedMember>();
SwapTest<WeakMember, Member>();
SwapTest<WeakMember, WeakMember>();
SwapTest<WeakMember, UntracedMember>();
SwapTest<UntracedMember, Member>();
SwapTest<UntracedMember, WeakMember>();
SwapTest<UntracedMember, UntracedMember>();
TEST_F(MemberTest, Swap) {
cppgc::Heap* heap = GetHeap();
SwapTest<Member, Member>(heap);
SwapTest<Member, WeakMember>(heap);
SwapTest<Member, UntracedMember>(heap);
SwapTest<WeakMember, Member>(heap);
SwapTest<WeakMember, WeakMember>(heap);
SwapTest<WeakMember, UntracedMember>(heap);
SwapTest<UntracedMember, Member>(heap);
SwapTest<UntracedMember, WeakMember>(heap);
SwapTest<UntracedMember, UntracedMember>(heap);
}
template <template <typename> class Member1, template <typename> class Member2>
void HeterogeneousConversionTest() {
void HeterogeneousConversionTest(cppgc::Heap* heap) {
{
GCed gced;
Member1<GCed> member1 = &gced;
Member1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
Member2<GCed> member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
DerivedGCed gced;
Member1<DerivedGCed> member1 = &gced;
Member1<DerivedGCed> member1 = MakeGarbageCollected<DerivedGCed>(heap);
Member2<GCed> member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
GCed gced;
Member1<GCed> member1 = &gced;
Member1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
Member2<GCed> member2;
member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
DerivedGCed gced;
Member1<DerivedGCed> member1 = &gced;
Member1<DerivedGCed> member1 = MakeGarbageCollected<DerivedGCed>(heap);
Member2<GCed> member2;
member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
}
TEST(MemberTest, HeterogeneousInterface) {
HeterogeneousConversionTest<Member, Member>();
HeterogeneousConversionTest<Member, WeakMember>();
HeterogeneousConversionTest<Member, UntracedMember>();
HeterogeneousConversionTest<WeakMember, Member>();
HeterogeneousConversionTest<WeakMember, WeakMember>();
HeterogeneousConversionTest<WeakMember, UntracedMember>();
HeterogeneousConversionTest<UntracedMember, Member>();
HeterogeneousConversionTest<UntracedMember, WeakMember>();
HeterogeneousConversionTest<UntracedMember, UntracedMember>();
TEST_F(MemberTest, HeterogeneousInterface) {
cppgc::Heap* heap = GetHeap();
HeterogeneousConversionTest<Member, Member>(heap);
HeterogeneousConversionTest<Member, WeakMember>(heap);
HeterogeneousConversionTest<Member, UntracedMember>(heap);
HeterogeneousConversionTest<WeakMember, Member>(heap);
HeterogeneousConversionTest<WeakMember, WeakMember>(heap);
HeterogeneousConversionTest<WeakMember, UntracedMember>(heap);
HeterogeneousConversionTest<UntracedMember, Member>(heap);
HeterogeneousConversionTest<UntracedMember, WeakMember>(heap);
HeterogeneousConversionTest<UntracedMember, UntracedMember>(heap);
}
template <template <typename> class Member1, template <typename> class Member2>
void EqualityTest() {
void EqualityTest(cppgc::Heap* heap) {
{
GCed gced;
Member1<GCed> member1 = &gced;
Member2<GCed> member2 = &gced;
GCed* gced = MakeGarbageCollected<GCed>(heap);
Member1<GCed> member1 = gced;
Member2<GCed> member2 = gced;
EXPECT_TRUE(member1 == member2);
EXPECT_FALSE(member1 != member2);
member2 = member1;
......@@ -182,35 +190,34 @@ void EqualityTest() {
EXPECT_FALSE(member1 != member2);
}
{
GCed gced1;
GCed gced2;
Member1<GCed> member1 = &gced1;
Member2<GCed> member2 = &gced2;
Member1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
Member2<GCed> member2 = MakeGarbageCollected<GCed>(heap);
EXPECT_TRUE(member1 != member2);
EXPECT_FALSE(member1 == member2);
}
}
TEST(MemberTest, EqualityTest) {
EqualityTest<Member, Member>();
EqualityTest<Member, WeakMember>();
EqualityTest<Member, UntracedMember>();
EqualityTest<WeakMember, Member>();
EqualityTest<WeakMember, WeakMember>();
EqualityTest<WeakMember, UntracedMember>();
EqualityTest<UntracedMember, Member>();
EqualityTest<UntracedMember, WeakMember>();
EqualityTest<UntracedMember, UntracedMember>();
TEST_F(MemberTest, EqualityTest) {
cppgc::Heap* heap = GetHeap();
EqualityTest<Member, Member>(heap);
EqualityTest<Member, WeakMember>(heap);
EqualityTest<Member, UntracedMember>(heap);
EqualityTest<WeakMember, Member>(heap);
EqualityTest<WeakMember, WeakMember>(heap);
EqualityTest<WeakMember, UntracedMember>(heap);
EqualityTest<UntracedMember, Member>(heap);
EqualityTest<UntracedMember, WeakMember>(heap);
EqualityTest<UntracedMember, UntracedMember>(heap);
}
TEST(MemberTest, WriteBarrierTriggered) {
TEST_F(MemberTest, WriteBarrierTriggered) {
CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered = 0;
CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered = 0;
GCed gced;
MemberWithCustomBarrier member1 = &gced;
GCed* gced = MakeGarbageCollected<GCed>(GetHeap());
MemberWithCustomBarrier member1 = gced;
EXPECT_EQ(1u, CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered);
EXPECT_EQ(0u, CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered);
member1 = &gced;
member1 = gced;
EXPECT_EQ(1u, CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered);
EXPECT_EQ(1u, CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered);
member1 = nullptr;
......@@ -228,13 +235,20 @@ TEST(MemberTest, WriteBarrierTriggered) {
EXPECT_EQ(3u, CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered);
}
TEST(MemberTest, CheckingPolocy) {
TEST_F(MemberTest, CheckingPolicy) {
static constexpr size_t kElements = 64u;
CustomCheckingPolicy::ChecksTriggered = 0u;
for (std::size_t i = 0; i < kElements; ++i) {
CustomCheckingPolicy::Cached.push_back(
MakeGarbageCollected<GCed>(GetHeap()));
}
MemberWithCustomChecking member;
for (GCed& item : CustomCheckingPolicy::Array) {
member = &item;
for (GCed* item : CustomCheckingPolicy::Cached) {
member = item;
}
EXPECT_EQ(CustomCheckingPolicy::Array.size(),
EXPECT_EQ(CustomCheckingPolicy::Cached.size(),
CustomCheckingPolicy::ChecksTriggered);
}
} // namespace internal
......
......@@ -113,24 +113,11 @@ TEST_F(TraceTraitTest, TraceGCedMixinThroughTraceDescriptor) {
EXPECT_EQ(1u, GCed::trace_callcount);
}
namespace {
template <typename T>
class MemberHolder final : public GarbageCollected<MemberHolder<T>> {
public:
void Trace(Visitor* visitor) { visitor->Trace(ref); }
Member<T> ref;
};
} // namespace
TEST_F(VisitorTest, DispatchTraceGCed) {
auto* gced = MakeGarbageCollected<GCed>(GetHeap());
auto* holder = MakeGarbageCollected<MemberHolder<GCed>>(GetHeap());
holder->ref = gced;
DispatchingVisitor visitor(gced, gced);
Member<GCed> ref = MakeGarbageCollected<GCed>(GetHeap());
DispatchingVisitor visitor(ref, ref);
EXPECT_EQ(0u, GCed::trace_callcount);
visitor.Trace(holder->ref);
visitor.Trace(ref);
EXPECT_EQ(1u, GCed::trace_callcount);
}
......@@ -139,11 +126,10 @@ TEST_F(VisitorTest, DispatchTraceGCedMixin) {
auto* gced_mixin = static_cast<GCedMixin*>(gced_mixin_app);
// Ensure that we indeed test dispatching an inner object.
EXPECT_NE(static_cast<void*>(gced_mixin_app), static_cast<void*>(gced_mixin));
auto* holder = MakeGarbageCollected<MemberHolder<GCedMixin>>(GetHeap());
holder->ref = gced_mixin;
Member<GCedMixin> ref = gced_mixin;
DispatchingVisitor visitor(gced_mixin, gced_mixin_app);
EXPECT_EQ(0u, GCed::trace_callcount);
visitor.Trace(holder->ref);
visitor.Trace(ref);
EXPECT_EQ(1u, GCed::trace_callcount);
}
......
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