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: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70345}
This commit is contained in:
Omer Katz 2020-10-06 16:08:32 +02:00 committed by Commit Bot
parent a282d2e9d2
commit 4d5ab15dc4
12 changed files with 151 additions and 20 deletions

View File

@ -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;
};
/**

View File

@ -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::

View File

@ -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; }

View File

@ -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)

View File

@ -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();

View File

@ -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

View File

@ -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 {

View File

@ -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) {}

View File

@ -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()));
}
}

View File

@ -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;

View File

@ -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

View File

@ -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());
}