| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/incremental-marking.h" | 5 #include "src/heap/incremental-marking.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/compilation-cache.h" | 8 #include "src/compilation-cache.h" |
| 9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
| 10 #include "src/heap/concurrent-marking.h" | 10 #include "src/heap/concurrent-marking.h" |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 544 |
| 545 heap_->CompletelyClearInstanceofCache(); | 545 heap_->CompletelyClearInstanceofCache(); |
| 546 heap_->isolate()->compilation_cache()->MarkCompactPrologue(); | 546 heap_->isolate()->compilation_cache()->MarkCompactPrologue(); |
| 547 | 547 |
| 548 // Mark strong roots grey. | 548 // Mark strong roots grey. |
| 549 IncrementalMarkingRootMarkingVisitor visitor(this); | 549 IncrementalMarkingRootMarkingVisitor visitor(this); |
| 550 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 550 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
| 551 | 551 |
| 552 if (FLAG_concurrent_marking) { | 552 if (FLAG_concurrent_marking) { |
| 553 ConcurrentMarking* concurrent_marking = heap_->concurrent_marking(); | 553 ConcurrentMarking* concurrent_marking = heap_->concurrent_marking(); |
| 554 marking_deque()->Iterate([concurrent_marking](HeapObject* obj) { | |
| 555 concurrent_marking->AddRoot(obj); | |
| 556 }); | |
| 557 concurrent_marking->StartTask(); | 554 concurrent_marking->StartTask(); |
| 558 } | 555 } |
| 559 | 556 |
| 560 // Ready to start incremental marking. | 557 // Ready to start incremental marking. |
| 561 if (FLAG_trace_incremental_marking) { | 558 if (FLAG_trace_incremental_marking) { |
| 562 heap()->isolate()->PrintWithTimestamp("[IncrementalMarking] Running\n"); | 559 heap()->isolate()->PrintWithTimestamp("[IncrementalMarking] Running\n"); |
| 563 } | 560 } |
| 564 } | 561 } |
| 565 | 562 |
| 566 void IncrementalMarking::StartBlackAllocation() { | 563 void IncrementalMarking::StartBlackAllocation() { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 } | 701 } |
| 705 } | 702 } |
| 706 | 703 |
| 707 void IncrementalMarking::FinalizeIncrementally() { | 704 void IncrementalMarking::FinalizeIncrementally() { |
| 708 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE_BODY); | 705 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_INCREMENTAL_FINALIZE_BODY); |
| 709 DCHECK(!finalize_marking_completed_); | 706 DCHECK(!finalize_marking_completed_); |
| 710 DCHECK(IsMarking()); | 707 DCHECK(IsMarking()); |
| 711 | 708 |
| 712 double start = heap_->MonotonicallyIncreasingTimeInMs(); | 709 double start = heap_->MonotonicallyIncreasingTimeInMs(); |
| 713 | 710 |
| 714 int old_marking_deque_top = marking_deque()->top(); | |
| 715 | |
| 716 // After finishing incremental marking, we try to discover all unmarked | 711 // After finishing incremental marking, we try to discover all unmarked |
| 717 // objects to reduce the marking load in the final pause. | 712 // objects to reduce the marking load in the final pause. |
| 718 // 1) We scan and mark the roots again to find all changes to the root set. | 713 // 1) We scan and mark the roots again to find all changes to the root set. |
| 719 // 2) Age and retain maps embedded in optimized code. | 714 // 2) Age and retain maps embedded in optimized code. |
| 720 // 3) Remove weak cell with live values from the list of weak cells, they | 715 // 3) Remove weak cell with live values from the list of weak cells, they |
| 721 // do not need processing during GC. | 716 // do not need processing during GC. |
| 722 MarkRoots(); | 717 MarkRoots(); |
| 723 | 718 |
| 724 if (incremental_marking_finalization_rounds_ == 0) { | 719 if (incremental_marking_finalization_rounds_ == 0) { |
| 725 // Map retaining is needed for perfromance, not correctness, | 720 // Map retaining is needed for perfromance, not correctness, |
| 726 // so we can do it only once at the beginning of the finalization. | 721 // so we can do it only once at the beginning of the finalization. |
| 727 RetainMaps(); | 722 RetainMaps(); |
| 728 } | 723 } |
| 729 ProcessWeakCells(); | 724 ProcessWeakCells(); |
| 730 | 725 |
| 731 int marking_progress = abs(old_marking_deque_top - marking_deque()->top()); | 726 int marking_progress = |
| 732 | 727 heap_->mark_compact_collector()->marking_deque()->Size() + |
| 733 marking_progress += static_cast<int>( | 728 static_cast<int>( |
| 734 heap_->local_embedder_heap_tracer()->NumberOfCachedWrappersToTrace()); | 729 heap_->local_embedder_heap_tracer()->NumberOfCachedWrappersToTrace()); |
| 735 | 730 |
| 736 double end = heap_->MonotonicallyIncreasingTimeInMs(); | 731 double end = heap_->MonotonicallyIncreasingTimeInMs(); |
| 737 double delta = end - start; | 732 double delta = end - start; |
| 738 if (FLAG_trace_incremental_marking) { | 733 if (FLAG_trace_incremental_marking) { |
| 739 heap()->isolate()->PrintWithTimestamp( | 734 heap()->isolate()->PrintWithTimestamp( |
| 740 "[IncrementalMarking] Finalize incrementally round %d, " | 735 "[IncrementalMarking] Finalize incrementally round %d, " |
| 741 "spent %d ms, marking progress %d.\n", | 736 "spent %d ms, marking progress %d.\n", |
| 742 static_cast<int>(delta), incremental_marking_finalization_rounds_, | 737 static_cast<int>(delta), incremental_marking_finalization_rounds_, |
| 743 marking_progress); | 738 marking_progress); |
| 744 } | 739 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 756 // TODO(hpayer): Move to an earlier point as soon as we make faster marking | 751 // TODO(hpayer): Move to an earlier point as soon as we make faster marking |
| 757 // progress. | 752 // progress. |
| 758 StartBlackAllocation(); | 753 StartBlackAllocation(); |
| 759 } | 754 } |
| 760 } | 755 } |
| 761 | 756 |
| 762 | 757 |
| 763 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { | 758 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
| 764 if (!IsMarking()) return; | 759 if (!IsMarking()) return; |
| 765 | 760 |
| 766 int current = marking_deque()->bottom(); | 761 MarkingDeque* marking_deque = |
| 767 int mask = marking_deque()->mask(); | 762 heap_->mark_compact_collector()->marking_deque(); |
| 768 int limit = marking_deque()->top(); | |
| 769 HeapObject** array = marking_deque()->array(); | |
| 770 int new_top = current; | |
| 771 | |
| 772 Map* filler_map = heap_->one_pointer_filler_map(); | 763 Map* filler_map = heap_->one_pointer_filler_map(); |
| 773 | 764 Heap* heap = heap_; |
| 774 while (current != limit) { | 765 marking_deque->Update([heap, filler_map](HeapObject* obj) -> HeapObject* { |
| 775 HeapObject* obj = array[current]; | |
| 776 DCHECK(obj->IsHeapObject()); | 766 DCHECK(obj->IsHeapObject()); |
| 777 current = ((current + 1) & mask); | |
| 778 // Only pointers to from space have to be updated. | 767 // Only pointers to from space have to be updated. |
| 779 if (heap_->InFromSpace(obj)) { | 768 if (heap->InFromSpace(obj)) { |
| 780 MapWord map_word = obj->map_word(); | 769 MapWord map_word = obj->map_word(); |
| 781 // There may be objects on the marking deque that do not exist anymore, | 770 // There may be objects on the marking deque that do not exist anymore, |
| 782 // e.g. left trimmed objects or objects from the root set (frames). | 771 // e.g. left trimmed objects or objects from the root set (frames). |
| 783 // If these object are dead at scavenging time, their marking deque | 772 // If these object are dead at scavenging time, their marking deque |
| 784 // entries will not point to forwarding addresses. Hence, we can discard | 773 // entries will not point to forwarding addresses. Hence, we can discard |
| 785 // them. | 774 // them. |
| 786 if (map_word.IsForwardingAddress()) { | 775 if (!map_word.IsForwardingAddress()) return nullptr; |
| 787 HeapObject* dest = map_word.ToForwardingAddress(); | 776 HeapObject* dest = map_word.ToForwardingAddress(); |
| 788 if (ObjectMarking::IsBlack(dest, marking_state(dest))) continue; | 777 if (ObjectMarking::IsBlack(dest, MarkingState::Internal(dest))) { |
| 789 array[new_top] = dest; | 778 // The object is already processed by the marker. |
| 790 new_top = ((new_top + 1) & mask); | 779 return nullptr; |
| 791 DCHECK(new_top != marking_deque()->bottom()); | |
| 792 DCHECK(ObjectMarking::IsGrey(obj, marking_state(obj)) || | |
| 793 (obj->IsFiller() && | |
| 794 ObjectMarking::IsWhite(obj, marking_state(obj)))); | |
| 795 } | 780 } |
| 796 } else if (obj->map() != filler_map) { | 781 DCHECK(ObjectMarking::IsGrey(obj, MarkingState::Internal(obj)) || |
| 782 (obj->IsFiller() && |
| 783 ObjectMarking::IsWhite(obj, MarkingState::Internal(obj)))); |
| 784 return dest; |
| 785 } else { |
| 797 // Skip one word filler objects that appear on the | 786 // Skip one word filler objects that appear on the |
| 798 // stack when we perform in place array shift. | 787 // stack when we perform in place array shift. |
| 799 array[new_top] = obj; | 788 DCHECK(ObjectMarking::IsGrey(obj, MarkingState::Internal(obj)) || |
| 800 new_top = ((new_top + 1) & mask); | |
| 801 DCHECK(new_top != marking_deque()->bottom()); | |
| 802 DCHECK(ObjectMarking::IsGrey(obj, marking_state(obj)) || | |
| 803 (obj->IsFiller() && | 789 (obj->IsFiller() && |
| 804 ObjectMarking::IsWhite(obj, marking_state(obj))) || | 790 ObjectMarking::IsWhite(obj, marking_state(obj))) || |
| 805 (MemoryChunk::FromAddress(obj->address()) | 791 (MemoryChunk::FromAddress(obj->address()) |
| 806 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && | 792 ->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && |
| 807 ObjectMarking::IsBlack(obj, marking_state(obj)))); | 793 ObjectMarking::IsBlack(obj, MarkingState::Internal(obj)))); |
| 794 return (obj->map() == filler_map) ? nullptr : obj; |
| 808 } | 795 } |
| 809 } | 796 }); |
| 810 marking_deque()->set_top(new_top); | |
| 811 } | 797 } |
| 812 | 798 |
| 813 | 799 |
| 814 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { | 800 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { |
| 815 MarkGrey(map); | 801 MarkGrey(map); |
| 816 | 802 |
| 817 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); | 803 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); |
| 818 | 804 |
| 819 #if ENABLE_SLOW_DCHECKS | 805 #if ENABLE_SLOW_DCHECKS |
| 820 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj, marking_state(obj)); | 806 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj, marking_state(obj)); |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 idle_marking_delay_counter_++; | 1163 idle_marking_delay_counter_++; |
| 1178 } | 1164 } |
| 1179 | 1165 |
| 1180 | 1166 |
| 1181 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1167 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
| 1182 idle_marking_delay_counter_ = 0; | 1168 idle_marking_delay_counter_ = 0; |
| 1183 } | 1169 } |
| 1184 | 1170 |
| 1185 } // namespace internal | 1171 } // namespace internal |
| 1186 } // namespace v8 | 1172 } // namespace v8 |
| OLD | NEW |