Commit a250aa77 authored by Darius Mercadier's avatar Darius Mercadier Committed by Commit Bot

[heap] add specialized freelist for maps

Bug: v8:9329
Change-Id: Ic9b107667e90ef975240e915fec86d6bf0692f8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1720818
Commit-Queue: Darius Mercadier <dmercadier@google.com>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62960}
parent 0cabc6a0
......@@ -3225,6 +3225,49 @@ FreeSpace FreeListMany::Allocate(size_t size_in_bytes, size_t* node_size) {
return node;
}
// ------------------------------------------------
// FreeListMap implementation
FreeListMap::FreeListMap() {
// Initializing base (FreeList) fields
number_of_categories_ = 1;
last_category_ = kOnlyCategory;
min_block_size_ = kMinBlockSize;
categories_ = new FreeListCategory*[number_of_categories_]();
Reset();
}
size_t FreeListMap::GuaranteedAllocatable(size_t maximum_freed) {
return maximum_freed;
}
Page* FreeListMap::GetPageForSize(size_t size_in_bytes) {
return GetPageForCategoryType(kOnlyCategory);
}
FreeListMap::~FreeListMap() { delete[] categories_; }
FreeSpace FreeListMap::Allocate(size_t size_in_bytes, size_t* node_size) {
DCHECK_GE(kMaxBlockSize, size_in_bytes);
// The following DCHECK ensures that maps are allocated one by one (ie,
// without folding). This assumption currently holds. However, if it were to
// become untrue in the future, you'll get an error here. To fix it, I would
// suggest removing the DCHECK, and replacing TryFindNodeIn by
// SearchForNodeInList below.
DCHECK_EQ(size_in_bytes, Map::kSize);
FreeSpace node = TryFindNodeIn(kOnlyCategory, size_in_bytes, node_size);
if (!node.is_null()) {
Page::FromHeapObject(node)->IncreaseAllocatedBytes(*node_size);
}
DCHECK_IMPLIES(node.is_null(), IsEmpty());
return node;
}
// ------------------------------------------------
// Generic FreeList methods (non alloc/free related)
......
......@@ -2005,6 +2005,30 @@ class V8_EXPORT_PRIVATE FreeListMany : public FreeList {
}
};
// FreeList for maps: since maps are all the same size, uses a single freelist.
class V8_EXPORT_PRIVATE FreeListMap : public FreeList {
public:
size_t GuaranteedAllocatable(size_t maximum_freed) override;
Page* GetPageForSize(size_t size_in_bytes) override;
FreeListMap();
~FreeListMap();
V8_WARN_UNUSED_RESULT FreeSpace Allocate(size_t size_in_bytes,
size_t* node_size) override;
private:
static const size_t kMinBlockSize = Map::kSize;
static const size_t kMaxBlockSize = Page::kPageSize;
static const FreeListCategoryType kOnlyCategory = 0;
FreeListCategoryType SelectFreeListCategoryType(
size_t size_in_bytes) override {
return kOnlyCategory;
}
};
// LocalAllocationBuffer represents a linear allocation area that is created
// from a given {AllocationResult} and can be used to allocate memory without
// synchronization.
......@@ -2968,8 +2992,7 @@ class MapSpace : public PagedSpace {
public:
// Creates a map space object.
explicit MapSpace(Heap* heap)
: PagedSpace(heap, MAP_SPACE, NOT_EXECUTABLE,
FreeList::CreateFreeList()) {}
: PagedSpace(heap, MAP_SPACE, NOT_EXECUTABLE, new FreeListMap()) {}
int RoundSizeDownToObjectAlignment(int size) override {
if (base::bits::IsPowerOfTwo(Map::kSize)) {
......
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