cppgc: Introduce AllocationHandle

Unified heap support in V8 requires having another (at least internal)
heap that implements a unfied garbage collection strategy. This will
not re-use the already existing cppgc::Heap because there should be no
way in creating such a heap externally or scheduling stand-alone
garbage collections.

In order to have a common token, this CL introduces AllocationHandle
which can be passed to MakeGarbageCollected to allocate C++ objects.
V8 (soon) and the stand-alone heap both have methods to retrieve such
a handle.

This works around a problem with creating diamond class hierarchies
when a base class would be exposed on the public API level.

Fast paths for Blink are still possible because allocation handles can
be cached the same way (e.g. global, or TLS) as a heap can be cached.

Tbr: yangguo@chromium.org
Bug: chromium:1056170
Change-Id: I8e9472a2c24ef82d1178953e8429b1fd8a2344bc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2238027
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68310}
This commit is contained in:
Michael Lippautz 2020-06-11 00:28:41 +02:00 committed by Commit Bot
parent 4559bd694f
commit 935d915186
26 changed files with 374 additions and 285 deletions

View File

@ -4133,7 +4133,6 @@ v8_source_set("cppgc_base") {
"src/heap/cppgc/gc-invoker.h",
"src/heap/cppgc/heap-growing.cc",
"src/heap/cppgc/heap-growing.h",
"src/heap/cppgc/heap-inl.h",
"src/heap/cppgc/heap-object-header-inl.h",
"src/heap/cppgc/heap-object-header.cc",
"src/heap/cppgc/heap-object-header.h",

View File

@ -11,7 +11,6 @@
#include "cppgc/custom-space.h"
#include "cppgc/garbage-collected.h"
#include "cppgc/heap.h"
#include "cppgc/internal/api-constants.h"
#include "cppgc/internal/gc-info.h"
@ -20,6 +19,15 @@ namespace cppgc {
template <typename T>
class MakeGarbageCollectedTraitBase;
namespace internal {
class ObjectAllocator;
} // namespace internal
/**
* AllocationHandle is used to allocate garbage-collected objects.
*/
class AllocationHandle;
namespace internal {
class V8_EXPORT MakeGarbageCollectedTraitInternal {
@ -36,9 +44,12 @@ class V8_EXPORT MakeGarbageCollectedTraitInternal {
atomic_mutable_bitfield->store(value, std::memory_order_release);
}
static void* Allocate(cppgc::Heap* heap, size_t size, GCInfoIndex index);
static void* Allocate(cppgc::Heap* heap, size_t size, GCInfoIndex index,
CustomSpaceIndex space_index);
static void* Allocate(
cppgc::AllocationHandle& handle, // NOLINT(runtime/references)
size_t size, GCInfoIndex index);
static void* Allocate(
cppgc::AllocationHandle& handle, // NOLINT(runtime/references)
size_t size, GCInfoIndex index, CustomSpaceIndex space_index);
friend class HeapObjectHeader;
};
@ -58,22 +69,26 @@ class MakeGarbageCollectedTraitBase
private:
template <typename U, typename CustomSpace>
struct SpacePolicy {
static void* Allocate(Heap* heap, size_t size) {
static void* Allocate(
AllocationHandle& handle, // NOLINT(runtime/references)
size_t size) {
// Custom space.
static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
"Custom space must inherit from CustomSpaceBase.");
return internal::MakeGarbageCollectedTraitInternal::Allocate(
heap, size, internal::GCInfoTrait<T>::Index(),
handle, size, internal::GCInfoTrait<T>::Index(),
CustomSpace::kSpaceIndex);
}
};
template <typename U>
struct SpacePolicy<U, void> {
static void* Allocate(Heap* heap, size_t size) {
static void* Allocate(
AllocationHandle& handle, // NOLINT(runtime/references)
size_t size) {
// Default space.
return internal::MakeGarbageCollectedTraitInternal::Allocate(
heap, size, internal::GCInfoTrait<T>::Index());
handle, size, internal::GCInfoTrait<T>::Index());
}
};
@ -81,12 +96,15 @@ class MakeGarbageCollectedTraitBase
/**
* Allocates memory for an object of type T.
*
* \param heap The heap to allocate this object on.
* \param handle AllocationHandle identifying the heap to allocate the object
* on.
* \param size The size that should be reserved for the object.
* \returns the memory to construct an object of type T on.
*/
static void* Allocate(Heap* heap, size_t size) {
return SpacePolicy<T, typename SpaceTrait<T>::Space>::Allocate(heap, size);
static void* Allocate(AllocationHandle& handle, // NOLINT(runtime/references)
size_t size) {
return SpacePolicy<T, typename SpaceTrait<T>::Space>::Allocate(handle,
size);
}
/**
@ -115,14 +133,16 @@ template <typename T>
class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
public:
template <typename... Args>
static T* Call(Heap* heap, Args&&... args) {
static T* Call(AllocationHandle& handle, // NOLINT(runtime/references)
Args&&... args) {
static_assert(internal::IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
static_assert(
!internal::IsGarbageCollectedMixinType<T>::value ||
sizeof(T) <= internal::api_constants::kLargeObjectSizeThreshold,
"GarbageCollectedMixin may not be a large object");
void* memory = MakeGarbageCollectedTraitBase<T>::Allocate(heap, sizeof(T));
void* memory =
MakeGarbageCollectedTraitBase<T>::Allocate(handle, sizeof(T));
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
@ -149,9 +169,10 @@ struct PostConstructionCallbackTrait {
* \returns an instance of type T.
*/
template <typename T, typename... Args>
T* MakeGarbageCollected(Heap* heap, Args&&... args) {
T* MakeGarbageCollected(AllocationHandle& handle, // NOLINT(runtime/references)
Args&&... args) {
T* object =
MakeGarbageCollectedTrait<T>::Call(heap, std::forward<Args>(args)...);
MakeGarbageCollectedTrait<T>::Call(handle, std::forward<Args>(args)...);
PostConstructionCallbackTrait<T>::Call(object);
return object;
}

View File

@ -18,6 +18,8 @@
*/
namespace cppgc {
class AllocationHandle;
namespace internal {
class Heap;
} // namespace internal
@ -119,6 +121,8 @@ class V8_EXPORT Heap {
const char* source, const char* reason,
StackState stack_state = StackState::kMayContainHeapPointers);
AllocationHandle& GetAllocationHandle();
private:
Heap() = default;

View File

@ -94,8 +94,8 @@ int main(int argc, char* argv[]) {
std::unique_ptr<cppgc::Heap> heap = cppgc::Heap::Create(cppgc_platform);
// Allocate a string rope on the managed heap.
auto* greeting = cppgc::MakeGarbageCollected<Rope>(
heap.get(), "Hello ",
cppgc::MakeGarbageCollected<Rope>(heap.get(), "World!"));
heap->GetAllocationHandle(), "Hello ",
cppgc::MakeGarbageCollected<Rope>(heap->GetAllocationHandle(), "World!"));
// Manually trigger garbage collection. The object greeting is held alive
// through conservative stack scanning.
heap->ForceGarbageCollectionSlow("V8 embedders example", "Testing");

View File

@ -6,7 +6,7 @@
#include "src/base/logging.h"
#include "src/base/macros.h"
#include "src/heap/cppgc/heap-inl.h"
#include "src/heap/cppgc/object-allocator-inl.h"
namespace cppgc {
namespace internal {
@ -15,19 +15,17 @@ STATIC_ASSERT(api_constants::kLargeObjectSizeThreshold ==
kLargeObjectSizeThreshold);
// static
void* MakeGarbageCollectedTraitInternal::Allocate(cppgc::Heap* heap,
size_t size,
GCInfoIndex index) {
DCHECK_NOT_NULL(heap);
return Heap::From(heap)->Allocate(size, index);
void* MakeGarbageCollectedTraitInternal::Allocate(
cppgc::AllocationHandle& handle, size_t size, GCInfoIndex index) {
return static_cast<ObjectAllocator&>(handle).AllocateObject(size, index);
}
// static
void* MakeGarbageCollectedTraitInternal::Allocate(
cppgc::Heap* heap, size_t size, GCInfoIndex index,
cppgc::AllocationHandle& handle, size_t size, GCInfoIndex index,
CustomSpaceIndex space_index) {
DCHECK_NOT_NULL(heap);
return Heap::From(heap)->Allocate(size, index, space_index);
return static_cast<ObjectAllocator&>(handle).AllocateObject(size, index,
space_index);
}
} // namespace internal

View File

@ -1,29 +0,0 @@
// 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.
#ifndef V8_HEAP_CPPGC_HEAP_INL_H_
#define V8_HEAP_CPPGC_HEAP_INL_H_
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/heap.h"
#include "src/heap/cppgc/object-allocator-inl.h"
namespace cppgc {
namespace internal {
void* Heap::Allocate(size_t size, GCInfoIndex index) {
DCHECK(is_allocation_allowed());
return object_allocator_.AllocateObject(size, index);
}
void* Heap::Allocate(size_t size, GCInfoIndex index,
CustomSpaceIndex space_index) {
DCHECK(is_allocation_allowed());
return object_allocator_.AllocateObject(size, index, space_index);
}
} // namespace internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_HEAP_INL_H_

View File

@ -50,6 +50,10 @@ void Heap::ForceGarbageCollectionSlow(const char* source, const char* reason,
internal::Heap::From(this)->CollectGarbage({stack_state});
}
AllocationHandle& Heap::GetAllocationHandle() {
return internal::Heap::From(this)->GetObjectAllocator();
}
namespace internal {
namespace {
@ -166,7 +170,7 @@ void Heap::CollectGarbage(Config config) {
// "Sweeping and finalization".
{
// Pre finalizers are forbidden from allocating objects
NoAllocationScope no_allocation_scope_(this);
ObjectAllocator::NoAllocationScope no_allocation_scope_(object_allocator_);
marker_->ProcessWeakness();
prefinalizer_handler_->InvokePreFinalizers();
}
@ -185,10 +189,5 @@ Heap::NoGCScope::NoGCScope(Heap* heap) : heap_(heap) { heap_->no_gc_scope_++; }
Heap::NoGCScope::~NoGCScope() { heap_->no_gc_scope_--; }
Heap::NoAllocationScope::NoAllocationScope(Heap* heap) : heap_(heap) {
heap_->no_allocation_scope_++;
}
Heap::NoAllocationScope::~NoAllocationScope() { heap_->no_allocation_scope_--; }
} // namespace internal
} // namespace cppgc

View File

@ -68,32 +68,15 @@ class V8_EXPORT_PRIVATE Heap final : public cppgc::Heap,
Heap* const heap_;
};
// NoAllocationScope is used in debug mode to catch unwanted allocations. E.g.
// allocations during GC.
class V8_EXPORT_PRIVATE NoAllocationScope final {
CPPGC_STACK_ALLOCATED();
public:
explicit NoAllocationScope(Heap* heap);
~NoAllocationScope();
NoAllocationScope(const NoAllocationScope&) = delete;
NoAllocationScope& operator=(const NoAllocationScope&) = delete;
private:
Heap* const heap_;
};
static Heap* From(cppgc::Heap* heap) { return static_cast<Heap*>(heap); }
static const Heap* From(const cppgc::Heap* heap) {
return static_cast<const Heap*>(heap);
}
Heap(std::shared_ptr<cppgc::Platform> platform,
cppgc::Heap::HeapOptions options);
~Heap() final;
inline void* Allocate(size_t size, GCInfoIndex index);
inline void* Allocate(size_t size, GCInfoIndex index,
CustomSpaceIndex space_index);
void CollectGarbage(Config config) final;
PreFinalizerHandler* prefinalizer_handler() {
@ -136,9 +119,10 @@ class V8_EXPORT_PRIVATE Heap final : public cppgc::Heap,
size_t ObjectPayloadSize() const;
ObjectAllocator& GetObjectAllocator() { return object_allocator_; }
private:
bool in_no_gc_scope() const { return no_gc_scope_ > 0; }
bool is_allocation_allowed() const { return no_allocation_scope_ == 0; }
RawHeap raw_heap_;
@ -166,7 +150,6 @@ class V8_EXPORT_PRIVATE Heap final : public cppgc::Heap,
size_t epoch_ = 0;
size_t no_gc_scope_ = 0;
size_t no_allocation_scope_ = 0;
friend class WriteBarrier;
friend class testing::TestWithHeap;

View File

@ -20,6 +20,7 @@ namespace cppgc {
namespace internal {
void* ObjectAllocator::AllocateObject(size_t size, GCInfoIndex gcinfo) {
DCHECK(is_allocation_allowed());
const size_t allocation_size =
RoundUp<kAllocationGranularity>(size + sizeof(HeapObjectHeader));
const RawHeap::RegularSpaceType type =
@ -30,6 +31,7 @@ void* ObjectAllocator::AllocateObject(size_t size, GCInfoIndex gcinfo) {
void* ObjectAllocator::AllocateObject(size_t size, GCInfoIndex gcinfo,
CustomSpaceIndex space_index) {
DCHECK(is_allocation_allowed());
const size_t allocation_size =
RoundUp<kAllocationGranularity>(size + sizeof(HeapObjectHeader));
return AllocateObjectOnSpace(

View File

@ -149,5 +149,15 @@ void ObjectAllocator::ResetLinearAllocationBuffers() {
visitor.Traverse(raw_heap_);
}
ObjectAllocator::NoAllocationScope::NoAllocationScope(
ObjectAllocator& allocator)
: allocator_(allocator) {
allocator.no_allocation_scope_++;
}
ObjectAllocator::NoAllocationScope::~NoAllocationScope() {
allocator_.no_allocation_scope_--;
}
} // namespace internal
} // namespace cppgc

View File

@ -5,18 +5,43 @@
#ifndef V8_HEAP_CPPGC_OBJECT_ALLOCATOR_H_
#define V8_HEAP_CPPGC_OBJECT_ALLOCATOR_H_
#include "include/cppgc/allocation.h"
#include "include/cppgc/internal/gc-info.h"
#include "include/cppgc/macros.h"
#include "src/heap/cppgc/heap-space.h"
#include "src/heap/cppgc/raw-heap.h"
namespace cppgc {
class V8_EXPORT AllocationHandle {
private:
AllocationHandle() = default;
friend class internal::ObjectAllocator;
};
namespace internal {
class StatsCollector;
class PageBackend;
class V8_EXPORT_PRIVATE ObjectAllocator final {
class V8_EXPORT_PRIVATE ObjectAllocator final : public cppgc::AllocationHandle {
public:
// NoAllocationScope is used in debug mode to catch unwanted allocations. E.g.
// allocations during GC.
class V8_EXPORT_PRIVATE NoAllocationScope final {
CPPGC_STACK_ALLOCATED();
public:
explicit NoAllocationScope(ObjectAllocator&);
~NoAllocationScope();
NoAllocationScope(const NoAllocationScope&) = delete;
NoAllocationScope& operator=(const NoAllocationScope&) = delete;
private:
ObjectAllocator& allocator_;
};
ObjectAllocator(RawHeap* heap, PageBackend* page_backend,
StatsCollector* stats_collector);
@ -32,6 +57,8 @@ class V8_EXPORT_PRIVATE ObjectAllocator final {
inline static RawHeap::RegularSpaceType GetInitialSpaceIndexForSize(
size_t size);
bool is_allocation_allowed() const { return no_allocation_scope_ == 0; }
inline void* AllocateObjectOnSpace(NormalPageSpace* space, size_t size,
GCInfoIndex gcinfo);
void* OutOfLineAllocate(NormalPageSpace*, size_t, GCInfoIndex);
@ -41,6 +68,7 @@ class V8_EXPORT_PRIVATE ObjectAllocator final {
RawHeap* raw_heap_;
PageBackend* page_backend_;
StatsCollector* stats_collector_;
size_t no_allocation_scope_ = 0;
};
} // namespace internal

View File

@ -132,8 +132,8 @@ TEST_F(ConcurrentSweeperTest, BackgroundSweepOfNormalPage) {
// Non finalizable objects are swept right away.
using GCedType = NormalNonFinalizable;
auto* unmarked_object = MakeGarbageCollected<GCedType>(GetHeap());
auto* marked_object = MakeGarbageCollected<GCedType>(GetHeap());
auto* unmarked_object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
auto* marked_object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
HeapObjectHeader::FromPayload(marked_object).TryMarkAtomic();
auto* page = BasePage::FromPayload(unmarked_object);
@ -166,8 +166,8 @@ TEST_F(ConcurrentSweeperTest, BackgroundSweepOfLargePage) {
// Non finalizable objects are swept right away.
using GCedType = LargeNonFinalizable;
auto* unmarked_object = MakeGarbageCollected<GCedType>(GetHeap());
auto* marked_object = MakeGarbageCollected<GCedType>(GetHeap());
auto* unmarked_object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
auto* marked_object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
HeapObjectHeader::FromPayload(marked_object).TryMarkAtomic();
auto* unmarked_page = BasePage::FromPayload(unmarked_object);
@ -204,7 +204,7 @@ TEST_F(ConcurrentSweeperTest, DeferredFinalizationOfNormalPage) {
BaseSpace* space = nullptr;
for (size_t i = 0; i < kNumberOfObjects; ++i) {
auto* object = MakeGarbageCollected<GCedType>(GetHeap());
auto* object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
objects.push_back(object);
auto* page = BasePage::FromPayload(object);
pages.insert(page);
@ -238,7 +238,7 @@ TEST_F(ConcurrentSweeperTest, DeferredFinalizationOfNormalPage) {
TEST_F(ConcurrentSweeperTest, DeferredFinalizationOfLargePage) {
using GCedType = LargeFinalizable;
auto* object = MakeGarbageCollected<GCedType>(GetHeap());
auto* object = MakeGarbageCollected<GCedType>(GetAllocationHandle());
auto* page = BasePage::FromPayload(object);
auto* space = page->space();
@ -268,13 +268,14 @@ TEST_F(ConcurrentSweeperTest, IncrementalSweeping) {
auto task_runner = GetPlatform().GetForegroundTaskRunner();
// Create two unmarked objects.
MakeGarbageCollected<NormalFinalizable>(GetHeap());
MakeGarbageCollected<LargeFinalizable>(GetHeap());
MakeGarbageCollected<NormalFinalizable>(GetAllocationHandle());
MakeGarbageCollected<LargeFinalizable>(GetAllocationHandle());
// Create two marked objects.
auto* marked_normal_object =
MakeGarbageCollected<NormalFinalizable>(GetHeap());
auto* marked_large_object = MakeGarbageCollected<LargeFinalizable>(GetHeap());
MakeGarbageCollected<NormalFinalizable>(GetAllocationHandle());
auto* marked_large_object =
MakeGarbageCollected<LargeFinalizable>(GetAllocationHandle());
auto& marked_normal_header =
HeapObjectHeader::FromPayload(marked_normal_object);

View File

@ -99,9 +99,12 @@ struct SpaceTrait<
namespace internal {
TEST_F(TestWithHeapWithCustomSpaces, AllocateOnCustomSpaces) {
auto* regular = MakeGarbageCollected<RegularGCed>(GetHeap());
auto* custom1 = MakeGarbageCollected<CustomGCed1>(GetHeap());
auto* custom2 = MakeGarbageCollected<CustomGCed2>(GetHeap());
auto* regular =
MakeGarbageCollected<RegularGCed>(GetHeap()->GetAllocationHandle());
auto* custom1 =
MakeGarbageCollected<CustomGCed1>(GetHeap()->GetAllocationHandle());
auto* custom2 =
MakeGarbageCollected<CustomGCed2>(GetHeap()->GetAllocationHandle());
EXPECT_EQ(RawHeap::kNumberOfRegularSpaces,
NormalPage::FromPayload(custom1)->space()->index());
EXPECT_EQ(RawHeap::kNumberOfRegularSpaces + 1,
@ -112,9 +115,12 @@ TEST_F(TestWithHeapWithCustomSpaces, AllocateOnCustomSpaces) {
TEST_F(TestWithHeapWithCustomSpaces,
AllocateOnCustomSpacesSpecifiedThroughBase) {
auto* regular = MakeGarbageCollected<RegularGCed>(GetHeap());
auto* custom1 = MakeGarbageCollected<CustomGCedFinal1>(GetHeap());
auto* custom2 = MakeGarbageCollected<CustomGCedFinal2>(GetHeap());
auto* regular =
MakeGarbageCollected<RegularGCed>(GetHeap()->GetAllocationHandle());
auto* custom1 =
MakeGarbageCollected<CustomGCedFinal1>(GetHeap()->GetAllocationHandle());
auto* custom2 =
MakeGarbageCollected<CustomGCedFinal2>(GetHeap()->GetAllocationHandle());
EXPECT_EQ(RawHeap::kNumberOfRegularSpaces,
NormalPage::FromPayload(custom1)->space()->index());
EXPECT_EQ(RawHeap::kNumberOfRegularSpaces,
@ -124,10 +130,10 @@ TEST_F(TestWithHeapWithCustomSpaces,
}
TEST_F(TestWithHeapWithCustomSpaces, SweepCustomSpace) {
MakeGarbageCollected<CustomGCedFinal1>(GetHeap());
MakeGarbageCollected<CustomGCedFinal2>(GetHeap());
MakeGarbageCollected<CustomGCed1>(GetHeap());
MakeGarbageCollected<CustomGCed2>(GetHeap());
MakeGarbageCollected<CustomGCedFinal1>(GetHeap()->GetAllocationHandle());
MakeGarbageCollected<CustomGCedFinal2>(GetHeap()->GetAllocationHandle());
MakeGarbageCollected<CustomGCed1>(GetHeap()->GetAllocationHandle());
MakeGarbageCollected<CustomGCed2>(GetHeap()->GetAllocationHandle());
EXPECT_EQ(0u, g_destructor_callcount);
PreciseGC();
EXPECT_EQ(4u, g_destructor_callcount);

View File

@ -70,9 +70,9 @@ TEST(GarbageCollectedTest, GarbageCollectedMixinTrait) {
}
TEST_F(GarbageCollectedTestWithHeap, GetObjectStartReturnsCurrentAddress) {
GCed* gced = MakeGarbageCollected<GCed>(GetHeap());
GCed* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
GCedWithMixin* gced_with_mixin =
MakeGarbageCollected<GCedWithMixin>(GetHeap());
MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle());
EXPECT_EQ(gced_with_mixin, static_cast<Mixin*>(gced_with_mixin)
->GetTraceDescriptor()
.base_object_payload);
@ -132,13 +132,14 @@ namespace internal {
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallback) {
EXPECT_EQ(0u, GCedWithPostConstructionCallback::cb_callcount);
MakeGarbageCollected<GCedWithPostConstructionCallback>(GetHeap());
MakeGarbageCollected<GCedWithPostConstructionCallback>(GetAllocationHandle());
EXPECT_EQ(1u, GCedWithPostConstructionCallback::cb_callcount);
}
TEST_F(GarbageCollectedTestWithHeap, PostConstructionCallbackForMixin) {
EXPECT_EQ(0u, MixinWithPostConstructionCallback::cb_callcount);
MakeGarbageCollected<GCedWithMixinWithPostConstructionCallback>(GetHeap());
MakeGarbageCollected<GCedWithMixinWithPostConstructionCallback>(
GetAllocationHandle());
EXPECT_EQ(1u, MixinWithPostConstructionCallback::cb_callcount);
}

View File

@ -42,7 +42,7 @@ class GCed : public GarbageCollected<GCed<Size>> {
} // namespace
TEST_F(PageTest, GetHeapForAllocatedObject) {
auto* gced = MakeGarbageCollected<GCed<1>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<1>>(GetAllocationHandle());
EXPECT_EQ(GetHeap(), GetHeapFromPayload(gced));
}
@ -61,36 +61,36 @@ TEST_F(PageTest, PredefinedSpaces) {
using SpaceType = RawHeap::RegularSpaceType;
RawHeap& heap = GetRawHeap();
{
auto* gced = MakeGarbageCollected<GCed<1>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<1>>(GetAllocationHandle());
BaseSpace* space = NormalPage::FromPayload(gced)->space();
EXPECT_EQ(heap.Space(SpaceType::kNormal1), space);
EXPECT_EQ(0u, space->index());
EXPECT_FALSE(space->is_large());
}
{
auto* gced = MakeGarbageCollected<GCed<32>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<32>>(GetAllocationHandle());
BaseSpace* space = NormalPage::FromPayload(gced)->space();
EXPECT_EQ(heap.Space(SpaceType::kNormal2), space);
EXPECT_EQ(1u, space->index());
EXPECT_FALSE(space->is_large());
}
{
auto* gced = MakeGarbageCollected<GCed<64>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<64>>(GetAllocationHandle());
BaseSpace* space = NormalPage::FromPayload(gced)->space();
EXPECT_EQ(heap.Space(SpaceType::kNormal3), space);
EXPECT_EQ(2u, space->index());
EXPECT_FALSE(space->is_large());
}
{
auto* gced = MakeGarbageCollected<GCed<128>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<128>>(GetAllocationHandle());
BaseSpace* space = NormalPage::FromPayload(gced)->space();
EXPECT_EQ(heap.Space(SpaceType::kNormal4), space);
EXPECT_EQ(3u, space->index());
EXPECT_FALSE(space->is_large());
}
{
auto* gced =
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
auto* gced = MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
BaseSpace* space = NormalPage::FromPayload(gced)->space();
EXPECT_EQ(heap.Space(SpaceType::kLarge), space);
EXPECT_EQ(4u, space->index());
@ -110,7 +110,7 @@ TEST_F(PageTest, NormalPageIndexing) {
std::vector<Persistent<Type>> persistents(kNumberOfObjects);
for (auto& p : persistents) {
p = MakeGarbageCollected<Type>(GetHeap());
p = MakeGarbageCollected<Type>(GetAllocationHandle());
}
const RawHeap& heap = GetRawHeap();
@ -135,7 +135,7 @@ TEST_F(PageTest, LargePageIndexing) {
std::vector<Persistent<Type>> persistents(kNumberOfObjects);
for (auto& p : persistents) {
p = MakeGarbageCollected<Type>(GetHeap());
p = MakeGarbageCollected<Type>(GetAllocationHandle());
}
const RawHeap& heap = GetRawHeap();
@ -160,7 +160,7 @@ TEST_F(PageTest, HeapObjectHeaderOnBasePageIndexing) {
std::vector<Persistent<Type>> persistents(kNumberOfObjects);
for (auto& p : persistents) {
p = MakeGarbageCollected<Type>(GetHeap());
p = MakeGarbageCollected<Type>(GetAllocationHandle());
}
const auto* page =
@ -180,7 +180,7 @@ TEST_F(PageTest, HeapObjectHeaderOnBasePageIndexing) {
TEST_F(PageTest, HeapObjectHeaderOnLargePageIndexing) {
constexpr size_t kObjectSize = 2 * kLargeObjectSizeThreshold;
using Type = GCed<kObjectSize>;
auto* gced = MakeGarbageCollected<Type>(GetHeap());
auto* gced = MakeGarbageCollected<Type>(GetAllocationHandle());
const auto* page = static_cast<LargePage*>(BasePage::FromPayload(gced));
const size_t expected_payload_size =
@ -260,7 +260,7 @@ TEST_F(PageTest, UnsweptPageDestruction) {
TEST_F(PageTest, ObjectHeaderFromInnerAddress) {
{
auto* object = MakeGarbageCollected<GCed<64>>(GetHeap());
auto* object = MakeGarbageCollected<GCed<64>>(GetAllocationHandle());
const HeapObjectHeader& expected = HeapObjectHeader::FromPayload(object);
for (auto* inner_ptr = reinterpret_cast<ConstAddress>(object);
@ -272,8 +272,8 @@ TEST_F(PageTest, ObjectHeaderFromInnerAddress) {
}
}
{
auto* object =
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
auto* object = MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
const HeapObjectHeader& expected = HeapObjectHeader::FromPayload(object);
const HeapObjectHeader& hoh =

View File

@ -52,7 +52,8 @@ class GCed : public GarbageCollected<Foo> {
} // namespace
TEST_F(GCHeapTest, PreciseGCReclaimsObjectOnStack) {
Foo* volatile do_not_access = MakeGarbageCollected<Foo>(GetHeap());
Foo* volatile do_not_access =
MakeGarbageCollected<Foo>(GetAllocationHandle());
USE(do_not_access);
EXPECT_EQ(0u, Foo::destructor_callcount);
PreciseGC();
@ -73,7 +74,7 @@ const void* ConservativeGCReturningObject(cppgc::Heap* heap,
} // namespace
TEST_F(GCHeapTest, ConservativeGCRetainsObjectOnStack) {
Foo* volatile object = MakeGarbageCollected<Foo>(GetHeap());
Foo* volatile object = MakeGarbageCollected<Foo>(GetAllocationHandle());
EXPECT_EQ(0u, Foo::destructor_callcount);
EXPECT_EQ(object, ConservativeGCReturningObject(GetHeap(), object));
EXPECT_EQ(0u, Foo::destructor_callcount);
@ -94,11 +95,11 @@ TEST_F(GCHeapTest, ObjectPayloadSize) {
Heap::NoGCScope no_gc_scope(Heap::From(GetHeap()));
for (size_t k = 0; k < kNumberOfObjectsPerArena; ++k) {
MakeGarbageCollected<GCed<kObjectSizes[0]>>(GetHeap());
MakeGarbageCollected<GCed<kObjectSizes[1]>>(GetHeap());
MakeGarbageCollected<GCed<kObjectSizes[2]>>(GetHeap());
MakeGarbageCollected<GCed<kObjectSizes[3]>>(GetHeap());
MakeGarbageCollected<GCed<kObjectSizes[4]>>(GetHeap());
MakeGarbageCollected<GCed<kObjectSizes[0]>>(GetAllocationHandle());
MakeGarbageCollected<GCed<kObjectSizes[1]>>(GetAllocationHandle());
MakeGarbageCollected<GCed<kObjectSizes[2]>>(GetAllocationHandle());
MakeGarbageCollected<GCed<kObjectSizes[3]>>(GetAllocationHandle());
MakeGarbageCollected<GCed<kObjectSizes[4]>>(GetAllocationHandle());
}
size_t aligned_object_sizes[arraysize(kObjectSizes)];

View File

@ -58,7 +58,7 @@ V8_NOINLINE T access(volatile const T& t) {
} // namespace
TEST_F(MarkerTest, PersistentIsMarked) {
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetAllocationHandle());
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
EXPECT_FALSE(header.IsMarked());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -66,8 +66,8 @@ TEST_F(MarkerTest, PersistentIsMarked) {
}
TEST_F(MarkerTest, ReachableMemberIsMarked) {
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
parent->SetChild(MakeGarbageCollected<GCed>(GetHeap()));
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
parent->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
HeapObjectHeader& header = HeapObjectHeader::FromPayload(parent->child());
EXPECT_FALSE(header.IsMarked());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -75,7 +75,7 @@ TEST_F(MarkerTest, ReachableMemberIsMarked) {
}
TEST_F(MarkerTest, UnreachableMemberIsNotMarked) {
Member<GCed> object = MakeGarbageCollected<GCed>(GetHeap());
Member<GCed> object = MakeGarbageCollected<GCed>(GetAllocationHandle());
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
EXPECT_FALSE(header.IsMarked());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -83,7 +83,7 @@ TEST_F(MarkerTest, UnreachableMemberIsNotMarked) {
}
TEST_F(MarkerTest, ObjectReachableFromStackIsMarked) {
GCed* object = MakeGarbageCollected<GCed>(GetHeap());
GCed* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_FALSE(HeapObjectHeader::FromPayload(object).IsMarked());
DoMarking({MarkingConfig::StackState::kMayContainHeapPointers});
EXPECT_TRUE(HeapObjectHeader::FromPayload(object).IsMarked());
@ -91,7 +91,7 @@ TEST_F(MarkerTest, ObjectReachableFromStackIsMarked) {
}
TEST_F(MarkerTest, ObjectReachableOnlyFromStackIsNotMarkedIfStackIsEmpty) {
GCed* object = MakeGarbageCollected<GCed>(GetHeap());
GCed* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
EXPECT_FALSE(header.IsMarked());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -101,14 +101,15 @@ TEST_F(MarkerTest, ObjectReachableOnlyFromStackIsNotMarkedIfStackIsEmpty) {
TEST_F(MarkerTest, WeakReferenceToUnreachableObjectIsCleared) {
{
WeakPersistent<GCed> weak_object = MakeGarbageCollected<GCed>(GetHeap());
WeakPersistent<GCed> weak_object =
MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_TRUE(weak_object);
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
EXPECT_FALSE(weak_object);
}
{
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
parent->SetWeakChild(MakeGarbageCollected<GCed>(GetHeap()));
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
parent->SetWeakChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
EXPECT_TRUE(parent->weak_child());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
EXPECT_FALSE(parent->weak_child());
@ -118,15 +119,15 @@ TEST_F(MarkerTest, WeakReferenceToUnreachableObjectIsCleared) {
TEST_F(MarkerTest, WeakReferenceToReachableObjectIsNotCleared) {
// Reachable from Persistent
{
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetAllocationHandle());
WeakPersistent<GCed> weak_object(object);
EXPECT_TRUE(weak_object);
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
EXPECT_TRUE(weak_object);
}
{
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> object = MakeGarbageCollected<GCed>(GetAllocationHandle());
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
parent->SetWeakChild(object);
EXPECT_TRUE(parent->weak_child());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -134,16 +135,17 @@ TEST_F(MarkerTest, WeakReferenceToReachableObjectIsNotCleared) {
}
// Reachable from Member
{
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
WeakPersistent<GCed> weak_object(MakeGarbageCollected<GCed>(GetHeap()));
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
WeakPersistent<GCed> weak_object(
MakeGarbageCollected<GCed>(GetAllocationHandle()));
parent->SetChild(weak_object);
EXPECT_TRUE(weak_object);
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
EXPECT_TRUE(weak_object);
}
{
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
parent->SetChild(MakeGarbageCollected<GCed>(GetHeap()));
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
parent->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
parent->SetWeakChild(parent->child());
EXPECT_TRUE(parent->weak_child());
DoMarking({MarkingConfig::StackState::kNoHeapPointers});
@ -151,7 +153,7 @@ TEST_F(MarkerTest, WeakReferenceToReachableObjectIsNotCleared) {
}
// Reachable from stack
{
GCed* object = MakeGarbageCollected<GCed>(GetHeap());
GCed* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
WeakPersistent<GCed> weak_object(object);
EXPECT_TRUE(weak_object);
DoMarking({MarkingConfig::StackState::kMayContainHeapPointers});
@ -159,8 +161,8 @@ TEST_F(MarkerTest, WeakReferenceToReachableObjectIsNotCleared) {
access(object);
}
{
GCed* object = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetHeap());
GCed* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
Persistent<GCed> parent = MakeGarbageCollected<GCed>(GetAllocationHandle());
parent->SetWeakChild(object);
EXPECT_TRUE(parent->weak_child());
DoMarking({MarkingConfig::StackState::kMayContainHeapPointers});
@ -171,10 +173,10 @@ TEST_F(MarkerTest, WeakReferenceToReachableObjectIsNotCleared) {
TEST_F(MarkerTest, DeepHierarchyIsMarked) {
static constexpr int kHierarchyDepth = 10;
Persistent<GCed> root = MakeGarbageCollected<GCed>(GetHeap());
Persistent<GCed> root = MakeGarbageCollected<GCed>(GetAllocationHandle());
GCed* parent = root;
for (int i = 0; i < kHierarchyDepth; ++i) {
parent->SetChild(MakeGarbageCollected<GCed>(GetHeap()));
parent->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
parent->SetWeakChild(parent->child());
parent = parent->child();
}
@ -189,9 +191,9 @@ TEST_F(MarkerTest, DeepHierarchyIsMarked) {
}
TEST_F(MarkerTest, NestedObjectsOnStackAreMarked) {
GCed* root = MakeGarbageCollected<GCed>(GetHeap());
root->SetChild(MakeGarbageCollected<GCed>(GetHeap()));
root->child()->SetChild(MakeGarbageCollected<GCed>(GetHeap()));
GCed* root = MakeGarbageCollected<GCed>(GetAllocationHandle());
root->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
root->child()->SetChild(MakeGarbageCollected<GCed>(GetAllocationHandle()));
DoMarking({MarkingConfig::StackState::kMayContainHeapPointers});
EXPECT_TRUE(HeapObjectHeader::FromPayload(root).IsMarked());
EXPECT_TRUE(HeapObjectHeader::FromPayload(root->child()).IsMarked());
@ -214,7 +216,7 @@ TEST_F(MarkerTest, InConstructionObjectIsEventuallyMarkedEmptyStack) {
Marker marker(Heap::From(GetHeap()));
marker.StartMarking({MarkingConfig::StackState::kMayContainHeapPointers});
GCedWithCallback* object = MakeGarbageCollected<GCedWithCallback>(
GetHeap(), [&marker](GCedWithCallback* obj) {
GetAllocationHandle(), [&marker](GCedWithCallback* obj) {
Member<GCedWithCallback> member(obj);
marker.GetMarkingVisitorForTesting()->Trace(member);
});
@ -226,14 +228,15 @@ TEST_F(MarkerTest, InConstructionObjectIsEventuallyMarkedEmptyStack) {
TEST_F(MarkerTest, InConstructionObjectIsEventuallyMarkedNonEmptyStack) {
Marker marker(Heap::From(GetHeap()));
marker.StartMarking({MarkingConfig::StackState::kMayContainHeapPointers});
MakeGarbageCollected<GCedWithCallback>(GetHeap(), [&marker](
GCedWithCallback* obj) {
Member<GCedWithCallback> member(obj);
marker.GetMarkingVisitorForTesting()->Trace(member);
EXPECT_FALSE(HeapObjectHeader::FromPayload(obj).IsMarked());
marker.FinishMarking({MarkingConfig::StackState::kMayContainHeapPointers});
EXPECT_TRUE(HeapObjectHeader::FromPayload(obj).IsMarked());
});
MakeGarbageCollected<GCedWithCallback>(
GetAllocationHandle(), [&marker](GCedWithCallback* obj) {
Member<GCedWithCallback> member(obj);
marker.GetMarkingVisitorForTesting()->Trace(member);
EXPECT_FALSE(HeapObjectHeader::FromPayload(obj).IsMarked());
marker.FinishMarking(
{MarkingConfig::StackState::kMayContainHeapPointers});
EXPECT_TRUE(HeapObjectHeader::FromPayload(obj).IsMarked());
});
}
} // namespace internal

View File

@ -54,7 +54,7 @@ TEST_F(MarkingVisitorTest, MarkedBytesAreInitiallyZero) {
// Strong refernces are marked.
TEST_F(MarkingVisitorTest, MarkMember) {
Member<GCed> object(MakeGarbageCollected<GCed>(GetHeap()));
Member<GCed> object(MakeGarbageCollected<GCed>(GetAllocationHandle()));
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
MutatorThreadMarkingVisitor visitor(GetMarker());
@ -67,7 +67,8 @@ TEST_F(MarkingVisitorTest, MarkMember) {
}
TEST_F(MarkingVisitorTest, MarkMemberMixin) {
GCedWithMixin* object(MakeGarbageCollected<GCedWithMixin>(GetHeap()));
GCedWithMixin* object(
MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle()));
Member<Mixin> mixin(object);
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
@ -81,7 +82,7 @@ TEST_F(MarkingVisitorTest, MarkMemberMixin) {
}
TEST_F(MarkingVisitorTest, MarkPersistent) {
Persistent<GCed> object(MakeGarbageCollected<GCed>(GetHeap()));
Persistent<GCed> object(MakeGarbageCollected<GCed>(GetAllocationHandle()));
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
MutatorThreadMarkingVisitor visitor(GetMarker());
@ -94,7 +95,8 @@ TEST_F(MarkingVisitorTest, MarkPersistent) {
}
TEST_F(MarkingVisitorTest, MarkPersistentMixin) {
GCedWithMixin* object(MakeGarbageCollected<GCedWithMixin>(GetHeap()));
GCedWithMixin* object(
MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle()));
Persistent<Mixin> mixin(object);
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
@ -110,7 +112,7 @@ TEST_F(MarkingVisitorTest, MarkPersistentMixin) {
// Weak references are not marked.
TEST_F(MarkingVisitorTest, DontMarkWeakMember) {
WeakMember<GCed> object(MakeGarbageCollected<GCed>(GetHeap()));
WeakMember<GCed> object(MakeGarbageCollected<GCed>(GetAllocationHandle()));
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
MutatorThreadMarkingVisitor visitor(GetMarker());
@ -123,7 +125,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakMember) {
}
TEST_F(MarkingVisitorTest, DontMarkWeakMemberMixin) {
GCedWithMixin* object(MakeGarbageCollected<GCedWithMixin>(GetHeap()));
GCedWithMixin* object(
MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle()));
WeakMember<Mixin> mixin(object);
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
@ -137,7 +140,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakMemberMixin) {
}
TEST_F(MarkingVisitorTest, DontMarkWeakPersistent) {
WeakPersistent<GCed> object(MakeGarbageCollected<GCed>(GetHeap()));
WeakPersistent<GCed> object(
MakeGarbageCollected<GCed>(GetAllocationHandle()));
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
MutatorThreadMarkingVisitor visitor(GetMarker());
@ -150,7 +154,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakPersistent) {
}
TEST_F(MarkingVisitorTest, DontMarkWeakPersistentMixin) {
GCedWithMixin* object(MakeGarbageCollected<GCedWithMixin>(GetHeap()));
GCedWithMixin* object(
MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle()));
WeakPersistent<Mixin> mixin(object);
HeapObjectHeader& header = HeapObjectHeader::FromPayload(object);
@ -202,7 +207,8 @@ TEST_F(MarkingVisitorTest, DontMarkMemberInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithInConstructionCallback>(
GetHeap(), [&visitor](GCedWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](GCedWithInConstructionCallback* obj) {
Member<GCedWithInConstructionCallback> object(obj);
visitor.Trace(object);
});
@ -213,7 +219,8 @@ TEST_F(MarkingVisitorTest, DontMarkMemberMixinInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithMixinWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithMixinWithInConstructionCallback>(
GetHeap(), [&visitor](MixinWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](MixinWithInConstructionCallback* obj) {
Member<MixinWithInConstructionCallback> mixin(obj);
visitor.Trace(mixin);
});
@ -224,7 +231,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakMemberInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithInConstructionCallback>(
GetHeap(), [&visitor](GCedWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](GCedWithInConstructionCallback* obj) {
WeakMember<GCedWithInConstructionCallback> object(obj);
visitor.Trace(object);
});
@ -235,7 +243,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakMemberMixinInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithMixinWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithMixinWithInConstructionCallback>(
GetHeap(), [&visitor](MixinWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](MixinWithInConstructionCallback* obj) {
WeakMember<MixinWithInConstructionCallback> mixin(obj);
visitor.Trace(mixin);
});
@ -246,7 +255,8 @@ TEST_F(MarkingVisitorTest, DontMarkPersistentInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithInConstructionCallback>(
GetHeap(), [&visitor](GCedWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](GCedWithInConstructionCallback* obj) {
Persistent<GCedWithInConstructionCallback> object(obj);
visitor.TraceRootForTesting(object, SourceLocation::Current());
});
@ -257,7 +267,8 @@ TEST_F(MarkingVisitorTest, DontMarkPersistentMixinInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithMixinWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithMixinWithInConstructionCallback>(
GetHeap(), [&visitor](MixinWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](MixinWithInConstructionCallback* obj) {
Persistent<MixinWithInConstructionCallback> mixin(obj);
visitor.TraceRootForTesting(mixin, SourceLocation::Current());
});
@ -268,7 +279,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakPersistentInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithInConstructionCallback>(
GetHeap(), [&visitor](GCedWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](GCedWithInConstructionCallback* obj) {
WeakPersistent<GCedWithInConstructionCallback> object(obj);
visitor.TraceRootForTesting(object, SourceLocation::Current());
});
@ -279,7 +291,8 @@ TEST_F(MarkingVisitorTest, DontMarkWeakPersistentMixinInConstruction) {
MutatorThreadMarkingVisitor visitor(GetMarker());
GCedWithMixinWithInConstructionCallback* gced =
MakeGarbageCollected<GCedWithMixinWithInConstructionCallback>(
GetHeap(), [&visitor](MixinWithInConstructionCallback* obj) {
GetAllocationHandle(),
[&visitor](MixinWithInConstructionCallback* obj) {
WeakPersistent<MixinWithInConstructionCallback> mixin(obj);
visitor.TraceRootForTesting(mixin, SourceLocation::Current());
});

View File

@ -87,7 +87,8 @@ TEST_F(MemberTest, Empty) {
template <template <typename> class MemberType>
void ClearTest(cppgc::Heap* heap) {
MemberType<GCed> member = MakeGarbageCollected<GCed>(heap);
MemberType<GCed> member =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_NE(nullptr, member.Get());
member.Clear();
EXPECT_EQ(nullptr, member.Get());
@ -102,7 +103,7 @@ TEST_F(MemberTest, Clear) {
template <template <typename> class MemberType>
void ReleaseTest(cppgc::Heap* heap) {
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType<GCed> member = gced;
EXPECT_NE(nullptr, member.Get());
GCed* raw = member.Release();
@ -120,8 +121,8 @@ TEST_F(MemberTest, Release) {
template <template <typename> class MemberType1,
template <typename> class MemberType2>
void SwapTest(cppgc::Heap* heap) {
GCed* gced1 = MakeGarbageCollected<GCed>(heap);
GCed* gced2 = MakeGarbageCollected<GCed>(heap);
GCed* gced1 = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
GCed* gced2 = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType1<GCed> member1 = gced1;
MemberType2<GCed> member2 = gced2;
EXPECT_EQ(gced1, member1.Get());
@ -148,23 +149,27 @@ template <template <typename> class MemberType1,
template <typename> class MemberType2>
void HeterogeneousConversionTest(cppgc::Heap* heap) {
{
MemberType1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
MemberType1<GCed> member1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType2<GCed> member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
MemberType1<DerivedGCed> member1 = MakeGarbageCollected<DerivedGCed>(heap);
MemberType1<DerivedGCed> member1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
MemberType2<GCed> member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
MemberType1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
MemberType1<GCed> member1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType2<GCed> member2;
member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
}
{
MemberType1<DerivedGCed> member1 = MakeGarbageCollected<DerivedGCed>(heap);
MemberType1<DerivedGCed> member1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
MemberType2<GCed> member2;
member2 = member1;
EXPECT_EQ(member1.Get(), member2.Get());
@ -188,25 +193,27 @@ template <template <typename> class MemberType,
template <typename> class PersistentType>
void PersistentConversionTest(cppgc::Heap* heap) {
{
PersistentType<GCed> persistent = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> persistent =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType<GCed> member = persistent;
EXPECT_EQ(persistent.Get(), member.Get());
}
{
PersistentType<DerivedGCed> persistent =
MakeGarbageCollected<DerivedGCed>(heap);
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
MemberType<GCed> member = persistent;
EXPECT_EQ(persistent.Get(), member.Get());
}
{
PersistentType<GCed> persistent = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> persistent =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType<GCed> member;
member = persistent;
EXPECT_EQ(persistent.Get(), member.Get());
}
{
PersistentType<DerivedGCed> persistent =
MakeGarbageCollected<DerivedGCed>(heap);
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
MemberType<GCed> member;
member = persistent;
EXPECT_EQ(persistent.Get(), member.Get());
@ -227,7 +234,7 @@ template <template <typename> class MemberType1,
template <typename> class MemberType2>
void EqualityTest(cppgc::Heap* heap) {
{
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType1<GCed> member1 = gced;
MemberType2<GCed> member2 = gced;
EXPECT_TRUE(member1 == member2);
@ -237,8 +244,10 @@ void EqualityTest(cppgc::Heap* heap) {
EXPECT_FALSE(member1 != member2);
}
{
MemberType1<GCed> member1 = MakeGarbageCollected<GCed>(heap);
MemberType2<GCed> member2 = MakeGarbageCollected<GCed>(heap);
MemberType1<GCed> member1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
MemberType2<GCed> member2 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_TRUE(member1 != member2);
EXPECT_FALSE(member1 == member2);
}
@ -260,7 +269,7 @@ TEST_F(MemberTest, EqualityTest) {
TEST_F(MemberTest, WriteBarrierTriggered) {
CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered = 0;
CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered = 0;
GCed* gced = MakeGarbageCollected<GCed>(GetHeap());
GCed* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
MemberWithCustomBarrier member1 = gced;
EXPECT_EQ(1u, CustomWriteBarrierPolicy::InitializingWriteBarriersTriggered);
EXPECT_EQ(0u, CustomWriteBarrierPolicy::AssigningWriteBarriersTriggered);
@ -290,7 +299,7 @@ TEST_F(MemberTest, CheckingPolicy) {
for (std::size_t i = 0; i < kElements; ++i) {
CustomCheckingPolicy::Cached.push_back(
MakeGarbageCollected<GCed>(GetHeap()));
MakeGarbageCollected<GCed>(GetAllocationHandle()));
}
MemberWithCustomChecking member;

View File

@ -114,7 +114,7 @@ TEST_F(PersistentTest, NullStateCtor) {
template <template <typename> class PersistentType>
void RawCtor(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
{
PersistentType<GCed> p = gced;
EXPECT_EQ(gced, p.Get());
@ -139,7 +139,8 @@ template <template <typename> class PersistentType>
void CopyCtor(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<GCed> p1 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
PersistentType<GCed> p2 = p1;
EXPECT_EQ(2u, GetRegion<PersistentType>(heap).NodesInUse());
@ -157,7 +158,8 @@ void CopyCtor(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<DerivedGCed> p1 = MakeGarbageCollected<DerivedGCed>(heap);
PersistentType<DerivedGCed> p1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
PersistentType<GCed> p2 = p1;
EXPECT_EQ(2u, GetRegion<PersistentType>(heap).NodesInUse());
@ -167,7 +169,8 @@ void CopyCtor(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
static constexpr size_t kSlots = 512u;
const PersistentType<GCed> prototype = MakeGarbageCollected<GCed>(heap);
const PersistentType<GCed> prototype =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
std::vector<PersistentType<GCed>> vector;
vector.reserve(kSlots);
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
@ -191,7 +194,7 @@ template <template <typename> class PersistentType>
void MoveCtor(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p1 = gced;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
PersistentType<GCed> p2 = std::move(p1);
@ -202,7 +205,8 @@ void MoveCtor(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<DerivedGCed> p1 = MakeGarbageCollected<DerivedGCed>(heap);
PersistentType<DerivedGCed> p1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
// Move ctor is not heterogeneous - fall back to copy ctor.
PersistentType<GCed> p2 = std::move(p1);
@ -233,7 +237,8 @@ template <template <typename> class PersistentType,
void MemberCtor(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
MemberType<GCed> m = MakeGarbageCollected<GCed>(heap);
MemberType<GCed> m =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p = m;
EXPECT_EQ(m.Get(), p.Get());
EXPECT_EQ(m, p);
@ -256,14 +261,16 @@ template <template <typename> class PersistentType>
void NullStateAssignemnt(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<GCed> p = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p = nullptr;
EXPECT_EQ(nullptr, p.Get());
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
}
{
PersistentType<GCed> p = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p = kSentinelPointer;
EXPECT_EQ(kSentinelPointer, p);
@ -271,7 +278,8 @@ void NullStateAssignemnt(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
}
{
PersistentType<GCed> p = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p = static_cast<GCed*>(0);
EXPECT_EQ(nullptr, p.Get());
@ -288,7 +296,7 @@ TEST_F(PersistentTest, NullStateAssignemnt) {
template <template <typename> class PersistentType>
void RawAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
{
PersistentType<GCed> p;
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
@ -317,7 +325,8 @@ template <template <typename> class PersistentType>
void CopyAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<GCed> p1 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p2;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p2 = p1;
@ -327,8 +336,10 @@ void CopyAssignment(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<GCed> p1 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p2 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p2 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(2u, GetRegion<PersistentType>(heap).NodesInUse());
p2 = p1;
// The old node from p2 must be dropped.
@ -338,7 +349,8 @@ void CopyAssignment(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<DerivedGCed> p1 = MakeGarbageCollected<DerivedGCed>(heap);
PersistentType<DerivedGCed> p1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
PersistentType<GCed> p2;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p2 = p1;
@ -349,7 +361,8 @@ void CopyAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
static constexpr size_t kSlots = 512u;
const PersistentType<GCed> prototype = MakeGarbageCollected<GCed>(heap);
const PersistentType<GCed> prototype =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
std::vector<PersistentType<GCed>> vector(kSlots);
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
size_t i = 0;
@ -374,7 +387,7 @@ template <template <typename> class PersistentType>
void MoveAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p1 = gced;
PersistentType<GCed> p2;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
@ -387,7 +400,8 @@ void MoveAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<GCed> p1;
PersistentType<GCed> p2 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p2 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
p2 = std::move(p1);
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
@ -396,9 +410,10 @@ void MoveAssignment(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p1 = gced;
PersistentType<GCed> p2 = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p2 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(2u, GetRegion<PersistentType>(heap).NodesInUse());
p2 = std::move(p1);
// The old node from p2 must be dropped.
@ -409,7 +424,8 @@ void MoveAssignment(cppgc::Heap* heap) {
}
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
PersistentType<DerivedGCed> p1 = MakeGarbageCollected<DerivedGCed>(heap);
PersistentType<DerivedGCed> p1 =
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
PersistentType<GCed> p2;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
// Move ctor is not heterogeneous - fall back to copy assignment.
@ -432,7 +448,8 @@ template <template <typename> class PersistentType,
void MemberAssignment(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
{
MemberType<GCed> m = MakeGarbageCollected<GCed>(heap);
MemberType<GCed> m =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p;
p = m;
EXPECT_EQ(m.Get(), p.Get());
@ -455,7 +472,8 @@ TEST_F(PersistentTest, MemberAssignment) {
template <template <typename> class PersistentType>
void ClearTest(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
PersistentType<GCed> p = MakeGarbageCollected<GCed>(heap);
PersistentType<GCed> p =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
EXPECT_NE(nullptr, p.Get());
p.Clear();
@ -472,7 +490,7 @@ TEST_F(PersistentTest, Clear) {
template <template <typename> class PersistentType>
void ReleaseTest(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType>(heap).NodesInUse());
GCed* gced = MakeGarbageCollected<GCed>(heap);
GCed* gced = MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType<GCed> p = gced;
EXPECT_EQ(1u, GetRegion<PersistentType>(heap).NodesInUse());
EXPECT_NE(nullptr, p.Get());
@ -494,7 +512,8 @@ void HeterogeneousConversion(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType1>(heap).NodesInUse());
EXPECT_EQ(0u, GetRegion<PersistentType2>(heap).NodesInUse());
{
PersistentType1<GCed> persistent1 = MakeGarbageCollected<GCed>(heap);
PersistentType1<GCed> persistent1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType2<GCed> persistent2 = persistent1;
EXPECT_EQ(persistent1.Get(), persistent2.Get());
EXPECT_EQ(1u, GetRegion<PersistentType1>(heap).NodesInUse());
@ -504,7 +523,7 @@ void HeterogeneousConversion(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType2>(heap).NodesInUse());
{
PersistentType1<DerivedGCed> persistent1 =
MakeGarbageCollected<DerivedGCed>(heap);
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
PersistentType2<GCed> persistent2 = persistent1;
EXPECT_EQ(persistent1.Get(), persistent2.Get());
EXPECT_EQ(1u, GetRegion<PersistentType1>(heap).NodesInUse());
@ -513,7 +532,8 @@ void HeterogeneousConversion(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType1>(heap).NodesInUse());
EXPECT_EQ(0u, GetRegion<PersistentType2>(heap).NodesInUse());
{
PersistentType1<GCed> persistent1 = MakeGarbageCollected<GCed>(heap);
PersistentType1<GCed> persistent1 =
MakeGarbageCollected<GCed>(heap->GetAllocationHandle());
PersistentType2<GCed> persistent2;
persistent2 = persistent1;
EXPECT_EQ(persistent1.Get(), persistent2.Get());
@ -524,7 +544,7 @@ void HeterogeneousConversion(cppgc::Heap* heap) {
EXPECT_EQ(0u, GetRegion<PersistentType2>(heap).NodesInUse());
{
PersistentType1<DerivedGCed> persistent1 =
MakeGarbageCollected<DerivedGCed>(heap);
MakeGarbageCollected<DerivedGCed>(heap->GetAllocationHandle());
PersistentType2<GCed> persistent2;
persistent2 = persistent1;
EXPECT_EQ(persistent1.Get(), persistent2.Get());
@ -546,7 +566,7 @@ TEST_F(PersistentTest, TraceStrong) {
static constexpr size_t kItems = 512;
std::vector<Persistent<GCed>> vec(kItems);
for (auto& p : vec) {
p = MakeGarbageCollected<GCed>(heap);
p = MakeGarbageCollected<GCed>(GetAllocationHandle());
}
{
GCed::trace_call_count = 0;
@ -581,7 +601,7 @@ TEST_F(PersistentTest, TraceWeak) {
static constexpr size_t kItems = 512;
std::vector<WeakPersistent<GCed>> vec(kItems);
for (auto& p : vec) {
p = MakeGarbageCollected<GCed>(heap);
p = MakeGarbageCollected<GCed>(GetAllocationHandle());
}
GCed::trace_call_count = 0;
RootVisitor v;
@ -599,7 +619,7 @@ TEST_F(PersistentTest, TraceWeak) {
#if CPPGC_SUPPORTS_SOURCE_LOCATION
TEST_F(PersistentTest, LocalizedPersistent) {
GCed* gced = MakeGarbageCollected<GCed>(GetHeap());
GCed* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
{
const auto expected_loc = SourceLocation::Current();
LocalizedPersistent<GCed> p = gced;

View File

@ -33,7 +33,7 @@ size_t GCed::prefinalizer_callcount = 0;
TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadObject) {
GCed::prefinalizer_callcount = 0;
auto* object = MakeGarbageCollected<GCed>(GetHeap());
auto* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
USE(object);
EXPECT_EQ(0u, GCed::prefinalizer_callcount);
PreciseGC();
@ -44,7 +44,7 @@ TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadObject) {
TEST_F(PrefinalizerTest, PrefinalizerNotCalledOnLiveObject) {
GCed::prefinalizer_callcount = 0;
auto* object = MakeGarbageCollected<GCed>(GetHeap());
auto* object = MakeGarbageCollected<GCed>(GetAllocationHandle());
HeapObjectHeader::FromPayload(object).TryMarkAtomic();
EXPECT_EQ(0u, GCed::prefinalizer_callcount);
PreciseGC();
@ -73,7 +73,7 @@ class GCedWithMixin : public GarbageCollected<GCedWithMixin>, public Mixin {
TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadMixinObject) {
Mixin::prefinalizer_callcount = 0;
auto* object = MakeGarbageCollected<GCedWithMixin>(GetHeap());
auto* object = MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle());
USE(object);
EXPECT_EQ(0u, Mixin::prefinalizer_callcount);
PreciseGC();
@ -84,7 +84,7 @@ TEST_F(PrefinalizerTest, PrefinalizerCalledOnDeadMixinObject) {
TEST_F(PrefinalizerTest, PrefinalizerNotCalledOnLiveMixinObject) {
Mixin::prefinalizer_callcount = 0;
auto* object = MakeGarbageCollected<GCedWithMixin>(GetHeap());
auto* object = MakeGarbageCollected<GCedWithMixin>(GetAllocationHandle());
HeapObjectHeader::FromPayload(object).TryMarkAtomic();
EXPECT_EQ(0u, Mixin::prefinalizer_callcount);
PreciseGC();
@ -153,7 +153,7 @@ TEST_F(PrefinalizerTest, PrefinalizerInvocationPreservesOrder) {
BaseMixin::prefinalizer_callcount = 0;
InheritingMixin::prefinalizer_callcount = 0;
GCedWithMixins::prefinalizer_callcount = 0;
auto* object = MakeGarbageCollected<GCedWithMixins>(GetHeap());
auto* object = MakeGarbageCollected<GCedWithMixins>(GetAllocationHandle());
USE(object);
EXPECT_EQ(0u, GCedWithMixins::prefinalizer_callcount);
EXPECT_EQ(0u, InheritingMixin::prefinalizer_callcount);
@ -176,7 +176,9 @@ class AllocatingPrefinalizer : public GarbageCollected<AllocatingPrefinalizer> {
public:
explicit AllocatingPrefinalizer(cppgc::Heap* heap) : heap_(heap) {}
void Trace(Visitor*) const {}
void PreFinalizer() { MakeGarbageCollected<GCed>(heap_); }
void PreFinalizer() {
MakeGarbageCollected<GCed>(heap_->GetAllocationHandle());
}
private:
cppgc::Heap* heap_;
@ -187,8 +189,8 @@ class AllocatingPrefinalizer : public GarbageCollected<AllocatingPrefinalizer> {
#ifdef DEBUG
TEST_F(PrefinalizerTest, PrefinalizerFailsOnAllcoation) {
auto* object =
MakeGarbageCollected<AllocatingPrefinalizer>(GetHeap(), GetHeap());
auto* object = MakeGarbageCollected<AllocatingPrefinalizer>(
GetAllocationHandle(), GetHeap());
USE(object);
EXPECT_DEATH_IF_SUPPORTED(PreciseGC(), "");
}

View File

@ -68,7 +68,7 @@ TEST_F(SweeperTest, SweepUnmarkedNormalObject) {
constexpr size_t kObjectSize = 8;
using Type = GCed<kObjectSize>;
MakeGarbageCollected<Type>(GetHeap());
MakeGarbageCollected<Type>(GetAllocationHandle());
EXPECT_EQ(0u, g_destructor_callcount);
@ -81,7 +81,7 @@ TEST_F(SweeperTest, DontSweepMarkedNormalObject) {
constexpr size_t kObjectSize = 8;
using Type = GCed<kObjectSize>;
auto* object = MakeGarbageCollected<Type>(GetHeap());
auto* object = MakeGarbageCollected<Type>(GetAllocationHandle());
MarkObject(object);
BasePage* page = BasePage::FromPayload(object);
BaseSpace* space = page->space();
@ -100,7 +100,7 @@ TEST_F(SweeperTest, SweepUnmarkedLargeObject) {
constexpr size_t kObjectSize = kLargeObjectSizeThreshold * 2;
using Type = GCed<kObjectSize>;
auto* object = MakeGarbageCollected<Type>(GetHeap());
auto* object = MakeGarbageCollected<Type>(GetAllocationHandle());
BasePage* page = BasePage::FromPayload(object);
BaseSpace* space = page->space();
@ -118,7 +118,7 @@ TEST_F(SweeperTest, DontSweepMarkedLargeObject) {
constexpr size_t kObjectSize = kLargeObjectSizeThreshold * 2;
using Type = GCed<kObjectSize>;
auto* object = MakeGarbageCollected<Type>(GetHeap());
auto* object = MakeGarbageCollected<Type>(GetAllocationHandle());
MarkObject(object);
BasePage* page = BasePage::FromPayload(object);
BaseSpace* space = page->space();
@ -140,7 +140,7 @@ TEST_F(SweeperTest, SweepMultipleObjectsOnPage) {
NormalPage::PayloadSize() / (sizeof(Type) + sizeof(HeapObjectHeader));
for (size_t i = 0; i < kNumberOfObjects; ++i) {
MakeGarbageCollected<Type>(GetHeap());
MakeGarbageCollected<Type>(GetAllocationHandle());
}
EXPECT_EQ(0u, g_destructor_callcount);
@ -151,11 +151,12 @@ TEST_F(SweeperTest, SweepMultipleObjectsOnPage) {
}
TEST_F(SweeperTest, SweepObjectsOnAllArenas) {
MakeGarbageCollected<GCed<1>>(GetHeap());
MakeGarbageCollected<GCed<32>>(GetHeap());
MakeGarbageCollected<GCed<64>>(GetHeap());
MakeGarbageCollected<GCed<128>>(GetHeap());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
MakeGarbageCollected<GCed<1>>(GetAllocationHandle());
MakeGarbageCollected<GCed<32>>(GetAllocationHandle());
MakeGarbageCollected<GCed<64>>(GetAllocationHandle());
MakeGarbageCollected<GCed<128>>(GetAllocationHandle());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
EXPECT_EQ(0u, g_destructor_callcount);
@ -165,9 +166,12 @@ TEST_F(SweeperTest, SweepObjectsOnAllArenas) {
}
TEST_F(SweeperTest, SweepMultiplePagesInSingleSpace) {
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(GetHeap());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
MakeGarbageCollected<GCed<2 * kLargeObjectSizeThreshold>>(
GetAllocationHandle());
EXPECT_EQ(0u, g_destructor_callcount);
@ -180,10 +184,10 @@ TEST_F(SweeperTest, CoalesceFreeListEntries) {
constexpr size_t kObjectSize = 32;
using Type = GCed<kObjectSize>;
auto* object1 = MakeGarbageCollected<Type>(GetHeap());
auto* object2 = MakeGarbageCollected<Type>(GetHeap());
auto* object3 = MakeGarbageCollected<Type>(GetHeap());
auto* object4 = MakeGarbageCollected<Type>(GetHeap());
auto* object1 = MakeGarbageCollected<Type>(GetAllocationHandle());
auto* object2 = MakeGarbageCollected<Type>(GetAllocationHandle());
auto* object3 = MakeGarbageCollected<Type>(GetAllocationHandle());
auto* object4 = MakeGarbageCollected<Type>(GetAllocationHandle());
MarkObject(object1);
MarkObject(object4);
@ -231,15 +235,16 @@ class GCInDestructor final : public GarbageCollected<GCInDestructor> {
TEST_F(SweeperTest, SweepDoesNotTriggerRecursiveGC) {
auto* internal_heap = internal::Heap::From(GetHeap());
size_t saved_epoch = internal_heap->epoch();
MakeGarbageCollected<GCInDestructor>(GetHeap(), internal_heap);
MakeGarbageCollected<GCInDestructor>(GetAllocationHandle(), internal_heap);
PreciseGC();
EXPECT_EQ(saved_epoch + 1, internal_heap->epoch());
}
TEST_F(SweeperTest, UnmarkObjects) {
auto* normal_object = MakeGarbageCollected<GCed<32>>(GetHeap());
auto* normal_object = MakeGarbageCollected<GCed<32>>(GetAllocationHandle());
auto* large_object =
MakeGarbageCollected<GCed<kLargeObjectSizeThreshold * 2>>(GetHeap());
MakeGarbageCollected<GCed<kLargeObjectSizeThreshold * 2>>(
GetAllocationHandle());
auto& normal_object_header = HeapObjectHeader::FromPayload(normal_object);
auto& large_object_header = HeapObjectHeader::FromPayload(large_object);

View File

@ -28,7 +28,9 @@ void TestWithPlatform::TearDownTestSuite() {
platform_.reset();
}
TestWithHeap::TestWithHeap() : heap_(Heap::Create(platform_)) {}
TestWithHeap::TestWithHeap()
: heap_(Heap::Create(platform_)),
allocation_handle_(heap_->GetAllocationHandle()) {}
void TestWithHeap::ResetLinearAllocationBuffers() {
Heap::From(GetHeap())->object_allocator().ResetLinearAllocationBuffers();

View File

@ -37,6 +37,10 @@ class TestWithHeap : public TestWithPlatform {
cppgc::Heap* GetHeap() const { return heap_.get(); }
cppgc::AllocationHandle& GetAllocationHandle() const {
return allocation_handle_;
}
std::unique_ptr<Marker>& GetMarkerRef() {
return Heap::From(GetHeap())->marker_;
}
@ -45,6 +49,7 @@ class TestWithHeap : public TestWithPlatform {
private:
std::unique_ptr<cppgc::Heap> heap_;
cppgc::AllocationHandle& allocation_handle_;
};
// Restrictive test fixture that supports allocation but will make sure no

View File

@ -53,13 +53,14 @@ class GCedMixinApplication : public GCed,
} // namespace
TEST_F(TraceTraitTest, GetObjectStartGCed) {
auto* gced = MakeGarbageCollected<GCed>(GetHeap());
auto* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_EQ(gced,
TraceTrait<GCed>::GetTraceDescriptor(gced).base_object_payload);
}
TEST_F(TraceTraitTest, GetObjectStartGCedMixin) {
auto* gced_mixin_app = MakeGarbageCollected<GCedMixinApplication>(GetHeap());
auto* gced_mixin_app =
MakeGarbageCollected<GCedMixinApplication>(GetAllocationHandle());
auto* gced_mixin = static_cast<GCedMixin*>(gced_mixin_app);
EXPECT_EQ(gced_mixin_app,
TraceTrait<GCedMixin>::GetTraceDescriptor(gced_mixin)
@ -67,14 +68,15 @@ TEST_F(TraceTraitTest, GetObjectStartGCedMixin) {
}
TEST_F(TraceTraitTest, TraceGCed) {
auto* gced = MakeGarbageCollected<GCed>(GetHeap());
auto* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_EQ(0u, GCed::trace_callcount);
TraceTrait<GCed>::Trace(nullptr, gced);
EXPECT_EQ(1u, GCed::trace_callcount);
}
TEST_F(TraceTraitTest, TraceGCedMixin) {
auto* gced_mixin_app = MakeGarbageCollected<GCedMixinApplication>(GetHeap());
auto* gced_mixin_app =
MakeGarbageCollected<GCedMixinApplication>(GetAllocationHandle());
auto* gced_mixin = static_cast<GCedMixin*>(gced_mixin_app);
EXPECT_EQ(0u, GCed::trace_callcount);
TraceTrait<GCedMixin>::Trace(nullptr, gced_mixin);
@ -82,7 +84,7 @@ TEST_F(TraceTraitTest, TraceGCedMixin) {
}
TEST_F(TraceTraitTest, TraceGCedThroughTraceDescriptor) {
auto* gced = MakeGarbageCollected<GCed>(GetHeap());
auto* gced = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_EQ(0u, GCed::trace_callcount);
TraceDescriptor desc = TraceTrait<GCed>::GetTraceDescriptor(gced);
desc.callback(nullptr, desc.base_object_payload);
@ -90,7 +92,8 @@ TEST_F(TraceTraitTest, TraceGCedThroughTraceDescriptor) {
}
TEST_F(TraceTraitTest, TraceGCedMixinThroughTraceDescriptor) {
auto* gced_mixin_app = MakeGarbageCollected<GCedMixinApplication>(GetHeap());
auto* gced_mixin_app =
MakeGarbageCollected<GCedMixinApplication>(GetAllocationHandle());
auto* gced_mixin = static_cast<GCedMixin*>(gced_mixin_app);
EXPECT_EQ(0u, GCed::trace_callcount);
TraceDescriptor desc = TraceTrait<GCedMixin>::GetTraceDescriptor(gced_mixin);
@ -128,7 +131,7 @@ class DispatchingVisitor final : public VisitorBase {
} // namespace
TEST_F(VisitorTest, DispatchTraceGCed) {
Member<GCed> ref = MakeGarbageCollected<GCed>(GetHeap());
Member<GCed> ref = MakeGarbageCollected<GCed>(GetAllocationHandle());
DispatchingVisitor visitor(ref, ref);
EXPECT_EQ(0u, GCed::trace_callcount);
visitor.Trace(ref);
@ -136,7 +139,8 @@ TEST_F(VisitorTest, DispatchTraceGCed) {
}
TEST_F(VisitorTest, DispatchTraceGCedMixin) {
auto* gced_mixin_app = MakeGarbageCollected<GCedMixinApplication>(GetHeap());
auto* gced_mixin_app =
MakeGarbageCollected<GCedMixinApplication>(GetAllocationHandle());
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));
@ -148,7 +152,7 @@ TEST_F(VisitorTest, DispatchTraceGCedMixin) {
}
TEST_F(VisitorTest, DispatchTraceWeakGCed) {
WeakMember<GCed> ref = MakeGarbageCollected<GCed>(GetHeap());
WeakMember<GCed> ref = MakeGarbageCollected<GCed>(GetAllocationHandle());
DispatchingVisitor visitor(ref, ref);
visitor.Trace(ref);
// No marking, so reference should be cleared.
@ -156,7 +160,8 @@ TEST_F(VisitorTest, DispatchTraceWeakGCed) {
}
TEST_F(VisitorTest, DispatchTraceWeakGCedMixin) {
auto* gced_mixin_app = MakeGarbageCollected<GCedMixinApplication>(GetHeap());
auto* gced_mixin_app =
MakeGarbageCollected<GCedMixinApplication>(GetAllocationHandle());
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));
@ -221,7 +226,8 @@ TEST_F(VisitorTest, DispatchRegisterWeakCallback) {
TEST_F(VisitorTest, DispatchRegisterWeakCallbackMethod) {
WeakCallbackVisitor visitor;
auto* gced = MakeGarbageCollected<GCedWithCustomWeakCallback>(GetHeap());
auto* gced =
MakeGarbageCollected<GCedWithCustomWeakCallback>(GetAllocationHandle());
WeakCallbackDispatcher::Setup(gced);
EXPECT_EQ(0u, WeakCallbackDispatcher::callback_callcount);
gced->Trace(&visitor);
@ -250,7 +256,7 @@ class GCedWithComposite final : public GarbageCollected<GCedWithComposite> {
TEST_F(VisitorTest, DispatchToCompositeObject) {
Member<GCedWithComposite> ref =
MakeGarbageCollected<GCedWithComposite>(GetHeap());
MakeGarbageCollected<GCedWithComposite>(GetAllocationHandle());
DispatchingVisitor visitor(ref, ref);
EXPECT_EQ(0u, Composite::callback_callcount);
visitor.Trace(ref);

View File

@ -170,8 +170,8 @@ TEST_F(WriteBarrierTest, EnableDisableIncrementalMarking) {
}
TEST_F(WriteBarrierTest, TriggersWhenMarkingIsOn) {
auto* object1 = MakeGarbageCollected<GCed>(GetHeap());
auto* object2 = MakeGarbageCollected<GCed>(GetHeap());
auto* object1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
auto* object2 = MakeGarbageCollected<GCed>(GetAllocationHandle());
{
ExpectWriteBarrierFires scope(marker(), {object1});
EXPECT_FALSE(object1->IsMarked());
@ -181,16 +181,16 @@ TEST_F(WriteBarrierTest, TriggersWhenMarkingIsOn) {
}
TEST_F(WriteBarrierTest, BailoutWhenMarkingIsOff) {
auto* object1 = MakeGarbageCollected<GCed>(GetHeap());
auto* object2 = MakeGarbageCollected<GCed>(GetHeap());
auto* object1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
auto* object2 = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_FALSE(object1->IsMarked());
object2->set_next(object1);
EXPECT_FALSE(object1->IsMarked());
}
TEST_F(WriteBarrierTest, BailoutIfMarked) {
auto* object1 = MakeGarbageCollected<GCed>(GetHeap());
auto* object2 = MakeGarbageCollected<GCed>(GetHeap());
auto* object1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
auto* object2 = MakeGarbageCollected<GCed>(GetAllocationHandle());
EXPECT_TRUE(HeapObjectHeader::FromPayload(object1).TryMarkAtomic());
{
ExpectNoWriteBarrierFires scope(marker(), {object1});
@ -199,18 +199,18 @@ TEST_F(WriteBarrierTest, BailoutIfMarked) {
}
TEST_F(WriteBarrierTest, MemberInitializingStoreNoBarrier) {
auto* object1 = MakeGarbageCollected<GCed>(GetHeap());
auto* object1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
{
ExpectNoWriteBarrierFires scope(marker(), {object1});
auto* object2 = MakeGarbageCollected<GCed>(GetHeap(), object1);
auto* object2 = MakeGarbageCollected<GCed>(GetAllocationHandle(), object1);
HeapObjectHeader& object2_header = HeapObjectHeader::FromPayload(object2);
EXPECT_FALSE(object2_header.IsMarked());
}
}
TEST_F(WriteBarrierTest, MemberReferenceAssignMember) {
auto* obj = MakeGarbageCollected<GCed>(GetHeap());
auto* ref_obj = MakeGarbageCollected<GCed>(GetHeap());
auto* obj = MakeGarbageCollected<GCed>(GetAllocationHandle());
auto* ref_obj = MakeGarbageCollected<GCed>(GetAllocationHandle());
Member<GCed>& m2 = ref_obj->next_ref();
Member<GCed> m3(obj);
{
@ -220,7 +220,7 @@ TEST_F(WriteBarrierTest, MemberReferenceAssignMember) {
}
TEST_F(WriteBarrierTest, MemberSetSentinelValueNoBarrier) {
auto* obj = MakeGarbageCollected<GCed>(GetHeap());
auto* obj = MakeGarbageCollected<GCed>(GetAllocationHandle());
Member<GCed>& m = obj->next_ref();
{
ExpectNoWriteBarrierFires scope(marker(), {});
@ -229,12 +229,12 @@ TEST_F(WriteBarrierTest, MemberSetSentinelValueNoBarrier) {
}
TEST_F(WriteBarrierTest, MemberCopySentinelValueNoBarrier) {
auto* obj1 = MakeGarbageCollected<GCed>(GetHeap());
auto* obj1 = MakeGarbageCollected<GCed>(GetAllocationHandle());
Member<GCed>& m1 = obj1->next_ref();
m1 = kSentinelPointer;
{
ExpectNoWriteBarrierFires scope(marker(), {});
auto* obj2 = MakeGarbageCollected<GCed>(GetHeap());
auto* obj2 = MakeGarbageCollected<GCed>(GetAllocationHandle());
obj2->next_ref() = m1;
}
}
@ -291,8 +291,8 @@ class ParentWithMixinPointer : public GarbageCollected<ParentWithMixinPointer> {
TEST_F(WriteBarrierTest, WriteBarrierOnUnmarkedMixinApplication) {
ParentWithMixinPointer* parent =
MakeGarbageCollected<ParentWithMixinPointer>(GetHeap());
auto* child = MakeGarbageCollected<Child>(GetHeap());
MakeGarbageCollected<ParentWithMixinPointer>(GetAllocationHandle());
auto* child = MakeGarbageCollected<Child>(GetAllocationHandle());
Mixin* mixin = static_cast<Mixin*>(child);
EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
{
@ -303,8 +303,8 @@ TEST_F(WriteBarrierTest, WriteBarrierOnUnmarkedMixinApplication) {
TEST_F(WriteBarrierTest, NoWriteBarrierOnMarkedMixinApplication) {
ParentWithMixinPointer* parent =
MakeGarbageCollected<ParentWithMixinPointer>(GetHeap());
auto* child = MakeGarbageCollected<Child>(GetHeap());
MakeGarbageCollected<ParentWithMixinPointer>(GetAllocationHandle());
auto* child = MakeGarbageCollected<Child>(GetAllocationHandle());
EXPECT_TRUE(HeapObjectHeader::FromPayload(child).TryMarkAtomic());
Mixin* mixin = static_cast<Mixin*>(child);
EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));