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 #ifndef V8_HEAP_MARK_COMPACT_H_ | 5 #ifndef V8_HEAP_MARK_COMPACT_H_ |
6 #define V8_HEAP_MARK_COMPACT_H_ | 6 #define V8_HEAP_MARK_COMPACT_H_ |
7 | 7 |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/heap/spaces.h" | 9 #include "src/heap/spaces.h" |
10 | 10 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 | 109 |
110 INLINE(static void BlackToGrey(HeapObject* obj)) { | 110 INLINE(static void BlackToGrey(HeapObject* obj)) { |
111 BlackToGrey(MarkBitFrom(obj)); | 111 BlackToGrey(MarkBitFrom(obj)); |
112 } | 112 } |
113 | 113 |
114 INLINE(static void AnyToGrey(MarkBit markbit)) { | 114 INLINE(static void AnyToGrey(MarkBit markbit)) { |
115 markbit.Set(); | 115 markbit.Set(); |
116 markbit.Next().Set(); | 116 markbit.Next().Set(); |
117 } | 117 } |
118 | 118 |
119 static void SetAllMarkBitsInRange(MarkBit start, MarkBit end); | |
120 static void ClearAllMarkBitsOfCellsContainedInRange(MarkBit start, | |
121 MarkBit end); | |
122 | |
123 void TransferMark(Address old_start, Address new_start); | 119 void TransferMark(Address old_start, Address new_start); |
124 | 120 |
125 #ifdef DEBUG | 121 #ifdef DEBUG |
126 enum ObjectColor { | 122 enum ObjectColor { |
127 BLACK_OBJECT, | 123 BLACK_OBJECT, |
128 WHITE_OBJECT, | 124 WHITE_OBJECT, |
129 GREY_OBJECT, | 125 GREY_OBJECT, |
130 IMPOSSIBLE_COLOR | 126 IMPOSSIBLE_COLOR |
131 }; | 127 }; |
132 | 128 |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
356 case JS_RETURN_SLOT: | 352 case JS_RETURN_SLOT: |
357 return "JS_RETURN_SLOT"; | 353 return "JS_RETURN_SLOT"; |
358 case NUMBER_OF_SLOT_TYPES: | 354 case NUMBER_OF_SLOT_TYPES: |
359 return "NUMBER_OF_SLOT_TYPES"; | 355 return "NUMBER_OF_SLOT_TYPES"; |
360 } | 356 } |
361 return "UNKNOWN SlotType"; | 357 return "UNKNOWN SlotType"; |
362 } | 358 } |
363 | 359 |
364 void UpdateSlots(Heap* heap); | 360 void UpdateSlots(Heap* heap); |
365 | 361 |
366 void UpdateSlotsWithFilter(Heap* heap); | |
367 | |
368 SlotsBuffer* next() { return next_; } | 362 SlotsBuffer* next() { return next_; } |
369 | 363 |
370 static int SizeOfChain(SlotsBuffer* buffer) { | 364 static int SizeOfChain(SlotsBuffer* buffer) { |
371 if (buffer == NULL) return 0; | 365 if (buffer == NULL) return 0; |
372 return static_cast<int>(buffer->idx_ + | 366 return static_cast<int>(buffer->idx_ + |
373 (buffer->chain_length_ - 1) * kNumberOfElements); | 367 (buffer->chain_length_ - 1) * kNumberOfElements); |
374 } | 368 } |
375 | 369 |
376 inline bool IsFull() { return idx_ == kNumberOfElements; } | 370 inline bool IsFull() { return idx_ == kNumberOfElements; } |
377 | 371 |
378 inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; } | 372 inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; } |
379 | 373 |
380 static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer, | 374 static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer) { |
381 bool code_slots_filtering_required) { | |
382 while (buffer != NULL) { | 375 while (buffer != NULL) { |
383 if (code_slots_filtering_required) { | 376 buffer->UpdateSlots(heap); |
384 buffer->UpdateSlotsWithFilter(heap); | |
385 } else { | |
386 buffer->UpdateSlots(heap); | |
387 } | |
388 buffer = buffer->next(); | 377 buffer = buffer->next(); |
389 } | 378 } |
390 } | 379 } |
391 | 380 |
392 enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW }; | 381 enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW }; |
393 | 382 |
394 static bool ChainLengthThresholdReached(SlotsBuffer* buffer) { | 383 static bool ChainLengthThresholdReached(SlotsBuffer* buffer) { |
395 return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold; | 384 return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold; |
396 } | 385 } |
397 | 386 |
(...skipping 18 matching lines...) Expand all Loading... | |
416 static bool AddTo(SlotsBufferAllocator* allocator, | 405 static bool AddTo(SlotsBufferAllocator* allocator, |
417 SlotsBuffer** buffer_address, SlotType type, Address addr, | 406 SlotsBuffer** buffer_address, SlotType type, Address addr, |
418 AdditionMode mode); | 407 AdditionMode mode); |
419 | 408 |
420 // Eliminates all stale entries from the slots buffer, i.e., slots that | 409 // Eliminates all stale entries from the slots buffer, i.e., slots that |
421 // are not part of live objects anymore. This method must be called after | 410 // are not part of live objects anymore. This method must be called after |
422 // marking, when the whole transitive closure is known and must be called | 411 // marking, when the whole transitive closure is known and must be called |
423 // before sweeping when mark bits are still intact. | 412 // before sweeping when mark bits are still intact. |
424 static void RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer); | 413 static void RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer); |
425 | 414 |
415 // Eliminate all slots that point to the given invalid_object. | |
416 static void RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer, | |
417 HeapObject* invalid_object); | |
418 | |
426 // Ensures that there are no invalid slots in the chain of slots buffers. | 419 // Ensures that there are no invalid slots in the chain of slots buffers. |
427 static void VerifySlots(Heap* heap, SlotsBuffer* buffer); | 420 static void VerifySlots(Heap* heap, SlotsBuffer* buffer); |
428 | 421 |
429 static const int kNumberOfElements = 1021; | 422 static const int kNumberOfElements = 1021; |
430 | 423 |
431 private: | 424 private: |
432 static const int kChainLengthThreshold = 15; | 425 static const int kChainLengthThreshold = 15; |
433 | 426 |
434 intptr_t idx_; | 427 intptr_t idx_; |
435 intptr_t chain_length_; | 428 intptr_t chain_length_; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
663 | 656 |
664 void MigrateObject(HeapObject* dst, HeapObject* src, int size, | 657 void MigrateObject(HeapObject* dst, HeapObject* src, int size, |
665 AllocationSpace to_old_space); | 658 AllocationSpace to_old_space); |
666 | 659 |
667 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size); | 660 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size); |
668 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size); | 661 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size); |
669 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size); | 662 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size); |
670 | 663 |
671 bool TryPromoteObject(HeapObject* object, int object_size); | 664 bool TryPromoteObject(HeapObject* object, int object_size); |
672 | 665 |
673 void InvalidateCode(Code* code); | |
674 | |
675 void ClearMarkbits(); | 666 void ClearMarkbits(); |
676 | 667 |
677 bool abort_incremental_marking() const { return abort_incremental_marking_; } | 668 bool abort_incremental_marking() const { return abort_incremental_marking_; } |
678 | 669 |
679 bool finalize_incremental_marking() const { | 670 bool finalize_incremental_marking() const { |
680 return finalize_incremental_marking_; | 671 return finalize_incremental_marking_; |
681 } | 672 } |
682 | 673 |
683 bool is_compacting() const { return compacting_; } | 674 bool is_compacting() const { return compacting_; } |
684 | 675 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 | 727 |
737 void InitializeMarkingDeque(); | 728 void InitializeMarkingDeque(); |
738 | 729 |
739 // The following four methods can just be called after marking, when the | 730 // The following four methods can just be called after marking, when the |
740 // whole transitive closure is known. They must be called before sweeping | 731 // whole transitive closure is known. They must be called before sweeping |
741 // when mark bits are still intact. | 732 // when mark bits are still intact. |
742 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); | 733 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); |
743 bool IsSlotInBlackObjectSlow(Page* p, Address slot); | 734 bool IsSlotInBlackObjectSlow(Page* p, Address slot); |
744 bool IsSlotInLiveObject(Address slot); | 735 bool IsSlotInLiveObject(Address slot); |
745 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); | 736 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); |
737 void RemoveObjectSlots(HeapObject* invalid_object); | |
Michael Starzinger
2015/06/30 08:54:19
nit: The comment above this block doesn't really a
Hannes Payer (out of office)
2015/06/30 09:02:10
Done.
| |
746 | 738 |
747 private: | 739 private: |
748 class SweeperTask; | 740 class SweeperTask; |
749 | 741 |
750 explicit MarkCompactCollector(Heap* heap); | 742 explicit MarkCompactCollector(Heap* heap); |
751 ~MarkCompactCollector(); | 743 ~MarkCompactCollector(); |
752 | 744 |
753 bool MarkInvalidatedCode(); | |
754 bool WillBeDeoptimized(Code* code); | 745 bool WillBeDeoptimized(Code* code); |
755 void RemoveDeadInvalidatedCode(); | |
756 void ProcessInvalidatedCode(ObjectVisitor* visitor); | |
757 void EvictPopularEvacuationCandidate(Page* page); | 746 void EvictPopularEvacuationCandidate(Page* page); |
758 void ClearInvalidSlotsBufferEntries(PagedSpace* space); | 747 void ClearInvalidSlotsBufferEntries(PagedSpace* space); |
759 void ClearInvalidStoreAndSlotsBufferEntries(); | 748 void ClearInvalidStoreAndSlotsBufferEntries(); |
760 | 749 |
761 void StartSweeperThreads(); | 750 void StartSweeperThreads(); |
762 | 751 |
763 #ifdef DEBUG | 752 #ifdef DEBUG |
764 enum CollectorState { | 753 enum CollectorState { |
765 IDLE, | 754 IDLE, |
766 PREPARE_GC, | 755 PREPARE_GC, |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
963 #endif | 952 #endif |
964 | 953 |
965 Heap* heap_; | 954 Heap* heap_; |
966 base::VirtualMemory* marking_deque_memory_; | 955 base::VirtualMemory* marking_deque_memory_; |
967 size_t marking_deque_memory_committed_; | 956 size_t marking_deque_memory_committed_; |
968 MarkingDeque marking_deque_; | 957 MarkingDeque marking_deque_; |
969 CodeFlusher* code_flusher_; | 958 CodeFlusher* code_flusher_; |
970 bool have_code_to_deoptimize_; | 959 bool have_code_to_deoptimize_; |
971 | 960 |
972 List<Page*> evacuation_candidates_; | 961 List<Page*> evacuation_candidates_; |
973 List<Code*> invalidated_code_; | |
974 | 962 |
975 SmartPointer<FreeList> free_list_old_space_; | 963 SmartPointer<FreeList> free_list_old_space_; |
976 | 964 |
977 friend class Heap; | 965 friend class Heap; |
978 }; | 966 }; |
979 | 967 |
980 | 968 |
981 class MarkBitCellIterator BASE_EMBEDDED { | 969 class MarkBitCellIterator BASE_EMBEDDED { |
982 public: | 970 public: |
983 explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { | 971 explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1031 private: | 1019 private: |
1032 MarkCompactCollector* collector_; | 1020 MarkCompactCollector* collector_; |
1033 }; | 1021 }; |
1034 | 1022 |
1035 | 1023 |
1036 const char* AllocationSpaceName(AllocationSpace space); | 1024 const char* AllocationSpaceName(AllocationSpace space); |
1037 } | 1025 } |
1038 } // namespace v8::internal | 1026 } // namespace v8::internal |
1039 | 1027 |
1040 #endif // V8_HEAP_MARK_COMPACT_H_ | 1028 #endif // V8_HEAP_MARK_COMPACT_H_ |
OLD | NEW |