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}
}
-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() {
void MarkCompactCollector::AddEvacuationCandidate(Page* p) {
+ DCHECK(!p->NeverEvacuate());
p->MarkEvacuationCandidate();
evacuation_candidates_.Add(p);
}
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) {
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());
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.
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;
inline SlotsBuffer** slots_buffer_address() { return &slots_buffer_; }
void MarkEvacuationCandidate() {
+ DCHECK(!IsFlagSet(NEVER_EVACUATE));
DCHECK(slots_buffer_ == NULL);
SetFlag(EVACUATION_CANDIDATE);
}