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

Unified Diff: src/mark-compact.cc

Issue 6970004: Introduce lazy sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 7 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
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 7ea3ff1a708438dee61548bc495b8a7f9d23150b..419aabd20cf2b9e1b73b932d666711013155bb16 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -163,16 +163,17 @@ void MarkCompactCollector::CollectGarbage() {
// Tell the tracer.
if (IsCompacting()) tracer_->set_is_compacting();
- if (heap_->incremental_marking()->IsStopped()) {
+ if (!heap_->incremental_marking()->IsMarking()) {
+ heap_->incremental_marking()->Abort();
MarkLiveObjects();
} else {
{
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
heap_->incremental_marking()->Finalize();
- ASSERT(heap_->incremental_marking()->IsStopped());
}
MarkLiveObjects();
}
+ ASSERT(heap_->incremental_marking()->IsStopped());
if (FLAG_collect_maps) ClearNonLiveTransitions();
@@ -2387,8 +2388,9 @@ static inline Address StartOfLiveObject(Address block_address, uint32_t cell) {
// because it means that any FreeSpace maps left actually describe a region of
// memory that can be ignored when scanning. Dead objects other than free
// spaces will not contain the free space map.
-static void SweepConservatively(PagedSpace* space,
- Page* p) {
+int MarkCompactCollector::SweepConservatively(PagedSpace* space, Page* p) {
+ int freed_bytes = 0;
+
MarkBit::CellType* cells = p->markbits()->cells();
p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY);
@@ -2411,15 +2413,15 @@ static void SweepConservatively(PagedSpace* space,
}
int size = block_address - p->ObjectAreaStart();
if (cell_index == last_cell_index) {
- space->Free(p->ObjectAreaStart(), size);
- return;
+ freed_bytes += space->Free(p->ObjectAreaStart(), size);
+ return freed_bytes;
}
// Grow the size of the start-of-page free space a little to get up to the
// first live object.
Address free_end = StartOfLiveObject(block_address, cells[cell_index]);
// Free the first free space.
size = free_end - p->ObjectAreaStart();
- space->Free(p->ObjectAreaStart(), size);
+ freed_bytes += space->Free(p->ObjectAreaStart(), size);
// The start of the current free area is represented in undigested form by
// the address of the last 32-word section that contained a live object and
// the marking bitmap for that cell, which describes where the live object
@@ -2448,7 +2450,7 @@ static void SweepConservatively(PagedSpace* space,
// so now we need to find the start of the first live object at the
// end of the free space.
free_end = StartOfLiveObject(block_address, cell);
- space->Free(free_start, free_end - free_start);
+ freed_bytes += space->Free(free_start, free_end - free_start);
}
}
// Update our undigested record of where the current free area started.
@@ -2460,8 +2462,10 @@ static void SweepConservatively(PagedSpace* space,
// Handle the free space at the end of the page.
if (block_address - free_start > 32 * kPointerSize) {
free_start = DigestFreeStart(free_start, free_start_cell);
- space->Free(free_start, block_address - free_start);
+ freed_bytes += space->Free(free_start, block_address - free_start);
}
+
+ return freed_bytes;
}
@@ -2512,31 +2516,38 @@ static void SweepPrecisely(PagedSpace* space,
void MarkCompactCollector::SweepSpace(PagedSpace* space,
SweeperType sweeper) {
- space->set_was_swept_conservatively(sweeper == CONSERVATIVE);
+ space->set_was_swept_conservatively(sweeper == CONSERVATIVE ||
+ sweeper == LAZY_CONSERVATIVE);
space->ClearStats();
PageIterator it(space);
- // 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 preceding current.
- Page* prev = Page::FromAddress(NULL);
+ int freed_bytes = 0;
+ int newspace_size = space->heap()->new_space()->Size();
while (it.has_next()) {
Page* p = it.next();
- space->IncreaseCapacity(p->ObjectAreaEnd() - p->ObjectAreaStart());
- if (sweeper == CONSERVATIVE) {
- SweepConservatively(space, p);
- } else {
- ASSERT(sweeper == PRECISE);
- SweepPrecisely(space, p);
+ switch (sweeper) {
+ case CONSERVATIVE:
+ SweepConservatively(space, p);
+ break;
+ case LAZY_CONSERVATIVE:
+ freed_bytes += SweepConservatively(space, p);
+ if (freed_bytes >= newspace_size && p != space->LastPage()) {
+ space->SetPagesToSweep(p->next_page(), space->LastPage());
+ return;
Erik Corry 2011/05/09 21:20:11 I think we will want to tune this heuristic. If w
+ }
+ break;
+ case PRECISE:
+ SweepPrecisely(space, p);
+ break;
+ default:
+ UNREACHABLE();
}
- prev = p;
}
+
// TODO(gc): set up allocation top and limit using the free list.
}
@@ -2548,7 +2559,8 @@ void MarkCompactCollector::SweepSpaces() {
#endif
ASSERT(!IsCompacting());
- SweeperType how_to_sweep = CONSERVATIVE;
+ SweeperType how_to_sweep =
+ FLAG_lazy_sweeping ? LAZY_CONSERVATIVE : CONSERVATIVE;
if (sweep_precisely_) how_to_sweep = PRECISE;
// Noncompacting collections simply sweep the spaces to clear the mark
// bits and free the nonlive blocks (for old and map spaces). We sweep

Powered by Google App Engine
This is Rietveld 408576698