 Chromium Code Reviews
 Chromium Code Reviews Issue 1428683002:
  [heap] Convert overapproximate weak closure phase into finalize incremental marking phase and revis…  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1428683002:
  [heap] Convert overapproximate weak closure phase into finalize incremental marking phase and revis…  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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 |