Index: src/heap/spaces.cc |
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc |
index 3a93a46814ead2a73588b9a7c7ede13d8a31f59d..82370f50664c9dfc9be356617aede01711ffce9f 100644 |
--- a/src/heap/spaces.cc |
+++ b/src/heap/spaces.cc |
@@ -1671,12 +1671,16 @@ bool SemiSpace::Commit() { |
DCHECK(!is_committed()); |
NewSpacePage* current = anchor(); |
const int num_pages = current_capacity_ / Page::kPageSize; |
- for (int i = 0; i < num_pages; i++) { |
+ for (int pages_added = 0; pages_added < num_pages; pages_added++) { |
NewSpacePage* new_page = |
heap() |
->memory_allocator() |
->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( |
NewSpacePage::kAllocatableMemory, this, executable()); |
+ if (new_page == nullptr) { |
+ RewindPages(current, pages_added); |
+ return false; |
+ } |
new_page->InsertAfter(current); |
current = new_page; |
} |
@@ -1724,28 +1728,43 @@ bool SemiSpace::GrowTo(int new_capacity) { |
DCHECK_GT(new_capacity, current_capacity_); |
const int delta = new_capacity - current_capacity_; |
DCHECK(IsAligned(delta, base::OS::AllocateAlignment())); |
- int delta_pages = delta / NewSpacePage::kPageSize; |
+ const int delta_pages = delta / NewSpacePage::kPageSize; |
NewSpacePage* last_page = anchor()->prev_page(); |
DCHECK_NE(last_page, anchor()); |
- while (delta_pages > 0) { |
+ for (int pages_added = 0; pages_added < delta_pages; pages_added++) { |
NewSpacePage* new_page = |
heap() |
->memory_allocator() |
->AllocatePage<NewSpacePage, MemoryAllocator::kPooled>( |
NewSpacePage::kAllocatableMemory, this, executable()); |
+ if (new_page == nullptr) { |
+ RewindPages(last_page, pages_added); |
+ return false; |
+ } |
new_page->InsertAfter(last_page); |
Bitmap::Clear(new_page); |
// Duplicate the flags that was set on the old page. |
new_page->SetFlags(last_page->GetFlags(), |
NewSpacePage::kCopyOnFlipFlagsMask); |
last_page = new_page; |
- delta_pages--; |
} |
AccountCommitted(static_cast<intptr_t>(delta)); |
current_capacity_ = new_capacity; |
return true; |
} |
+void SemiSpace::RewindPages(NewSpacePage* start, int num_pages) { |
+ NewSpacePage* new_last_page = nullptr; |
+ NewSpacePage* last_page = start; |
+ while (num_pages > 0) { |
+ DCHECK_NE(last_page, anchor()); |
+ new_last_page = last_page->prev_page(); |
+ last_page->prev_page()->set_next_page(last_page->next_page()); |
+ last_page->next_page()->set_prev_page(last_page->prev_page()); |
+ last_page = new_last_page; |
+ num_pages--; |
+ } |
+} |
bool SemiSpace::ShrinkTo(int new_capacity) { |
DCHECK_EQ(new_capacity & NewSpacePage::kPageAlignmentMask, 0); |