Chromium Code Reviews| 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 |