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

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

Issue 2796233003: [heap] Evacuation for young generation (Closed)
Patch Set: Disable flag Created 3 years, 8 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/spaces.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 f6d98bed55126cc86cfe0e779855bcb0fbee145a..e892c8983bd76823cb44710a91fbb65b8bd5af80 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -304,6 +304,30 @@ class FullEvacuationVerifier : public EvacuationVerifier {
}
};
+class YoungGenerationEvacuationVerifier : public EvacuationVerifier {
+ public:
+ explicit YoungGenerationEvacuationVerifier(Heap* heap)
+ : EvacuationVerifier(heap) {}
+
+ void Run() override {
+ VerifyRoots(VISIT_ALL_IN_SCAVENGE);
+ VerifyEvacuation(heap_->new_space());
+ VerifyEvacuation(heap_->old_space());
+ VerifyEvacuation(heap_->code_space());
+ VerifyEvacuation(heap_->map_space());
+ }
+
+ protected:
+ void VerifyPointers(Object** start, Object** end) override {
+ for (Object** current = start; current < end; current++) {
+ if ((*current)->IsHeapObject()) {
+ HeapObject* object = HeapObject::cast(*current);
+ CHECK_IMPLIES(heap()->InNewSpace(object), heap()->InToSpace(object));
+ }
+ }
+ }
+};
+
} // namespace
#endif // VERIFY_HEAP
@@ -440,7 +464,7 @@ void MarkCompactCollector::CollectGarbage() {
StartSweepSpaces();
- EvacuateNewSpaceAndCandidates();
+ Evacuate();
Finish();
}
@@ -1600,6 +1624,66 @@ class ExternalStringTableCleaner : public RootVisitor {
Heap* heap_;
};
+// Helper class for pruning the string table.
+class YoungGenerationExternalStringTableCleaner : public RootVisitor {
+ public:
+ YoungGenerationExternalStringTableCleaner(
+ const MinorMarkCompactCollector& collector)
+ : heap_(collector.heap()), collector_(collector) {}
+
+ void VisitRootPointers(Root root, Object** start, Object** end) override {
+ DCHECK_EQ(static_cast<int>(root),
+ static_cast<int>(Root::kExternalStringsTable));
+ // Visit all HeapObject pointers in [start, end).
+ for (Object** p = start; p < end; p++) {
+ Object* o = *p;
+ if (o->IsHeapObject()) {
+ HeapObject* heap_object = HeapObject::cast(o);
+ if (ObjectMarking::IsWhite(heap_object,
+ collector_.marking_state(heap_object))) {
+ if (o->IsExternalString()) {
+ heap_->FinalizeExternalString(String::cast(*p));
+ } else {
+ // The original external string may have been internalized.
+ DCHECK(o->IsThinString());
+ }
+ // Set the entry to the_hole_value (as deleted).
+ *p = heap_->the_hole_value();
+ }
+ }
+ }
+ }
+
+ private:
+ Heap* heap_;
+ const MinorMarkCompactCollector& collector_;
+};
+
+// Marked young generation objects and all old generation objects will be
+// retained.
+class MinorMarkCompactWeakObjectRetainer : public WeakObjectRetainer {
+ public:
+ explicit MinorMarkCompactWeakObjectRetainer(
+ const MinorMarkCompactCollector& collector)
+ : collector_(collector) {}
+
+ virtual Object* RetainAs(Object* object) {
+ HeapObject* heap_object = HeapObject::cast(object);
+ if (!collector_.heap()->InNewSpace(heap_object)) return object;
+
+ DCHECK(!ObjectMarking::IsGrey(heap_object,
+ collector_.marking_state(heap_object)));
+ if (ObjectMarking::IsBlack(heap_object,
+ collector_.marking_state(heap_object))) {
+ return object;
+ }
+ return nullptr;
+ }
+
+ private:
+ const MinorMarkCompactCollector& collector_;
+};
+
// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
// are retained.
class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
@@ -1724,7 +1808,6 @@ class RecordMigratedSlotVisitor : public ObjectVisitor {
collector_->RecordRelocSlot(host, rinfo, cell);
}
- // Entries that will never move.
inline void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) override {
DCHECK_EQ(host, rinfo->host());
DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode()));
@@ -1781,6 +1864,76 @@ class ProfilingMigrationObserver final : public MigrationObserver {
}
};
+class YoungGenerationMigrationObserver final : public MigrationObserver {
+ public:
+ YoungGenerationMigrationObserver(Heap* heap,
+ MarkCompactCollector* mark_compact_collector)
+ : MigrationObserver(heap),
+ mark_compact_collector_(mark_compact_collector) {}
+
+ inline void Move(AllocationSpace dest, HeapObject* src, HeapObject* dst,
+ int size) final {
+ // Migrate color to old generation marking in case the object survived young
+ // generation garbage collection.
+ if (heap_->incremental_marking()->IsMarking()) {
+ DCHECK(ObjectMarking::IsWhite(
+ dst, mark_compact_collector_->marking_state(dst)));
+ heap_->incremental_marking()->TransferColor<MarkBit::ATOMIC>(src, dst);
+ }
+ }
+
+ protected:
+ base::Mutex mutex_;
+ MarkCompactCollector* mark_compact_collector_;
+};
+
+class YoungGenerationRecordMigratedSlotVisitor final
+ : public RecordMigratedSlotVisitor {
+ public:
+ explicit YoungGenerationRecordMigratedSlotVisitor(
+ MarkCompactCollector* collector)
+ : RecordMigratedSlotVisitor(collector) {}
+
+ inline void VisitCodeEntry(JSFunction* host, Address code_entry_slot) final {
+ Address code_entry = Memory::Address_at(code_entry_slot);
+ if (Page::FromAddress(code_entry)->IsEvacuationCandidate() &&
+ IsLive(host)) {
+ RememberedSet<OLD_TO_OLD>::InsertTyped(Page::FromAddress(code_entry_slot),
+ nullptr, CODE_ENTRY_SLOT,
+ code_entry_slot);
+ }
+ }
+
+ void VisitCodeTarget(Code* host, RelocInfo* rinfo) final { UNREACHABLE(); }
+ void VisitDebugTarget(Code* host, RelocInfo* rinfo) final { UNREACHABLE(); }
+ void VisitEmbeddedPointer(Code* host, RelocInfo* rinfo) final {
+ UNREACHABLE();
+ }
+ void VisitCellPointer(Code* host, RelocInfo* rinfo) final { UNREACHABLE(); }
+ void VisitCodeAgeSequence(Code* host, RelocInfo* rinfo) final {
+ UNREACHABLE();
+ }
+
+ private:
+ // Only record slots for host objects that are considered as live by the full
+ // collector.
+ inline bool IsLive(HeapObject* object) {
+ return ObjectMarking::IsBlack(object, collector_->marking_state(object));
+ }
+
+ inline void RecordMigratedSlot(HeapObject* host, Object* value,
+ Address slot) final {
+ if (value->IsHeapObject()) {
+ Page* p = Page::FromAddress(reinterpret_cast<Address>(value));
+ if (p->InNewSpace()) {
+ RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot);
+ } else if (p->IsEvacuationCandidate() && IsLive(host)) {
+ RememberedSet<OLD_TO_OLD>::Insert(Page::FromAddress(slot), slot);
+ }
+ }
+ }
+};
+
class HeapObjectVisitor {
public:
virtual ~HeapObjectVisitor() {}
@@ -2363,11 +2516,11 @@ SlotCallbackResult MinorMarkCompactCollector::CheckAndMarkObject(
return REMOVE_SLOT;
}
-static bool IsUnmarkedObject(Heap* heap, Object** p) {
+static bool IsUnmarkedObjectForYoungGeneration(Heap* heap, Object** p) {
DCHECK_IMPLIES(heap->InNewSpace(*p), heap->InToSpace(*p));
return heap->InNewSpace(*p) &&
!ObjectMarking::IsBlack(HeapObject::cast(*p),
- MarkingState::Internal(HeapObject::cast(*p)));
+ MarkingState::External(HeapObject::cast(*p)));
}
void MinorMarkCompactCollector::MarkLiveObjects() {
@@ -2416,11 +2569,11 @@ void MinorMarkCompactCollector::MarkLiveObjects() {
{
TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_MARK_GLOBAL_HANDLES);
isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending(
- &IsUnmarkedObject);
+ &IsUnmarkedObjectForYoungGeneration);
isolate()
->global_handles()
- ->IterateNewSpaceWeakUnmodifiedRoots<GlobalHandles::VISIT_OTHERS>(
- &root_visitor);
+ ->IterateNewSpaceWeakUnmodifiedRoots<
+ GlobalHandles::HANDLE_PHANTOM_NODES_VISIT_OTHERS>(&root_visitor);
ProcessMarkingDeque();
}
@@ -2452,14 +2605,106 @@ void MinorMarkCompactCollector::EmptyMarkingDeque() {
}
void MinorMarkCompactCollector::CollectGarbage() {
- MarkLiveObjects();
+ heap()->mark_compact_collector()->sweeper().EnsureNewSpaceCompleted();
+ MarkLiveObjects();
+ ClearNonLiveReferences();
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
YoungGenerationMarkingVerifier verifier(heap());
verifier.Run();
}
#endif // VERIFY_HEAP
+
+ Evacuate();
+#ifdef VERIFY_HEAP
+ if (FLAG_verify_heap) {
+ YoungGenerationEvacuationVerifier verifier(heap());
+ verifier.Run();
+ }
+#endif // VERIFY_HEAP
+
+ heap()->incremental_marking()->UpdateMarkingDequeAfterScavenge();
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MINOR_MC_CLEAR_LIVENESS);
+ for (Page* p : PageRange(heap()->new_space()->FromSpaceStart(),
+ heap()->new_space()->FromSpaceEnd())) {
+ marking_state(p).ClearLiveness();
+ }
+ }
+}
+
+void MinorMarkCompactCollector::ClearNonLiveReferences() {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR);
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_STRING_TABLE);
+ // Internalized strings are always stored in old space, so there is no need
+ // to clean them here.
+ YoungGenerationExternalStringTableCleaner external_visitor(*this);
+ heap()->external_string_table_.IterateNewSpaceStrings(&external_visitor);
+ heap()->external_string_table_.CleanUpNewSpaceStrings();
+ }
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_LISTS);
+ // Process the weak references.
+ MinorMarkCompactWeakObjectRetainer retainer(*this);
+ heap()->ProcessYoungWeakReferences(&retainer);
+ }
+}
+
+void MinorMarkCompactCollector::EvacuatePrologue() {
+ NewSpace* new_space = heap()->new_space();
+ // Append the list of new space pages to be processed.
+ for (Page* p : PageRange(new_space->bottom(), new_space->top())) {
+ new_space_evacuation_pages_.Add(p);
+ }
+ new_space->Flip();
+ new_space->ResetAllocationInfo();
+}
+
+void MinorMarkCompactCollector::EvacuateEpilogue() {
+ heap()->new_space()->set_age_mark(heap()->new_space()->top());
+}
+
+void MinorMarkCompactCollector::Evacuate() {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE);
+ Heap::RelocationLock relocation_lock(heap());
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_PROLOGUE);
+ EvacuatePrologue();
+ }
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_COPY);
+ EvacuatePagesInParallel();
+ }
+
+ UpdatePointersAfterEvacuation();
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_REBALANCE);
+ if (!heap()->new_space()->Rebalance()) {
+ FatalProcessOutOfMemory("NewSpace::Rebalance");
+ }
+ }
+
+ // Give pages that are queued to be freed back to the OS.
+ heap()->memory_allocator()->unmapper()->FreeQueuedChunks();
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_CLEAN_UP);
+ // TODO(mlippautz): Implement page promotion.
+ new_space_evacuation_pages_.Rewind(0);
+ }
+
+ {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_EPILOGUE);
+ EvacuateEpilogue();
+ }
}
void MarkCompactCollector::MarkLiveObjects() {
@@ -3316,9 +3561,55 @@ bool FullEvacuator::RawEvacuatePage(Page* page, intptr_t* live_bytes) {
return success;
}
+class YoungGenerationEvacuator : public Evacuator {
+ public:
+ YoungGenerationEvacuator(MinorMarkCompactCollector* collector,
+ RecordMigratedSlotVisitor* record_visitor)
+ : Evacuator(collector->heap(), record_visitor), collector_(collector) {}
+
+ protected:
+ bool RawEvacuatePage(Page* page, intptr_t* live_bytes) override;
+
+ MinorMarkCompactCollector* collector_;
+};
+
+bool YoungGenerationEvacuator::RawEvacuatePage(Page* page,
+ intptr_t* live_bytes) {
+ bool success = false;
+ LiveObjectVisitor object_visitor;
+ const MarkingState state = collector_->marking_state(page);
+ *live_bytes = state.live_bytes();
+ switch (ComputeEvacuationMode(page)) {
+ case kObjectsNewToOld:
+ success = object_visitor.VisitBlackObjects(
+ page, state, &new_space_visitor_, LiveObjectVisitor::kClearMarkbits);
+ DCHECK(success);
+ ArrayBufferTracker::ProcessBuffers(
+ page, ArrayBufferTracker::kUpdateForwardedRemoveOthers);
+ break;
+ case kPageNewToOld:
+ // TODO(mlippautz): Implement page promotion.
+ UNREACHABLE();
+ break;
+ case kPageNewToNew:
+ // TODO(mlippautz): Implement page promotion.
+ UNREACHABLE();
+ break;
+ case kObjectsOldToOld:
+ UNREACHABLE();
+ break;
+ }
+ return success;
+}
+
class EvacuationJobTraits {
public:
- typedef int* PerPageData; // Pointer to number of aborted pages.
+ struct PageData {
+ int* abandoned_pages; // Pointer to number of aborted pages.
+ MarkingState marking_state;
+ };
+
+ typedef PageData PerPageData;
typedef Evacuator* PerTaskData;
static const bool NeedSequentialFinalization = true;
@@ -3351,7 +3642,7 @@ class EvacuationJobTraits {
p->ClearEvacuationCandidate();
// Slots have already been recorded so we just need to add it to the
// sweeper, which will happen after updating pointers.
- *data += 1;
+ *data.abandoned_pages += 1;
}
break;
default:
@@ -3363,7 +3654,8 @@ class EvacuationJobTraits {
template <class Evacuator, class Collector>
void MarkCompactCollectorBase::CreateAndExecuteEvacuationTasks(
Collector* collector, PageParallelJob<EvacuationJobTraits>* job,
- RecordMigratedSlotVisitor* record_visitor, const intptr_t live_bytes,
+ RecordMigratedSlotVisitor* record_visitor,
+ MigrationObserver* migration_observer, const intptr_t live_bytes,
const int& abandoned_pages) {
// Used for trace summary.
double compaction_speed = 0;
@@ -3383,6 +3675,8 @@ void MarkCompactCollectorBase::CreateAndExecuteEvacuationTasks(
for (int i = 0; i < wanted_num_tasks; i++) {
evacuators[i] = new Evacuator(collector, record_visitor);
if (profiling) evacuators[i]->AddObserver(&profiling_observer);
+ if (migration_observer != nullptr)
+ evacuators[i]->AddObserver(migration_observer);
}
job->Run(wanted_num_tasks, [evacuators](int i) { return evacuators[i]; });
const Address top = heap()->new_space()->top();
@@ -3421,7 +3715,7 @@ void MarkCompactCollector::EvacuatePagesInParallel() {
intptr_t live_bytes = 0;
for (Page* page : old_space_evacuation_pages_) {
live_bytes += MarkingState::Internal(page).live_bytes();
- job.AddPage(page, &abandoned_pages);
+ job.AddPage(page, {&abandoned_pages, marking_state(page)});
}
const bool reduce_memory = heap()->ShouldReduceMemory();
@@ -3440,13 +3734,36 @@ void MarkCompactCollector::EvacuatePagesInParallel() {
}
}
- job.AddPage(page, &abandoned_pages);
+ job.AddPage(page, {&abandoned_pages, marking_state(page)});
}
DCHECK_GE(job.NumberOfPages(), 1);
RecordMigratedSlotVisitor record_visitor(this);
- CreateAndExecuteEvacuationTasks<FullEvacuator>(this, &job, &record_visitor,
- live_bytes, abandoned_pages);
+ CreateAndExecuteEvacuationTasks<FullEvacuator>(
+ this, &job, &record_visitor, nullptr, live_bytes, abandoned_pages);
+}
+
+void MinorMarkCompactCollector::EvacuatePagesInParallel() {
+ PageParallelJob<EvacuationJobTraits> job(
+ heap_, heap_->isolate()->cancelable_task_manager(),
+ &page_parallel_job_semaphore_);
+ int abandoned_pages = 0;
+ intptr_t live_bytes = 0;
+
+ for (Page* page : new_space_evacuation_pages_) {
+ intptr_t live_bytes_on_page = marking_state(page).live_bytes();
+ live_bytes += live_bytes_on_page;
+ // TODO(mlippautz): Implement page promotion.
+ job.AddPage(page, {&abandoned_pages, marking_state(page)});
+ }
+ DCHECK_GE(job.NumberOfPages(), 1);
+
+ YoungGenerationMigrationObserver observer(heap(),
+ heap()->mark_compact_collector());
+ YoungGenerationRecordMigratedSlotVisitor record_visitor(
+ heap()->mark_compact_collector());
+ CreateAndExecuteEvacuationTasks<YoungGenerationEvacuator>(
+ this, &job, &record_visitor, &observer, live_bytes, abandoned_pages);
}
class EvacuationWeakObjectRetainer : public WeakObjectRetainer {
@@ -3681,7 +3998,7 @@ void MarkCompactCollector::Sweeper::AddSweptPageSafe(PagedSpace* space,
swept_list_[space->identity()].Add(page);
}
-void MarkCompactCollector::EvacuateNewSpaceAndCandidates() {
+void MarkCompactCollector::Evacuate() {
TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE);
Heap::RelocationLock relocation_lock(heap());
@@ -3771,6 +4088,7 @@ class PointerUpdateJobTraits {
private:
static void UpdateUntypedPointers(Heap* heap, MemoryChunk* chunk) {
+ base::LockGuard<base::RecursiveMutex> guard(chunk->mutex());
if (type == OLD_TO_NEW) {
RememberedSet<OLD_TO_NEW>::Iterate(chunk, [heap](Address slot) {
return CheckAndUpdateOldToNewSlot(heap, slot);
@@ -3877,17 +4195,23 @@ void UpdatePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
class ToSpacePointerUpdateJobTraits {
public:
- typedef std::pair<Address, Address> PerPageData;
+ struct PageData {
+ Address start;
+ Address end;
+ MarkingState marking_state;
+ };
+
+ typedef PageData PerPageData;
typedef PointersUpdatingVisitor* PerTaskData;
static bool ProcessPageInParallel(Heap* heap, PerTaskData visitor,
- MemoryChunk* chunk, PerPageData limits) {
+ MemoryChunk* chunk, PerPageData page_data) {
if (chunk->IsFlagSet(Page::PAGE_NEW_NEW_PROMOTION)) {
// New->new promoted pages contain garbage so they require iteration
// using markbits.
- ProcessPageInParallelVisitLive(heap, visitor, chunk, limits);
+ ProcessPageInParallelVisitLive(heap, visitor, chunk, page_data);
} else {
- ProcessPageInParallelVisitAll(heap, visitor, chunk, limits);
+ ProcessPageInParallelVisitAll(heap, visitor, chunk, page_data);
}
return true;
}
@@ -3899,8 +4223,8 @@ class ToSpacePointerUpdateJobTraits {
private:
static void ProcessPageInParallelVisitAll(Heap* heap, PerTaskData visitor,
MemoryChunk* chunk,
- PerPageData limits) {
- for (Address cur = limits.first; cur < limits.second;) {
+ PerPageData page_data) {
+ for (Address cur = page_data.start; cur < page_data.end;) {
HeapObject* object = HeapObject::FromAddress(cur);
Map* map = object->map();
int size = object->SizeFromMap(map);
@@ -3911,8 +4235,8 @@ class ToSpacePointerUpdateJobTraits {
static void ProcessPageInParallelVisitLive(Heap* heap, PerTaskData visitor,
MemoryChunk* chunk,
- PerPageData limits) {
- LiveObjectIterator<kBlackObjects> it(chunk, MarkingState::Internal(chunk));
+ PerPageData page_data) {
+ LiveObjectIterator<kBlackObjects> it(chunk, page_data.marking_state);
HeapObject* object = NULL;
while ((object = it.Next()) != NULL) {
Map* map = object->map();
@@ -3922,7 +4246,10 @@ class ToSpacePointerUpdateJobTraits {
}
};
-void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
+template <class MarkingStateProvider>
+void UpdateToSpacePointersInParallel(
+ Heap* heap, base::Semaphore* semaphore,
+ const MarkingStateProvider& marking_state_provider) {
PageParallelJob<ToSpacePointerUpdateJobTraits> job(
heap, heap->isolate()->cancelable_task_manager(), semaphore);
Address space_start = heap->new_space()->bottom();
@@ -3931,7 +4258,7 @@ void UpdateToSpacePointersInParallel(Heap* heap, base::Semaphore* semaphore) {
Address start =
page->Contains(space_start) ? space_start : page->area_start();
Address end = page->Contains(space_end) ? space_end : page->area_end();
- job.AddPage(page, std::make_pair(start, end));
+ job.AddPage(page, {start, end, marking_state_provider.marking_state(page)});
}
PointersUpdatingVisitor visitor;
int num_tasks = FLAG_parallel_pointer_update ? job.NumberOfPages() : 1;
@@ -3945,7 +4272,8 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
{
TRACE_GC(heap()->tracer(),
GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW);
- UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_);
+ UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_,
+ *this);
// Update roots.
PointersUpdatingVisitor updating_visitor;
heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
@@ -3971,6 +4299,36 @@ void MarkCompactCollector::UpdatePointersAfterEvacuation() {
}
}
+void MinorMarkCompactCollector::UpdatePointersAfterEvacuation() {
+ TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS);
+
+ PointersUpdatingVisitor updating_visitor;
+
+ {
+ TRACE_GC(heap()->tracer(),
+ GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_TO_NEW);
+ UpdateToSpacePointersInParallel(heap_, &page_parallel_job_semaphore_,
+ *this);
+ // TODO(mlippautz): Iteration mode is not optimal as we process all
+ // global handles. Find a way to only process the ones related to new
+ // space.
+ heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE);
+ UpdatePointersInParallel<OLD_TO_NEW>(heap_, &page_parallel_job_semaphore_);
+ }
+
+ {
+ TRACE_GC(heap()->tracer(),
+ GCTracer::Scope::MC_EVACUATE_UPDATE_POINTERS_WEAK);
+
+ EvacuationWeakObjectRetainer evacuation_object_retainer;
+ heap()->ProcessWeakListRoots(&evacuation_object_retainer);
+
+ // Update pointers from external string table.
+ heap()->UpdateNewSpaceReferencesInExternalStringTable(
+ &UpdateReferenceInExternalStringTableEntry);
+ heap()->IterateEncounteredWeakCollections(&updating_visitor);
+ }
+}
void MarkCompactCollector::ReleaseEvacuationCandidates() {
for (Page* p : old_space_evacuation_pages_) {
@@ -4086,7 +4444,7 @@ void MarkCompactCollector::StartSweepSpace(PagedSpace* space) {
DCHECK(p->SweepingDone());
if (p->IsEvacuationCandidate()) {
- // Will be processed in EvacuateNewSpaceAndCandidates.
+ // Will be processed in Evacuate.
DCHECK(evacuation_candidates_.length() > 0);
continue;
}
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698