[heap] Do not clear mark bits of left trimmed old object start.

BUG=chromium:694255

Review-Url: https://codereview.chromium.org/2731363002
Cr-Commit-Position: refs/heads/master@{#43645}
This commit is contained in:
hpayer 2017-03-07 07:16:49 -08:00 committed by Commit bot
parent 7bc196d2a5
commit 6517b4477c
5 changed files with 21 additions and 32 deletions

View File

@ -3200,16 +3200,6 @@ FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
// we still do it.
CreateFillerObjectAt(old_start, bytes_to_trim, ClearRecordedSlots::kYes);
// Clear the mark bits of the black area that belongs now to the filler.
// This is an optimization. The sweeper will release black fillers anyway.
if (incremental_marking()->black_allocation() &&
Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(object))) {
Page* page = Page::FromAddress(old_start);
page->markbits()->ClearRange(
page->AddressToMarkbitIndex(old_start),
page->AddressToMarkbitIndex(old_start + bytes_to_trim));
}
// Initialize header of the trimmed array. Since left trimming is only
// performed on pages which are not concurrently swept creating a filler
// object does not require synchronization.

View File

@ -138,25 +138,13 @@ void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from,
MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to);
MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from);
#ifdef DEBUG
Marking::ObjectColor old_color = Marking::Color(old_mark_bit);
#endif
if (Marking::IsBlack(old_mark_bit)) {
Marking::MarkWhite(old_mark_bit);
Marking::WhiteToBlack(new_mark_bit);
return;
Marking::MarkBlack(new_mark_bit);
} else if (Marking::IsGrey(old_mark_bit)) {
Marking::MarkWhite(old_mark_bit);
Marking::WhiteToGrey(new_mark_bit);
Marking::MarkGrey(new_mark_bit);
heap->mark_compact_collector()->marking_deque()->Push(to);
heap->incremental_marking()->RestartIfNotMarking();
}
#ifdef DEBUG
Marking::ObjectColor new_color = Marking::Color(new_mark_bit);
DCHECK(new_color == old_color);
#endif
}
class IncrementalMarkingMarkingVisitor
@ -835,10 +823,10 @@ intptr_t IncrementalMarking::ProcessMarkingDeque(
completion == FORCE_COMPLETION)) {
HeapObject* obj = marking_deque->Pop();
// Left trimming may result in white filler objects on the marking deque.
// Ignore these objects.
// Left trimming may result in white, grey, or black filler objects on the
// marking deque. Ignore these objects.
if (obj->IsFiller()) {
DCHECK(ObjectMarking::IsImpossible(obj) || ObjectMarking::IsWhite(obj));
DCHECK(!ObjectMarking::IsImpossible(obj));
continue;
}

View File

@ -179,9 +179,13 @@ HeapObject* LiveObjectIterator<T>::Next() {
// We found a live object.
if (object != nullptr) {
if (map == heap()->one_pointer_filler_map()) {
// Black areas together with slack tracking may result in black one
// word filler objects. We filter these objects out in the iterator.
if (object->IsFiller()) {
// There are two reasons why we can get black or grey fillers:
// 1) Black areas together with slack tracking may result in black one
// word filler objects.
// 2) Left trimming may leave black or grey fillers behind because we
// do not clear the old location of the object start.
// We filter these objects out in the iterator.
object = nullptr;
} else {
break;

View File

@ -304,6 +304,13 @@ class Marking : public AllStatic {
markbit.Next().Clear();
}
INLINE(static void MarkGrey(MarkBit markbit)) { markbit.Set(); }
INLINE(static void MarkBlack(MarkBit markbit)) {
markbit.Set();
markbit.Next().Set();
}
INLINE(static void BlackToGrey(MarkBit markbit)) {
DCHECK(IsBlack(markbit));
markbit.Next().Clear();

View File

@ -6372,7 +6372,7 @@ TEST(ContinuousLeftTrimFixedArrayInBlackArea) {
HeapObject* filler = HeapObject::FromAddress(previous->address());
CHECK(filler->IsFiller());
CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(trimmed)));
CHECK(Marking::IsImpossible(ObjectMarking::MarkBitFrom(previous)));
CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(previous)));
previous = trimmed;
}
@ -6383,7 +6383,7 @@ TEST(ContinuousLeftTrimFixedArrayInBlackArea) {
HeapObject* filler = HeapObject::FromAddress(previous->address());
CHECK(filler->IsFiller());
CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(trimmed)));
CHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(previous)));
CHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(previous)));
previous = trimmed;
}
}