Index: src/heap/spaces.cc |
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc |
index 204275ab5979fd17b68d07757470e4903b45df35..f042a8ef7e043b85a257190e53afda0e09535841 100644 |
--- a/src/heap/spaces.cc |
+++ b/src/heap/spaces.cc |
@@ -2125,25 +2125,25 @@ bool FreeListCategory::ContainsPageFreeListItemsInList(Page* p) { |
FreeSpace* FreeListCategory::PickNodeFromList(int* node_size) { |
FreeSpace* node = top(); |
+ if (node == nullptr) return nullptr; |
- if (node == NULL) return NULL; |
- |
- while (node != NULL && |
- Page::FromAddress(node->address())->IsEvacuationCandidate()) { |
+ Page* page = Page::FromAddress(node->address()); |
+ while ((node != nullptr) && page->IsEvacuationCandidate()) { |
available_ -= node->Size(); |
+ page->add_available_in_free_list(type_, -(node->Size())); |
node = node->next(); |
} |
- if (node != NULL) { |
+ if (node != nullptr) { |
set_top(node->next()); |
*node_size = node->Size(); |
available_ -= *node_size; |
} else { |
- set_top(NULL); |
+ set_top(nullptr); |
} |
- if (top() == NULL) { |
- set_end(NULL); |
+ if (top() == nullptr) { |
+ set_end(nullptr); |
} |
return node; |
@@ -2153,10 +2153,10 @@ FreeSpace* FreeListCategory::PickNodeFromList(int* node_size) { |
FreeSpace* FreeListCategory::PickNodeFromList(int size_in_bytes, |
int* node_size) { |
FreeSpace* node = PickNodeFromList(node_size); |
- if (node != NULL && *node_size < size_in_bytes) { |
+ if ((node != nullptr) && (*node_size < size_in_bytes)) { |
Free(node, *node_size); |
*node_size = 0; |
- return NULL; |
+ return nullptr; |
} |
return node; |
} |
@@ -2164,50 +2164,38 @@ FreeSpace* FreeListCategory::PickNodeFromList(int size_in_bytes, |
FreeSpace* FreeListCategory::SearchForNodeInList(int size_in_bytes, |
int* node_size) { |
- FreeSpace* return_node = nullptr; |
- FreeSpace* top_node = top(); |
- |
- for (FreeSpace** node_it = &top_node; *node_it != NULL; |
- node_it = (*node_it)->next_address()) { |
- FreeSpace* cur_node = *node_it; |
- while (cur_node != NULL && |
- Page::FromAddress(cur_node->address())->IsEvacuationCandidate()) { |
- int size = cur_node->Size(); |
+ FreeSpace* prev_non_evac_node = nullptr; |
+ for (FreeSpace* cur_node = top(); cur_node != nullptr; |
+ cur_node = cur_node->next()) { |
+ int size = cur_node->size(); |
+ Page* page_for_node = Page::FromAddress(cur_node->address()); |
+ |
+ if ((size >= size_in_bytes) || page_for_node->IsEvacuationCandidate()) { |
+ // The node is either large enough or contained in an evacuation |
+ // candidate. In both cases we need to unlink it from the list. |
available_ -= size; |
- Page::FromAddress(cur_node->address()) |
- ->add_available_in_free_list(type_, -size); |
- cur_node = cur_node->next(); |
- } |
- |
- // Update iterator. |
- *node_it = cur_node; |
- |
- if (cur_node == nullptr) { |
- set_end(nullptr); |
- break; |
- } |
- |
- int size = cur_node->Size(); |
- if (size >= size_in_bytes) { |
- // Large enough node found. Unlink it from the list. |
- return_node = cur_node; |
- *node_it = cur_node->next(); |
+ if (cur_node == top()) { |
+ set_top(cur_node->next()); |
+ } |
+ if (cur_node == end()) { |
+ set_end(prev_non_evac_node); |
+ } |
+ if (prev_non_evac_node != nullptr) { |
+ prev_non_evac_node->set_next(cur_node->next()); |
+ } |
+ // For evacuation candidates we continue. |
+ if (page_for_node->IsEvacuationCandidate()) { |
+ page_for_node->add_available_in_free_list(type_, -size); |
+ continue; |
+ } |
+ // Otherwise we have a large enough node and can return. |
*node_size = size; |
- available_ -= size; |
- Page::FromAddress(return_node->address()) |
- ->add_available_in_free_list(type_, -size); |
- break; |
+ return cur_node; |
} |
- } |
- // Top could've changed if we took the first node. Update top and end |
- // accordingly. |
- set_top(top_node); |
- if (top() == nullptr) { |
- set_end(nullptr); |
+ prev_non_evac_node = cur_node; |
} |
- |
- return return_node; |
+ return nullptr; |
} |
@@ -2329,36 +2317,28 @@ FreeSpace* FreeList::FindNodeIn(FreeListCategoryType category, int* node_size) { |
FreeSpace* FreeList::FindNodeFor(int size_in_bytes, int* node_size) { |
- FreeSpace* node = NULL; |
- Page* page = NULL; |
+ FreeSpace* node = nullptr; |
+ Page* page = nullptr; |
if (size_in_bytes <= kSmallAllocationMax) { |
node = FindNodeIn(kSmall, node_size); |
- if (node != NULL) { |
- DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
- return node; |
- } |
+ if (node != nullptr) return node; |
} |
if (size_in_bytes <= kMediumAllocationMax) { |
node = FindNodeIn(kMedium, node_size); |
- if (node != NULL) { |
- DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
- return node; |
- } |
+ if (node != nullptr) return node; |
} |
if (size_in_bytes <= kLargeAllocationMax) { |
node = FindNodeIn(kLarge, node_size); |
- if (node != NULL) { |
- DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
- return node; |
- } |
+ if (node != nullptr) return node; |
} |
node = huge_list_.SearchForNodeInList(size_in_bytes, node_size); |
- |
- if (node != NULL) { |
+ if (node != nullptr) { |
+ page = Page::FromAddress(node->address()); |
+ page->add_available_in_large_free_list(-(*node_size)); |
DCHECK(IsVeryLong() || Available() == SumFreeLists()); |
return node; |
} |
@@ -2586,7 +2566,7 @@ void PagedSpace::RepairFreeListsAfterDeserialization() { |
} |
-void PagedSpace::EvictEvacuationCandidatesFromFreeLists() { |
+void PagedSpace::EvictEvacuationCandidatesFromLinearAllocationArea() { |
if (allocation_info_.top() >= allocation_info_.limit()) return; |
if (Page::FromAllocationTop(allocation_info_.top()) |
@@ -2596,8 +2576,8 @@ void PagedSpace::EvictEvacuationCandidatesFromFreeLists() { |
static_cast<int>(allocation_info_.limit() - allocation_info_.top()); |
heap()->CreateFillerObjectAt(allocation_info_.top(), remaining); |
- allocation_info_.set_top(NULL); |
- allocation_info_.set_limit(NULL); |
+ allocation_info_.set_top(nullptr); |
+ allocation_info_.set_limit(nullptr); |
} |
} |