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