Index: src/heap/incremental-marking.cc |
diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc |
index f578d43b474481c6b8acb984f53210fbc3366579..c00df0cfb5bc46d596e4358ae81daa3db8e78eeb 100644 |
--- a/src/heap/incremental-marking.cc |
+++ b/src/heap/incremental-marking.cc |
@@ -49,10 +49,10 @@ IncrementalMarking::IncrementalMarking(Heap* heap) |
bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object* value) { |
HeapObject* value_heap_obj = HeapObject::cast(value); |
- MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); |
+ MarkBit value_bit = ObjectMarking::MarkBitFrom(value_heap_obj); |
DCHECK(!Marking::IsImpossible(value_bit)); |
- MarkBit obj_bit = Marking::MarkBitFrom(obj); |
+ MarkBit obj_bit = ObjectMarking::MarkBitFrom(obj); |
DCHECK(!Marking::IsImpossible(obj_bit)); |
bool is_black = Marking::IsBlack(obj_bit); |
@@ -150,7 +150,7 @@ void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
static void MarkObjectGreyDoNotEnqueue(Object* obj) { |
if (obj->IsHeapObject()) { |
HeapObject* heap_obj = HeapObject::cast(obj); |
- MarkBit mark_bit = Marking::MarkBitFrom(HeapObject::cast(obj)); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(HeapObject::cast(obj)); |
if (Marking::IsBlack(mark_bit)) { |
MemoryChunk::IncrementLiveBytesFromGC(heap_obj, -heap_obj->Size()); |
} |
@@ -158,6 +158,44 @@ static void MarkObjectGreyDoNotEnqueue(Object* obj) { |
} |
} |
+void IncrementalMarking::TransferMark(Heap* heap, Address old_start, |
+ Address new_start) { |
+ // This is only used when resizing an object. |
+ DCHECK(MemoryChunk::FromAddress(old_start) == |
+ MemoryChunk::FromAddress(new_start)); |
+ |
+ if (!heap->incremental_marking()->IsMarking() || |
+ Page::FromAddress(old_start)->IsFlagSet(Page::BLACK_PAGE)) |
+ return; |
+ |
+ // If the mark doesn't move, we don't check the color of the object. |
+ // It doesn't matter whether the object is black, since it hasn't changed |
+ // size, so the adjustment to the live data count will be zero anyway. |
+ if (old_start == new_start) return; |
+ |
+ MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(new_start); |
+ MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(old_start); |
+ |
+#ifdef DEBUG |
+ Marking::ObjectColor old_color = Marking::Color(old_mark_bit); |
+#endif |
+ |
+ if (Marking::IsBlack(old_mark_bit)) { |
+ Marking::BlackToWhite(old_mark_bit); |
+ Marking::MarkBlack(new_mark_bit); |
+ return; |
+ } else if (Marking::IsGrey(old_mark_bit)) { |
+ Marking::GreyToWhite(old_mark_bit); |
+ heap->incremental_marking()->WhiteToGreyAndPush( |
+ HeapObject::FromAddress(new_start), new_mark_bit); |
+ heap->incremental_marking()->RestartIfNotMarking(); |
+ } |
+ |
+#ifdef DEBUG |
+ Marking::ObjectColor new_color = Marking::Color(new_mark_bit); |
+ DCHECK(new_color == old_color); |
+#endif |
+} |
static inline void MarkBlackOrKeepBlack(HeapObject* heap_object, |
MarkBit mark_bit, int size) { |
@@ -167,7 +205,6 @@ static inline void MarkBlackOrKeepBlack(HeapObject* heap_object, |
MemoryChunk::IncrementLiveBytesFromGC(heap_object, size); |
} |
- |
class IncrementalMarkingMarkingVisitor |
: public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> { |
public: |
@@ -214,10 +251,10 @@ class IncrementalMarkingMarkingVisitor |
} while (scan_until_end && start_offset < object_size); |
chunk->set_progress_bar(start_offset); |
if (start_offset < object_size) { |
- if (Marking::IsGrey(Marking::MarkBitFrom(object))) { |
+ if (Marking::IsGrey(ObjectMarking::MarkBitFrom(object))) { |
heap->mark_compact_collector()->marking_deque()->Unshift(object); |
} else { |
- DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); |
+ DCHECK(Marking::IsBlack(ObjectMarking::MarkBitFrom(object))); |
heap->mark_compact_collector()->UnshiftBlack(object); |
} |
heap->incremental_marking()->NotifyIncompleteScanOfObject( |
@@ -269,7 +306,7 @@ class IncrementalMarkingMarkingVisitor |
// Returns true if object needed marking and false otherwise. |
INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { |
HeapObject* heap_object = HeapObject::cast(obj); |
- MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); |
if (Marking::IsWhite(mark_bit)) { |
Marking::MarkBlack(mark_bit); |
MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size()); |
@@ -280,7 +317,7 @@ class IncrementalMarkingMarkingVisitor |
}; |
void IncrementalMarking::IterateBlackObject(HeapObject* object) { |
- if (IsMarking() && Marking::IsBlack(Marking::MarkBitFrom(object))) { |
+ if (IsMarking() && Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { |
Page* page = Page::FromAddress(object->address()); |
if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { |
// IterateBlackObject requires us to visit the whole object. |
@@ -654,7 +691,8 @@ bool ShouldRetainMap(Map* map, int age) { |
} |
Object* constructor = map->GetConstructor(); |
if (!constructor->IsHeapObject() || |
- Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(constructor)))) { |
+ Marking::IsWhite( |
+ ObjectMarking::MarkBitFrom(HeapObject::cast(constructor)))) { |
// The constructor is dead, no new objects with this map can |
// be created. Do not retain this map. |
return false; |
@@ -683,7 +721,7 @@ void IncrementalMarking::RetainMaps() { |
int age = Smi::cast(retained_maps->Get(i + 1))->value(); |
int new_age; |
Map* map = Map::cast(cell->value()); |
- MarkBit map_mark = Marking::MarkBitFrom(map); |
+ MarkBit map_mark = ObjectMarking::MarkBitFrom(map); |
if (i >= number_of_disposed_maps && !map_retaining_is_disabled && |
Marking::IsWhite(map_mark)) { |
if (ShouldRetainMap(map, age)) { |
@@ -691,7 +729,8 @@ void IncrementalMarking::RetainMaps() { |
} |
Object* prototype = map->prototype(); |
if (age > 0 && prototype->IsHeapObject() && |
- Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) { |
+ Marking::IsWhite( |
+ ObjectMarking::MarkBitFrom(HeapObject::cast(prototype)))) { |
// The prototype is not marked, age the map. |
new_age = age - 1; |
} else { |
@@ -803,7 +842,7 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
new_top = ((new_top + 1) & mask); |
DCHECK(new_top != marking_deque->bottom()); |
#ifdef DEBUG |
- MarkBit mark_bit = Marking::MarkBitFrom(obj); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
DCHECK(Marking::IsGrey(mark_bit) || |
(obj->IsFiller() && Marking::IsWhite(mark_bit))); |
#endif |
@@ -815,7 +854,7 @@ void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
new_top = ((new_top + 1) & mask); |
DCHECK(new_top != marking_deque->bottom()); |
#ifdef DEBUG |
- MarkBit mark_bit = Marking::MarkBitFrom(obj); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
DCHECK(Marking::IsGrey(mark_bit) || |
(obj->IsFiller() && Marking::IsWhite(mark_bit)) || |
@@ -833,7 +872,7 @@ void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { |
IncrementalMarkingMarkingVisitor::IterateBody(map, obj); |
- MarkBit mark_bit = Marking::MarkBitFrom(obj); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
#if ENABLE_SLOW_DCHECKS |
MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
SLOW_DCHECK(Marking::IsGrey(mark_bit) || |
@@ -846,7 +885,7 @@ void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { |
void IncrementalMarking::MarkObject(Heap* heap, HeapObject* obj) { |
- MarkBit mark_bit = Marking::MarkBitFrom(obj); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
if (Marking::IsWhite(mark_bit)) { |
heap->incremental_marking()->WhiteToGreyAndPush(obj, mark_bit); |
} |
@@ -933,7 +972,7 @@ void IncrementalMarking::Hurry() { |
HeapObject* cache = HeapObject::cast( |
Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); |
if (!cache->IsUndefined(heap_->isolate())) { |
- MarkBit mark_bit = Marking::MarkBitFrom(cache); |
+ MarkBit mark_bit = ObjectMarking::MarkBitFrom(cache); |
if (Marking::IsGrey(mark_bit)) { |
Marking::GreyToBlack(mark_bit); |
MemoryChunk::IncrementLiveBytesFromGC(cache, cache->Size()); |