Index: src/heap/incremental-marking.cc |
diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc |
index 51b91badccaf7ef01b60096b808f062d5671bc0e..1ebfc9a4f6499c3c918264f0ee215273b8a51f6e 100644 |
--- a/src/heap/incremental-marking.cc |
+++ b/src/heap/incremental-marking.cc |
@@ -46,6 +46,36 @@ IncrementalMarking::IncrementalMarking(Heap* heap) |
request_type_(COMPLETE_MARKING) {} |
+bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot, |
+ Object* value) { |
+ HeapObject* value_heap_obj = HeapObject::cast(value); |
+ MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); |
+ if (Marking::IsWhite(value_bit)) { |
+ MarkBit obj_bit = Marking::MarkBitFrom(obj); |
+ if (Marking::IsBlack(obj_bit)) { |
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
+ if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { |
+ if (chunk->IsLeftOfProgressBar(slot)) { |
+ WhiteToGreyAndPush(value_heap_obj, value_bit); |
+ RestartIfNotMarking(); |
+ } else { |
+ return false; |
+ } |
+ } else { |
+ BlackToGreyAndUnshift(obj, obj_bit); |
+ RestartIfNotMarking(); |
+ return false; |
+ } |
+ } else { |
+ return false; |
+ } |
+ } |
+ if (!is_compacting_) return false; |
+ MarkBit obj_bit = Marking::MarkBitFrom(obj); |
+ return Marking::IsBlack(obj_bit); |
+} |
+ |
+ |
void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot, |
Object* value) { |
if (BaseRecordWrite(obj, slot, value) && slot != NULL) { |
@@ -133,6 +163,58 @@ void IncrementalMarking::RecordWriteIntoCodeSlow(HeapObject* obj, |
} |
+void IncrementalMarking::RecordWrites(HeapObject* obj) { |
+ if (IsMarking()) { |
+ MarkBit obj_bit = Marking::MarkBitFrom(obj); |
+ if (Marking::IsBlack(obj_bit)) { |
+ MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
+ if (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR)) { |
+ chunk->set_progress_bar(0); |
+ } |
+ BlackToGreyAndUnshift(obj, obj_bit); |
+ RestartIfNotMarking(); |
+ } |
+ } |
+} |
+ |
+ |
+void IncrementalMarking::BlackToGreyAndUnshift(HeapObject* obj, |
+ MarkBit mark_bit) { |
+ DCHECK(Marking::MarkBitFrom(obj) == mark_bit); |
+ DCHECK(obj->Size() >= 2 * kPointerSize); |
+ DCHECK(IsMarking()); |
+ Marking::BlackToGrey(mark_bit); |
+ int obj_size = obj->Size(); |
+ MemoryChunk::IncrementLiveBytesFromGC(obj, -obj_size); |
+ bytes_scanned_ -= obj_size; |
+ int64_t old_bytes_rescanned = bytes_rescanned_; |
+ bytes_rescanned_ = old_bytes_rescanned + obj_size; |
+ if ((bytes_rescanned_ >> 20) != (old_bytes_rescanned >> 20)) { |
+ if (bytes_rescanned_ > 2 * heap_->PromotedSpaceSizeOfObjects()) { |
+ // If we have queued twice the heap size for rescanning then we are |
+ // going around in circles, scanning the same objects again and again |
+ // as the program mutates the heap faster than we can incrementally |
+ // trace it. In this case we switch to non-incremental marking in |
+ // order to finish off this marking phase. |
+ if (FLAG_trace_incremental_marking) { |
+ PrintIsolate( |
+ heap()->isolate(), |
+ "Hurrying incremental marking because of lack of progress\n"); |
+ } |
+ marking_speed_ = kMaxMarkingSpeed; |
+ } |
+ } |
+ |
+ heap_->mark_compact_collector()->marking_deque()->Unshift(obj); |
+} |
+ |
+ |
+void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
+ Marking::WhiteToGrey(mark_bit); |
+ heap_->mark_compact_collector()->marking_deque()->Push(obj); |
+} |
+ |
+ |
static void MarkObjectGreyDoNotEnqueue(Object* obj) { |
if (obj->IsHeapObject()) { |
HeapObject* heap_obj = HeapObject::cast(obj); |