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/gc-idle-time-handler.h" | 10 #include "src/heap/gc-idle-time-handler.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 bytes_rescanned_(0), | 35 bytes_rescanned_(0), |
36 should_hurry_(false), | 36 should_hurry_(false), |
37 marking_speed_(0), | 37 marking_speed_(0), |
38 bytes_scanned_(0), | 38 bytes_scanned_(0), |
39 allocated_(0), | 39 allocated_(0), |
40 write_barriers_invoked_since_last_step_(0), | 40 write_barriers_invoked_since_last_step_(0), |
41 idle_marking_delay_counter_(0), | 41 idle_marking_delay_counter_(0), |
42 no_marking_scope_depth_(0), | 42 no_marking_scope_depth_(0), |
43 unscanned_bytes_of_large_object_(0), | 43 unscanned_bytes_of_large_object_(0), |
44 was_activated_(false), | 44 was_activated_(false), |
45 weak_closure_was_overapproximated_(false), | 45 finalize_marking_completed_(false), |
46 weak_closure_approximation_rounds_(0), | 46 incremental_marking_finalization_rounds_(0), |
47 request_type_(COMPLETE_MARKING) {} | 47 request_type_(COMPLETE_MARKING) {} |
48 | 48 |
49 | 49 |
50 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot, | 50 bool IncrementalMarking::BaseRecordWrite(HeapObject* obj, Object** slot, |
51 Object* value) { | 51 Object* value) { |
52 HeapObject* value_heap_obj = HeapObject::cast(value); | 52 HeapObject* value_heap_obj = HeapObject::cast(value); |
53 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); | 53 MarkBit value_bit = Marking::MarkBitFrom(value_heap_obj); |
54 if (Marking::IsWhite(value_bit)) { | 54 if (Marking::IsWhite(value_bit)) { |
55 MarkBit obj_bit = Marking::MarkBitFrom(obj); | 55 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
56 if (Marking::IsBlack(obj_bit)) { | 56 if (Marking::IsBlack(obj_bit)) { |
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 IncrementalMarkingRootMarkingVisitor visitor(this); | 616 IncrementalMarkingRootMarkingVisitor visitor(this); |
617 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 617 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
618 | 618 |
619 // Ready to start incremental marking. | 619 // Ready to start incremental marking. |
620 if (FLAG_trace_incremental_marking) { | 620 if (FLAG_trace_incremental_marking) { |
621 PrintF("[IncrementalMarking] Running\n"); | 621 PrintF("[IncrementalMarking] Running\n"); |
622 } | 622 } |
623 } | 623 } |
624 | 624 |
625 | 625 |
| 626 void IncrementalMarking::MarkRoots() { |
| 627 DCHECK(FLAG_finalize_marking_incrementally); |
| 628 DCHECK(!finalize_marking_completed_); |
| 629 DCHECK(IsMarking()); |
| 630 |
| 631 IncrementalMarkingRootMarkingVisitor visitor(this); |
| 632 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
| 633 } |
| 634 |
| 635 |
626 void IncrementalMarking::MarkObjectGroups() { | 636 void IncrementalMarking::MarkObjectGroups() { |
627 DCHECK(FLAG_overapproximate_weak_closure); | 637 DCHECK(FLAG_finalize_marking_incrementally); |
628 DCHECK(!weak_closure_was_overapproximated_); | 638 DCHECK(!finalize_marking_completed_); |
| 639 DCHECK(IsMarking()); |
| 640 |
| 641 IncrementalMarkingRootMarkingVisitor visitor(this); |
| 642 heap_->mark_compact_collector()->MarkImplicitRefGroups(&MarkObject); |
| 643 heap_->isolate()->global_handles()->IterateObjectGroups( |
| 644 &visitor, &MarkCompactCollector::IsUnmarkedHeapObjectWithHeap); |
| 645 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); |
| 646 heap_->isolate()->global_handles()->RemoveObjectGroups(); |
| 647 } |
| 648 |
| 649 |
| 650 void IncrementalMarking::FinalizeIncrementally() { |
| 651 DCHECK(FLAG_finalize_marking_incrementally); |
| 652 DCHECK(!finalize_marking_completed_); |
629 DCHECK(IsMarking()); | 653 DCHECK(IsMarking()); |
630 | 654 |
631 int old_marking_deque_top = | 655 int old_marking_deque_top = |
632 heap_->mark_compact_collector()->marking_deque()->top(); | 656 heap_->mark_compact_collector()->marking_deque()->top(); |
633 | 657 |
634 heap_->mark_compact_collector()->MarkImplicitRefGroups(&MarkObject); | 658 // After finishing incremental marking, we try to discover all unmarked |
635 | 659 // objects to reduce the marking load in the final pause. |
636 IncrementalMarkingRootMarkingVisitor visitor(this); | 660 // 1) We scan and mark the roots again to find all changes to the root set. |
637 heap_->isolate()->global_handles()->IterateObjectGroups( | 661 // 2) We mark the object groups. |
638 &visitor, &MarkCompactCollector::IsUnmarkedHeapObjectWithHeap); | 662 MarkRoots(); |
| 663 MarkObjectGroups(); |
639 | 664 |
640 int marking_progress = | 665 int marking_progress = |
641 abs(old_marking_deque_top - | 666 abs(old_marking_deque_top - |
642 heap_->mark_compact_collector()->marking_deque()->top()); | 667 heap_->mark_compact_collector()->marking_deque()->top()) / |
| 668 kPointerSize; |
643 | 669 |
644 ++weak_closure_approximation_rounds_; | 670 ++incremental_marking_finalization_rounds_; |
645 if ((weak_closure_approximation_rounds_ >= | 671 if ((incremental_marking_finalization_rounds_ >= |
646 FLAG_max_object_groups_marking_rounds) || | 672 FLAG_max_incremental_marking_finalization_rounds) || |
647 (marking_progress < FLAG_min_progress_during_object_groups_marking)) { | 673 (marking_progress < |
648 weak_closure_was_overapproximated_ = true; | 674 FLAG_min_progress_during_incremental_marking_finalization)) { |
| 675 finalize_marking_completed_ = true; |
649 } | 676 } |
650 | |
651 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); | |
652 heap_->isolate()->global_handles()->RemoveObjectGroups(); | |
653 } | 677 } |
654 | 678 |
655 | 679 |
656 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { | 680 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
657 if (!IsMarking()) return; | 681 if (!IsMarking()) return; |
658 | 682 |
659 MarkingDeque* marking_deque = | 683 MarkingDeque* marking_deque = |
660 heap_->mark_compact_collector()->marking_deque(); | 684 heap_->mark_compact_collector()->marking_deque(); |
661 int current = marking_deque->bottom(); | 685 int current = marking_deque->bottom(); |
662 int mask = marking_deque->mask(); | 686 int mask = marking_deque->mask(); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
853 IncrementalMarking::set_should_hurry(false); | 877 IncrementalMarking::set_should_hurry(false); |
854 ResetStepCounters(); | 878 ResetStepCounters(); |
855 PatchIncrementalMarkingRecordWriteStubs(heap_, | 879 PatchIncrementalMarkingRecordWriteStubs(heap_, |
856 RecordWriteStub::STORE_BUFFER_ONLY); | 880 RecordWriteStub::STORE_BUFFER_ONLY); |
857 DeactivateIncrementalWriteBarrier(); | 881 DeactivateIncrementalWriteBarrier(); |
858 DCHECK(heap_->mark_compact_collector()->marking_deque()->IsEmpty()); | 882 DCHECK(heap_->mark_compact_collector()->marking_deque()->IsEmpty()); |
859 heap_->isolate()->stack_guard()->ClearGC(); | 883 heap_->isolate()->stack_guard()->ClearGC(); |
860 } | 884 } |
861 | 885 |
862 | 886 |
863 void IncrementalMarking::OverApproximateWeakClosure(CompletionAction action) { | 887 void IncrementalMarking::FinalizeMarking(CompletionAction action) { |
864 DCHECK(FLAG_overapproximate_weak_closure); | 888 DCHECK(FLAG_finalize_marking_incrementally); |
865 DCHECK(!weak_closure_was_overapproximated_); | 889 DCHECK(!finalize_marking_completed_); |
866 if (FLAG_trace_incremental_marking) { | 890 if (FLAG_trace_incremental_marking) { |
867 PrintF("[IncrementalMarking] requesting weak closure overapproximation.\n"); | 891 PrintF( |
| 892 "[IncrementalMarking] requesting finalization of incremental " |
| 893 "marking.\n"); |
868 } | 894 } |
869 request_type_ = OVERAPPROXIMATION; | 895 request_type_ = FINALIZATION; |
870 if (action == GC_VIA_STACK_GUARD) { | 896 if (action == GC_VIA_STACK_GUARD) { |
871 heap_->isolate()->stack_guard()->RequestGC(); | 897 heap_->isolate()->stack_guard()->RequestGC(); |
872 } | 898 } |
873 } | 899 } |
874 | 900 |
875 | 901 |
876 void IncrementalMarking::MarkingComplete(CompletionAction action) { | 902 void IncrementalMarking::MarkingComplete(CompletionAction action) { |
877 state_ = COMPLETE; | 903 state_ = COMPLETE; |
878 // We will set the stack guard to request a GC now. This will mean the rest | 904 // We will set the stack guard to request a GC now. This will mean the rest |
879 // of the GC gets performed as soon as possible (we can't do a GC here in a | 905 // of the GC gets performed as soon as possible (we can't do a GC here in a |
880 // record-write context). If a few things get allocated between now and then | 906 // record-write context). If a few things get allocated between now and then |
881 // that shouldn't make us do a scavenge and keep being incremental, so we set | 907 // that shouldn't make us do a scavenge and keep being incremental, so we set |
882 // the should-hurry flag to indicate that there can't be much work left to do. | 908 // the should-hurry flag to indicate that there can't be much work left to do. |
883 set_should_hurry(true); | 909 set_should_hurry(true); |
884 if (FLAG_trace_incremental_marking) { | 910 if (FLAG_trace_incremental_marking) { |
885 PrintF("[IncrementalMarking] Complete (normal).\n"); | 911 PrintF("[IncrementalMarking] Complete (normal).\n"); |
886 } | 912 } |
887 request_type_ = COMPLETE_MARKING; | 913 request_type_ = COMPLETE_MARKING; |
888 if (action == GC_VIA_STACK_GUARD) { | 914 if (action == GC_VIA_STACK_GUARD) { |
889 heap_->isolate()->stack_guard()->RequestGC(); | 915 heap_->isolate()->stack_guard()->RequestGC(); |
890 } | 916 } |
891 } | 917 } |
892 | 918 |
893 | 919 |
894 void IncrementalMarking::Epilogue() { | 920 void IncrementalMarking::Epilogue() { |
895 was_activated_ = false; | 921 was_activated_ = false; |
896 weak_closure_was_overapproximated_ = false; | 922 finalize_marking_completed_ = false; |
897 weak_closure_approximation_rounds_ = 0; | 923 incremental_marking_finalization_rounds_ = 0; |
898 } | 924 } |
899 | 925 |
900 | 926 |
901 double IncrementalMarking::AdvanceIncrementalMarking( | 927 double IncrementalMarking::AdvanceIncrementalMarking( |
902 intptr_t step_size_in_bytes, double deadline_in_ms, | 928 intptr_t step_size_in_bytes, double deadline_in_ms, |
903 IncrementalMarking::StepActions step_actions) { | 929 IncrementalMarking::StepActions step_actions) { |
904 DCHECK(!IsStopped()); | 930 DCHECK(!IsStopped()); |
905 | 931 |
906 if (step_size_in_bytes == 0) { | 932 if (step_size_in_bytes == 0) { |
907 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( | 933 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 } | 1091 } |
1066 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { | 1092 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { |
1067 bytes_scanned_ = 0; | 1093 bytes_scanned_ = 0; |
1068 StartMarking(); | 1094 StartMarking(); |
1069 } | 1095 } |
1070 } else if (state_ == MARKING) { | 1096 } else if (state_ == MARKING) { |
1071 bytes_processed = ProcessMarkingDeque(bytes_to_process); | 1097 bytes_processed = ProcessMarkingDeque(bytes_to_process); |
1072 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { | 1098 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { |
1073 if (completion == FORCE_COMPLETION || | 1099 if (completion == FORCE_COMPLETION || |
1074 IsIdleMarkingDelayCounterLimitReached()) { | 1100 IsIdleMarkingDelayCounterLimitReached()) { |
1075 if (FLAG_overapproximate_weak_closure && | 1101 if (FLAG_finalize_marking_incrementally && |
1076 !weak_closure_was_overapproximated_) { | 1102 !finalize_marking_completed_) { |
1077 OverApproximateWeakClosure(action); | 1103 FinalizeMarking(action); |
1078 } else { | 1104 } else { |
1079 MarkingComplete(action); | 1105 MarkingComplete(action); |
1080 } | 1106 } |
1081 } else { | 1107 } else { |
1082 IncrementIdleMarkingDelayCounter(); | 1108 IncrementIdleMarkingDelayCounter(); |
1083 } | 1109 } |
1084 } | 1110 } |
1085 } | 1111 } |
1086 | 1112 |
1087 steps_count_++; | 1113 steps_count_++; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1153 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1128 idle_marking_delay_counter_++; | 1154 idle_marking_delay_counter_++; |
1129 } | 1155 } |
1130 | 1156 |
1131 | 1157 |
1132 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1158 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1133 idle_marking_delay_counter_ = 0; | 1159 idle_marking_delay_counter_ = 0; |
1134 } | 1160 } |
1135 } // namespace internal | 1161 } // namespace internal |
1136 } // namespace v8 | 1162 } // namespace v8 |
OLD | NEW |