Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(573)

Unified Diff: src/spaces.cc

Issue 7149016: Multi-page growing and shrinking new-space (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Address review comments Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/spaces.cc
diff --git a/src/spaces.cc b/src/spaces.cc
index c91a50f39d6eae75fffa224643b6927b87310ff2..f9f0a429d43531eaa787baab184955091a2c86c2 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -410,8 +410,9 @@ NewSpacePage* NewSpacePage::Initialize(Heap* heap,
: MemoryChunk::IN_FROM_SPACE);
ASSERT(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE
: MemoryChunk::IN_TO_SPACE));
- heap->incremental_marking()->SetNewSpacePageFlags(chunk);
- return static_cast<NewSpacePage*>(chunk);
+ NewSpacePage* page = static_cast<NewSpacePage*>(chunk);
+ heap->incremental_marking()->SetNewSpacePageFlags(page);
+ return page;
}
@@ -967,7 +968,6 @@ void NewSpace::Grow() {
}
}
}
- allocation_info_.limit = to_space_.page_high();
ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
}
@@ -997,6 +997,14 @@ void NewSpace::Shrink() {
void NewSpace::UpdateAllocationInfo() {
allocation_info_.top = to_space_.page_low();
allocation_info_.limit = to_space_.page_high();
+
+ // Lower limit during incremental marking.
+ if (heap()->incremental_marking()->IsMarking() &&
+ inline_allocation_limit_step() != 0) {
+ Address new_limit =
+ allocation_info_.top + inline_allocation_limit_step();
+ allocation_info_.limit = Min(new_limit, allocation_info_.limit);
+ }
ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
}
@@ -1015,7 +1023,7 @@ void NewSpace::ResetAllocationInfo() {
bool NewSpace::AddFreshPage() {
Address top = allocation_info_.top;
- if (top == NewSpacePage::FromLimit(top)->body()) {
+ if (NewSpacePage::IsAtStart(top)) {
// The current page is already empty. Don't try to make another.
// We should only get here if someone asks to allocate more
@@ -1032,6 +1040,7 @@ bool NewSpace::AddFreshPage() {
int remaining_in_page =
static_cast<int>(NewSpacePage::FromLimit(top)->body_limit() - top);
heap()->CreateFillerObjectAt(top, remaining_in_page);
+
UpdateAllocationInfo();
return true;
}
@@ -1046,42 +1055,43 @@ void NewSpace::Verify() {
// There should be objects packed in from the low address up to the
// allocation pointer.
- NewSpacePage* page = to_space_.first_page();
- Address current = page->body();
+ Address current = to_space_.first_page()->body();
CHECK_EQ(current, to_space_.space_low());
while (current != top()) {
- if (current == page->body_limit()) {
- // At end of page, switch to next page.
- page = page->next_page();
- // Next page should be valid.
- CHECK(!page->is_anchor());
- current = page->body();
- }
- // The allocation pointer should not be in the middle of an object.
- CHECK(!page->ContainsLimit(top()) || current < top());
+ if (!NewSpacePage::IsAtEnd(current)) {
+ // The allocation pointer should not be in the middle of an object.
+ CHECK(!NewSpacePage::FromLimit(current)->ContainsLimit(top()) ||
+ current < top());
- HeapObject* object = HeapObject::FromAddress(current);
+ HeapObject* object = HeapObject::FromAddress(current);
- // The first word should be a map, and we expect all map pointers to
- // be in map space.
- Map* map = object->map();
- CHECK(map->IsMap());
- CHECK(heap()->map_space()->Contains(map));
+ // The first word should be a map, and we expect all map pointers to
+ // be in map space.
+ Map* map = object->map();
+ CHECK(map->IsMap());
+ CHECK(heap()->map_space()->Contains(map));
- // The object should not be code or a map.
- CHECK(!object->IsMap());
- CHECK(!object->IsCode());
+ // The object should not be code or a map.
+ CHECK(!object->IsMap());
+ CHECK(!object->IsCode());
- // The object itself should look OK.
- object->Verify();
+ // The object itself should look OK.
+ object->Verify();
- // All the interior pointers should be contained in the heap.
- VerifyPointersVisitor visitor;
- int size = object->Size();
- object->IterateBody(map->instance_type(), size, &visitor);
+ // All the interior pointers should be contained in the heap.
+ VerifyPointersVisitor visitor;
+ int size = object->Size();
+ object->IterateBody(map->instance_type(), size, &visitor);
- current += size;
+ current += size;
+ } else {
+ // At end of page, switch to next page.
+ NewSpacePage* page = NewSpacePage::FromLimit(current)->next_page();
+ // Next page should be valid.
+ CHECK(!page->is_anchor());
+ current = page->body();
+ }
}
// Check semi-spaces.
@@ -1126,24 +1136,18 @@ void SemiSpace::TearDown() {
bool SemiSpace::Grow() {
- return false; // TODO(gc): Temporary hack while semispaces are only one page.
// Double the semispace size but only up to maximum capacity.
- int maximum_extra = maximum_capacity_ - capacity_;
- int extra = Min(RoundUp(capacity_, static_cast<int>(OS::AllocateAlignment())),
- maximum_extra);
- if (!heap()->isolate()->memory_allocator()->CommitBlock(
- space_high(), extra, executable())) {
- return false;
- }
- capacity_ += extra;
- return true;
+ ASSERT(static_cast<size_t>(Page::kPageSize) > OS::AllocateAlignment());
+ int new_capacity = Min(maximum_capacity_,
+ RoundUp(capacity_ * 2, static_cast<int>(Page::kPageSize)));
+ return GrowTo(new_capacity);
}
bool SemiSpace::GrowTo(int new_capacity) {
- return false; // TODO(gc): Temporary hack while semispaces are only one page.
ASSERT(new_capacity <= maximum_capacity_);
ASSERT(new_capacity > capacity_);
+ int pages_before = capacity_ / Page::kPageSize;
size_t delta = new_capacity - capacity_;
ASSERT(IsAligned(delta, OS::AllocateAlignment()));
if (!heap()->isolate()->memory_allocator()->CommitBlock(
@@ -1151,12 +1155,26 @@ bool SemiSpace::GrowTo(int new_capacity) {
return false;
}
capacity_ = new_capacity;
+ int pages_after = capacity_ / Page::kPageSize;
+ NewSpacePage* last_page = anchor()->prev_page();
+ ASSERT(last_page != anchor());
+ for (int i = pages_before; i < pages_after; i++) {
+ Address page_address = start_ + i * Page::kPageSize;
+ NewSpacePage* new_page = NewSpacePage::Initialize(heap(),
+ page_address,
+ this);
+ new_page->InsertAfter(last_page);
+ new_page->markbits()->Clear();
+ // Duplicate the flags that was set on the old page.
+ new_page->SetFlags(last_page->GetFlags(),
+ NewSpacePage::kCopyOnFlipFlagsMask);
+ last_page = new_page;
+ }
return true;
}
bool SemiSpace::ShrinkTo(int new_capacity) {
- return false; // TODO(gc): Temporary hack while semispaces are only one page.
ASSERT(new_capacity >= initial_capacity_);
ASSERT(new_capacity < capacity_);
size_t delta = capacity_ - new_capacity;
@@ -1166,6 +1184,14 @@ bool SemiSpace::ShrinkTo(int new_capacity) {
return false;
}
capacity_ = new_capacity;
+
+ int pages_after = capacity_ / Page::kPageSize;
+ NewSpacePage* new_last_page =
+ NewSpacePage::FromAddress(start_ + (pages_after - 1) * Page::kPageSize);
+ new_last_page->set_next_page(anchor());
+ anchor()->set_next_page(new_last_page);
+ ASSERT(current_page_ == first_page());
+
return true;
}
@@ -1289,13 +1315,25 @@ void SemiSpace::Verify() {
: MemoryChunk::IN_TO_SPACE));
CHECK(!page->IsFlagSet(is_from_space ? MemoryChunk::IN_TO_SPACE
: MemoryChunk::IN_FROM_SPACE));
+ CHECK(page->IsFlagSet(MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING));
+ if (!is_from_space) {
+ // The pointers-from-here-are-interesting flag isn't updated dynamically
+ // on from-space pages, so it might be out of sync with the marking state.
+ if (page->heap()->incremental_marking()->IsMarking()) {
+ CHECK(page->IsFlagSet(MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING));
+ } else {
+ CHECK(!page->IsFlagSet(
+ MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING));
+ }
+ }
+ CHECK(page->IsFlagSet(MemoryChunk::SCAN_ON_SCAVENGE));
CHECK(page->prev_page()->next_page() == page);
page = page->next_page();
}
}
-void SemiSpace::ValidateRange(Address start, Address end) {
+void SemiSpace::AssertValidRange(Address start, Address end) {
// Addresses belong to same semi-space
NewSpacePage* page = NewSpacePage::FromAddress(start);
NewSpacePage* end_page = NewSpacePage::FromLimit(end);
@@ -1342,13 +1380,9 @@ SemiSpaceIterator::SemiSpaceIterator(Address from, Address to) {
void SemiSpaceIterator::Initialize(Address start,
Address end,
HeapObjectCallback size_func) {
-#ifdef DEBUG
- SemiSpace::ValidateRange(start, end);
-#endif
- NewSpacePage* page = NewSpacePage::FromAddress(start);
+ SemiSpace::AssertValidRange(start, end);
current_ = start;
limit_ = end;
- current_page_limit_ = page->body_limit();
size_func_ = size_func;
}
« no previous file with comments | « src/spaces.h ('k') | src/spaces-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698