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