Chromium Code Reviews| Index: src/heap/spaces.cc |
| diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc |
| index 8982a2953273abbe35993b57ab63ee43d42ae0d7..db3525d8db25a53f175c74845e412711d9f2b3da 100644 |
| --- a/src/heap/spaces.cc |
| +++ b/src/heap/spaces.cc |
| @@ -1484,8 +1484,9 @@ void PagedSpace::Verify(ObjectVisitor* visitor) { |
| bool NewSpace::SetUp(int initial_semispace_capacity, |
| int maximum_semispace_capacity) { |
| - DCHECK(initial_semispace_capacity <= maximum_semispace_capacity); |
| + DCHECK_LE(initial_semispace_capacity, maximum_semispace_capacity); |
| DCHECK(base::bits::IsPowerOfTwo32(maximum_semispace_capacity)); |
| + DCHECK_GE(initial_semispace_capacity, 2 * Page::kPageSize); |
| to_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity); |
| from_space_.SetUp(initial_semispace_capacity, maximum_semispace_capacity); |
| @@ -1586,8 +1587,16 @@ bool SemiSpace::EnsureCurrentCapacity() { |
| 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_); |
| + if (to_remove == current_page_) { |
| + // Corner case: All pages have been moved within new space. We are |
| + // removing the page that contains the top pointer and need to set |
| + // it to the end of the intermediate generation. |
| + NewSpace* new_space = heap()->new_space(); |
| + CHECK_EQ(new_space->top(), current_page_->area_start()); |
| + current_page_ = to_remove->prev_page(); |
| + CHECK(current_page_->InIntermediateGeneration()); |
| + new_space->SetAllocationInfo(page_high(), page_high()); |
|
Hannes Payer (out of office)
2016/09/27 08:28:31
can we set top and limit to null?
Michael Lippautz
2016/09/27 11:13:47
As discussed offline, there are quite some callers
|
| + } |
| to_remove->Unlink(); |
| heap()->memory_allocator()->Free<MemoryAllocator::kPooledAndQueue>( |
| to_remove); |
| @@ -1913,9 +1922,6 @@ bool SemiSpace::Commit() { |
| } |
| Reset(); |
| AccountCommitted(current_capacity_); |
| - if (age_mark_ == nullptr) { |
| - age_mark_ = first_page()->area_start(); |
| - } |
| committed_ = true; |
| return true; |
| } |
| @@ -2027,7 +2033,7 @@ void SemiSpace::FixPagesFlags(intptr_t flags, intptr_t mask) { |
| if (id_ == kToSpace) { |
| page->ClearFlag(MemoryChunk::IN_FROM_SPACE); |
| page->SetFlag(MemoryChunk::IN_TO_SPACE); |
| - page->ClearFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| + page->ClearFlag(MemoryChunk::IN_INTERMEDIATE_GENERATION); |
| page->ResetLiveBytes(); |
| } else { |
| page->SetFlag(MemoryChunk::IN_FROM_SPACE); |
| @@ -2070,7 +2076,6 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { |
| std::swap(from->current_capacity_, to->current_capacity_); |
| std::swap(from->maximum_capacity_, to->maximum_capacity_); |
| std::swap(from->minimum_capacity_, to->minimum_capacity_); |
| - std::swap(from->age_mark_, to->age_mark_); |
| std::swap(from->committed_, to->committed_); |
| std::swap(from->anchor_, to->anchor_); |
| std::swap(from->current_page_, to->current_page_); |
| @@ -2079,16 +2084,33 @@ void SemiSpace::Swap(SemiSpace* from, SemiSpace* to) { |
| from->FixPagesFlags(0, 0); |
| } |
| +void NewSpace::SealIntermediateGeneration() { |
| + fragmentation_in_intermediate_generation_ = 0; |
| + const Address mark = top(); |
| -void SemiSpace::set_age_mark(Address mark) { |
| - DCHECK_EQ(Page::FromAllocationAreaAddress(mark)->owner(), this); |
| - age_mark_ = mark; |
| - // Mark all pages up to the one containing mark. |
| - for (Page* p : NewSpacePageRange(space_start(), mark)) { |
| - p->SetFlag(MemoryChunk::NEW_SPACE_BELOW_AGE_MARK); |
| + for (Page* p : NewSpacePageRange(to_space_.space_start(), mark)) { |
| + p->SetFlag(MemoryChunk::IN_INTERMEDIATE_GENERATION); |
| } |
| -} |
| + Page* p = Page::FromAllocationAreaAddress(mark); |
| + if (mark < p->area_end()) { |
| + heap()->CreateFillerObjectAt(mark, static_cast<int>(p->area_end() - mark), |
| + ClearRecordedSlots::kNo); |
| + fragmentation_in_intermediate_generation_ = |
| + static_cast<size_t>(p->area_end() - mark); |
| + DCHECK_EQ(to_space_.current_page(), p); |
| + if (to_space_.AdvancePage()) { |
| + UpdateAllocationInfo(); |
| + } else { |
| + allocation_info_.Reset(to_space_.page_high(), to_space_.page_high()); |
|
Hannes Payer (out of office)
2016/09/27 08:28:31
same as above, wouldn't it be cleaner to set top a
Michael Lippautz
2016/09/27 11:13:47
See above.
|
| + } |
| + } |
| + if (FLAG_trace_gc_verbose) { |
| + PrintIsolate(heap()->isolate(), |
| + "Sealing intermediate generation: bytes_lost=%zu\n", |
| + fragmentation_in_intermediate_generation_); |
| + } |
| +} |
| #ifdef DEBUG |
| void SemiSpace::Print() {} |