Index: src/heap/spaces.cc |
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc |
index a0eae92d69f994b9d78be8d544b86beb6bd8eacd..c8b8baa0fe3964202fc5305c54b40599b2243a82 100644 |
--- a/src/heap/spaces.cc |
+++ b/src/heap/spaces.cc |
@@ -1386,7 +1386,6 @@ void NewSpace::TearDown() { |
from_space_.TearDown(); |
} |
- |
void NewSpace::Flip() { SemiSpace::Swap(&from_space_, &to_space_); } |
@@ -1432,6 +1431,48 @@ void NewSpace::Shrink() { |
DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_); |
} |
+bool NewSpace::Rebalance() { |
+ CHECK(heap()->promotion_queue()->is_empty()); |
+ // Order here is important to make use of the page pool. |
+ return to_space_.EnsureCurrentCapacity() && |
+ from_space_.EnsureCurrentCapacity(); |
+} |
+ |
+bool SemiSpace::EnsureCurrentCapacity() { |
+ if (is_committed()) { |
+ const int expected_pages = current_capacity_ / Page::kPageSize; |
+ int actual_pages = 0; |
+ Page* current_page = anchor()->next_page(); |
+ while (current_page != anchor()) { |
+ actual_pages++; |
+ current_page = current_page->next_page(); |
+ if (actual_pages > expected_pages) { |
+ Page* to_remove = current_page->prev_page(); |
+ // Make sure we don't overtake the actual top pointer. |
+ CHECK_NE(to_remove, current_page_); |
+ to_remove->Unlink(); |
+ heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>( |
+ to_remove); |
+ } |
+ } |
+ while (actual_pages < expected_pages) { |
+ actual_pages++; |
+ current_page = |
+ heap()->memory_allocator()->AllocatePage<MemoryAllocator::kPooled>( |
+ Page::kAllocatableMemory, this, executable()); |
+ if (current_page == nullptr) return false; |
+ DCHECK_NOT_NULL(current_page); |
+ current_page->InsertAfter(anchor()); |
+ Bitmap::Clear(current_page); |
+ current_page->SetFlags(anchor()->prev_page()->GetFlags(), |
+ Page::kCopyAllFlags); |
+ heap()->CreateFillerObjectAt(current_page->area_start(), |
+ current_page->area_size(), |
+ ClearRecordedSlots::kNo); |
+ } |
+ } |
+ return true; |
+} |
void LocalAllocationBuffer::Close() { |
if (IsValid()) { |
@@ -1488,7 +1529,6 @@ void NewSpace::ResetAllocationInfo() { |
Address old_top = allocation_info_.top(); |
to_space_.Reset(); |
UpdateAllocationInfo(); |
- pages_used_ = 0; |
// Clear all mark-bits in the to-space. |
NewSpacePageIterator it(&to_space_); |
while (it.has_next()) { |
@@ -1534,7 +1574,6 @@ bool NewSpace::AddFreshPage() { |
int remaining_in_page = static_cast<int>(limit - top); |
heap()->CreateFillerObjectAt(top, remaining_in_page, ClearRecordedSlots::kNo); |
- pages_used_++; |
UpdateAllocationInfo(); |
return true; |
@@ -1872,23 +1911,21 @@ void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { |
void SemiSpace::Reset() { |
DCHECK_NE(anchor_.next_page(), &anchor_); |
current_page_ = anchor_.next_page(); |
+ pages_used_ = 0; |
} |
-bool SemiSpace::ReplaceWithEmptyPage(Page* old_page) { |
- // TODO(mlippautz): We do not have to get a new page here when the semispace |
- // is uncommitted later on. |
- Page* new_page = heap()->memory_allocator()->AllocatePage( |
- Page::kAllocatableMemory, this, executable()); |
- if (new_page == nullptr) return false; |
- Bitmap::Clear(new_page); |
- new_page->SetFlags(old_page->GetFlags(), Page::kCopyAllFlags); |
- new_page->set_next_page(old_page->next_page()); |
- new_page->set_prev_page(old_page->prev_page()); |
- old_page->next_page()->set_prev_page(new_page); |
- old_page->prev_page()->set_next_page(new_page); |
- heap()->CreateFillerObjectAt(new_page->area_start(), new_page->area_size(), |
- ClearRecordedSlots::kNo); |
- return true; |
+void SemiSpace::RemovePage(Page* page) { |
+ if (current_page_ == page) { |
+ current_page_ = page->prev_page(); |
+ } |
+ page->Unlink(); |
+} |
+ |
+void SemiSpace::PrependPage(Page* page) { |
+ page->SetFlags(current_page()->GetFlags(), Page::kCopyAllFlags); |
+ page->set_owner(this); |
+ page->InsertAfter(anchor()); |
+ pages_used_++; |
} |
void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { |