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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 112 |
113 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, | 113 void IncrementalMarking::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, |
114 Object* value) { | 114 Object* value) { |
115 if (BaseRecordWrite(host, value)) { | 115 if (BaseRecordWrite(host, value)) { |
116 // Object is not going to be rescanned. We need to record the slot. | 116 // Object is not going to be rescanned. We need to record the slot. |
117 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value); | 117 heap_->mark_compact_collector()->RecordRelocSlot(host, rinfo, value); |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { | 122 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
Hannes Payer (out of office)
2017/01/18 14:43:35
mark_bit is now not used anymore. That was an opti
Michael Lippautz
2017/01/18 15:58:07
Done.
| |
123 Marking::WhiteToGrey(mark_bit); | 123 ObjectMarking::WhiteToGrey(obj); |
124 heap_->mark_compact_collector()->marking_deque()->Push(obj); | 124 heap_->mark_compact_collector()->marking_deque()->Push(obj); |
125 } | 125 } |
126 | 126 |
127 | 127 |
128 static void MarkObjectGreyDoNotEnqueue(Object* obj) { | 128 static void MarkObjectGreyDoNotEnqueue(Object* obj) { |
129 if (obj->IsHeapObject()) { | 129 if (obj->IsHeapObject()) { |
130 HeapObject* heap_obj = HeapObject::cast(obj); | 130 HeapObject* heap_obj = HeapObject::cast(obj); |
131 MarkBit mark_bit = ObjectMarking::MarkBitFrom(HeapObject::cast(obj)); | 131 ObjectMarking::AnyToGrey(heap_obj); |
132 if (Marking::IsBlack(mark_bit)) { | |
133 MemoryChunk::IncrementLiveBytes(heap_obj, -heap_obj->Size()); | |
134 } | |
135 Marking::AnyToGrey(mark_bit); | |
136 } | 132 } |
137 } | 133 } |
138 | 134 |
139 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, | 135 void IncrementalMarking::TransferMark(Heap* heap, HeapObject* from, |
140 HeapObject* to) { | 136 HeapObject* to) { |
137 DCHECK(MemoryChunk::FromAddress(from->address())->SweepingDone()); | |
141 // This is only used when resizing an object. | 138 // This is only used when resizing an object. |
142 DCHECK(MemoryChunk::FromAddress(from->address()) == | 139 DCHECK(MemoryChunk::FromAddress(from->address()) == |
143 MemoryChunk::FromAddress(to->address())); | 140 MemoryChunk::FromAddress(to->address())); |
144 | 141 |
145 if (!heap->incremental_marking()->IsMarking()) return; | 142 if (!heap->incremental_marking()->IsMarking()) return; |
146 | 143 |
147 // If the mark doesn't move, we don't check the color of the object. | 144 // If the mark doesn't move, we don't check the color of the object. |
148 // It doesn't matter whether the object is black, since it hasn't changed | 145 // It doesn't matter whether the object is black, since it hasn't changed |
149 // size, so the adjustment to the live data count will be zero anyway. | 146 // size, so the adjustment to the live data count will be zero anyway. |
150 if (from == to) return; | 147 if (from == to) return; |
151 | 148 |
152 MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to); | 149 MarkBit new_mark_bit = ObjectMarking::MarkBitFrom(to); |
153 MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from); | 150 MarkBit old_mark_bit = ObjectMarking::MarkBitFrom(from); |
154 | 151 |
155 #ifdef DEBUG | 152 #ifdef DEBUG |
156 Marking::ObjectColor old_color = Marking::Color(old_mark_bit); | 153 Marking::ObjectColor old_color = Marking::Color(old_mark_bit); |
157 #endif | 154 #endif |
158 | 155 |
159 if (Marking::IsBlack(old_mark_bit)) { | 156 if (Marking::IsBlack(old_mark_bit)) { |
160 Marking::BlackToWhite(old_mark_bit); | 157 Marking::BlackToWhite(old_mark_bit); |
161 Marking::MarkBlack(new_mark_bit); | 158 Marking::WhiteToBlack(new_mark_bit); |
162 return; | 159 return; |
163 } else if (Marking::IsGrey(old_mark_bit)) { | 160 } else if (Marking::IsGrey(old_mark_bit)) { |
164 Marking::GreyToWhite(old_mark_bit); | 161 Marking::GreyToWhite(old_mark_bit); |
165 heap->incremental_marking()->WhiteToGreyAndPush(to, new_mark_bit); | 162 Marking::WhiteToGrey(new_mark_bit); |
Hannes Payer (out of office)
2017/01/18 14:43:35
Why not calling WhiteToGreyAndPush?
Michael Lippautz
2017/01/18 15:58:07
WhiteToGreyAndPush uses ObjectMarking which potent
| |
163 heap->mark_compact_collector()->marking_deque()->Push(to); | |
166 heap->incremental_marking()->RestartIfNotMarking(); | 164 heap->incremental_marking()->RestartIfNotMarking(); |
167 } | 165 } |
168 | 166 |
169 #ifdef DEBUG | 167 #ifdef DEBUG |
170 Marking::ObjectColor new_color = Marking::Color(new_mark_bit); | 168 Marking::ObjectColor new_color = Marking::Color(new_mark_bit); |
171 DCHECK(new_color == old_color); | 169 DCHECK(new_color == old_color); |
172 #endif | 170 #endif |
173 } | 171 } |
174 | 172 |
175 class IncrementalMarkingMarkingVisitor | 173 class IncrementalMarkingMarkingVisitor |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 INLINE(static void MarkObject(Heap* heap, Object* obj)) { | 258 INLINE(static void MarkObject(Heap* heap, Object* obj)) { |
261 IncrementalMarking::MarkGrey(heap, HeapObject::cast(obj)); | 259 IncrementalMarking::MarkGrey(heap, HeapObject::cast(obj)); |
262 } | 260 } |
263 | 261 |
264 // Marks the object black without pushing it on the marking stack. | 262 // Marks the object black without pushing it on the marking stack. |
265 // Returns true if object needed marking and false otherwise. | 263 // Returns true if object needed marking and false otherwise. |
266 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { | 264 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { |
267 HeapObject* heap_object = HeapObject::cast(obj); | 265 HeapObject* heap_object = HeapObject::cast(obj); |
268 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); | 266 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); |
269 if (Marking::IsWhite(mark_bit)) { | 267 if (Marking::IsWhite(mark_bit)) { |
270 Marking::MarkBlack(mark_bit); | 268 ObjectMarking::WhiteToBlack(heap_object); |
271 MemoryChunk::IncrementLiveBytes(heap_object, heap_object->Size()); | |
272 return true; | 269 return true; |
273 } | 270 } |
274 return false; | 271 return false; |
275 } | 272 } |
276 }; | 273 }; |
277 | 274 |
278 void IncrementalMarking::IterateBlackObject(HeapObject* object) { | 275 void IncrementalMarking::IterateBlackObject(HeapObject* object) { |
279 if (IsMarking() && Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { | 276 if (IsMarking() && Marking::IsBlack(ObjectMarking::MarkBitFrom(object))) { |
280 Page* page = Page::FromAddress(object->address()); | 277 Page* page = Page::FromAddress(object->address()); |
281 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { | 278 if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) { |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
856 void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) { | 853 void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) { |
857 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); | 854 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); |
858 if (Marking::IsWhite(mark_bit)) { | 855 if (Marking::IsWhite(mark_bit)) { |
859 heap->incremental_marking()->WhiteToGreyAndPush(object, mark_bit); | 856 heap->incremental_marking()->WhiteToGreyAndPush(object, mark_bit); |
860 } | 857 } |
861 } | 858 } |
862 | 859 |
863 void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { | 860 void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { |
864 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); | 861 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
865 if (Marking::IsBlack(mark_bit)) return; | 862 if (Marking::IsBlack(mark_bit)) return; |
866 Marking::GreyToBlack(mark_bit); | 863 ObjectMarking::GreyToBlack(obj); |
867 MemoryChunk::IncrementLiveBytes(obj, size); | |
868 } | 864 } |
869 | 865 |
870 intptr_t IncrementalMarking::ProcessMarkingDeque( | 866 intptr_t IncrementalMarking::ProcessMarkingDeque( |
871 intptr_t bytes_to_process, ForceCompletionAction completion) { | 867 intptr_t bytes_to_process, ForceCompletionAction completion) { |
872 intptr_t bytes_processed = 0; | 868 intptr_t bytes_processed = 0; |
873 MarkingDeque* marking_deque = | 869 MarkingDeque* marking_deque = |
874 heap_->mark_compact_collector()->marking_deque(); | 870 heap_->mark_compact_collector()->marking_deque(); |
875 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || | 871 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || |
876 completion == FORCE_COMPLETION)) { | 872 completion == FORCE_COMPLETION)) { |
877 HeapObject* obj = marking_deque->Pop(); | 873 HeapObject* obj = marking_deque->Pop(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
930 | 926 |
931 Object* context = heap_->native_contexts_list(); | 927 Object* context = heap_->native_contexts_list(); |
932 while (!context->IsUndefined(heap_->isolate())) { | 928 while (!context->IsUndefined(heap_->isolate())) { |
933 // GC can happen when the context is not fully initialized, | 929 // GC can happen when the context is not fully initialized, |
934 // so the cache can be undefined. | 930 // so the cache can be undefined. |
935 HeapObject* cache = HeapObject::cast( | 931 HeapObject* cache = HeapObject::cast( |
936 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); | 932 Context::cast(context)->get(Context::NORMALIZED_MAP_CACHE_INDEX)); |
937 if (!cache->IsUndefined(heap_->isolate())) { | 933 if (!cache->IsUndefined(heap_->isolate())) { |
938 MarkBit mark_bit = ObjectMarking::MarkBitFrom(cache); | 934 MarkBit mark_bit = ObjectMarking::MarkBitFrom(cache); |
939 if (Marking::IsGrey(mark_bit)) { | 935 if (Marking::IsGrey(mark_bit)) { |
940 Marking::GreyToBlack(mark_bit); | 936 ObjectMarking::GreyToBlack(cache); |
941 MemoryChunk::IncrementLiveBytes(cache, cache->Size()); | |
942 } | 937 } |
943 } | 938 } |
944 context = Context::cast(context)->next_context_link(); | 939 context = Context::cast(context)->next_context_link(); |
945 } | 940 } |
946 } | 941 } |
947 | 942 |
948 | 943 |
949 void IncrementalMarking::Stop() { | 944 void IncrementalMarking::Stop() { |
950 if (IsStopped()) return; | 945 if (IsStopped()) return; |
951 if (FLAG_trace_incremental_marking) { | 946 if (FLAG_trace_incremental_marking) { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1212 idle_marking_delay_counter_++; | 1207 idle_marking_delay_counter_++; |
1213 } | 1208 } |
1214 | 1209 |
1215 | 1210 |
1216 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1211 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1217 idle_marking_delay_counter_ = 0; | 1212 idle_marking_delay_counter_ = 0; |
1218 } | 1213 } |
1219 | 1214 |
1220 } // namespace internal | 1215 } // namespace internal |
1221 } // namespace v8 | 1216 } // namespace v8 |
OLD | NEW |