From 515d26063468c392db6ad8efc5cf267a6556c8a5 Mon Sep 17 00:00:00 2001 From: yangguo Date: Thu, 12 Feb 2015 08:47:50 -0800 Subject: [PATCH] Mark pages created during bootstrapping as never-evacuate. This is to ensure that immutable immortal objects created during bootstrapping are not relocated. R=hpayer@chromium.org Review URL: https://codereview.chromium.org/905773004 Cr-Commit-Position: refs/heads/master@{#26625} --- src/heap/heap.cc | 12 +++++++++++- src/heap/mark-compact.cc | 4 ++-- src/heap/spaces.cc | 3 +++ src/heap/spaces.h | 11 ++++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/heap/heap.cc b/src/heap/heap.cc index 45a15a2..07b47b0 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc @@ -5620,7 +5620,17 @@ void Heap::SetStackLimits() { } -void Heap::NotifyDeserializationComplete() { deserialization_complete_ = true; } +void Heap::NotifyDeserializationComplete() { + deserialization_complete_ = true; +#ifdef DEBUG + // All pages right after bootstrapping must be marked as never-evacuate. + PagedSpaces spaces(this); + for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { + PageIterator it(s); + while (it.has_next()) CHECK(it.next()->NeverEvacuate()); + } +#endif // DEBUG +} void Heap::TearDown() { diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index e4e5258..de0b0af 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -242,6 +242,7 @@ void MarkCompactCollector::TearDown() { void MarkCompactCollector::AddEvacuationCandidate(Page* p) { + DCHECK(!p->NeverEvacuate()); p->MarkEvacuationCandidate(); evacuation_candidates_.Add(p); } @@ -719,10 +720,9 @@ void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { Candidate* least = NULL; PageIterator it(space); - if (it.has_next()) it.next(); // Never compact the first page. - while (it.has_next()) { Page* p = it.next(); + if (p->NeverEvacuate()) continue; p->ClearEvacuationCandidate(); if (FLAG_stress_compaction) { diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc index 1a0d0bb..de752f3 100644 --- a/src/heap/spaces.cc +++ b/src/heap/spaces.cc @@ -1032,6 +1032,9 @@ bool PagedSpace::Expand() { executable()); if (p == NULL) return false; + // Pages created during bootstrapping may contain immortal immovable objects. + if (!heap()->deserialization_complete()) p->MarkNeverEvacuate(); + DCHECK(Capacity() <= max_capacity_); p->InsertAfter(anchor_.prev_page()); diff --git a/src/heap/spaces.h b/src/heap/spaces.h index efb784c..3a6bd30 100644 --- a/src/heap/spaces.h +++ b/src/heap/spaces.h @@ -373,6 +373,7 @@ class MemoryChunk { CONTAINS_ONLY_DATA, EVACUATION_CANDIDATE, RESCAN_ON_EVACUATION, + NEVER_EVACUATE, // May contain immortal immutables. // WAS_SWEPT indicates that marking bits have been cleared by the sweeper, // otherwise marking bits are still intact. @@ -604,7 +605,14 @@ class MemoryChunk { static const int kFlagsOffset = kPointerSize; - bool IsEvacuationCandidate() { return IsFlagSet(EVACUATION_CANDIDATE); } + bool NeverEvacuate() { return IsFlagSet(NEVER_EVACUATE); } + + void MarkNeverEvacuate() { SetFlag(NEVER_EVACUATE); } + + bool IsEvacuationCandidate() { + DCHECK(!(IsFlagSet(NEVER_EVACUATE) && IsFlagSet(EVACUATION_CANDIDATE))); + return IsFlagSet(EVACUATION_CANDIDATE); + } bool ShouldSkipEvacuationSlotRecording() { return (flags_ & kSkipEvacuationSlotsRecordingMask) != 0; @@ -619,6 +627,7 @@ class MemoryChunk { inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; } void MarkEvacuationCandidate() { + DCHECK(!IsFlagSet(NEVER_EVACUATE)); DCHECK(slots_buffer_ == NULL); SetFlag(EVACUATION_CANDIDATE); } -- 2.7.4