Index: src/heap/mark-compact.h |
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h |
index cd207bcda27ba792ec2291abead68006c86932be..c726fe53fe876c5461e98f0d744525747eca477f 100644 |
--- a/src/heap/mark-compact.h |
+++ b/src/heap/mark-compact.h |
@@ -400,6 +400,99 @@ class MarkCompactCollector { |
public: |
class Evacuator; |
+ class Sweeper { |
+ public: |
+ class SweeperTask; |
+ |
+ enum SweepingMode { SWEEP_ONLY, SWEEP_AND_VISIT_LIVE_OBJECTS }; |
+ enum SkipListRebuildingMode { REBUILD_SKIP_LIST, IGNORE_SKIP_LIST }; |
+ enum FreeSpaceTreatmentMode { IGNORE_FREE_SPACE, ZAP_FREE_SPACE }; |
+ enum SweepingParallelism { SWEEP_ON_MAIN_THREAD, SWEEP_IN_PARALLEL }; |
+ |
+ typedef std::vector<Page*> SweepingList; |
+ typedef List<Page*> SweptList; |
+ |
+ enum SweepingSpace { |
+ kOldSpace, |
+ kCodeSpace, |
+ kMapSpace, |
+ kNumberOfSweepingSpaces, |
+ }; |
+ |
+ template <SweepingMode sweeping_mode, SweepingParallelism parallelism, |
+ SkipListRebuildingMode skip_list_mode, |
+ FreeSpaceTreatmentMode free_space_mode> |
+ static int UnmanagedSweep(PagedSpace* space, Page* p, ObjectVisitor* v); |
+ |
+ explicit Sweeper(Heap* heap) |
+ : heap_(heap), |
+ pending_sweeper_tasks_semaphore_(0), |
+ sweeping_in_progress_(false) {} |
+ |
+ bool sweeping_in_progress() { return sweeping_in_progress_; } |
+ |
+ void AddPage(PagedSpace* space, Page* page); |
+ void AddLatePage(SweepingSpace space, Page* page); |
+ void CommitLateList(SweepingSpace space); |
+ |
+ int HelpSweepInParallel(Page* page, PagedSpace* space); |
+ int HelpSweepInParallel(PagedSpace* space, int required_freed_bytes, |
+ int max_pages = 0); |
+ |
+ void StartSweeping(); |
+ void SweepOrWaitUntilSweepingCompleted(Page* page); |
+ void EnsureCompleted(); |
+ bool IsSweepingCompleted(); |
+ void ParallelSweepSpacesComplete(); |
+ |
+ void AddSweptPageSafe(PagedSpace* space, Page* page); |
+ Page* GetSweptPage(PagedSpace* space); |
+ |
+ private: |
+ AllocationSpace allocation_space(SweepingSpace space) { |
+ switch (space) { |
+ case kOldSpace: |
+ return OLD_SPACE; |
+ case kCodeSpace: |
+ return CODE_SPACE; |
+ case kMapSpace: |
+ return MAP_SPACE; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ UNREACHABLE(); |
+ return OLD_SPACE; |
+ } |
+ |
+ SweepingSpace sweeping_space(AllocationSpace space) { |
+ switch (space) { |
+ case OLD_SPACE: |
+ return kOldSpace; |
+ case CODE_SPACE: |
+ return kCodeSpace; |
+ case MAP_SPACE: |
+ return kMapSpace; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ UNREACHABLE(); |
+ return kOldSpace; |
+ } |
+ |
+ void PrepareAddPage(SweepingSpace space, Page* page); |
+ |
+ Heap* heap_; |
+ base::Mutex mutex_; |
+ base::Semaphore pending_sweeper_tasks_semaphore_; |
+ SweptList swept_list_[kNumberOfSweepingSpaces]; |
+ SweepingList sweeping_list_[kNumberOfSweepingSpaces]; |
+ SweepingList* late_sweeping_list_[kNumberOfSweepingSpaces]; |
+ SweepingList* tmp_late_sweeping_list_[kNumberOfSweepingSpaces]; |
+ bool sweeping_in_progress_; |
+ |
+ friend class SweeperTask; |
+ }; |
+ |
enum IterationMode { |
kKeepMarking, |
kClearMarkbits, |
@@ -490,38 +583,19 @@ class MarkCompactCollector { |
MarkingParity marking_parity() { return marking_parity_; } |
- // Concurrent and parallel sweeping support. If required_freed_bytes was set |
- // to a value larger than 0, then sweeping returns after a block of at least |
- // required_freed_bytes was freed. If required_freed_bytes was set to zero |
- // then the whole given space is swept. It returns the size of the maximum |
- // continuous freed memory chunk. |
- int SweepInParallel(PagedSpace* space, int required_freed_bytes, |
- int max_pages = 0); |
- |
- // Sweeps a given page concurrently to the sweeper threads. It returns the |
- // size of the maximum continuous freed memory chunk. |
- int SweepInParallel(Page* page, PagedSpace* space); |
- |
// Ensures that sweeping is finished. |
// |
// Note: Can only be called safely from main thread. |
void EnsureSweepingCompleted(); |
- void SweepOrWaitUntilSweepingCompleted(Page* page); |
- |
// Help out in sweeping the corresponding space and refill memory that has |
// been regained. |
// |
// Note: Thread-safe. |
void SweepAndRefill(CompactionSpace* space); |
- // If sweeper threads are not active this method will return true. If |
- // this is a latency issue we should be smarter here. Otherwise, it will |
- // return true if the sweeper threads are done processing the pages. |
- bool IsSweepingCompleted(); |
- |
// Checks if sweeping is in progress right now on any space. |
- bool sweeping_in_progress() { return sweeping_in_progress_; } |
+ bool sweeping_in_progress() { return sweeper().sweeping_in_progress(); } |
void set_evacuation(bool evacuation) { evacuation_ = evacuation; } |
@@ -562,27 +636,13 @@ class MarkCompactCollector { |
// address range. |
void RemoveObjectSlots(Address start_slot, Address end_slot); |
- base::Mutex* swept_pages_mutex() { return &swept_pages_mutex_; } |
- List<Page*>* swept_pages(AllocationSpace id) { |
- switch (id) { |
- case OLD_SPACE: |
- return &swept_old_space_pages_; |
- case CODE_SPACE: |
- return &swept_code_space_pages_; |
- case MAP_SPACE: |
- return &swept_map_space_pages_; |
- default: |
- UNREACHABLE(); |
- } |
- return nullptr; |
- } |
+ Sweeper& sweeper() { return sweeper_; } |
private: |
class EvacuateNewSpaceVisitor; |
class EvacuateOldSpaceVisitor; |
class EvacuateVisitorBase; |
class HeapObjectVisitor; |
- class SweeperTask; |
typedef std::vector<Page*> SweepingList; |
@@ -591,8 +651,6 @@ class MarkCompactCollector { |
bool WillBeDeoptimized(Code* code); |
void ClearInvalidRememberedSetSlots(); |
- void StartSweeperThreads(); |
- |
void ComputeEvacuationHeuristics(int area_size, |
int* target_fragmentation_percent, |
int* max_evacuated_bytes); |
@@ -761,8 +819,6 @@ class MarkCompactCollector { |
// evacuation. |
// |
- inline SweepingList& sweeping_list(Space* space); |
- |
// If we are not compacting the heap, we simply sweep the spaces except |
// for the large object space, clearing mark bits and adding unmarked |
// regions to each space's free list. |
@@ -797,10 +853,6 @@ class MarkCompactCollector { |
// up other pages for sweeping. |
void StartSweepSpace(PagedSpace* space); |
- // Finalizes the parallel sweeping phase. Marks all the pages that were |
- // swept in parallel. |
- void ParallelSweepSpacesComplete(); |
- |
#ifdef DEBUG |
friend class MarkObjectVisitor; |
static void VisitObject(HeapObject* obj); |
@@ -819,30 +871,17 @@ class MarkCompactCollector { |
List<Page*> evacuation_candidates_; |
List<NewSpacePage*> newspace_evacuation_candidates_; |
- base::Mutex swept_pages_mutex_; |
- List<Page*> swept_old_space_pages_; |
- List<Page*> swept_code_space_pages_; |
- List<Page*> swept_map_space_pages_; |
- |
- SweepingList sweeping_list_old_space_; |
- SweepingList sweeping_list_code_space_; |
- SweepingList sweeping_list_map_space_; |
- |
// True if we are collecting slots to perform evacuation from evacuation |
// candidates. |
bool compacting_; |
- // True if concurrent or parallel sweeping is currently in progress. |
- bool sweeping_in_progress_; |
- |
- // Semaphore used to synchronize sweeper tasks. |
- base::Semaphore pending_sweeper_tasks_semaphore_; |
- |
// Semaphore used to synchronize compaction tasks. |
base::Semaphore pending_compaction_tasks_semaphore_; |
bool black_allocation_; |
+ Sweeper sweeper_; |
+ |
friend class Heap; |
friend class StoreBuffer; |
}; |