288b545ad0
This is needed to trace objects found durinbg stack scanning. Bug: chromium:1056170 Change-Id: I1280d98f2fe69281c514b3a7d4a57f909a2eed96 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2190425 Commit-Queue: Omer Katz <omerkatz@chromium.org> Reviewed-by: Anton Bikineev <bikineev@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#67788}
147 lines
4.9 KiB
C++
147 lines
4.9 KiB
C++
// 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 "include/cppgc/garbage-collected.h"
|
|
|
|
#include "include/cppgc/allocation.h"
|
|
#include "include/cppgc/type-traits.h"
|
|
#include "src/heap/cppgc/heap-object-header-inl.h"
|
|
#include "src/heap/cppgc/heap.h"
|
|
#include "test/unittests/heap/cppgc/tests.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace cppgc {
|
|
namespace internal {
|
|
|
|
namespace {
|
|
|
|
class GCed : public GarbageCollected<GCed> {
|
|
public:
|
|
void Trace(Visitor*) const {}
|
|
};
|
|
class NotGCed {};
|
|
class Mixin : public GarbageCollectedMixin {};
|
|
class GCedWithMixin : public GarbageCollected<GCedWithMixin>, public Mixin {
|
|
USING_GARBAGE_COLLECTED_MIXIN();
|
|
};
|
|
class OtherMixin : public GarbageCollectedMixin {};
|
|
class MergedMixins : public Mixin, public OtherMixin {
|
|
MERGE_GARBAGE_COLLECTED_MIXINS();
|
|
|
|
public:
|
|
void Trace(cppgc::Visitor* visitor) const override {
|
|
Mixin::Trace(visitor);
|
|
OtherMixin::Trace(visitor);
|
|
}
|
|
};
|
|
class GCWithMergedMixins : public GCed, public MergedMixins {
|
|
USING_GARBAGE_COLLECTED_MIXIN();
|
|
|
|
public:
|
|
void Trace(cppgc::Visitor* visitor) const override {
|
|
MergedMixins::Trace(visitor);
|
|
}
|
|
};
|
|
|
|
class GarbageCollectedTestWithHeap
|
|
: public testing::TestSupportingAllocationOnly {};
|
|
|
|
} // namespace
|
|
|
|
TEST(GarbageCollectedTest, GarbageCollectedTrait) {
|
|
STATIC_ASSERT(!IsGarbageCollectedType<int>::value);
|
|
STATIC_ASSERT(!IsGarbageCollectedType<NotGCed>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedType<GCed>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedType<Mixin>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedType<GCedWithMixin>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedType<MergedMixins>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedType<GCWithMergedMixins>::value);
|
|
}
|
|
|
|
TEST(GarbageCollectedTest, GarbageCollectedMixinTrait) {
|
|
STATIC_ASSERT(!IsGarbageCollectedMixinType<int>::value);
|
|
STATIC_ASSERT(!IsGarbageCollectedMixinType<GCed>::value);
|
|
STATIC_ASSERT(!IsGarbageCollectedMixinType<NotGCed>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedMixinType<Mixin>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedMixinType<GCedWithMixin>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedMixinType<MergedMixins>::value);
|
|
STATIC_ASSERT(IsGarbageCollectedMixinType<GCWithMergedMixins>::value);
|
|
}
|
|
|
|
TEST_F(GarbageCollectedTestWithHeap, GetObjectStartReturnsCurrentAddress) {
|
|
GCed* gced = MakeGarbageCollected<GCed>(GetHeap());
|
|
GCedWithMixin* gced_with_mixin =
|
|
MakeGarbageCollected<GCedWithMixin>(GetHeap());
|
|
EXPECT_EQ(gced_with_mixin, static_cast<Mixin*>(gced_with_mixin)
|
|
->GetTraceDescriptor()
|
|
.base_object_payload);
|
|
EXPECT_NE(gced, static_cast<Mixin*>(gced_with_mixin)
|
|
->GetTraceDescriptor()
|
|
.base_object_payload);
|
|
}
|
|
|
|
namespace {
|
|
|
|
class GCedWithPostConstructionCallback final : public GCed {
|
|
public:
|
|
static size_t cb_callcount;
|
|
GCedWithPostConstructionCallback() { cb_callcount = 0; }
|
|
};
|
|
size_t GCedWithPostConstructionCallback::cb_callcount;
|
|
|
|
class MixinWithPostConstructionCallback {
|
|
public:
|
|
static size_t cb_callcount;
|
|
MixinWithPostConstructionCallback() { cb_callcount = 0; }
|
|
using MarkerForMixinWithPostConstructionCallback = int;
|
|
};
|
|
size_t MixinWithPostConstructionCallback::cb_callcount;
|
|
|
|
class GCedWithMixinWithPostConstructionCallback final
|
|
: public GCed,
|
|
public MixinWithPostConstructionCallback {};
|
|
|
|
} // namespace
|
|
} // namespace internal
|
|
|
|
template <>
|
|
struct PostConstructionCallbackTrait<
|
|
internal::GCedWithPostConstructionCallback> {
|
|
static void Call(internal::GCedWithPostConstructionCallback* object) {
|
|
EXPECT_FALSE(
|
|
internal::HeapObjectHeader::FromPayload(object).IsInConstruction());
|
|
internal::GCedWithPostConstructionCallback::cb_callcount++;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct PostConstructionCallbackTrait<
|
|
T,
|
|
internal::void_t<typename T::MarkerForMixinWithPostConstructionCallback>> {
|
|
// The parameter could just be T*.
|
|
static void Call(
|
|
internal::GCedWithMixinWithPostConstructionCallback* object) {
|
|
EXPECT_FALSE(
|
|
internal::HeapObjectHeader::FromPayload(object).IsInConstruction());
|
|
internal::GCedWithMixinWithPostConstructionCallback::cb_callcount++;
|
|
}
|
|
};
|
|
|
|
namespace internal {
|
|
|
|
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallback) {
|
|
EXPECT_EQ(0u, GCedWithPostConstructionCallback::cb_callcount);
|
|
MakeGarbageCollected<GCedWithPostConstructionCallback>(GetHeap());
|
|
EXPECT_EQ(1u, GCedWithPostConstructionCallback::cb_callcount);
|
|
}
|
|
|
|
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallbackForMixin) {
|
|
EXPECT_EQ(0u, MixinWithPostConstructionCallback::cb_callcount);
|
|
MakeGarbageCollected<GCedWithMixinWithPostConstructionCallback>(GetHeap());
|
|
EXPECT_EQ(1u, MixinWithPostConstructionCallback::cb_callcount);
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace cppgc
|