Index: src/mark-compact.cc |
diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
index 3270457ed747f9beda541b19be453bd6fe25fc35..2ff1ce98500e5aa6e9c03faad4bd07b3c3736a8b 100644 |
--- a/src/mark-compact.cc |
+++ b/src/mark-compact.cc |
@@ -45,7 +45,7 @@ MarkCompactCollector::MarkCompactCollector(Heap* heap) : // NOLINT |
marking_parity_(ODD_MARKING_PARITY), |
compacting_(false), |
was_marked_incrementally_(false), |
- sweeping_in_progress_(false), |
+ sweeping_pending_(false), |
pending_sweeper_jobs_semaphore_(0), |
sequential_sweeping_(false), |
tracer_(NULL), |
@@ -573,7 +573,7 @@ class MarkCompactCollector::SweeperTask : public v8::Task { |
void MarkCompactCollector::StartSweeperThreads() { |
ASSERT(free_list_old_pointer_space_.get()->IsEmpty()); |
ASSERT(free_list_old_data_space_.get()->IsEmpty()); |
- sweeping_in_progress_ = true; |
+ sweeping_pending_ = true; |
for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
isolate()->sweeper_threads()[i]->StartSweeping(); |
} |
@@ -588,17 +588,8 @@ void MarkCompactCollector::StartSweeperThreads() { |
} |
-void MarkCompactCollector::EnsureSweepingCompleted() { |
- ASSERT(sweeping_in_progress_ == true); |
- |
- // If sweeping is not completed, we try to complete it here. If we do not |
- // have sweeper threads we have to complete since we do not have a good |
- // indicator for a swept space in that case. |
- if (!AreSweeperThreadsActivated() || !IsSweepingCompleted()) { |
- SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0); |
- SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0); |
- } |
- |
+void MarkCompactCollector::WaitUntilSweepingCompleted() { |
+ ASSERT(sweeping_pending_ == true); |
for (int i = 0; i < isolate()->num_sweeper_threads(); i++) { |
isolate()->sweeper_threads()[i]->WaitForSweeperThread(); |
} |
@@ -608,7 +599,7 @@ void MarkCompactCollector::EnsureSweepingCompleted() { |
pending_sweeper_jobs_semaphore_.Wait(); |
} |
ParallelSweepSpacesComplete(); |
- sweeping_in_progress_ = false; |
+ sweeping_pending_ = false; |
RefillFreeList(heap()->paged_space(OLD_DATA_SPACE)); |
RefillFreeList(heap()->paged_space(OLD_POINTER_SPACE)); |
heap()->paged_space(OLD_DATA_SPACE)->ResetUnsweptFreeBytes(); |
@@ -622,7 +613,6 @@ bool MarkCompactCollector::IsSweepingCompleted() { |
return false; |
} |
} |
- |
if (FLAG_job_based_sweeping) { |
if (!pending_sweeper_jobs_semaphore_.WaitFor( |
base::TimeDelta::FromSeconds(0))) { |
@@ -630,7 +620,6 @@ bool MarkCompactCollector::IsSweepingCompleted() { |
} |
pending_sweeper_jobs_semaphore_.Signal(); |
} |
- |
return true; |
} |
@@ -659,6 +648,12 @@ bool MarkCompactCollector::AreSweeperThreadsActivated() { |
} |
+bool MarkCompactCollector::IsConcurrentSweepingInProgress(PagedSpace* space) { |
+ return (space == NULL || space->is_swept_concurrently()) && |
+ sweeping_pending_; |
+} |
+ |
+ |
void Marking::TransferMark(Address old_start, Address new_start) { |
// This is only used when resizing an object. |
ASSERT(MemoryChunk::FromAddress(old_start) == |
@@ -964,9 +959,9 @@ void MarkCompactCollector::Prepare(GCTracer* tracer) { |
ASSERT(!FLAG_never_compact || !FLAG_always_compact); |
- if (sweeping_in_progress()) { |
+ if (IsConcurrentSweepingInProgress()) { |
// Instead of waiting we could also abort the sweeper threads here. |
- EnsureSweepingCompleted(); |
+ WaitUntilSweepingCompleted(); |
} |
// Clear marking bits if incremental marking is aborted. |
@@ -4011,7 +4006,7 @@ intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, |
static_cast<int>(size)); |
max_freed_bytes = Max(freed_bytes, max_freed_bytes); |
ASSERT_EQ(0, p->LiveBytes()); |
- return free_list->GuaranteedAllocatable(max_freed_bytes); |
+ return freed_bytes; |
} |
// Grow the size of the start-of-page free space a little to get up to the |
@@ -4068,7 +4063,7 @@ intptr_t MarkCompactCollector::SweepConservatively(PagedSpace* space, |
} |
p->ResetLiveBytes(); |
- return free_list->GuaranteedAllocatable(max_freed_bytes); |
+ return max_freed_bytes; |
} |
@@ -4102,6 +4097,7 @@ int MarkCompactCollector::SweepInParallel(PagedSpace* space, |
void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
space->set_is_iterable(sweeper == PRECISE); |
+ space->set_is_swept_concurrently(sweeper == CONCURRENT_CONSERVATIVE); |
space->ClearStats(); |
// We defensively initialize end_of_unswept_pages_ here with the first page |
@@ -4146,6 +4142,15 @@ void MarkCompactCollector::SweepSpace(PagedSpace* space, SweeperType sweeper) { |
} |
switch (sweeper) { |
+ case CONSERVATIVE: { |
+ if (FLAG_gc_verbose) { |
+ PrintF("Sweeping 0x%" V8PRIxPTR " conservatively.\n", |
+ reinterpret_cast<intptr_t>(p)); |
+ } |
+ SweepConservatively<SWEEP_ON_MAIN_THREAD>(space, NULL, p); |
+ pages_swept++; |
+ break; |
+ } |
case CONCURRENT_CONSERVATIVE: |
case PARALLEL_CONSERVATIVE: { |
if (!parallel_sweeping_active) { |
@@ -4207,10 +4212,11 @@ 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; |
- |
+ SweeperType how_to_sweep = CONSERVATIVE; |
+ if (AreSweeperThreadsActivated()) { |
+ if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_CONSERVATIVE; |
+ if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_CONSERVATIVE; |
+ } |
if (sweep_precisely_) how_to_sweep = PRECISE; |
MoveEvacuationCandidatesToEndOfPagesList(); |
@@ -4232,7 +4238,7 @@ void MarkCompactCollector::SweepSpaces() { |
} |
if (how_to_sweep == PARALLEL_CONSERVATIVE) { |
- EnsureSweepingCompleted(); |
+ WaitUntilSweepingCompleted(); |
} |
} |
RemoveDeadInvalidatedCode(); |