| 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);
|
|
|