Commit 4d5ab15d authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

cppgc: Mark custom spaces as compactable

To support compaction of backing stores in blink, we need to distinguish
custom spaces holding backing stores from other custom spaces.
Custom space compactablity is explicitly declared as an enum value and
propagated to BaseSpace as a bool flag.

Note that even if/when general compaction is implemented/enabled for
normal pages we will still need such a marking for supporting
non-compactable custom spaces.

Bug: v8:10990
Change-Id: I165a0268ded121e91399834a4091e88e57f2565c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2449973
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70345}
parent a282d2e9
......@@ -14,6 +14,8 @@ struct CustomSpaceIndex {
size_t value;
};
enum class CustomSpaceCompactability { kNotCompactable, kCompactable };
/**
* Top-level base class for custom spaces. Users must inherit from CustomSpace
* below.
......@@ -22,6 +24,7 @@ class CustomSpaceBase {
public:
virtual ~CustomSpaceBase() = default;
virtual CustomSpaceIndex GetCustomSpaceIndex() const = 0;
virtual bool IsCompactable() const = 0;
};
/**
......@@ -47,6 +50,12 @@ class CustomSpace : public CustomSpaceBase {
CustomSpaceIndex GetCustomSpaceIndex() const final {
return ConcreteCustomSpace::kSpaceIndex;
}
bool IsCompactable() const final {
return ConcreteCustomSpace::kSupportsCompaction;
}
protected:
static constexpr bool kSupportsCompaction = false;
};
/**
......
......@@ -105,7 +105,9 @@ void UnifiedHeapMarker::AddObject(void* object) {
} // namespace
CppHeap::CppHeap(v8::Isolate* isolate, size_t custom_spaces)
CppHeap::CppHeap(
v8::Isolate* isolate,
const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>& custom_spaces)
: cppgc::internal::HeapBase(std::make_shared<CppgcPlatformAdapter>(isolate),
custom_spaces,
cppgc::internal::HeapBase::StackSupport::
......
......@@ -19,7 +19,9 @@ namespace internal {
class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
public v8::EmbedderHeapTracer {
public:
CppHeap(v8::Isolate* isolate, size_t custom_spaces);
CppHeap(v8::Isolate* isolate,
const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>&
custom_spaces);
HeapBase& AsBase() { return *this; }
const HeapBase& AsBase() const { return *this; }
......
......@@ -53,8 +53,10 @@ class ObjectSizeCounter : private HeapVisitor<ObjectSizeCounter> {
} // namespace
HeapBase::HeapBase(std::shared_ptr<cppgc::Platform> platform,
size_t custom_spaces, StackSupport stack_support)
HeapBase::HeapBase(
std::shared_ptr<cppgc::Platform> platform,
const std::vector<std::unique_ptr<CustomSpaceBase>>& custom_spaces,
StackSupport stack_support)
: raw_heap_(this, custom_spaces),
platform_(std::move(platform)),
#if defined(CPPGC_CAGED_HEAP)
......
......@@ -62,7 +62,8 @@ class V8_EXPORT_PRIVATE HeapBase {
HeapBase& heap_;
};
HeapBase(std::shared_ptr<cppgc::Platform> platform, size_t custom_spaces,
HeapBase(std::shared_ptr<cppgc::Platform> platform,
const std::vector<std::unique_ptr<CustomSpaceBase>>& custom_spaces,
StackSupport stack_support);
virtual ~HeapBase();
......
......@@ -14,8 +14,11 @@
namespace cppgc {
namespace internal {
BaseSpace::BaseSpace(RawHeap* heap, size_t index, PageType type)
: heap_(heap), index_(index), type_(type) {}
BaseSpace::BaseSpace(RawHeap* heap, size_t index, PageType type,
bool is_compactable)
: heap_(heap), index_(index), type_(type), is_compactable_(is_compactable) {
USE(is_compactable_);
}
void BaseSpace::AddPage(BasePage* page) {
v8::base::LockGuard<v8::base::Mutex> lock(&pages_mutex_);
......@@ -36,11 +39,12 @@ BaseSpace::Pages BaseSpace::RemoveAllPages() {
return pages;
}
NormalPageSpace::NormalPageSpace(RawHeap* heap, size_t index)
: BaseSpace(heap, index, PageType::kNormal) {}
NormalPageSpace::NormalPageSpace(RawHeap* heap, size_t index,
bool is_compactable)
: BaseSpace(heap, index, PageType::kNormal, is_compactable) {}
LargePageSpace::LargePageSpace(RawHeap* heap, size_t index)
: BaseSpace(heap, index, PageType::kLarge) {}
: BaseSpace(heap, index, PageType::kLarge, false /* is_compactable */) {}
} // namespace internal
} // namespace cppgc
......@@ -47,9 +47,12 @@ class V8_EXPORT_PRIVATE BaseSpace {
void RemovePage(BasePage*);
Pages RemoveAllPages();
bool is_compactable() const { return is_compactable_; }
protected:
enum class PageType { kNormal, kLarge };
explicit BaseSpace(RawHeap* heap, size_t index, PageType type);
explicit BaseSpace(RawHeap* heap, size_t index, PageType type,
bool is_compactable);
private:
RawHeap* heap_;
......@@ -57,6 +60,7 @@ class V8_EXPORT_PRIVATE BaseSpace {
v8::base::Mutex pages_mutex_;
const size_t index_;
const PageType type_;
const bool is_compactable_;
};
class V8_EXPORT_PRIVATE NormalPageSpace final : public BaseSpace {
......@@ -92,7 +96,7 @@ class V8_EXPORT_PRIVATE NormalPageSpace final : public BaseSpace {
return From(const_cast<BaseSpace*>(space));
}
NormalPageSpace(RawHeap* heap, size_t index);
NormalPageSpace(RawHeap* heap, size_t index, bool is_compactable);
LinearAllocationBuffer& linear_allocation_buffer() { return current_lab_; }
const LinearAllocationBuffer& linear_allocation_buffer() const {
......
......@@ -77,7 +77,7 @@ void CheckConfig(Heap::Config config) {
Heap::Heap(std::shared_ptr<cppgc::Platform> platform,
cppgc::Heap::HeapOptions options)
: HeapBase(platform, options.custom_spaces.size(), options.stack_support),
: HeapBase(platform, options.custom_spaces, options.stack_support),
gc_invoker_(this, platform_.get(), options.stack_support),
growing_(&gc_invoker_, stats_collector_.get(),
options.resource_constraints) {}
......
......@@ -12,17 +12,20 @@ namespace internal {
// static
constexpr size_t RawHeap::kNumberOfRegularSpaces;
RawHeap::RawHeap(HeapBase* heap, size_t custom_spaces) : main_heap_(heap) {
RawHeap::RawHeap(
HeapBase* heap,
const std::vector<std::unique_ptr<CustomSpaceBase>>& custom_spaces)
: main_heap_(heap) {
size_t i = 0;
for (; i < static_cast<size_t>(RegularSpaceType::kLarge); ++i) {
spaces_.push_back(std::make_unique<NormalPageSpace>(this, i));
spaces_.push_back(std::make_unique<NormalPageSpace>(this, i, false));
}
spaces_.push_back(std::make_unique<LargePageSpace>(
this, static_cast<size_t>(RegularSpaceType::kLarge)));
DCHECK_EQ(kNumberOfRegularSpaces, spaces_.size());
for (size_t j = 0; j < custom_spaces; j++) {
spaces_.push_back(
std::make_unique<NormalPageSpace>(this, kNumberOfRegularSpaces + j));
for (size_t j = 0; j < custom_spaces.size(); j++) {
spaces_.push_back(std::make_unique<NormalPageSpace>(
this, kNumberOfRegularSpaces + j, custom_spaces[j]->IsCompactable()));
}
}
......
......@@ -47,7 +47,8 @@ class V8_EXPORT_PRIVATE RawHeap final {
using iterator = Spaces::iterator;
using const_iterator = Spaces::const_iterator;
explicit RawHeap(HeapBase* heap, size_t custom_spaces);
RawHeap(HeapBase* heap,
const std::vector<std::unique_ptr<CustomSpaceBase>>& custom_spaces);
RawHeap(const RawHeap&) = delete;
RawHeap& operator=(const RawHeap&) = delete;
......
......@@ -141,4 +141,106 @@ TEST_F(TestWithHeapWithCustomSpaces, SweepCustomSpace) {
}
} // namespace internal
// Test custom space compactability.
class CompactableCustomSpace : public CustomSpace<CompactableCustomSpace> {
public:
static constexpr size_t kSpaceIndex = 0;
static constexpr bool kSupportsCompaction = true;
};
class NotCompactableCustomSpace
: public CustomSpace<NotCompactableCustomSpace> {
public:
static constexpr size_t kSpaceIndex = 1;
static constexpr bool kSupportsCompaction = false;
};
class DefaultCompactableCustomSpace
: public CustomSpace<DefaultCompactableCustomSpace> {
public:
static constexpr size_t kSpaceIndex = 2;
// By default space are not compactable.
};
namespace internal {
namespace {
class TestWithHeapWithCompactableCustomSpaces
: public testing::TestWithPlatform {
protected:
TestWithHeapWithCompactableCustomSpaces() {
Heap::HeapOptions options;
options.custom_spaces.emplace_back(
std::make_unique<CompactableCustomSpace>());
options.custom_spaces.emplace_back(
std::make_unique<NotCompactableCustomSpace>());
options.custom_spaces.emplace_back(
std::make_unique<DefaultCompactableCustomSpace>());
heap_ = Heap::Create(platform_, std::move(options));
g_destructor_callcount = 0;
}
void PreciseGC() {
heap_->ForceGarbageCollectionSlow("TestWithHeapWithCompactableCustomSpaces",
"Testing",
cppgc::Heap::StackState::kNoHeapPointers);
}
cppgc::Heap* GetHeap() const { return heap_.get(); }
private:
std::unique_ptr<cppgc::Heap> heap_;
};
class CompactableGCed final : public GarbageCollected<CompactableGCed> {
public:
void Trace(Visitor*) const {}
};
class NotCompactableGCed final : public GarbageCollected<NotCompactableGCed> {
public:
void Trace(Visitor*) const {}
};
class DefaultCompactableGCed final
: public GarbageCollected<DefaultCompactableGCed> {
public:
void Trace(Visitor*) const {}
};
} // namespace
} // namespace internal
template <>
struct SpaceTrait<internal::CompactableGCed> {
using Space = CompactableCustomSpace;
};
template <>
struct SpaceTrait<internal::NotCompactableGCed> {
using Space = NotCompactableCustomSpace;
};
template <>
struct SpaceTrait<internal::DefaultCompactableGCed> {
using Space = DefaultCompactableCustomSpace;
};
namespace internal {
TEST_F(TestWithHeapWithCompactableCustomSpaces,
AllocateOnCompactableCustomSpaces) {
auto* compactable =
MakeGarbageCollected<CompactableGCed>(GetHeap()->GetAllocationHandle());
auto* not_compactable = MakeGarbageCollected<NotCompactableGCed>(
GetHeap()->GetAllocationHandle());
auto* default_compactable = MakeGarbageCollected<DefaultCompactableGCed>(
GetHeap()->GetAllocationHandle());
EXPECT_TRUE(NormalPage::FromPayload(compactable)->space()->is_compactable());
EXPECT_FALSE(
NormalPage::FromPayload(not_compactable)->space()->is_compactable());
EXPECT_FALSE(
NormalPage::FromPayload(default_compactable)->space()->is_compactable());
}
} // namespace internal
} // namespace cppgc
......@@ -45,7 +45,8 @@ class UnifiedHeapTest : public TestWithHeapInternals {
: saved_incremental_marking_wrappers_(FLAG_incremental_marking_wrappers) {
FLAG_incremental_marking_wrappers = false;
cppgc::InitializeProcess(V8::GetCurrentPlatform()->GetPageAllocator());
cpp_heap_ = std::make_unique<CppHeap>(v8_isolate(), 0);
cpp_heap_ = std::make_unique<CppHeap>(
v8_isolate(), std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>());
heap()->SetEmbedderHeapTracer(&cpp_heap());
}
......
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