[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:
Hannes Payer 2018-02-01 22:14:56 +01:00 committed by Commit Bot
parent cb01cbf2f3
commit 158e78014b
3 changed files with 33 additions and 28 deletions

View File

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

View File

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

View File

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