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:
parent
a282d2e9d2
commit
4d5ab15dc4
@ -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());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user