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 |
119 void TransferMark(Address old_start, Address new_start); | 123 void TransferMark(Address old_start, Address new_start); |
120 | 124 |
121 #ifdef DEBUG | 125 #ifdef DEBUG |
122 enum ObjectColor { | 126 enum ObjectColor { |
123 BLACK_OBJECT, | 127 BLACK_OBJECT, |
124 WHITE_OBJECT, | 128 WHITE_OBJECT, |
125 GREY_OBJECT, | 129 GREY_OBJECT, |
126 IMPOSSIBLE_COLOR | 130 IMPOSSIBLE_COLOR |
127 }; | 131 }; |
128 | 132 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 void Add(ObjectSlot slot) { | 318 void Add(ObjectSlot slot) { |
315 DCHECK(0 <= idx_ && idx_ < kNumberOfElements); | 319 DCHECK(0 <= idx_ && idx_ < kNumberOfElements); |
316 #ifdef DEBUG | 320 #ifdef DEBUG |
317 if (slot >= reinterpret_cast<ObjectSlot>(NUMBER_OF_SLOT_TYPES)) { | 321 if (slot >= reinterpret_cast<ObjectSlot>(NUMBER_OF_SLOT_TYPES)) { |
318 DCHECK_NOT_NULL(*slot); | 322 DCHECK_NOT_NULL(*slot); |
319 } | 323 } |
320 #endif | 324 #endif |
321 slots_[idx_++] = slot; | 325 slots_[idx_++] = slot; |
322 } | 326 } |
323 | 327 |
324 // Should be used for testing only. | |
325 ObjectSlot Get(intptr_t i) { | |
326 DCHECK(i >= 0 && i < kNumberOfElements); | |
327 return slots_[i]; | |
328 } | |
329 | |
330 enum SlotType { | 328 enum SlotType { |
331 EMBEDDED_OBJECT_SLOT, | 329 EMBEDDED_OBJECT_SLOT, |
332 OBJECT_SLOT, | 330 OBJECT_SLOT, |
333 RELOCATED_CODE_OBJECT, | 331 RELOCATED_CODE_OBJECT, |
334 CELL_TARGET_SLOT, | 332 CELL_TARGET_SLOT, |
335 CODE_TARGET_SLOT, | 333 CODE_TARGET_SLOT, |
336 CODE_ENTRY_SLOT, | 334 CODE_ENTRY_SLOT, |
337 DEBUG_TARGET_SLOT, | 335 DEBUG_TARGET_SLOT, |
338 NUMBER_OF_SLOT_TYPES | 336 NUMBER_OF_SLOT_TYPES |
339 }; | 337 }; |
(...skipping 15 matching lines...) Expand all Loading... |
355 case DEBUG_TARGET_SLOT: | 353 case DEBUG_TARGET_SLOT: |
356 return "DEBUG_TARGET_SLOT"; | 354 return "DEBUG_TARGET_SLOT"; |
357 case NUMBER_OF_SLOT_TYPES: | 355 case NUMBER_OF_SLOT_TYPES: |
358 return "NUMBER_OF_SLOT_TYPES"; | 356 return "NUMBER_OF_SLOT_TYPES"; |
359 } | 357 } |
360 return "UNKNOWN SlotType"; | 358 return "UNKNOWN SlotType"; |
361 } | 359 } |
362 | 360 |
363 void UpdateSlots(Heap* heap); | 361 void UpdateSlots(Heap* heap); |
364 | 362 |
| 363 void UpdateSlotsWithFilter(Heap* heap); |
| 364 |
365 SlotsBuffer* next() { return next_; } | 365 SlotsBuffer* next() { return next_; } |
366 | 366 |
367 static int SizeOfChain(SlotsBuffer* buffer) { | 367 static int SizeOfChain(SlotsBuffer* buffer) { |
368 if (buffer == NULL) return 0; | 368 if (buffer == NULL) return 0; |
369 return static_cast<int>(buffer->idx_ + | 369 return static_cast<int>(buffer->idx_ + |
370 (buffer->chain_length_ - 1) * kNumberOfElements); | 370 (buffer->chain_length_ - 1) * kNumberOfElements); |
371 } | 371 } |
372 | 372 |
373 inline bool IsFull() { return idx_ == kNumberOfElements; } | 373 inline bool IsFull() { return idx_ == kNumberOfElements; } |
374 | 374 |
375 inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; } | 375 inline bool HasSpaceForTypedSlot() { return idx_ < kNumberOfElements - 1; } |
376 | 376 |
377 static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer) { | 377 static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer, |
| 378 bool code_slots_filtering_required) { |
378 while (buffer != NULL) { | 379 while (buffer != NULL) { |
379 buffer->UpdateSlots(heap); | 380 if (code_slots_filtering_required) { |
| 381 buffer->UpdateSlotsWithFilter(heap); |
| 382 } else { |
| 383 buffer->UpdateSlots(heap); |
| 384 } |
380 buffer = buffer->next(); | 385 buffer = buffer->next(); |
381 } | 386 } |
382 } | 387 } |
383 | 388 |
384 enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW }; | 389 enum AdditionMode { FAIL_ON_OVERFLOW, IGNORE_OVERFLOW }; |
385 | 390 |
386 static bool ChainLengthThresholdReached(SlotsBuffer* buffer) { | 391 static bool ChainLengthThresholdReached(SlotsBuffer* buffer) { |
387 return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold; | 392 return buffer != NULL && buffer->chain_length_ >= kChainLengthThreshold; |
388 } | 393 } |
389 | 394 |
(...skipping 18 matching lines...) Expand all Loading... |
408 static bool AddTo(SlotsBufferAllocator* allocator, | 413 static bool AddTo(SlotsBufferAllocator* allocator, |
409 SlotsBuffer** buffer_address, SlotType type, Address addr, | 414 SlotsBuffer** buffer_address, SlotType type, Address addr, |
410 AdditionMode mode); | 415 AdditionMode mode); |
411 | 416 |
412 // Eliminates all stale entries from the slots buffer, i.e., slots that | 417 // Eliminates all stale entries from the slots buffer, i.e., slots that |
413 // are not part of live objects anymore. This method must be called after | 418 // are not part of live objects anymore. This method must be called after |
414 // marking, when the whole transitive closure is known and must be called | 419 // marking, when the whole transitive closure is known and must be called |
415 // before sweeping when mark bits are still intact. | 420 // before sweeping when mark bits are still intact. |
416 static void RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer); | 421 static void RemoveInvalidSlots(Heap* heap, SlotsBuffer* buffer); |
417 | 422 |
418 // Eliminate all slots that are within the given address range. | |
419 static void RemoveObjectSlots(Heap* heap, SlotsBuffer* buffer, | |
420 Address start_slot, Address end_slot); | |
421 | |
422 // Ensures that there are no invalid slots in the chain of slots buffers. | 423 // Ensures that there are no invalid slots in the chain of slots buffers. |
423 static void VerifySlots(Heap* heap, SlotsBuffer* buffer); | 424 static void VerifySlots(Heap* heap, SlotsBuffer* buffer); |
424 | 425 |
425 static const int kNumberOfElements = 1021; | 426 static const int kNumberOfElements = 1021; |
426 | 427 |
427 private: | 428 private: |
428 static const int kChainLengthThreshold = 15; | 429 static const int kChainLengthThreshold = 15; |
429 | 430 |
430 intptr_t idx_; | 431 intptr_t idx_; |
431 intptr_t chain_length_; | 432 intptr_t chain_length_; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 | 660 |
660 void MigrateObject(HeapObject* dst, HeapObject* src, int size, | 661 void MigrateObject(HeapObject* dst, HeapObject* src, int size, |
661 AllocationSpace to_old_space); | 662 AllocationSpace to_old_space); |
662 | 663 |
663 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size); | 664 void MigrateObjectTagged(HeapObject* dst, HeapObject* src, int size); |
664 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size); | 665 void MigrateObjectMixed(HeapObject* dst, HeapObject* src, int size); |
665 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size); | 666 void MigrateObjectRaw(HeapObject* dst, HeapObject* src, int size); |
666 | 667 |
667 bool TryPromoteObject(HeapObject* object, int object_size); | 668 bool TryPromoteObject(HeapObject* object, int object_size); |
668 | 669 |
| 670 void InvalidateCode(Code* code); |
| 671 |
669 void ClearMarkbits(); | 672 void ClearMarkbits(); |
670 | 673 |
671 bool abort_incremental_marking() const { return abort_incremental_marking_; } | 674 bool abort_incremental_marking() const { return abort_incremental_marking_; } |
672 | 675 |
673 bool finalize_incremental_marking() const { | 676 bool finalize_incremental_marking() const { |
674 return finalize_incremental_marking_; | 677 return finalize_incremental_marking_; |
675 } | 678 } |
676 | 679 |
677 bool is_compacting() const { return compacting_; } | 680 bool is_compacting() const { return compacting_; } |
678 | 681 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 void InitializeMarkingDeque(); | 734 void InitializeMarkingDeque(); |
732 | 735 |
733 // The following four methods can just be called after marking, when the | 736 // The following four methods can just be called after marking, when the |
734 // whole transitive closure is known. They must be called before sweeping | 737 // whole transitive closure is known. They must be called before sweeping |
735 // when mark bits are still intact. | 738 // when mark bits are still intact. |
736 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); | 739 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); |
737 bool IsSlotInBlackObjectSlow(Page* p, Address slot); | 740 bool IsSlotInBlackObjectSlow(Page* p, Address slot); |
738 bool IsSlotInLiveObject(Address slot); | 741 bool IsSlotInLiveObject(Address slot); |
739 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); | 742 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); |
740 | 743 |
741 // Removes all the slots in the slot buffers that are within the given | |
742 // address range. | |
743 void RemoveObjectSlots(Address start_slot, Address end_slot); | |
744 | |
745 private: | 744 private: |
746 class SweeperTask; | 745 class SweeperTask; |
747 | 746 |
748 explicit MarkCompactCollector(Heap* heap); | 747 explicit MarkCompactCollector(Heap* heap); |
749 ~MarkCompactCollector(); | 748 ~MarkCompactCollector(); |
750 | 749 |
| 750 bool MarkInvalidatedCode(); |
751 bool WillBeDeoptimized(Code* code); | 751 bool WillBeDeoptimized(Code* code); |
| 752 void RemoveDeadInvalidatedCode(); |
| 753 void ProcessInvalidatedCode(ObjectVisitor* visitor); |
752 void EvictPopularEvacuationCandidate(Page* page); | 754 void EvictPopularEvacuationCandidate(Page* page); |
753 void ClearInvalidSlotsBufferEntries(PagedSpace* space); | 755 void ClearInvalidSlotsBufferEntries(PagedSpace* space); |
754 void ClearInvalidStoreAndSlotsBufferEntries(); | 756 void ClearInvalidStoreAndSlotsBufferEntries(); |
755 | 757 |
756 void StartSweeperThreads(); | 758 void StartSweeperThreads(); |
757 | 759 |
758 #ifdef DEBUG | 760 #ifdef DEBUG |
759 enum CollectorState { | 761 enum CollectorState { |
760 IDLE, | 762 IDLE, |
761 PREPARE_GC, | 763 PREPARE_GC, |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 #endif | 960 #endif |
959 | 961 |
960 Heap* heap_; | 962 Heap* heap_; |
961 base::VirtualMemory* marking_deque_memory_; | 963 base::VirtualMemory* marking_deque_memory_; |
962 size_t marking_deque_memory_committed_; | 964 size_t marking_deque_memory_committed_; |
963 MarkingDeque marking_deque_; | 965 MarkingDeque marking_deque_; |
964 CodeFlusher* code_flusher_; | 966 CodeFlusher* code_flusher_; |
965 bool have_code_to_deoptimize_; | 967 bool have_code_to_deoptimize_; |
966 | 968 |
967 List<Page*> evacuation_candidates_; | 969 List<Page*> evacuation_candidates_; |
| 970 List<Code*> invalidated_code_; |
968 | 971 |
969 base::SmartPointer<FreeList> free_list_old_space_; | 972 base::SmartPointer<FreeList> free_list_old_space_; |
970 | 973 |
971 friend class Heap; | 974 friend class Heap; |
972 }; | 975 }; |
973 | 976 |
974 | 977 |
975 class MarkBitCellIterator BASE_EMBEDDED { | 978 class MarkBitCellIterator BASE_EMBEDDED { |
976 public: | 979 public: |
977 explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { | 980 explicit MarkBitCellIterator(MemoryChunk* chunk) : chunk_(chunk) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 private: | 1028 private: |
1026 MarkCompactCollector* collector_; | 1029 MarkCompactCollector* collector_; |
1027 }; | 1030 }; |
1028 | 1031 |
1029 | 1032 |
1030 const char* AllocationSpaceName(AllocationSpace space); | 1033 const char* AllocationSpaceName(AllocationSpace space); |
1031 } | 1034 } |
1032 } // namespace v8::internal | 1035 } // namespace v8::internal |
1033 | 1036 |
1034 #endif // V8_HEAP_MARK_COMPACT_H_ | 1037 #endif // V8_HEAP_MARK_COMPACT_H_ |
OLD | NEW |