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 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 } | 881 } |
882 | 882 |
883 | 883 |
884 void IncrementalMarking::MarkObject(Heap* heap, HeapObject* obj) { | 884 void IncrementalMarking::MarkObject(Heap* heap, HeapObject* obj) { |
885 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); | 885 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
886 if (Marking::IsWhite(mark_bit)) { | 886 if (Marking::IsWhite(mark_bit)) { |
887 heap->incremental_marking()->WhiteToGreyAndPush(obj, mark_bit); | 887 heap->incremental_marking()->WhiteToGreyAndPush(obj, mark_bit); |
888 } | 888 } |
889 } | 889 } |
890 | 890 |
891 | 891 intptr_t IncrementalMarking::ProcessMarkingDeque( |
892 intptr_t IncrementalMarking::ProcessMarkingDeque(intptr_t bytes_to_process) { | 892 intptr_t bytes_to_process, ForceCompletionAction completion) { |
893 intptr_t bytes_processed = 0; | 893 intptr_t bytes_processed = 0; |
894 Map* one_pointer_filler_map = heap_->one_pointer_filler_map(); | |
895 Map* two_pointer_filler_map = heap_->two_pointer_filler_map(); | |
896 MarkingDeque* marking_deque = | 894 MarkingDeque* marking_deque = |
897 heap_->mark_compact_collector()->marking_deque(); | 895 heap_->mark_compact_collector()->marking_deque(); |
898 while (!marking_deque->IsEmpty() && bytes_processed < bytes_to_process) { | 896 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || |
| 897 completion == FORCE_COMPLETION)) { |
899 HeapObject* obj = marking_deque->Pop(); | 898 HeapObject* obj = marking_deque->Pop(); |
900 | 899 |
901 // Explicitly skip one and two word fillers. Incremental markbit patterns | 900 // Left trimming may result in white filler objects on the marking deque. |
902 // are correct only for objects that occupy at least two words. | 901 // Ignore these objects. |
903 // Moreover, slots filtering for left-trimmed arrays works only when | 902 if (obj->IsFiller()) { |
904 // the distance between the old array start and the new array start | 903 DCHECK(Marking::IsImpossible(ObjectMarking::MarkBitFrom(obj)) || |
905 // is greater than two if both starts are marked. | 904 Marking::IsWhite(ObjectMarking::MarkBitFrom(obj))); |
| 905 continue; |
| 906 } |
| 907 |
906 Map* map = obj->map(); | 908 Map* map = obj->map(); |
907 if (map == one_pointer_filler_map || map == two_pointer_filler_map) | |
908 continue; | |
909 | |
910 int size = obj->SizeFromMap(map); | 909 int size = obj->SizeFromMap(map); |
911 unscanned_bytes_of_large_object_ = 0; | 910 unscanned_bytes_of_large_object_ = 0; |
912 VisitObject(map, obj, size); | 911 VisitObject(map, obj, size); |
913 bytes_processed += size - unscanned_bytes_of_large_object_; | 912 bytes_processed += size - unscanned_bytes_of_large_object_; |
914 } | 913 } |
915 return bytes_processed; | 914 return bytes_processed; |
916 } | 915 } |
917 | 916 |
918 | 917 |
919 void IncrementalMarking::ProcessMarkingDeque() { | |
920 Map* filler_map = heap_->one_pointer_filler_map(); | |
921 MarkingDeque* marking_deque = | |
922 heap_->mark_compact_collector()->marking_deque(); | |
923 while (!marking_deque->IsEmpty()) { | |
924 HeapObject* obj = marking_deque->Pop(); | |
925 | |
926 // Explicitly skip one word fillers. Incremental markbit patterns are | |
927 // correct only for objects that occupy at least two words. | |
928 Map* map = obj->map(); | |
929 if (map == filler_map) continue; | |
930 | |
931 VisitObject(map, obj, obj->SizeFromMap(map)); | |
932 } | |
933 } | |
934 | |
935 | |
936 void IncrementalMarking::Hurry() { | 918 void IncrementalMarking::Hurry() { |
937 // A scavenge may have pushed new objects on the marking deque (due to black | 919 // A scavenge may have pushed new objects on the marking deque (due to black |
938 // allocation) even in COMPLETE state. This may happen if scavenges are | 920 // allocation) even in COMPLETE state. This may happen if scavenges are |
939 // forced e.g. in tests. It should not happen when COMPLETE was set when | 921 // forced e.g. in tests. It should not happen when COMPLETE was set when |
940 // incremental marking finished and a regular GC was triggered after that | 922 // incremental marking finished and a regular GC was triggered after that |
941 // because should_hurry_ will force a full GC. | 923 // because should_hurry_ will force a full GC. |
942 if (!heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { | 924 if (!heap_->mark_compact_collector()->marking_deque()->IsEmpty()) { |
943 double start = 0.0; | 925 double start = 0.0; |
944 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) { | 926 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) { |
945 start = heap_->MonotonicallyIncreasingTimeInMs(); | 927 start = heap_->MonotonicallyIncreasingTimeInMs(); |
946 if (FLAG_trace_incremental_marking) { | 928 if (FLAG_trace_incremental_marking) { |
947 PrintF("[IncrementalMarking] Hurry\n"); | 929 PrintF("[IncrementalMarking] Hurry\n"); |
948 } | 930 } |
949 } | 931 } |
950 // TODO(gc) hurry can mark objects it encounters black as mutator | 932 // TODO(gc) hurry can mark objects it encounters black as mutator |
951 // was stopped. | 933 // was stopped. |
952 ProcessMarkingDeque(); | 934 ProcessMarkingDeque(0, FORCE_COMPLETION); |
953 state_ = COMPLETE; | 935 state_ = COMPLETE; |
954 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) { | 936 if (FLAG_trace_incremental_marking || FLAG_print_cumulative_gc_stat) { |
955 double end = heap_->MonotonicallyIncreasingTimeInMs(); | 937 double end = heap_->MonotonicallyIncreasingTimeInMs(); |
956 double delta = end - start; | 938 double delta = end - start; |
957 heap_->tracer()->AddMarkingTime(delta); | 939 heap_->tracer()->AddMarkingTime(delta); |
958 if (FLAG_trace_incremental_marking) { | 940 if (FLAG_trace_incremental_marking) { |
959 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", | 941 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", |
960 static_cast<int>(delta)); | 942 static_cast<int>(delta)); |
961 } | 943 } |
962 } | 944 } |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1278 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1260 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1279 idle_marking_delay_counter_++; | 1261 idle_marking_delay_counter_++; |
1280 } | 1262 } |
1281 | 1263 |
1282 | 1264 |
1283 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1265 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1284 idle_marking_delay_counter_ = 0; | 1266 idle_marking_delay_counter_ = 0; |
1285 } | 1267 } |
1286 } // namespace internal | 1268 } // namespace internal |
1287 } // namespace v8 | 1269 } // namespace v8 |
OLD | NEW |