Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index cd207bc..d6adb03 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -5,6 +5,8 @@
#ifndef V8_HEAP_MARK_COMPACT_H_
#define V8_HEAP_MARK_COMPACT_H_
+#include <deque>
+
#include "src/base/bits.h"
#include "src/heap/spaces.h"
#include "src/heap/store-buffer.h"
@@ -400,6 +402,74 @@
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::deque<Page*> SweepingList;
+ typedef List<Page*> SweptList;
+
+ template <SweepingMode sweeping_mode, SweepingParallelism parallelism,
+ SkipListRebuildingMode skip_list_mode,
+ FreeSpaceTreatmentMode free_space_mode>
+ static int RawSweep(PagedSpace* space, Page* p, ObjectVisitor* v);
+
+ explicit Sweeper(Heap* heap)
+ : heap_(heap),
+ pending_sweeper_tasks_semaphore_(0),
+ sweeping_in_progress_(false),
+ late_pages_(false),
+ num_sweeping_tasks_(0) {}
+
+ bool sweeping_in_progress() { return sweeping_in_progress_; }
+ bool contains_late_pages() { return late_pages_; }
+
+ void AddPage(AllocationSpace space, Page* page);
+ void AddLatePage(AllocationSpace space, Page* page);
+
+ int ParallelSweepSpace(AllocationSpace identity, int required_freed_bytes,
+ int max_pages = 0);
+ int ParallelSweepPage(Page* page, PagedSpace* space);
+
+ void StartSweeping();
+ void StartSweepingHelper(AllocationSpace space_to_start);
+ void EnsureCompleted();
+ bool IsSweepingCompleted();
+ void SweepOrWaitUntilSweepingCompleted(Page* page);
+
+ void AddSweptPageSafe(PagedSpace* space, Page* page);
+ Page* GetSweptPageSafe(PagedSpace* space);
+
+ private:
+ static const int kAllocationSpaces = LAST_PAGED_SPACE + 1;
+
+ template <typename Callback>
+ void ForAllSweepingSpaces(Callback callback) {
+ for (int i = 0; i < kAllocationSpaces; i++) {
+ callback(static_cast<AllocationSpace>(i));
+ }
+ }
+
+ Page* GetSweepingPageSafe(AllocationSpace space);
+ void AddSweepingPageSafe(AllocationSpace space, Page* page);
+
+ void PrepareToBeSweptPage(AllocationSpace space, Page* page);
+
+ Heap* heap_;
+ base::Semaphore pending_sweeper_tasks_semaphore_;
+ base::Mutex mutex_;
+ SweptList swept_list_[kAllocationSpaces];
+ SweepingList sweeping_list_[kAllocationSpaces];
+ bool sweeping_in_progress_;
+ bool late_pages_;
+ int num_sweeping_tasks_;
+ };
+
enum IterationMode {
kKeepMarking,
kClearMarkbits,
@@ -451,8 +521,6 @@
CodeFlusher* code_flusher() { return code_flusher_; }
inline bool is_code_flushing_enabled() const { return code_flusher_ != NULL; }
- enum SweepingParallelism { SWEEP_ON_MAIN_THREAD, SWEEP_IN_PARALLEL };
-
#ifdef VERIFY_HEAP
void VerifyValidStoreAndSlotsBufferEntries();
void VerifyMarkbitsAreClean();
@@ -490,38 +558,19 @@
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,62 +611,39 @@
// 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_; }
+
+ std::vector<std::pair<void*, void*>>& wrappers_to_trace() {
+ return wrappers_to_trace_;
}
+ void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
+
+ EmbedderHeapTracer* embedder_heap_tracer() { return embedder_heap_tracer_; }
+
+ bool UsingEmbedderHeapTracer() { return embedder_heap_tracer(); }
+
+ void TracePossibleWrapper(JSObject* js_object);
+
+ void RegisterExternallyReferencedObject(Object** object);
+
private:
+ class EvacuateNewSpacePageVisitor;
class EvacuateNewSpaceVisitor;
class EvacuateOldSpaceVisitor;
+ class EvacuateRecordOnlyVisitor;
class EvacuateVisitorBase;
class HeapObjectVisitor;
- class SweeperTask;
-
- typedef std::vector<Page*> SweepingList;
explicit MarkCompactCollector(Heap* heap);
bool WillBeDeoptimized(Code* code);
void ClearInvalidRememberedSetSlots();
- void StartSweeperThreads();
-
void ComputeEvacuationHeuristics(int area_size,
int* target_fragmentation_percent,
int* max_evacuated_bytes);
-#ifdef DEBUG
- enum CollectorState {
- IDLE,
- PREPARE_GC,
- MARK_LIVE_OBJECTS,
- SWEEP_SPACES,
- ENCODE_FORWARDING_ADDRESSES,
- UPDATE_POINTERS,
- RELOCATE_OBJECTS
- };
-
- // The current stage of the collector.
- CollectorState state_;
-#endif
-
- MarkingParity marking_parity_;
-
- bool was_marked_incrementally_;
-
- bool evacuation_;
-
// Finishes GC, performs heap verification if enabled.
void Finish();
@@ -678,8 +704,8 @@
// or overflowed in the heap. This respects references only considered in
// the final atomic marking pause including the following:
// - Processing of objects reachable through Harmony WeakMaps.
- // - Objects reachable due to host application logic like object groups
- // or implicit references' groups.
+ // - Objects reachable due to host application logic like object groups,
+ // implicit references' groups, or embedder heap tracing.
void ProcessEphemeralMarking(ObjectVisitor* visitor,
bool only_process_harmony_weak_collections);
@@ -761,8 +787,6 @@
// 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.
@@ -782,25 +806,20 @@
// Iterates through all live objects on a page using marking information.
// Returns whether all objects have successfully been visited.
- bool VisitLiveObjects(MemoryChunk* page, HeapObjectVisitor* visitor,
+ template <class Visitor>
+ bool VisitLiveObjects(MemoryChunk* page, Visitor* visitor,
IterationMode mode);
void VisitLiveObjectsBody(Page* page, ObjectVisitor* visitor);
void RecomputeLiveBytes(MemoryChunk* page);
- void SweepAbortedPages();
-
void ReleaseEvacuationCandidates();
// Starts sweeping of a space by contributing on the main thread and setting
// 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);
@@ -810,39 +829,52 @@
#endif
Heap* heap_;
- base::VirtualMemory* marking_deque_memory_;
- size_t marking_deque_memory_committed_;
- MarkingDeque marking_deque_;
- CodeFlusher* code_flusher_;
- bool have_code_to_deoptimize_;
- List<Page*> evacuation_candidates_;
- List<NewSpacePage*> newspace_evacuation_candidates_;
+ base::Semaphore page_parallel_job_semaphore_;
- base::Mutex swept_pages_mutex_;
- List<Page*> swept_old_space_pages_;
- List<Page*> swept_code_space_pages_;
- List<Page*> swept_map_space_pages_;
+#ifdef DEBUG
+ enum CollectorState {
+ IDLE,
+ PREPARE_GC,
+ MARK_LIVE_OBJECTS,
+ SWEEP_SPACES,
+ ENCODE_FORWARDING_ADDRESSES,
+ UPDATE_POINTERS,
+ RELOCATE_OBJECTS
+ };
- SweepingList sweeping_list_old_space_;
- SweepingList sweeping_list_code_space_;
- SweepingList sweeping_list_map_space_;
+ // The current stage of the collector.
+ CollectorState state_;
+#endif
+
+ MarkingParity marking_parity_;
+
+ bool was_marked_incrementally_;
+
+ bool evacuation_;
// 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_;
+ bool have_code_to_deoptimize_;
+
+ base::VirtualMemory* marking_deque_memory_;
+ size_t marking_deque_memory_committed_;
+ MarkingDeque marking_deque_;
+ std::vector<std::pair<void*, void*>> wrappers_to_trace_;
+
+ CodeFlusher* code_flusher_;
+
+ EmbedderHeapTracer* embedder_heap_tracer_;
+
+ List<Page*> evacuation_candidates_;
+ List<Page*> newspace_evacuation_candidates_;
+
+ Sweeper sweeper_;
+
friend class Heap;
friend class StoreBuffer;
};