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

Unified Diff: src/mark-compact.cc

Issue 398333002: Concurrent/parallel precise sweeping. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index ffe87156e5a10669fbe56a98a790f78b0b465e60..a927fb49e8e1be2188ab57827f2e85947d704946 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -208,7 +208,7 @@ static void VerifyEvacuation(PagedSpace* space) {
// TODO(hpayer): Bring back VerifyEvacuation for parallel-concurrently
// swept pages.
if ((FLAG_concurrent_sweeping || FLAG_parallel_sweeping) &&
- !space->is_iterable()) return;
+ !space->swept_precisely()) return;
PageIterator it(space);
while (it.has_next()) {
@@ -2051,7 +2051,7 @@ int MarkCompactCollector::DiscoverAndEvacuateBlackObjectsOnPage(
static void DiscoverGreyObjectsInSpace(Heap* heap,
MarkingDeque* marking_deque,
PagedSpace* space) {
- if (space->is_iterable()) {
+ if (space->swept_precisely()) {
HeapObjectIterator it(space);
DiscoverGreyObjectsWithIterator(heap, marking_deque, &it);
} else {
@@ -3132,7 +3132,7 @@ void MarkCompactCollector::EvacuatePages() {
ASSERT(p->IsEvacuationCandidate() ||
p->IsFlagSet(Page::RESCAN_ON_EVACUATION));
ASSERT(static_cast<int>(p->parallel_sweeping()) ==
- MemoryChunk::PARALLEL_SWEEPING_DONE);
+ MemoryChunk::SWEEPING_DONE);
if (p->IsEvacuationCandidate()) {
// During compaction we might have to request a new page.
// Check that space still have room for that.
@@ -3228,6 +3228,20 @@ enum FreeSpaceTreatmentMode {
};
+template<MarkCompactCollector::SweepingParallelism mode>
+static intptr_t Free(PagedSpace* space,
+ FreeList* free_list,
+ Address start,
+ int size) {
+ if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
+ ASSERT(free_list == NULL);
+ return space->Free(start, size);
+ } else {
+ return size - free_list->Free(start, size);
+ }
+}
+
+
// 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
@@ -3235,22 +3249,30 @@ enum FreeSpaceTreatmentMode {
// Slots in live objects pointing into evacuation candidates are updated
// if requested.
template<SweepingMode sweeping_mode,
+ MarkCompactCollector::SweepingParallelism parallelism,
SkipListRebuildingMode skip_list_mode,
FreeSpaceTreatmentMode free_space_mode>
-static void SweepPrecisely(PagedSpace* space,
+static int SweepPrecisely(PagedSpace* space,
+ FreeList* free_list,
Page* p,
ObjectVisitor* v) {
ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
ASSERT_EQ(skip_list_mode == REBUILD_SKIP_LIST,
space->identity() == CODE_SPACE);
ASSERT((p->skip_list() == NULL) || (skip_list_mode == REBUILD_SKIP_LIST));
+ ASSERT(parallelism == MarkCompactCollector::SWEEP_ON_MAIN_THREAD ||
+ sweeping_mode == SWEEP_ONLY);
double start_time = 0.0;
if (FLAG_print_cumulative_gc_stat) {
start_time = base::OS::TimeCurrentMillis();
}
- p->MarkSweptPrecisely();
+ if (parallelism == MarkCompactCollector::SWEEP_IN_PARALLEL) {
+ p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
+ } else {
+ p->MarkSweptPrecisely();
+ }
Address free_start = p->area_start();
ASSERT(reinterpret_cast<intptr_t>(free_start) % (32 * kPointerSize) == 0);
@@ -3262,6 +3284,9 @@ static void SweepPrecisely(PagedSpace* space,
skip_list->Clear();
}
+ intptr_t freed_bytes = 0;
+ intptr_t max_freed_bytes = 0;
+
for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) {
Address cell_base = it.CurrentCellBase();
MarkBit::CellType* cell = it.CurrentCell();
@@ -3270,10 +3295,12 @@ static void SweepPrecisely(PagedSpace* space,
for ( ; live_objects != 0; live_objects--) {
Address free_end = cell_base + offsets[live_index++] * kPointerSize;
if (free_end != free_start) {
+ int size = static_cast<int>(free_end - free_start);
if (free_space_mode == ZAP_FREE_SPACE) {
- memset(free_start, 0xcc, static_cast<int>(free_end - free_start));
+ memset(free_start, 0xcc, size);
}
- space->Free(free_start, static_cast<int>(free_end - free_start));
+ freed_bytes = Free<parallelism>(space, free_list, free_start, size);
+ max_freed_bytes = Max(freed_bytes, max_freed_bytes);
#ifdef ENABLE_GDB_JIT_INTERFACE
if (FLAG_gdbjit && space->identity() == CODE_SPACE) {
GDBJITInterface::RemoveCodeRange(free_start, free_end);
@@ -3304,10 +3331,12 @@ static void SweepPrecisely(PagedSpace* space,
*cell = 0;
}
if (free_start != p->area_end()) {
+ int size = static_cast<int>(p->area_end() - free_start);
if (free_space_mode == ZAP_FREE_SPACE) {
- memset(free_start, 0xcc, static_cast<int>(p->area_end() - free_start));
+ memset(free_start, 0xcc, size);
}
- space->Free(free_start, static_cast<int>(p->area_end() - free_start));
+ freed_bytes = Free<parallelism>(space, free_list, free_start, size);
+ max_freed_bytes = Max(freed_bytes, max_freed_bytes);
#ifdef ENABLE_GDB_JIT_INTERFACE
if (FLAG_gdbjit && space->identity() == CODE_SPACE) {
GDBJITInterface::RemoveCodeRange(free_start, p->area_end());
@@ -3318,6 +3347,7 @@ static void SweepPrecisely(PagedSpace* space,
if (FLAG_print_cumulative_gc_stat) {
space->heap()->AddSweepingTime(base::OS::TimeCurrentMillis() - start_time);
}
+ return FreeList::GuaranteedAllocatable(static_cast<int>(max_freed_bytes));
}
@@ -3553,21 +3583,24 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
break;
case OLD_POINTER_SPACE:
SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
+ SWEEP_ON_MAIN_THREAD,
IGNORE_SKIP_LIST,
IGNORE_FREE_SPACE>(
- space, p, &updating_visitor);
+ 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, p, &updating_visitor);
+ space, NULL, p, &updating_visitor);
} else {
SweepPrecisely<SWEEP_AND_VISIT_LIVE_OBJECTS,
+ SWEEP_ON_MAIN_THREAD,
REBUILD_SKIP_LIST,
IGNORE_FREE_SPACE>(
- space, p, &updating_visitor);
+ space, NULL, p, &updating_visitor);
}
break;
default:
@@ -3939,19 +3972,6 @@ static inline Address StartOfLiveObject(Address block_address, uint32_t cell) {
}
-template<MarkCompactCollector::SweepingParallelism mode>
-static intptr_t Free(PagedSpace* space,
- FreeList* free_list,
- Address start,
- int size) {
- if (mode == MarkCompactCollector::SWEEP_ON_MAIN_THREAD) {
- return space->Free(start, size);
- } else {
- return size - free_list->Free(start, size);
- }
-}
-
-
// Force instantiation of templatized SweepConservatively method for
// SWEEP_ON_MAIN_THREAD mode.
template intptr_t MarkCompactCollector::
@@ -3974,9 +3994,9 @@ template intptr_t MarkCompactCollector::
// memory that can be ignored when scanning. Dead objects other than free
// spaces will not contain the free space map.
template<MarkCompactCollector::SweepingParallelism mode>
-intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
- FreeList* free_list,
- Page* p) {
+int MarkCompactCollector::SweepConservatively(PagedSpace* space,
+ FreeList* free_list,
+ Page* p) {
ASSERT(!p->IsEvacuationCandidate() && !p->WasSwept());
ASSERT((mode == MarkCompactCollector::SWEEP_IN_PARALLEL &&
free_list != NULL) ||
@@ -3986,7 +4006,7 @@ intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space,
// When parallel sweeping is active, the page will be marked after
// sweeping by the main thread.
if (mode == MarkCompactCollector::SWEEP_IN_PARALLEL) {
- p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_FINALIZE);
+ p->set_parallel_sweeping(MemoryChunk::SWEEPING_FINALIZE);
} else {
p->MarkSweptConservatively();
}
@@ -4083,10 +4103,17 @@ int MarkCompactCollector::SweepInParallel(PagedSpace* space,
int max_freed_overall = 0;
while (it.has_next()) {
Page* p = it.next();
-
if (p->TryParallelSweeping()) {
- max_freed = static_cast<int>(SweepConservatively<SWEEP_IN_PARALLEL>(
- space, &private_free_list, p));
+ if (space->swept_precisely()) {
+ max_freed = SweepPrecisely<SWEEP_ONLY,
+ SWEEP_IN_PARALLEL,
+ IGNORE_SKIP_LIST,
+ IGNORE_FREE_SPACE>(
+ space, &private_free_list, p, NULL);
+ } else {
+ max_freed = SweepConservatively<SWEEP_IN_PARALLEL>(
+ space, &private_free_list, p);
+ }
ASSERT(max_freed >= 0);
free_list->Concatenate(&private_free_list);
if (required_freed_bytes > 0 && max_freed >= required_freed_bytes) {
@@ -4101,7 +4128,9 @@ int MarkCompactCollector::SweepInParallel(PagedSpace* space,
void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
- space->set_is_iterable(sweeper == PRECISE);
+ 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
@@ -4116,7 +4145,7 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
while (it.has_next()) {
Page* p = it.next();
- ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
+ ASSERT(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
// Clear sweeping flags indicating that marking bits are still intact.
p->ClearSweptPrecisely();
@@ -4161,26 +4190,55 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) {
PrintF("Sweeping 0x%" V8PRIxPTR " conservatively in parallel.\n",
reinterpret_cast<intptr_t>(p));
}
- p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_PENDING);
+ p->set_parallel_sweeping(MemoryChunk::SWEEPING_PENDING);
space->IncreaseUnsweptFreeBytes(p);
}
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: {
if (FLAG_gc_verbose) {
PrintF("Sweeping 0x%" V8PRIxPTR " precisely.\n",
reinterpret_cast<intptr_t>(p));
}
if (space->identity() == CODE_SPACE && FLAG_zap_code_space) {
- SweepPrecisely<SWEEP_ONLY, REBUILD_SKIP_LIST, ZAP_FREE_SPACE>(
- space, p, NULL);
+ SweepPrecisely<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, REBUILD_SKIP_LIST, IGNORE_FREE_SPACE>(
- space, p, NULL);
+ SweepPrecisely<SWEEP_ONLY,
+ SWEEP_ON_MAIN_THREAD,
+ REBUILD_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, NULL, p, NULL);
} else {
- SweepPrecisely<SWEEP_ONLY, IGNORE_SKIP_LIST, IGNORE_FREE_SPACE>(
- space, p, NULL);
+ SweepPrecisely<SWEEP_ONLY,
+ SWEEP_ON_MAIN_THREAD,
+ IGNORE_SKIP_LIST,
+ IGNORE_FREE_SPACE>(space, NULL, p, NULL);
}
pages_swept++;
break;
@@ -4202,6 +4260,21 @@ 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;
+}
+
+
+static bool ShouldWaitForSweeperThreads(
+ MarkCompactCollector::SweeperType type) {
+ return type == MarkCompactCollector::PARALLEL_CONSERVATIVE ||
+ type == MarkCompactCollector::PARALLEL_PRECISE;
+}
+
+
void MarkCompactCollector::SweepSpaces() {
GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
#ifdef DEBUG
@@ -4210,7 +4283,12 @@ void MarkCompactCollector::SweepSpaces() {
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;
MoveEvacuationCandidatesToEndOfPagesList();
@@ -4226,12 +4304,11 @@ void MarkCompactCollector::SweepSpaces() {
SweepSpace(heap()->old_data_space(), how_to_sweep);
}
- if (how_to_sweep == PARALLEL_CONSERVATIVE ||
- how_to_sweep == CONCURRENT_CONSERVATIVE) {
+ if (ShouldStartSweeperThreads(how_to_sweep)) {
StartSweeperThreads();
}
- if (how_to_sweep == PARALLEL_CONSERVATIVE) {
+ if (ShouldWaitForSweeperThreads(how_to_sweep)) {
EnsureSweepingCompleted();
}
}
@@ -4267,11 +4344,15 @@ void MarkCompactCollector::ParallelSweepSpaceComplete(PagedSpace* space) {
PageIterator it(space);
while (it.has_next()) {
Page* p = it.next();
- if (p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_FINALIZE) {
- p->set_parallel_sweeping(MemoryChunk::PARALLEL_SWEEPING_DONE);
- p->MarkSweptConservatively();
+ if (p->parallel_sweeping() == MemoryChunk::SWEEPING_FINALIZE) {
+ p->set_parallel_sweeping(MemoryChunk::SWEEPING_DONE);
+ if (space->swept_precisely()) {
+ p->MarkSweptPrecisely();
+ } else {
+ p->MarkSweptConservatively();
+ }
}
- ASSERT(p->parallel_sweeping() == MemoryChunk::PARALLEL_SWEEPING_DONE);
+ ASSERT(p->parallel_sweeping() == MemoryChunk::SWEEPING_DONE);
}
}
« 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