diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index b4fe7a3a0b..65b1361148 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -3292,8 +3292,13 @@ void MarkCompactCollector::EvacuatePagesInParallel() { // happens upon moving (which we potentially didn't do). // - Leave the page in the list of pages of a space since we could not // fully evacuate it. + // - Mark them for rescanning for store buffer entries as we otherwise + // might have stale store buffer entries that become "valid" again + // after reusing the memory. Note that all existing store buffer + // entries of such pages are filtered before rescanning. DCHECK(p->IsEvacuationCandidate()); p->SetFlag(Page::COMPACTION_WAS_ABORTED); + p->set_scan_on_scavenge(true); abandoned_pages++; break; case MemoryChunk::kCompactingFinalize: @@ -3705,9 +3710,6 @@ void MarkCompactCollector::EvacuateNewSpaceAndCandidates() { // First pass on aborted pages, fixing up all live objects. if (p->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { - // Clearing the evacuation candidate flag here has the effect of - // stopping recording of slots for it in the following pointer - // update phases. p->ClearEvacuationCandidate(); VisitLiveObjects(p, &updating_visitor); } diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h index 1b7cef59e4..8f178cd25a 100644 --- a/src/heap/mark-compact.h +++ b/src/heap/mark-compact.h @@ -797,6 +797,7 @@ class MarkCompactCollector { base::Semaphore pending_compaction_tasks_semaphore_; friend class Heap; + friend class StoreBuffer; }; diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc index ebc513a4fc..bd1b638635 100644 --- a/src/heap/store-buffer.cc +++ b/src/heap/store-buffer.cc @@ -490,13 +490,22 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { } } } else { - heap_->mark_compact_collector()->SweepOrWaitUntilSweepingCompleted( - page); - HeapObjectIterator iterator(page); - for (HeapObject* heap_object = iterator.Next(); heap_object != NULL; - heap_object = iterator.Next()) { - // We iterate over objects that contain new space pointers only. - heap_object->IterateBody(&visitor); + if (page->IsFlagSet(Page::COMPACTION_WAS_ABORTED)) { + // Aborted pages require iterating using mark bits because they + // don't have an iterable object layout before sweeping (which can + // only happen later). Note that we can never reach an + // aborted page through the scavenger. + DCHECK_EQ(heap_->gc_state(), Heap::MARK_COMPACT); + heap_->mark_compact_collector()->VisitLiveObjects(page, &visitor); + } else { + heap_->mark_compact_collector() + ->SweepOrWaitUntilSweepingCompleted(page); + HeapObjectIterator iterator(page); + for (HeapObject* heap_object = iterator.Next(); + heap_object != nullptr; heap_object = iterator.Next()) { + // We iterate over objects that contain new space pointers only. + heap_object->IterateBody(&visitor); + } } } }