Commit 63c6f7da authored by ulan's avatar ulan Committed by Commit bot

Avoid evacuation of popular pages.

This breaks the (evacuation -> slots buffer overflow -> abort -> new GC -> evacuation) cycle for popular pages.

BUG=

Review URL: https://codereview.chromium.org/1037433002

Cr-Commit-Position: refs/heads/master@{#27868}
parent c66a2f7b
...@@ -60,7 +60,7 @@ void MarkCompactCollector::RecordSlot(Object** anchor_slot, Object** slot, ...@@ -60,7 +60,7 @@ void MarkCompactCollector::RecordSlot(Object** anchor_slot, Object** slot,
!ShouldSkipEvacuationSlotRecording(anchor_slot)) { !ShouldSkipEvacuationSlotRecording(anchor_slot)) {
if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
object_page->slots_buffer_address(), slot, mode)) { object_page->slots_buffer_address(), slot, mode)) {
EvictEvacuationCandidate(object_page); EvictPopularEvacuationCandidate(object_page);
} }
} }
} }
......
...@@ -774,6 +774,11 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { ...@@ -774,6 +774,11 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
while (it.has_next()) { while (it.has_next()) {
Page* p = it.next(); Page* p = it.next();
if (p->NeverEvacuate()) continue; if (p->NeverEvacuate()) continue;
if (p->IsFlagSet(Page::POPULAR_PAGE)) {
// This page had slots buffer overflow on previous GC, skip it.
p->ClearFlag(Page::POPULAR_PAGE);
continue;
}
// Invariant: Evacuation candidates are just created when marking is // Invariant: Evacuation candidates are just created when marking is
// started. At the end of a GC all evacuation candidates are cleared and // started. At the end of a GC all evacuation candidates are cleared and
...@@ -4617,13 +4622,13 @@ void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) { ...@@ -4617,13 +4622,13 @@ void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) {
SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW); SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW);
} }
if (!success) { if (!success) {
EvictEvacuationCandidate(target_page); EvictPopularEvacuationCandidate(target_page);
} }
} }
} }
void MarkCompactCollector::EvictEvacuationCandidate(Page* page) { void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) {
if (FLAG_trace_fragmentation) { if (FLAG_trace_fragmentation) {
PrintF("Page %p is too popular. Disabling evacuation.\n", PrintF("Page %p is too popular. Disabling evacuation.\n",
reinterpret_cast<void*>(page)); reinterpret_cast<void*>(page));
...@@ -4635,6 +4640,9 @@ void MarkCompactCollector::EvictEvacuationCandidate(Page* page) { ...@@ -4635,6 +4640,9 @@ void MarkCompactCollector::EvictEvacuationCandidate(Page* page) {
// should stop slots recording entirely. // should stop slots recording entirely.
page->ClearEvacuationCandidate(); page->ClearEvacuationCandidate();
DCHECK(!page->IsFlagSet(Page::POPULAR_PAGE));
page->SetFlag(Page::POPULAR_PAGE);
// We were not collecting slots on this page that point // We were not collecting slots on this page that point
// to other evacuation candidates thus we have to // to other evacuation candidates thus we have to
// rescan the page after evacuation to discover and update all // rescan the page after evacuation to discover and update all
...@@ -4651,7 +4659,7 @@ void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) { ...@@ -4651,7 +4659,7 @@ void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) {
target_page->slots_buffer_address(), target_page->slots_buffer_address(),
SlotsBuffer::CODE_ENTRY_SLOT, slot, SlotsBuffer::CODE_ENTRY_SLOT, slot,
SlotsBuffer::FAIL_ON_OVERFLOW)) { SlotsBuffer::FAIL_ON_OVERFLOW)) {
EvictEvacuationCandidate(target_page); EvictPopularEvacuationCandidate(target_page);
} }
} }
} }
......
...@@ -724,7 +724,7 @@ class MarkCompactCollector { ...@@ -724,7 +724,7 @@ class MarkCompactCollector {
bool WillBeDeoptimized(Code* code); bool WillBeDeoptimized(Code* code);
void RemoveDeadInvalidatedCode(); void RemoveDeadInvalidatedCode();
void ProcessInvalidatedCode(ObjectVisitor* visitor); void ProcessInvalidatedCode(ObjectVisitor* visitor);
void EvictEvacuationCandidate(Page* page); void EvictPopularEvacuationCandidate(Page* page);
void ClearInvalidSlotsBufferEntries(PagedSpace* space); void ClearInvalidSlotsBufferEntries(PagedSpace* space);
void ClearInvalidStoreAndSlotsBufferEntries(); void ClearInvalidStoreAndSlotsBufferEntries();
......
...@@ -367,6 +367,7 @@ class MemoryChunk { ...@@ -367,6 +367,7 @@ class MemoryChunk {
EVACUATION_CANDIDATE, EVACUATION_CANDIDATE,
RESCAN_ON_EVACUATION, RESCAN_ON_EVACUATION,
NEVER_EVACUATE, // May contain immortal immutables. NEVER_EVACUATE, // May contain immortal immutables.
POPULAR_PAGE, // Slots buffer of this page overflowed on the previous GC.
// WAS_SWEPT indicates that marking bits have been cleared by the sweeper, // WAS_SWEPT indicates that marking bits have been cleared by the sweeper,
// otherwise marking bits are still intact. // otherwise marking bits are still intact.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment