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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 HeapObject::FromAddress(new_start), new_mark_bit); | 188 HeapObject::FromAddress(new_start), new_mark_bit); |
189 heap->incremental_marking()->RestartIfNotMarking(); | 189 heap->incremental_marking()->RestartIfNotMarking(); |
190 } | 190 } |
191 | 191 |
192 #ifdef DEBUG | 192 #ifdef DEBUG |
193 Marking::ObjectColor new_color = Marking::Color(new_mark_bit); | 193 Marking::ObjectColor new_color = Marking::Color(new_mark_bit); |
194 DCHECK(new_color == old_color); | 194 DCHECK(new_color == old_color); |
195 #endif | 195 #endif |
196 } | 196 } |
197 | 197 |
198 static inline void MarkBlackOrKeepBlack(HeapObject* heap_object, | |
199 MarkBit mark_bit, int size) { | |
200 DCHECK(!Marking::IsImpossible(mark_bit)); | |
201 if (Marking::IsBlack(mark_bit)) return; | |
202 Marking::MarkBlack(mark_bit); | |
203 MemoryChunk::IncrementLiveBytesFromGC(heap_object, size); | |
204 } | |
205 | |
206 class IncrementalMarkingMarkingVisitor | 198 class IncrementalMarkingMarkingVisitor |
207 : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> { | 199 : public StaticMarkingVisitor<IncrementalMarkingMarkingVisitor> { |
208 public: | 200 public: |
209 static void Initialize() { | 201 static void Initialize() { |
210 StaticMarkingVisitor<IncrementalMarkingMarkingVisitor>::Initialize(); | 202 StaticMarkingVisitor<IncrementalMarkingMarkingVisitor>::Initialize(); |
211 table_.Register(kVisitFixedArray, &VisitFixedArrayIncremental); | 203 table_.Register(kVisitFixedArray, &VisitFixedArrayIncremental); |
212 table_.Register(kVisitNativeContext, &VisitNativeContextIncremental); | 204 table_.Register(kVisitNativeContext, &VisitNativeContextIncremental); |
213 table_.Register(kVisitJSRegExp, &VisitJSRegExp); | 205 table_.Register(kVisitJSRegExp, &VisitJSRegExp); |
214 } | 206 } |
215 | 207 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 Object* target = *p; | 279 Object* target = *p; |
288 if (target->IsHeapObject()) { | 280 if (target->IsHeapObject()) { |
289 heap->mark_compact_collector()->RecordSlot(object, p, target); | 281 heap->mark_compact_collector()->RecordSlot(object, p, target); |
290 MarkObject(heap, target); | 282 MarkObject(heap, target); |
291 } | 283 } |
292 } | 284 } |
293 } | 285 } |
294 | 286 |
295 // Marks the object grey and pushes it on the marking stack. | 287 // Marks the object grey and pushes it on the marking stack. |
296 INLINE(static void MarkObject(Heap* heap, Object* obj)) { | 288 INLINE(static void MarkObject(Heap* heap, Object* obj)) { |
297 IncrementalMarking::MarkObject(heap, HeapObject::cast(obj)); | 289 IncrementalMarking::MarkGrey(heap, HeapObject::cast(obj)); |
298 } | 290 } |
299 | 291 |
300 // Marks the object black without pushing it on the marking stack. | 292 // Marks the object black without pushing it on the marking stack. |
301 // Returns true if object needed marking and false otherwise. | 293 // Returns true if object needed marking and false otherwise. |
302 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { | 294 INLINE(static bool MarkObjectWithoutPush(Heap* heap, Object* obj)) { |
303 HeapObject* heap_object = HeapObject::cast(obj); | 295 HeapObject* heap_object = HeapObject::cast(obj); |
304 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); | 296 MarkBit mark_bit = ObjectMarking::MarkBitFrom(heap_object); |
305 if (Marking::IsWhite(mark_bit)) { | 297 if (Marking::IsWhite(mark_bit)) { |
306 Marking::MarkBlack(mark_bit); | 298 Marking::MarkBlack(mark_bit); |
307 MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size()); | 299 MemoryChunk::IncrementLiveBytesFromGC(heap_object, heap_object->Size()); |
(...skipping 24 matching lines...) Expand all Loading... |
332 | 324 |
333 void VisitPointers(Object** start, Object** end) override { | 325 void VisitPointers(Object** start, Object** end) override { |
334 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 326 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
335 } | 327 } |
336 | 328 |
337 private: | 329 private: |
338 void MarkObjectByPointer(Object** p) { | 330 void MarkObjectByPointer(Object** p) { |
339 Object* obj = *p; | 331 Object* obj = *p; |
340 if (!obj->IsHeapObject()) return; | 332 if (!obj->IsHeapObject()) return; |
341 | 333 |
342 IncrementalMarking::MarkObject(heap_, HeapObject::cast(obj)); | 334 IncrementalMarking::MarkGrey(heap_, HeapObject::cast(obj)); |
343 } | 335 } |
344 | 336 |
345 Heap* heap_; | 337 Heap* heap_; |
346 }; | 338 }; |
347 | 339 |
348 | 340 |
349 void IncrementalMarking::Initialize() { | 341 void IncrementalMarking::Initialize() { |
350 IncrementalMarkingMarkingVisitor::Initialize(); | 342 IncrementalMarkingMarkingVisitor::Initialize(); |
351 } | 343 } |
352 | 344 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); | 618 heap_->IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); |
627 } | 619 } |
628 | 620 |
629 | 621 |
630 void IncrementalMarking::MarkObjectGroups() { | 622 void IncrementalMarking::MarkObjectGroups() { |
631 DCHECK(!heap_->UsingEmbedderHeapTracer()); | 623 DCHECK(!heap_->UsingEmbedderHeapTracer()); |
632 DCHECK(!finalize_marking_completed_); | 624 DCHECK(!finalize_marking_completed_); |
633 DCHECK(IsMarking()); | 625 DCHECK(IsMarking()); |
634 | 626 |
635 IncrementalMarkingRootMarkingVisitor visitor(this); | 627 IncrementalMarkingRootMarkingVisitor visitor(this); |
636 heap_->mark_compact_collector()->MarkImplicitRefGroups(&MarkObject); | 628 heap_->mark_compact_collector()->MarkImplicitRefGroups(&MarkGrey); |
637 heap_->isolate()->global_handles()->IterateObjectGroups( | 629 heap_->isolate()->global_handles()->IterateObjectGroups( |
638 &visitor, &MarkCompactCollector::IsUnmarkedHeapObjectWithHeap); | 630 &visitor, &MarkCompactCollector::IsUnmarkedHeapObjectWithHeap); |
639 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); | 631 heap_->isolate()->global_handles()->RemoveImplicitRefGroups(); |
640 heap_->isolate()->global_handles()->RemoveObjectGroups(); | 632 heap_->isolate()->global_handles()->RemoveObjectGroups(); |
641 } | 633 } |
642 | 634 |
643 | 635 |
644 void IncrementalMarking::ProcessWeakCells() { | 636 void IncrementalMarking::ProcessWeakCells() { |
645 DCHECK(!finalize_marking_completed_); | 637 DCHECK(!finalize_marking_completed_); |
646 DCHECK(IsMarking()); | 638 DCHECK(IsMarking()); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 DCHECK(retained_maps->Get(i)->IsWeakCell()); | 705 DCHECK(retained_maps->Get(i)->IsWeakCell()); |
714 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); | 706 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); |
715 if (cell->cleared()) continue; | 707 if (cell->cleared()) continue; |
716 int age = Smi::cast(retained_maps->Get(i + 1))->value(); | 708 int age = Smi::cast(retained_maps->Get(i + 1))->value(); |
717 int new_age; | 709 int new_age; |
718 Map* map = Map::cast(cell->value()); | 710 Map* map = Map::cast(cell->value()); |
719 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); | 711 MarkBit map_mark = ObjectMarking::MarkBitFrom(map); |
720 if (i >= number_of_disposed_maps && !map_retaining_is_disabled && | 712 if (i >= number_of_disposed_maps && !map_retaining_is_disabled && |
721 Marking::IsWhite(map_mark)) { | 713 Marking::IsWhite(map_mark)) { |
722 if (ShouldRetainMap(map, age)) { | 714 if (ShouldRetainMap(map, age)) { |
723 MarkObject(heap(), map); | 715 MarkGrey(heap(), map); |
724 } | 716 } |
725 Object* prototype = map->prototype(); | 717 Object* prototype = map->prototype(); |
726 if (age > 0 && prototype->IsHeapObject() && | 718 if (age > 0 && prototype->IsHeapObject() && |
727 Marking::IsWhite( | 719 Marking::IsWhite( |
728 ObjectMarking::MarkBitFrom(HeapObject::cast(prototype)))) { | 720 ObjectMarking::MarkBitFrom(HeapObject::cast(prototype)))) { |
729 // The prototype is not marked, age the map. | 721 // The prototype is not marked, age the map. |
730 new_age = age - 1; | 722 new_age = age - 1; |
731 } else { | 723 } else { |
732 // The prototype and the constructor are marked, this map keeps only | 724 // The prototype and the constructor are marked, this map keeps only |
733 // transition tree alive, not JSObjects. Do not age the map. | 725 // transition tree alive, not JSObjects. Do not age the map. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && | 848 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && |
857 Marking::IsBlack(mark_bit))); | 849 Marking::IsBlack(mark_bit))); |
858 #endif | 850 #endif |
859 } | 851 } |
860 } | 852 } |
861 marking_deque->set_top(new_top); | 853 marking_deque->set_top(new_top); |
862 } | 854 } |
863 | 855 |
864 | 856 |
865 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { | 857 void IncrementalMarking::VisitObject(Map* map, HeapObject* obj, int size) { |
866 MarkObject(heap_, map); | 858 MarkGrey(heap_, map); |
867 | 859 |
868 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); | 860 IncrementalMarkingMarkingVisitor::IterateBody(map, obj); |
869 | 861 |
| 862 #if ENABLE_SLOW_DCHECKS |
870 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); | 863 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
871 #if ENABLE_SLOW_DCHECKS | |
872 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 864 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
873 SLOW_DCHECK(Marking::IsGrey(mark_bit) || | 865 SLOW_DCHECK(Marking::IsGrey(mark_bit) || |
874 (obj->IsFiller() && Marking::IsWhite(mark_bit)) || | 866 (obj->IsFiller() && Marking::IsWhite(mark_bit)) || |
875 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && | 867 (chunk->IsFlagSet(MemoryChunk::HAS_PROGRESS_BAR) && |
876 Marking::IsBlack(mark_bit))); | 868 Marking::IsBlack(mark_bit))); |
877 #endif | 869 #endif |
878 MarkBlackOrKeepBlack(obj, mark_bit, size); | 870 MarkBlack(obj, size); |
879 } | 871 } |
880 | 872 |
| 873 void IncrementalMarking::MarkGrey(Heap* heap, HeapObject* object) { |
| 874 MarkBit mark_bit = ObjectMarking::MarkBitFrom(object); |
| 875 if (Marking::IsWhite(mark_bit)) { |
| 876 heap->incremental_marking()->WhiteToGreyAndPush(object, mark_bit); |
| 877 } |
| 878 } |
881 | 879 |
882 void IncrementalMarking::MarkObject(Heap* heap, HeapObject* obj) { | 880 void IncrementalMarking::MarkBlack(HeapObject* obj, int size) { |
883 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); | 881 MarkBit mark_bit = ObjectMarking::MarkBitFrom(obj); |
884 if (Marking::IsWhite(mark_bit)) { | 882 if (Marking::IsBlack(mark_bit)) return; |
885 heap->incremental_marking()->WhiteToGreyAndPush(obj, mark_bit); | 883 Marking::GreyToBlack(mark_bit); |
886 } | 884 MemoryChunk::IncrementLiveBytesFromGC(obj, size); |
887 } | 885 } |
888 | 886 |
889 intptr_t IncrementalMarking::ProcessMarkingDeque( | 887 intptr_t IncrementalMarking::ProcessMarkingDeque( |
890 intptr_t bytes_to_process, ForceCompletionAction completion) { | 888 intptr_t bytes_to_process, ForceCompletionAction completion) { |
891 intptr_t bytes_processed = 0; | 889 intptr_t bytes_processed = 0; |
892 MarkingDeque* marking_deque = | 890 MarkingDeque* marking_deque = |
893 heap_->mark_compact_collector()->marking_deque(); | 891 heap_->mark_compact_collector()->marking_deque(); |
894 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || | 892 while (!marking_deque->IsEmpty() && (bytes_processed < bytes_to_process || |
895 completion == FORCE_COMPLETION)) { | 893 completion == FORCE_COMPLETION)) { |
896 HeapObject* obj = marking_deque->Pop(); | 894 HeapObject* obj = marking_deque->Pop(); |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1256 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1259 idle_marking_delay_counter_++; | 1257 idle_marking_delay_counter_++; |
1260 } | 1258 } |
1261 | 1259 |
1262 | 1260 |
1263 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1261 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1264 idle_marking_delay_counter_ = 0; | 1262 idle_marking_delay_counter_ = 0; |
1265 } | 1263 } |
1266 } // namespace internal | 1264 } // namespace internal |
1267 } // namespace v8 | 1265 } // namespace v8 |
OLD | NEW |