Index: src/heap/spaces-inl.h |
diff --git a/src/heap/spaces-inl.h b/src/heap/spaces-inl.h |
index f96455eba1ddec15cd42b5d67b88b4eb2779801c..a9b03a89f703374f9e4be6fddbc0494ae4065395 100644 |
--- a/src/heap/spaces-inl.h |
+++ b/src/heap/spaces-inl.h |
@@ -262,13 +262,21 @@ Page* Page::Initialize(Heap* heap, MemoryChunk* chunk, Executability executable, |
DCHECK(page->area_size() <= kAllocatableMemory); |
DCHECK(chunk->owner() == owner); |
owner->IncreaseCapacity(page->area_size()); |
- owner->Free(page->area_start(), page->area_size()); |
- |
heap->incremental_marking()->SetOldSpacePageFlags(chunk); |
+ // Make sure that categories are initialized before freeing the area. |
+ page->InitializeFreeListCategories(); |
+ owner->Free(page->area_start(), page->area_size()); |
+ |
return page; |
} |
+void Page::InitializeFreeListCategories() { |
+ for (int i = kFirstCategory; i < kNumberOfCategories; i++) { |
+ categories_[i].Initialize(static_cast<FreeListCategoryType>(i)); |
+ } |
+} |
+ |
void MemoryChunk::IncrementLiveBytesFromGC(HeapObject* object, int by) { |
MemoryChunk::FromAddress(object->address())->IncrementLiveBytes(by); |
} |
@@ -314,6 +322,24 @@ bool PagedSpace::Contains(Object* o) { |
return p->owner() == this; |
} |
+void PagedSpace::UnlinkFreeListCategories(Page* page) { |
+ DCHECK_EQ(this, page->owner()); |
+ page->ForAllFreeListCategories([this](FreeListCategory* category) { |
+ DCHECK_EQ(free_list(), category->owner()); |
+ free_list()->RemoveCategory(category); |
+ }); |
+} |
+ |
+intptr_t PagedSpace::RelinkFreeListCategories(Page* page) { |
+ DCHECK_EQ(this, page->owner()); |
+ intptr_t added = 0; |
+ page->ForAllFreeListCategories([&added](FreeListCategory* category) { |
+ added += category->available(); |
+ category->Relink(); |
+ }); |
+ return added; |
+} |
+ |
MemoryChunk* MemoryChunk::FromAnyPointerAddress(Heap* heap, Address addr) { |
MemoryChunk* chunk = MemoryChunk::FromAddress(addr); |
uintptr_t offset = addr - chunk->address(); |
@@ -327,6 +353,27 @@ Page* Page::FromAnyPointerAddress(Heap* heap, Address addr) { |
return static_cast<Page*>(MemoryChunk::FromAnyPointerAddress(heap, addr)); |
} |
+void Page::MarkNeverAllocateForTesting() { |
+ DCHECK(!IsFlagSet(NEVER_ALLOCATE_ON_PAGE)); |
+ SetFlag(NEVER_ALLOCATE_ON_PAGE); |
+ reinterpret_cast<PagedSpace*>(owner())->free_list()->EvictFreeListItems(this); |
+} |
+ |
+void Page::MarkEvacuationCandidate() { |
+ DCHECK(!IsFlagSet(NEVER_EVACUATE)); |
+ DCHECK_NULL(old_to_old_slots_); |
+ DCHECK_NULL(typed_old_to_old_slots_); |
+ SetFlag(EVACUATION_CANDIDATE); |
+ reinterpret_cast<PagedSpace*>(owner())->free_list()->EvictFreeListItems(this); |
+} |
+ |
+void Page::ClearEvacuationCandidate() { |
+ DCHECK_NULL(old_to_old_slots_); |
+ DCHECK_NULL(typed_old_to_old_slots_); |
+ ClearFlag(EVACUATION_CANDIDATE); |
+ InitializeFreeListCategories(); |
+} |
+ |
MemoryChunkIterator::MemoryChunkIterator(Heap* heap, Mode mode) |
: state_(kOldSpaceState), |
mode_(mode), |
@@ -375,18 +422,29 @@ MemoryChunk* MemoryChunkIterator::next() { |
return nullptr; |
} |
- |
void Page::set_next_page(Page* page) { |
DCHECK(page->owner() == owner()); |
set_next_chunk(page); |
} |
- |
void Page::set_prev_page(Page* page) { |
DCHECK(page->owner() == owner()); |
set_prev_chunk(page); |
} |
+Page* FreeListCategory::page() { |
+ return Page::FromAddress(reinterpret_cast<Address>(this)); |
+} |
+ |
+FreeList* FreeListCategory::owner() { |
+ return reinterpret_cast<PagedSpace*>( |
+ Page::FromAddress(reinterpret_cast<Address>(this))->owner()) |
+ ->free_list(); |
+} |
+ |
+bool FreeListCategory::is_linked() { |
+ return prev_ != nullptr || next_ != nullptr || owner()->top(type_) == this; |
+} |
// Try linear allocation in the page of alloc_info's allocation top. Does |
// not contain slow case logic (e.g. move to the next page or try free list |