| 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 |