[heap] Remove heap dependency from FreeList and restructure surrounding code a bit.
This is a preparation CL for OOL free-lists. Bug: chromium:774108 Change-Id: Ied7853d1d625f650ced135faec4b729d880961c3 Reviewed-on: https://chromium-review.googlesource.com/897809 Commit-Queue: Hannes Payer <hpayer@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#51048}
This commit is contained in:
parent
cb01cbf2f3
commit
158e78014b
@ -1377,9 +1377,7 @@ intptr_t Space::GetNextInlineAllocationStepSize() {
|
||||
|
||||
PagedSpace::PagedSpace(Heap* heap, AllocationSpace space,
|
||||
Executability executable)
|
||||
: SpaceWithLinearArea(heap, space, executable),
|
||||
anchor_(this),
|
||||
free_list_(this) {
|
||||
: SpaceWithLinearArea(heap, space, executable), anchor_(this) {
|
||||
area_size_ = MemoryAllocator::PageAreaSize(space);
|
||||
accounting_stats_.Clear();
|
||||
}
|
||||
@ -1582,7 +1580,8 @@ bool PagedSpace::Expand() {
|
||||
// Pages created during bootstrapping may contain immortal immovable objects.
|
||||
if (!heap()->deserialization_complete()) page->MarkNeverEvacuate();
|
||||
AddPage(page);
|
||||
Free(page->area_start(), page->area_size());
|
||||
Free(page->area_start(), page->area_size(),
|
||||
SpaceAccountingMode::kSpaceAccounted);
|
||||
DCHECK(Capacity() <= heap()->MaxOldGenerationSize());
|
||||
return true;
|
||||
}
|
||||
@ -1618,7 +1617,8 @@ void PagedSpace::DecreaseLimit(Address new_limit) {
|
||||
DCHECK_GE(old_limit, new_limit);
|
||||
if (new_limit != old_limit) {
|
||||
SetTopAndLimit(top(), new_limit);
|
||||
Free(new_limit, old_limit - new_limit);
|
||||
Free(new_limit, old_limit - new_limit,
|
||||
SpaceAccountingMode::kSpaceAccounted);
|
||||
if (heap()->incremental_marking()->black_allocation()) {
|
||||
Page::FromAllocationAreaAddress(new_limit)->DestroyBlackArea(new_limit,
|
||||
old_limit);
|
||||
@ -1704,7 +1704,8 @@ void PagedSpace::FreeLinearAllocationArea() {
|
||||
InlineAllocationStep(current_top, nullptr, nullptr, 0);
|
||||
SetTopAndLimit(nullptr, nullptr);
|
||||
DCHECK_GE(current_limit, current_top);
|
||||
Free(current_top, current_limit - current_top);
|
||||
Free(current_top, current_limit - current_top,
|
||||
SpaceAccountingMode::kSpaceAccounted);
|
||||
}
|
||||
|
||||
void PagedSpace::ReleasePage(Page* page) {
|
||||
@ -1800,7 +1801,7 @@ bool PagedSpace::RefillLinearAllocationAreaFromFreeList(size_t size_in_bytes) {
|
||||
DCHECK_LE(limit, end);
|
||||
DCHECK_LE(size_in_bytes, limit - start);
|
||||
if (limit != end) {
|
||||
Free(limit, end - limit);
|
||||
Free(limit, end - limit, SpaceAccountingMode::kSpaceAccounted);
|
||||
}
|
||||
SetLinearAllocationArea(start, limit);
|
||||
|
||||
@ -2650,7 +2651,7 @@ FreeSpace* FreeListCategory::TryPickNodeFromList(size_t minimum_size,
|
||||
|
||||
FreeSpace* node = PickNodeFromList(node_size);
|
||||
if ((node != nullptr) && (*node_size < minimum_size)) {
|
||||
Free(node, *node_size, kLinkCategory);
|
||||
Free(node->address(), *node_size, kLinkCategory);
|
||||
*node_size = 0;
|
||||
return nullptr;
|
||||
}
|
||||
@ -2683,9 +2684,10 @@ FreeSpace* FreeListCategory::SearchForNodeInList(size_t minimum_size,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FreeListCategory::Free(FreeSpace* free_space, size_t size_in_bytes,
|
||||
void FreeListCategory::Free(Address start, size_t size_in_bytes,
|
||||
FreeMode mode) {
|
||||
CHECK(page()->CanAllocate());
|
||||
FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start));
|
||||
free_space->set_next(top());
|
||||
set_top(free_space);
|
||||
available_ += size_in_bytes;
|
||||
@ -2713,7 +2715,7 @@ void FreeListCategory::Relink() {
|
||||
owner()->AddCategory(this);
|
||||
}
|
||||
|
||||
FreeList::FreeList(PagedSpace* owner) : owner_(owner), wasted_bytes_(0) {
|
||||
FreeList::FreeList() : wasted_bytes_(0) {
|
||||
for (int i = kFirstCategory; i < kNumberOfCategories; i++) {
|
||||
categories_[i] = nullptr;
|
||||
}
|
||||
@ -2731,11 +2733,6 @@ void FreeList::Reset() {
|
||||
}
|
||||
|
||||
size_t FreeList::Free(Address start, size_t size_in_bytes, FreeMode mode) {
|
||||
if (size_in_bytes == 0) return 0;
|
||||
|
||||
owner()->heap()->CreateFillerObjectAt(start, static_cast<int>(size_in_bytes),
|
||||
ClearRecordedSlots::kNo);
|
||||
|
||||
Page* page = Page::FromAddress(start);
|
||||
page->DecreaseAllocatedBytes(size_in_bytes);
|
||||
|
||||
@ -2746,11 +2743,10 @@ size_t FreeList::Free(Address start, size_t size_in_bytes, FreeMode mode) {
|
||||
return size_in_bytes;
|
||||
}
|
||||
|
||||
FreeSpace* free_space = FreeSpace::cast(HeapObject::FromAddress(start));
|
||||
// Insert other blocks at the head of a free list of the appropriate
|
||||
// magnitude.
|
||||
FreeListCategoryType type = SelectFreeListCategoryType(size_in_bytes);
|
||||
page->free_list_category(type)->Free(free_space, size_in_bytes, mode);
|
||||
page->free_list_category(type)->Free(start, size_in_bytes, mode);
|
||||
DCHECK_EQ(page->AvailableInFreeList(),
|
||||
page->AvailableInFreeListFromAllocatedBytes());
|
||||
return 0;
|
||||
|
@ -139,6 +139,8 @@ enum FreeListCategoryType {
|
||||
|
||||
enum FreeMode { kLinkCategory, kDoNotLinkCategory };
|
||||
|
||||
enum class SpaceAccountingMode { kSpaceAccounted, kSpaceUnaccounted };
|
||||
|
||||
enum RememberedSetType {
|
||||
OLD_TO_NEW,
|
||||
OLD_TO_OLD,
|
||||
@ -180,7 +182,7 @@ class FreeListCategory {
|
||||
// category is currently unlinked.
|
||||
void Relink();
|
||||
|
||||
void Free(FreeSpace* node, size_t size_in_bytes, FreeMode mode);
|
||||
void Free(Address address, size_t size_in_bytes, FreeMode mode);
|
||||
|
||||
// Picks a node from the list and stores its size in |node_size|. Returns
|
||||
// nullptr if the category is empty.
|
||||
@ -1751,7 +1753,7 @@ class V8_EXPORT_PRIVATE FreeList {
|
||||
return kHuge;
|
||||
}
|
||||
|
||||
explicit FreeList(PagedSpace* owner);
|
||||
FreeList();
|
||||
|
||||
// Adds a node on the free list. The block of size {size_in_bytes} starting
|
||||
// at {start} is placed on the free list. The return value is the number of
|
||||
@ -1799,7 +1801,6 @@ class V8_EXPORT_PRIVATE FreeList {
|
||||
size_t EvictFreeListItems(Page* page);
|
||||
bool ContainsPageFreeListItems(Page* page);
|
||||
|
||||
PagedSpace* owner() { return owner_; }
|
||||
size_t wasted_bytes() { return wasted_bytes_.Value(); }
|
||||
|
||||
template <typename Callback>
|
||||
@ -1894,13 +1895,10 @@ class V8_EXPORT_PRIVATE FreeList {
|
||||
return categories_[type];
|
||||
}
|
||||
|
||||
PagedSpace* owner_;
|
||||
base::AtomicNumber<size_t> wasted_bytes_;
|
||||
FreeListCategory* categories_[kNumberOfCategories];
|
||||
|
||||
friend class FreeListCategory;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeList);
|
||||
};
|
||||
|
||||
// LocalAllocationBuffer represents a linear allocation area that is created
|
||||
@ -2106,11 +2104,22 @@ class V8_EXPORT_PRIVATE PagedSpace
|
||||
MUST_USE_RESULT inline AllocationResult AllocateRaw(
|
||||
int size_in_bytes, AllocationAlignment alignment);
|
||||
|
||||
size_t Free(Address start, size_t size_in_bytes, SpaceAccountingMode mode) {
|
||||
if (size_in_bytes == 0) return 0;
|
||||
heap_->CreateFillerObjectAt(start, static_cast<int>(size_in_bytes),
|
||||
ClearRecordedSlots::kNo);
|
||||
if (mode == SpaceAccountingMode::kSpaceAccounted) {
|
||||
return AccountedFree(start, size_in_bytes);
|
||||
} else {
|
||||
return UnaccountedFree(start, size_in_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Give a block of memory to the space's free list. It might be added to
|
||||
// the free list or accounted as waste.
|
||||
// If add_to_freelist is false then just accounting stats are updated and
|
||||
// no attempt to add area to free list is made.
|
||||
size_t Free(Address start, size_t size_in_bytes) {
|
||||
size_t AccountedFree(Address start, size_t size_in_bytes) {
|
||||
size_t wasted = free_list_.Free(start, size_in_bytes, kLinkCategory);
|
||||
Page* page = Page::FromAddress(start);
|
||||
accounting_stats_.DecreaseAllocatedBytes(size_in_bytes, page);
|
||||
|
@ -279,8 +279,8 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode,
|
||||
memset(free_start, 0xCC, size);
|
||||
}
|
||||
if (free_list_mode == REBUILD_FREE_LIST) {
|
||||
freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree(
|
||||
free_start, size);
|
||||
freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free(
|
||||
free_start, size, SpaceAccountingMode::kSpaceUnaccounted);
|
||||
max_freed_bytes = Max(freed_bytes, max_freed_bytes);
|
||||
} else {
|
||||
p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size),
|
||||
@ -318,8 +318,8 @@ int Sweeper::RawSweep(Page* p, FreeListRebuildingMode free_list_mode,
|
||||
memset(free_start, 0xCC, size);
|
||||
}
|
||||
if (free_list_mode == REBUILD_FREE_LIST) {
|
||||
freed_bytes = reinterpret_cast<PagedSpace*>(space)->UnaccountedFree(
|
||||
free_start, size);
|
||||
freed_bytes = reinterpret_cast<PagedSpace*>(space)->Free(
|
||||
free_start, size, SpaceAccountingMode::kSpaceUnaccounted);
|
||||
max_freed_bytes = Max(freed_bytes, max_freed_bytes);
|
||||
} else {
|
||||
p->heap()->CreateFillerObjectAt(free_start, static_cast<int>(size),
|
||||
|
Loading…
Reference in New Issue
Block a user