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

Unified Diff: src/mark-compact.cc

Issue 1683001: Put empty pages discovered during sweeping to the end of the list of pages... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 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/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mark-compact.cc
===================================================================
--- src/mark-compact.cc (revision 4449)
+++ src/mark-compact.cc (working copy)
@@ -1055,15 +1055,22 @@
PageIterator it(space, PageIterator::PAGES_IN_USE);
while (it.has_next()) {
Page* p = it.next();
- // The offset of each live object in the page from the first live object
- // in the page.
- int offset = 0;
- EncodeForwardingAddressesInRange<Alloc,
- EncodeForwardingAddressInPagedSpace,
- ProcessNonLive>(
- p->ObjectAreaStart(),
- p->AllocationTop(),
- &offset);
+
+ if (p->WasInUseBeforeMC()) {
+ // The offset of each live object in the page from the first live object
+ // in the page.
+ int offset = 0;
+ EncodeForwardingAddressesInRange<Alloc,
+ EncodeForwardingAddressInPagedSpace,
+ ProcessNonLive>(
+ p->ObjectAreaStart(),
+ p->AllocationTop(),
+ &offset);
+ } else {
+ // Mark whole unused page as a free region.
+ EncodeFreeRegion(p->ObjectAreaStart(),
+ p->AllocationTop() - p->ObjectAreaStart());
+ }
}
}
@@ -1277,6 +1284,23 @@
static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) {
PageIterator it(space, PageIterator::PAGES_IN_USE);
+
+ // During sweeping of paged space we are trying to find longest sequences
+ // of pages without live objects and free them (instead of putting them on
+ // the free list).
+ Page* prev = NULL; // Page preceding current.
+ Page* first_empty_page = NULL; // First empty page in a sequence.
+ Page* prec_first_empty_page = NULL; // Page preceding first empty page.
+
+ // If last used page of space ends with a sequence of dead objects
+ // we can adjust allocation top instead of puting this free area into
+ // the free list. Thus during sweeping we keep track of such areas
+ // and defer their deallocation until the sweeping of the next page
+ // is done: if one of the next pages contains live objects we have
+ // to put such area into the free list.
+ Address last_free_start = NULL;
+ int last_free_size = 0;
+
while (it.has_next()) {
Page* p = it.next();
@@ -1291,8 +1315,9 @@
if (object->IsMarked()) {
object->ClearMark();
MarkCompactCollector::tracer()->decrement_marked_count();
+
if (!is_previous_alive) { // Transition from free to live.
- dealloc(free_start, static_cast<int>(current - free_start));
+ dealloc(free_start, static_cast<int>(current - free_start), true);
is_previous_alive = true;
}
} else {
@@ -1306,39 +1331,112 @@
// loop.
}
- // If the last region was not live we need to deallocate from
- // free_start to the allocation top in the page.
- if (!is_previous_alive) {
- int free_size = static_cast<int>(p->AllocationTop() - free_start);
- if (free_size > 0) {
- dealloc(free_start, free_size);
+ bool page_is_empty = (p->ObjectAreaStart() == p->AllocationTop())
+ || (!is_previous_alive && free_start == p->ObjectAreaStart());
+
+ if (page_is_empty) {
+ // This page is empty. Check whether we are in the middle of
+ // sequence of empty pages and start one if not.
+ if (first_empty_page == NULL) {
+ first_empty_page = p;
+ prec_first_empty_page = prev;
}
+
+ if (!is_previous_alive) {
+ // There are dead objects on this page. Update space accounting stats
+ // without putting anything into free list.
+ int size_in_bytes = static_cast<int>(p->AllocationTop() - free_start);
+ if (size_in_bytes > 0) {
+ dealloc(free_start, size_in_bytes, false);
+ }
+ }
+ } else {
+ // This page is not empty. Sequence of empty pages ended on the previous
+ // one.
+ if (first_empty_page != NULL) {
+ space->FreePages(prec_first_empty_page, prev);
+ prec_first_empty_page = first_empty_page = NULL;
+ }
+
+ // If there is a free ending area on one of the previous pages we have
+ // deallocate that area and put it on the free list.
+ if (last_free_size > 0) {
+ dealloc(last_free_start, last_free_size, true);
+ last_free_start = NULL;
+ last_free_size = 0;
+ }
+
+ // If the last region of this page was not live we remember it.
+ if (!is_previous_alive) {
+ ASSERT(last_free_size == 0);
+ last_free_size = static_cast<int>(p->AllocationTop() - free_start);
+ last_free_start = free_start;
+ }
}
+
+ prev = p;
}
+
+ // We reached end of space. See if we need to adjust allocation top.
+ Address new_allocation_top = NULL;
+
+ if (first_empty_page != NULL) {
+ // Last used pages in space are empty. We can move allocation top backwards
+ // to the beginning of first empty page.
+ ASSERT(prev == space->AllocationTopPage());
+
+ new_allocation_top = first_empty_page->ObjectAreaStart();
+ }
+
+ if (last_free_size > 0) {
+ // There was a free ending area on the previous page.
+ // Deallocate it without putting it into freelist and move allocation
+ // top to the beginning of this free area.
+ dealloc(last_free_start, last_free_size, false);
+ new_allocation_top = last_free_start;
+ }
+
+ if (new_allocation_top != NULL) {
+ Page* new_allocation_top_page = Page::FromAllocationTop(new_allocation_top);
+
+ ASSERT(((first_empty_page == NULL) &&
+ (new_allocation_top_page == space->AllocationTopPage())) ||
+ ((first_empty_page != NULL) && (last_free_size > 0) &&
+ (new_allocation_top_page == prec_first_empty_page)) ||
+ ((first_empty_page != NULL) && (last_free_size == 0) &&
+ (new_allocation_top_page == first_empty_page)));
+
+ space->SetTop(new_allocation_top,
+ new_allocation_top_page->ObjectAreaEnd());
+ }
}
void MarkCompactCollector::DeallocateOldPointerBlock(Address start,
- int size_in_bytes) {
+ int size_in_bytes,
+ bool add_to_freelist) {
Heap::ClearRSetRange(start, size_in_bytes);
- Heap::old_pointer_space()->Free(start, size_in_bytes);
+ Heap::old_pointer_space()->Free(start, size_in_bytes, add_to_freelist);
}
void MarkCompactCollector::DeallocateOldDataBlock(Address start,
- int size_in_bytes) {
- Heap::old_data_space()->Free(start, size_in_bytes);
+ int size_in_bytes,
+ bool add_to_freelist) {
+ Heap::old_data_space()->Free(start, size_in_bytes, add_to_freelist);
}
void MarkCompactCollector::DeallocateCodeBlock(Address start,
- int size_in_bytes) {
- Heap::code_space()->Free(start, size_in_bytes);
+ int size_in_bytes,
+ bool add_to_freelist) {
+ Heap::code_space()->Free(start, size_in_bytes, add_to_freelist);
}
void MarkCompactCollector::DeallocateMapBlock(Address start,
- int size_in_bytes) {
+ int size_in_bytes,
+ bool add_to_freelist) {
// Objects in map space are assumed to have size Map::kSize and a
// valid map in their first word. Thus, we break the free block up into
// chunks and free them separately.
@@ -1346,13 +1444,14 @@
Heap::ClearRSetRange(start, size_in_bytes);
Address end = start + size_in_bytes;
for (Address a = start; a < end; a += Map::kSize) {
- Heap::map_space()->Free(a);
+ Heap::map_space()->Free(a, add_to_freelist);
}
}
void MarkCompactCollector::DeallocateCellBlock(Address start,
- int size_in_bytes) {
+ int size_in_bytes,
+ bool add_to_freelist) {
// Free-list elements in cell space are assumed to have a fixed size.
// We break the free block into chunks and add them to the free list
// individually.
@@ -1361,7 +1460,7 @@
Heap::ClearRSetRange(start, size_in_bytes);
Address end = start + size_in_bytes;
for (Address a = start; a < end; a += size) {
- Heap::cell_space()->Free(a);
+ Heap::cell_space()->Free(a, add_to_freelist);
}
}
« no previous file with comments | « src/mark-compact.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698