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() { | |
ulan
2015/10/28 10:36:19
We are not tracking this pause in any of the histo
Hannes Payer (out of office)
2015/10/28 11:42:54
Good point! I will do that in a separate CL.
| |
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 MarkRoots(); |
635 | 659 MarkObjectGroups(); |
636 IncrementalMarkingRootMarkingVisitor visitor(this); | |
637 heap_->isolate()->global_handles()->IterateObjectGroups( | |
638 &visitor, &MarkCompactCollector::IsUnmarkedHeapObjectWithHeap); | |
639 | 660 |
640 int marking_progress = | 661 int marking_progress = |
641 abs(old_marking_deque_top - | 662 abs(old_marking_deque_top - |
642 heap_->mark_compact_collector()->marking_deque()->top()); | 663 heap_->mark_compact_collector()->marking_deque()->top()) / |
664 kPointerSize; | |
643 | 665 |
644 ++weak_closure_approximation_rounds_; | 666 ++incremental_marking_finalization_rounds_; |
645 if ((weak_closure_approximation_rounds_ >= | 667 if ((incremental_marking_finalization_rounds_ >= |
646 FLAG_max_object_groups_marking_rounds) || | 668 FLAG_max_incremental_marking_finalization_rounds) || |
647 (marking_progress < FLAG_min_progress_during_object_groups_marking)) { | 669 (marking_progress < |
648 weak_closure_was_overapproximated_ = true; | 670 FLAG_min_progress_during_incremental_marking_finalization)) { |
671 finalize_marking_completed_ = true; | |
649 } | 672 } |
650 | |
651 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); | |
652 heap_->isolate()->global_handles()->RemoveObjectGroups(); | |
653 } | 673 } |
654 | 674 |
655 | 675 |
656 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { | 676 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() { |
657 if (!IsMarking()) return; | 677 if (!IsMarking()) return; |
658 | 678 |
659 MarkingDeque* marking_deque = | 679 MarkingDeque* marking_deque = |
660 heap_->mark_compact_collector()->marking_deque(); | 680 heap_->mark_compact_collector()->marking_deque(); |
661 int current = marking_deque->bottom(); | 681 int current = marking_deque->bottom(); |
662 int mask = marking_deque->mask(); | 682 int mask = marking_deque->mask(); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
853 IncrementalMarking::set_should_hurry(false); | 873 IncrementalMarking::set_should_hurry(false); |
854 ResetStepCounters(); | 874 ResetStepCounters(); |
855 PatchIncrementalMarkingRecordWriteStubs(heap_, | 875 PatchIncrementalMarkingRecordWriteStubs(heap_, |
856 RecordWriteStub::STORE_BUFFER_ONLY); | 876 RecordWriteStub::STORE_BUFFER_ONLY); |
857 DeactivateIncrementalWriteBarrier(); | 877 DeactivateIncrementalWriteBarrier(); |
858 DCHECK(heap_->mark_compact_collector()->marking_deque()->IsEmpty()); | 878 DCHECK(heap_->mark_compact_collector()->marking_deque()->IsEmpty()); |
859 heap_->isolate()->stack_guard()->ClearGC(); | 879 heap_->isolate()->stack_guard()->ClearGC(); |
860 } | 880 } |
861 | 881 |
862 | 882 |
863 void IncrementalMarking::OverApproximateWeakClosure(CompletionAction action) { | 883 void IncrementalMarking::FinalizeMarking(CompletionAction action) { |
864 DCHECK(FLAG_overapproximate_weak_closure); | 884 DCHECK(FLAG_finalize_marking_incrementally); |
865 DCHECK(!weak_closure_was_overapproximated_); | 885 DCHECK(!finalize_marking_completed_); |
866 if (FLAG_trace_incremental_marking) { | 886 if (FLAG_trace_incremental_marking) { |
867 PrintF("[IncrementalMarking] requesting weak closure overapproximation.\n"); | 887 PrintF( |
888 "[IncrementalMarking] requesting finalization of incremental " | |
889 "marking.\n"); | |
868 } | 890 } |
869 request_type_ = OVERAPPROXIMATION; | 891 request_type_ = FINALIZATION; |
870 if (action == GC_VIA_STACK_GUARD) { | 892 if (action == GC_VIA_STACK_GUARD) { |
871 heap_->isolate()->stack_guard()->RequestGC(); | 893 heap_->isolate()->stack_guard()->RequestGC(); |
872 } | 894 } |
873 } | 895 } |
874 | 896 |
875 | 897 |
876 void IncrementalMarking::MarkingComplete(CompletionAction action) { | 898 void IncrementalMarking::MarkingComplete(CompletionAction action) { |
877 state_ = COMPLETE; | 899 state_ = COMPLETE; |
878 // We will set the stack guard to request a GC now. This will mean the rest | 900 // 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 | 901 // 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 | 902 // 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 | 903 // 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. | 904 // the should-hurry flag to indicate that there can't be much work left to do. |
883 set_should_hurry(true); | 905 set_should_hurry(true); |
884 if (FLAG_trace_incremental_marking) { | 906 if (FLAG_trace_incremental_marking) { |
885 PrintF("[IncrementalMarking] Complete (normal).\n"); | 907 PrintF("[IncrementalMarking] Complete (normal).\n"); |
886 } | 908 } |
887 request_type_ = COMPLETE_MARKING; | 909 request_type_ = COMPLETE_MARKING; |
888 if (action == GC_VIA_STACK_GUARD) { | 910 if (action == GC_VIA_STACK_GUARD) { |
889 heap_->isolate()->stack_guard()->RequestGC(); | 911 heap_->isolate()->stack_guard()->RequestGC(); |
890 } | 912 } |
891 } | 913 } |
892 | 914 |
893 | 915 |
894 void IncrementalMarking::Epilogue() { | 916 void IncrementalMarking::Epilogue() { |
895 was_activated_ = false; | 917 was_activated_ = false; |
896 weak_closure_was_overapproximated_ = false; | 918 finalize_marking_completed_ = false; |
897 weak_closure_approximation_rounds_ = 0; | 919 incremental_marking_finalization_rounds_ = 0; |
898 } | 920 } |
899 | 921 |
900 | 922 |
901 double IncrementalMarking::AdvanceIncrementalMarking( | 923 double IncrementalMarking::AdvanceIncrementalMarking( |
902 intptr_t step_size_in_bytes, double deadline_in_ms, | 924 intptr_t step_size_in_bytes, double deadline_in_ms, |
903 IncrementalMarking::StepActions step_actions) { | 925 IncrementalMarking::StepActions step_actions) { |
904 DCHECK(!IsStopped()); | 926 DCHECK(!IsStopped()); |
905 | 927 |
906 if (step_size_in_bytes == 0) { | 928 if (step_size_in_bytes == 0) { |
907 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( | 929 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 } | 1087 } |
1066 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { | 1088 if (!heap_->mark_compact_collector()->sweeping_in_progress()) { |
1067 bytes_scanned_ = 0; | 1089 bytes_scanned_ = 0; |
1068 StartMarking(); | 1090 StartMarking(); |
1069 } | 1091 } |
1070 } else if (state_ == MARKING) { | 1092 } else if (state_ == MARKING) { |
1071 bytes_processed = ProcessMarkingDeque(bytes_to_process); | 1093 bytes_processed = ProcessMarkingDeque(bytes_to_process); |
1072 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { | 1094 if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { |
1073 if (completion == FORCE_COMPLETION || | 1095 if (completion == FORCE_COMPLETION || |
1074 IsIdleMarkingDelayCounterLimitReached()) { | 1096 IsIdleMarkingDelayCounterLimitReached()) { |
1075 if (FLAG_overapproximate_weak_closure && | 1097 if (FLAG_finalize_marking_incrementally && |
1076 !weak_closure_was_overapproximated_) { | 1098 !finalize_marking_completed_) { |
1077 OverApproximateWeakClosure(action); | 1099 FinalizeMarking(action); |
1078 } else { | 1100 } else { |
1079 MarkingComplete(action); | 1101 MarkingComplete(action); |
1080 } | 1102 } |
1081 } else { | 1103 } else { |
1082 IncrementIdleMarkingDelayCounter(); | 1104 IncrementIdleMarkingDelayCounter(); |
1083 } | 1105 } |
1084 } | 1106 } |
1085 } | 1107 } |
1086 | 1108 |
1087 steps_count_++; | 1109 steps_count_++; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1149 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1128 idle_marking_delay_counter_++; | 1150 idle_marking_delay_counter_++; |
1129 } | 1151 } |
1130 | 1152 |
1131 | 1153 |
1132 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1154 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1133 idle_marking_delay_counter_ = 0; | 1155 idle_marking_delay_counter_ = 0; |
1134 } | 1156 } |
1135 } // namespace internal | 1157 } // namespace internal |
1136 } // namespace v8 | 1158 } // namespace v8 |
OLD | NEW |