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

Unified Diff: src/heap/mark-compact.cc

Issue 479113004: Remove conservative sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index f114ba3f229e471809db91f7e90aaa2d780e9c00..e4057ff4b551a1a8f5d31bdb2827150d2e7ec413 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -41,7 +41,6 @@ MarkCompactCollector::MarkCompactCollector(Heap* heap)
#ifdef DEBUG
state_(IDLE),
#endif
- sweep_precisely_(false),
reduce_memory_footprint_(false),
abort_incremental_marking_(false),
marking_parity_(ODD_MARKING_PARITY),
@@ -200,7 +199,6 @@ static void VerifyEvacuation(NewSpace* space) {
static void VerifyEvacuation(Heap* heap, PagedSpace* space) {
- if (!space->swept_precisely()) return;
if (FLAG_use_allocation_folding &&
(space == heap->old_pointer_space() || space == heap->old_data_space())) {
return;
@@ -3126,7 +3124,7 @@ void MarkCompactCollector::EvacuateLiveObjectsFromPage(Page* p) {
AlwaysAllocateScope always_allocate(isolate());
PagedSpace* space = static_cast<PagedSpace*>(p->owner());
DCHECK(p->IsEvacuationCandidate() && !p->WasSwept());
- p->MarkSweptPrecisely();
+ p->SetWasSwept();
int offsets[16];
@@ -3290,10 +3288,7 @@ static intptr_t Free(PagedSpace* space, FreeList* free_list, Address start,
}
-// Sweep a space precisely. After this has been done the space can
-// be iterated precisely, hitting only the live objects. Code space
-// is always swept precisely because we want to be able to iterate
-// over it. Map space is swept precisely, because it is not compacted.
+// Sweeps a page. After sweeping the page can be iterated.
// Slots in live objects pointing into evacuation candidates are updated
// if requested.
// Returns the size of the biggest continuous freed memory chunk in bytes.
@@ -3301,8 +3296,8 @@ template <SweepingMode sweeping_mode,
MarkCompactCollector::SweepingParallelism parallelism,
SkipListRebuildingMode skip_list_mode,
FreeSpaceTreatmentMode free_space_mode>
-static int SweepPrecisely(PagedSpace* space, FreeList* free_list, Page* p,
- ObjectVisitor* v) {
+static int Sweep(PagedSpace* space, FreeList* free_list, Page* p,
+ ObjectVisitor* v) {
DCHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
DCHECK_EQ(skip_list_mode == REBUILD_SKIP_LIST,
space->identity() == CODE_SPACE);
@@ -3384,7 +3379,7 @@ static int SweepPrecisely(PagedSpace* space, FreeList* free_list, Page* p,
// sweeping by the main thread.
p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
} else {
- p->MarkSweptPrecisely();
+ p->SetWasSwept();
}
return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
}
@@ -3621,22 +3616,24 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
switch (space->identity()) {
case OLD_DATA_SPACE:
- SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
+ Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
+ IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
+ &updating_visitor);
break;
case OLD_POINTER_SPACE:
- SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
- IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(
- space, NULL, p, &updating_visitor);
+ Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
+ IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
+ &updating_visitor);
break;
case CODE_SPACE:
if (FLAG_zap_code_space) {
- SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
- REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(
- space, NULL, p, &updating_visitor);
+ Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
+ REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(space, NULL, p,
+ &updating_visitor);
} else {
- SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
- REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(
- space, NULL, p, &updating_visitor);
+ Sweep<SWEEP_AND_VISIT_LIVE_OBJECTS, SWEEP_ON_MAIN_THREAD,
+ REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(space, NULL, p,
+ &updating_visitor);
}
break;
default:
@@ -4119,182 +4116,6 @@ static inline int MarkWordToObjectStarts(uint32_t mark_bits, int* starts) {
}
-static inline Address DigestFreeStart(Address approximate_free_start,
- uint32_t free_start_cell) {
- DCHECK(free_start_cell != 0);
-
- // No consecutive 1 bits.
- DCHECK((free_start_cell & (free_start_cell << 1)) == 0);
-
- int offsets[16];
- uint32_t cell = free_start_cell;
- int offset_of_last_live;
- if ((cell & 0x80000000u) != 0) {
- // This case would overflow below.
- offset_of_last_live = 31;
- } else {
- // Remove all but one bit, the most significant. This is an optimization
- // that may or may not be worthwhile.
- cell |= cell >> 16;
- cell |= cell >> 8;
- cell |= cell >> 4;
- cell |= cell >> 2;
- cell |= cell >> 1;
- cell = (cell + 1) >> 1;
- int live_objects = MarkWordToObjectStarts(cell, offsets);
- DCHECK(live_objects == 1);
- offset_of_last_live = offsets[live_objects - 1];
- }
- Address last_live_start =
- approximate_free_start + offset_of_last_live * kPointerSize;
- HeapObject* last_live = HeapObject::FromAddress(last_live_start);
- Address free_start = last_live_start + last_live->Size();
- return free_start;
-}
-
-
-static inline Address StartOfLiveObject(Address block_address, uint32_t cell) {
- DCHECK(cell != 0);
-
- // No consecutive 1 bits.
- DCHECK((cell & (cell << 1)) == 0);
-
- int offsets[16];
- if (cell == 0x80000000u) { // Avoid overflow below.
- return block_address + 31 * kPointerSize;
- }
- uint32_t first_set_bit = ((cell ^ (cell - 1)) + 1) >> 1;
- DCHECK((first_set_bit & cell) == first_set_bit);
- int live_objects = MarkWordToObjectStarts(first_set_bit, offsets);
- DCHECK(live_objects == 1);
- USE(live_objects);
- return block_address + offsets[0] * kPointerSize;
-}
-
-
-// Force instantiation of templatized SweepConservatively method for
-// SWEEP_ON_MAIN_THREAD mode.
-template int MarkCompactCollector::SweepConservatively<
- MarkCompactCollector::SWEEP_ON_MAIN_THREAD>(PagedSpace*, FreeList*, Page*);
-
-
-// Force instantiation of templatized SweepConservatively method for
-// SWEEP_IN_PARALLEL mode.
-template int MarkCompactCollector::SweepConservatively<
- MarkCompactCollector::SWEEP_IN_PARALLEL>(PagedSpace*, FreeList*, Page*);
-
-
-// Sweeps a space conservatively. After this has been done the larger free
-// spaces have been put on the free list and the smaller ones have been
-// ignored and left untouched. A free space is always either ignored or put
-// on the free list, never split up into two parts. This is important
-// 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.
-template <MarkCompactCollector::SweepingParallelism mode>
-int MarkCompactCollector::SweepConservatively(PagedSpace* space,
- FreeList* free_list, Page* p) {
- DCHECK(!p->IsEvacuationCandidate() && !p->WasSwept());
- DCHECK(
- (mode == MarkCompactCollector::SWEEP_IN_PARALLEL && free_list != NULL) ||
- (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD &&
- free_list == NULL));
-
- intptr_t freed_bytes = 0;
- intptr_t max_freed_bytes = 0;
- size_t size = 0;
-
- // Skip over all the dead objects at the start of the page and mark them free.
- Address cell_base = 0;
- MarkBit::CellType* cell = NULL;
- MarkBitCellIterator it(p);
- for (; !it.Done(); it.Advance()) {
- cell_base = it.CurrentCellBase();
- cell = it.CurrentCell();
- if (*cell != 0) break;
- }
-
- if (it.Done()) {
- size = p->area_end() - p->area_start();
- freed_bytes =
- Free<mode>(space, free_list, p->area_start(), static_cast<int>(size));
- max_freed_bytes = Max(freed_bytes, max_freed_bytes);
- DCHECK_EQ(0, p->LiveBytes());
- if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) {
- // When concurrent sweeping is active, the page will be marked after
- // sweeping by the main thread.
- p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
- } else {
- p->MarkSweptConservatively();
- }
- return FreeList::GuaranteedAllocatable(static_cast<int>(max_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(cell_base, *cell);
- // Free the first free space.
- size = free_end - p->area_start();
- freed_bytes =
- Free<mode>(space, free_list, p->area_start(), static_cast<int>(size));
- max_freed_bytes = Max(freed_bytes, max_freed_bytes);
-
- // 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
- // started. Unless we find a large free space in the bitmap we will not
- // digest this pair into a real address. We start the iteration here at the
- // first word in the marking bit map that indicates a live object.
- Address free_start = cell_base;
- MarkBit::CellType free_start_cell = *cell;
-
- for (; !it.Done(); it.Advance()) {
- cell_base = it.CurrentCellBase();
- cell = it.CurrentCell();
- if (*cell != 0) {
- // We have a live object. Check approximately whether it is more than 32
- // words since the last live object.
- if (cell_base - free_start > 32 * kPointerSize) {
- free_start = DigestFreeStart(free_start, free_start_cell);
- if (cell_base - free_start > 32 * kPointerSize) {
- // Now that we know the exact start of the free space it still looks
- // like we have a large enough free space to be worth bothering with.
- // so now we need to find the start of the first live object at the
- // end of the free space.
- free_end = StartOfLiveObject(cell_base, *cell);
- freed_bytes = Free<mode>(space, free_list, free_start,
- static_cast<int>(free_end - free_start));
- max_freed_bytes = Max(freed_bytes, max_freed_bytes);
- }
- }
- // Update our undigested record of where the current free area started.
- free_start = cell_base;
- free_start_cell = *cell;
- // Clear marking bits for current cell.
- *cell = 0;
- }
- }
-
- // Handle the free space at the end of the page.
- if (cell_base - free_start > 32 * kPointerSize) {
- free_start = DigestFreeStart(free_start, free_start_cell);
- freed_bytes = Free<mode>(space, free_list, free_start,
- static_cast<int>(p->area_end() - free_start));
- max_freed_bytes = Max(freed_bytes, max_freed_bytes);
- }
-
- p->ResetLiveBytes();
- if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) {
- // When concurrent sweeping is active, the page will be marked after
- // sweeping by the main thread.
- p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
- } else {
- p->MarkSweptConservatively();
- }
- return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
-}
-
-
int MarkCompactCollector::SweepInParallel(PagedSpace* space,
int required_freed_bytes) {
int max_freed = 0;
@@ -4321,14 +4142,8 @@ int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
? free_list_old_pointer_space_.get()
: free_list_old_data_space_.get();
FreeList private_free_list(space);
- if (space->swept_precisely()) {
- max_freed = SweepPrecisely<SWEEP_ONLY, SWEEP_IN_PARALLEL,
- IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(
- space, &private_free_list, page, NULL);
- } else {
- max_freed = SweepConservatively<SWEEP_IN_PARALLEL>(
- space, &private_free_list, page);
- }
+ max_freed = Sweep<SWEEP_ONLY, SWEEP_IN_PARALLEL, IGNORE_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, &private_free_list, page, NULL);
free_list->Concatenate(&private_free_list);
}
return max_freed;
@@ -4336,9 +4151,6 @@ int MarkCompactCollector::SweepInParallel(Page* page, PagedSpace* space) {
void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
- space->set_swept_precisely(sweeper == PRECISE ||
- sweeper == CONCURRENT_PRECISE ||
- sweeper == PARALLEL_PRECISE);
space->ClearStats();
// We defensively initialize end_of_unswept_pages_ here with the first page
@@ -4356,8 +4168,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
// Clear sweeping flags indicating that marking bits are still intact.
- p->ClearSweptPrecisely();
- p->ClearSweptConservatively();
+ p->ClearWasSwept();
if (p->IsFlagSet(Page::RESCAN_ON_EVACUATION) ||
p->IsEvacuationCandidate()) {
@@ -4383,19 +4194,20 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
}
switch (sweeper) {
- case CONCURRENT_CONSERVATIVE:
- case PARALLEL_CONSERVATIVE: {
+ case CONCURRENT_SWEEPING:
+ case PARALLEL_SWEEPING:
if (!parallel_sweeping_active) {
if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n",
+ PrintF("Sweeping 0x%" V8PRIxPTR ".\n",
reinterpret_cast<intptr_t>(p));
}
- SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p);
+ Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, NULL, p, NULL);
pages_swept++;
parallel_sweeping_active = true;
} else {
if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n",
+ PrintF("Sweeping 0x%" V8PRIxPTR " in parallel.\n",
reinterpret_cast<intptr_t>(p));
}
p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING);
@@ -4403,42 +4215,19 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
}
space->set_end_of_unswept_pages(p);
break;
- }
- case CONCURRENT_PRECISE:
- case PARALLEL_PRECISE:
- if (!parallel_sweeping_active) {
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
- reinterpret_cast<intptr_t>(p));
- }
- SweepPrecisely<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
- IGNORE_FREE_SPACE>(space, NULL, p, NULL);
- pages_swept++;
- parallel_sweeping_active = true;
- } else {
- if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n",
- reinterpret_cast<intptr_t>(p));
- }
- p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING);
- space->IncreaseUnsweptFreeBytes(p);
- }
- space->set_end_of_unswept_pages(p);
- break;
- case PRECISE: {
+ case SEQUENTIAL_SWEEPING: {
if (FLAG_gc_verbose) {
- PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
- reinterpret_cast<intptr_t>(p));
+ PrintF("Sweeping 0x%" V8PRIxPTR ".\n", reinterpret_cast<intptr_t>(p));
}
if (space->identity() == CODE_SPACE && FLAG_zap_code_space) {
- SweepPrecisely<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
- ZAP_FREE_SPACE>(space, NULL, p, NULL);
+ Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
+ ZAP_FREE_SPACE>(space, NULL, p, NULL);
} else if (space->identity() == CODE_SPACE) {
- SweepPrecisely<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
- IGNORE_FREE_SPACE>(space, NULL, p, NULL);
+ Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, REBUILD_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, NULL, p, NULL);
} else {
- SweepPrecisely<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
- IGNORE_FREE_SPACE>(space, NULL, p, NULL);
+ Sweep<SWEEP_ONLY, SWEEP_ON_MAIN_THREAD, IGNORE_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, NULL, p, NULL);
}
pages_swept++;
break;
@@ -4458,17 +4247,14 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
static bool ShouldStartSweeperThreads(MarkCompactCollector::SweeperType type) {
- return type == MarkCompactCollector::PARALLEL_CONSERVATIVE ||
- type == MarkCompactCollector::CONCURRENT_CONSERVATIVE ||
- type == MarkCompactCollector::PARALLEL_PRECISE ||
- type == MarkCompactCollector::CONCURRENT_PRECISE;
+ return type == MarkCompactCollector::PARALLEL_SWEEPING ||
+ type == MarkCompactCollector::CONCURRENT_SWEEPING;
}
static bool ShouldWaitForSweeperThreads(
MarkCompactCollector::SweeperType type) {
- return type == MarkCompactCollector::PARALLEL_CONSERVATIVE ||
- type == MarkCompactCollector::PARALLEL_PRECISE;
+ return type == MarkCompactCollector::PARALLEL_SWEEPING;
}
@@ -4482,16 +4268,9 @@ void MarkCompactCollector::SweepSpaces() {
#ifdef DEBUG
state_ = SWEEP_SPACES;
#endif
- SweeperType how_to_sweep = CONCURRENT_CONSERVATIVE;
- if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE;
- if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE;
- if (FLAG_always_precise_sweeping && FLAG_parallel_sweeping) {
- how_to_sweep = PARALLEL_PRECISE;
- }
- if (FLAG_always_precise_sweeping && FLAG_concurrent_sweeping) {
- how_to_sweep = CONCURRENT_PRECISE;
- }
- if (sweep_precisely_) how_to_sweep = PRECISE;
+ SweeperType how_to_sweep = CONCURRENT_SWEEPING;
+ if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_SWEEPING;
+ if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_SWEEPING;
MoveEvacuationCandidatesToEndOfPagesList();
@@ -4522,14 +4301,14 @@ void MarkCompactCollector::SweepSpaces() {
{
GCTracer::Scope sweep_scope(heap()->tracer(),
GCTracer::Scope::MC_SWEEP_CODE);
- SweepSpace(heap()->code_space(), PRECISE);
+ SweepSpace(heap()->code_space(), SEQUENTIAL_SWEEPING);
}
{
GCTracer::Scope sweep_scope(heap()->tracer(),
GCTracer::Scope::MC_SWEEP_CELL);
- SweepSpace(heap()->cell_space(), PRECISE);
- SweepSpace(heap()->property_cell_space(), PRECISE);
+ SweepSpace(heap()->cell_space(), SEQUENTIAL_SWEEPING);
+ SweepSpace(heap()->property_cell_space(), SEQUENTIAL_SWEEPING);
}
EvacuateNewSpaceAndCandidates();
@@ -4540,7 +4319,7 @@ void MarkCompactCollector::SweepSpaces() {
{
GCTracer::Scope sweep_scope(heap()->tracer(),
GCTracer::Scope::MC_SWEEP_MAP);
- SweepSpace(heap()->map_space(), PRECISE);
+ SweepSpace(heap()->map_space(), SEQUENTIAL_SWEEPING);
}
// Deallocate unmarked objects and clear marked bits for marked objects.
@@ -4562,11 +4341,7 @@ void MarkCompactCollector::ParallelSweepSpaceComplete(PagedSpace* space) {
Page* p = it.next();
if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) {
p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE);
- if (space->swept_precisely()) {
- p->MarkSweptPrecisely();
- } else {
- p->MarkSweptConservatively();
- }
+ p->SetWasSwept();
}
DCHECK(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
}
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698