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,
!ShouldSkipEvacuationSlotRecording(anchor_slot)) {
if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
object_page->slots_buffer_address(), slot, mode)) {
EvictEvacuationCandidate(object_page);
EvictPopularEvacuationCandidate(object_page);
}
}
}
......
......@@ -774,6 +774,11 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
while (it.has_next()) {
Page* p = it.next();
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
// started. At the end of a GC all evacuation candidates are cleared and
......@@ -4617,13 +4622,13 @@ void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) {
SlotTypeForRMode(rmode), rinfo->pc(), SlotsBuffer::FAIL_ON_OVERFLOW);
}
if (!success) {
EvictEvacuationCandidate(target_page);
EvictPopularEvacuationCandidate(target_page);
}
}
}
void MarkCompactCollector::EvictEvacuationCandidate(Page* page) {
void MarkCompactCollector::EvictPopularEvacuationCandidate(Page* page) {
if (FLAG_trace_fragmentation) {
PrintF("Page %p is too popular. Disabling evacuation.\n",
reinterpret_cast<void*>(page));
......@@ -4635,6 +4640,9 @@ void MarkCompactCollector::EvictEvacuationCandidate(Page* page) {
// should stop slots recording entirely.
page->ClearEvacuationCandidate();
DCHECK(!page->IsFlagSet(Page::POPULAR_PAGE));
page->SetFlag(Page::POPULAR_PAGE);
// We were not collecting slots on this page that point
// to other evacuation candidates thus we have to
// rescan the page after evacuation to discover and update all
......@@ -4651,7 +4659,7 @@ void MarkCompactCollector::RecordCodeEntrySlot(Address slot, Code* target) {
target_page->slots_buffer_address(),
SlotsBuffer::CODE_ENTRY_SLOT, slot,
SlotsBuffer::FAIL_ON_OVERFLOW)) {
EvictEvacuationCandidate(target_page);
EvictPopularEvacuationCandidate(target_page);
}
}
}
......
......@@ -724,7 +724,7 @@ class MarkCompactCollector {
bool WillBeDeoptimized(Code* code);
void RemoveDeadInvalidatedCode();
void ProcessInvalidatedCode(ObjectVisitor* visitor);
void EvictEvacuationCandidate(Page* page);
void EvictPopularEvacuationCandidate(Page* page);
void ClearInvalidSlotsBufferEntries(PagedSpace* space);
void ClearInvalidStoreAndSlotsBufferEntries();
......
......@@ -367,6 +367,7 @@ class MemoryChunk {
EVACUATION_CANDIDATE,
RESCAN_ON_EVACUATION,
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,
// 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