Commit 4dee3fbd authored by Anton Bikineev's avatar Anton Bikineev Committed by V8 LUCI CQ

cppgc: Provide operator==(Raw, Member) to avoid Member decompression

The operator with raw pointer allows us to avoid Member decompression,
which is more expensive than compression. It's also quite frequently
called (e.g. in HeapHashSet::find()).

The existing operator
  template <...>
  bool operator==(const Member<T1>&, const Member<T2>&);
was not called for
  GCed* raw = ...;
  member == raw;
because the compiler wouldn't deduce `T2` in `const Member<T2>` as
`GCed` when the initializer expression `raw` is of different type
(`GCed*`).

Bug: chromium:1325007
Change-Id: Ie1ee12bad28081c66f4e08a146467fd7c040bb70
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3757344Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81702}
parent 7ccbd7be
This diff is collapsed.
......@@ -170,6 +170,15 @@ struct IsComplete {
decltype(IsSizeOfKnown(std::declval<T*>()))::value;
};
template <typename T, typename U>
constexpr bool IsDecayedSameV =
std::is_same_v<std::decay_t<T>, std::decay_t<U>>;
template <typename B, typename D>
constexpr bool IsStrictlyBaseOfV =
std::is_base_of_v<std::decay_t<B>, std::decay_t<D>> &&
!IsDecayedSameV<B, D>;
} // namespace internal
/**
......
......@@ -21,9 +21,15 @@ namespace internal {
namespace {
struct GCed : GarbageCollected<GCed> {
double d;
virtual void Trace(cppgc::Visitor*) const {}
};
struct DerivedGCed : GCed {
struct DerivedMixin : GarbageCollectedMixin {
void Trace(cppgc::Visitor* v) const override {}
};
struct DerivedGCed : GCed, DerivedMixin {
void Trace(cppgc::Visitor* v) const override { GCed::Trace(v); }
};
......@@ -335,10 +341,19 @@ void EqualityTest(cppgc::Heap* heap) {
MemberType1<GCed> member1 = gced;
MemberType2<GCed> member2 = gced;
EXPECT_TRUE(member1 == member2);
EXPECT_TRUE(member1 == gced);
EXPECT_TRUE(member2 == gced);
EXPECT_FALSE(member1 != member2);
EXPECT_FALSE(member1 != gced);
EXPECT_FALSE(member2 != gced);
member2 = member1;
EXPECT_TRUE(member1 == member2);
EXPECT_TRUE(member1 == gced);
EXPECT_TRUE(member2 == gced);
EXPECT_FALSE(member1 != member2);
EXPECT_FALSE(member1 != gced);
EXPECT_FALSE(member2 != gced);
}
{
MemberType1<GCed> member1 =
......@@ -346,7 +361,9 @@ void EqualityTest(cppgc::Heap* heap) {
MemberType2<GCed> member2 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_TRUE(member1 != member2);
EXPECT_TRUE(member1 != member2.Get());
EXPECT_FALSE(member1 == member2);
EXPECT_FALSE(member1 == member2.Get());
}
}
......@@ -363,6 +380,56 @@ TEST_F(MemberTest, EqualityTest) {
EqualityTest<UntracedMember, UntracedMember>(heap);
}
TEST_F(MemberTest, HeterogeneousEqualityTest) {
cppgc::Heap* heap = GetHeap();
{
auto* gced = MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
auto* derived = static_cast<DerivedMixin*>(gced);
ASSERT_NE(reinterpret_cast<void*>(gced), reinterpret_cast<void*>(derived));
}
{
auto* gced = MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
Member<DerivedGCed> member = gced;
#define EXPECT_MIXIN_EQUAL(Mixin) \
EXPECT_TRUE(member == mixin); \
EXPECT_TRUE(member == gced); \
EXPECT_TRUE(mixin == gced); \
EXPECT_FALSE(member != mixin); \
EXPECT_FALSE(member != gced); \
EXPECT_FALSE(mixin != gced);
{
// Construct from raw.
Member<DerivedMixin> mixin = gced;
EXPECT_MIXIN_EQUAL(mixin);
}
{
// Copy construct from member.
Member<DerivedMixin> mixin = member;
EXPECT_MIXIN_EQUAL(mixin);
}
{
// Move construct from member.
Member<DerivedMixin> mixin = std::move(member);
member = gced;
EXPECT_MIXIN_EQUAL(mixin);
}
{
// Copy assign from member.
Member<DerivedMixin> mixin;
mixin = member;
EXPECT_MIXIN_EQUAL(mixin);
}
{
// Move assign from member.
Member<DerivedMixin> mixin;
mixin = std::move(member);
member = gced;
EXPECT_MIXIN_EQUAL(mixin);
}
#undef EXPECT_MIXIN_EQUAL
}
}
TEST_F(MemberTest, WriteBarrierTriggered) {
CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered = 0;
CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered = 0;
......
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