| 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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 | 175 |
| 176 private: | 176 private: |
| 177 Heap* heap_; | 177 Heap* heap_; |
| 178 }; | 178 }; |
| 179 | 179 |
| 180 // ---------------------------------------------------------------------------- | 180 // ---------------------------------------------------------------------------- |
| 181 // Marking deque for tracing live objects. | 181 // Marking deque for tracing live objects. |
| 182 class MarkingDeque { | 182 class MarkingDeque { |
| 183 public: | 183 public: |
| 184 MarkingDeque() | 184 MarkingDeque() |
| 185 : array_(NULL), top_(0), bottom_(0), mask_(0), overflowed_(false) {} | 185 : array_(NULL), |
| 186 top_(0), |
| 187 bottom_(0), |
| 188 mask_(0), |
| 189 overflowed_(false), |
| 190 in_use_(false) {} |
| 186 | 191 |
| 187 void Initialize(Address low, Address high) { | 192 void Initialize(Address low, Address high); |
| 188 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); | 193 void Uninitialize(bool aborting = false); |
| 189 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); | |
| 190 array_ = obj_low; | |
| 191 mask_ = base::bits::RoundDownToPowerOfTwo32( | |
| 192 static_cast<uint32_t>(obj_high - obj_low)) - | |
| 193 1; | |
| 194 top_ = bottom_ = 0; | |
| 195 overflowed_ = false; | |
| 196 } | |
| 197 | 194 |
| 198 inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } | 195 inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } |
| 199 | 196 |
| 200 inline bool IsEmpty() { return top_ == bottom_; } | 197 inline bool IsEmpty() { return top_ == bottom_; } |
| 201 | 198 |
| 202 bool overflowed() const { return overflowed_; } | 199 bool overflowed() const { return overflowed_; } |
| 203 | 200 |
| 201 bool in_use() const { return in_use_; } |
| 202 |
| 204 void ClearOverflowed() { overflowed_ = false; } | 203 void ClearOverflowed() { overflowed_ = false; } |
| 205 | 204 |
| 206 void SetOverflowed() { overflowed_ = true; } | 205 void SetOverflowed() { overflowed_ = true; } |
| 207 | 206 |
| 208 // Push the (marked) object on the marking stack if there is room, | 207 // Push the (marked) object on the marking stack if there is room, |
| 209 // otherwise mark the object as overflowed and wait for a rescan of the | 208 // otherwise mark the object as overflowed and wait for a rescan of the |
| 210 // heap. | 209 // heap. |
| 211 INLINE(void PushBlack(HeapObject* object)) { | 210 INLINE(void PushBlack(HeapObject* object)) { |
| 212 DCHECK(object->IsHeapObject()); | 211 DCHECK(object->IsHeapObject()); |
| 213 DCHECK(object->map()->IsMap()); | 212 DCHECK(object->map()->IsMap()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 235 INLINE(HeapObject* Pop()) { | 234 INLINE(HeapObject* Pop()) { |
| 236 DCHECK(!IsEmpty()); | 235 DCHECK(!IsEmpty()); |
| 237 top_ = ((top_ - 1) & mask_); | 236 top_ = ((top_ - 1) & mask_); |
| 238 HeapObject* object = array_[top_]; | 237 HeapObject* object = array_[top_]; |
| 239 DCHECK(object->IsHeapObject()); | 238 DCHECK(object->IsHeapObject()); |
| 240 return object; | 239 return object; |
| 241 } | 240 } |
| 242 | 241 |
| 243 INLINE(void UnshiftGrey(HeapObject* object)) { | 242 INLINE(void UnshiftGrey(HeapObject* object)) { |
| 244 DCHECK(object->IsHeapObject()); | 243 DCHECK(object->IsHeapObject()); |
| 245 DCHECK(Marking::IsGrey(Marking::MarkBitFrom(object))); | |
| 246 if (IsFull()) { | 244 if (IsFull()) { |
| 247 SetOverflowed(); | 245 SetOverflowed(); |
| 248 } else { | 246 } else { |
| 249 bottom_ = ((bottom_ - 1) & mask_); | 247 bottom_ = ((bottom_ - 1) & mask_); |
| 250 array_[bottom_] = object; | 248 array_[bottom_] = object; |
| 251 } | 249 } |
| 252 } | 250 } |
| 253 | 251 |
| 254 INLINE(void UnshiftBlack(HeapObject* object)) { | 252 INLINE(void UnshiftBlack(HeapObject* object)) { |
| 255 DCHECK(object->IsHeapObject()); | 253 DCHECK(object->IsHeapObject()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 272 | 270 |
| 273 private: | 271 private: |
| 274 HeapObject** array_; | 272 HeapObject** array_; |
| 275 // array_[(top - 1) & mask_] is the top element in the deque. The Deque is | 273 // array_[(top - 1) & mask_] is the top element in the deque. The Deque is |
| 276 // empty when top_ == bottom_. It is full when top_ + 1 == bottom | 274 // empty when top_ == bottom_. It is full when top_ + 1 == bottom |
| 277 // (mod mask + 1). | 275 // (mod mask + 1). |
| 278 int top_; | 276 int top_; |
| 279 int bottom_; | 277 int bottom_; |
| 280 int mask_; | 278 int mask_; |
| 281 bool overflowed_; | 279 bool overflowed_; |
| 280 bool in_use_; |
| 282 | 281 |
| 283 DISALLOW_COPY_AND_ASSIGN(MarkingDeque); | 282 DISALLOW_COPY_AND_ASSIGN(MarkingDeque); |
| 284 }; | 283 }; |
| 285 | 284 |
| 286 | 285 |
| 287 class SlotsBufferAllocator { | 286 class SlotsBufferAllocator { |
| 288 public: | 287 public: |
| 289 SlotsBuffer* AllocateBuffer(SlotsBuffer* next_buffer); | 288 SlotsBuffer* AllocateBuffer(SlotsBuffer* next_buffer); |
| 290 void DeallocateBuffer(SlotsBuffer* buffer); | 289 void DeallocateBuffer(SlotsBuffer* buffer); |
| 291 | 290 |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 // Special case for processing weak references in a full collection. We need | 712 // Special case for processing weak references in a full collection. We need |
| 714 // to artificially keep AllocationSites alive for a time. | 713 // to artificially keep AllocationSites alive for a time. |
| 715 void MarkAllocationSite(AllocationSite* site); | 714 void MarkAllocationSite(AllocationSite* site); |
| 716 | 715 |
| 717 // Mark objects in implicit references groups if their parent object | 716 // Mark objects in implicit references groups if their parent object |
| 718 // is marked. | 717 // is marked. |
| 719 void MarkImplicitRefGroups(MarkObjectFunction mark_object); | 718 void MarkImplicitRefGroups(MarkObjectFunction mark_object); |
| 720 | 719 |
| 721 MarkingDeque* marking_deque() { return &marking_deque_; } | 720 MarkingDeque* marking_deque() { return &marking_deque_; } |
| 722 | 721 |
| 723 void EnsureMarkingDequeIsCommittedAndInitialize(size_t max_size = 4 * MB); | 722 static const size_t kMaxMarkingDequeSize = 4 * MB; |
| 723 static const size_t kMinMarkingDequeSize = 256 * KB; |
| 724 |
| 725 void EnsureMarkingDequeIsCommittedAndInitialize(size_t max_size) { |
| 726 if (!marking_deque_.in_use()) { |
| 727 EnsureMarkingDequeIsCommitted(max_size); |
| 728 InitializeMarkingDeque(); |
| 729 } |
| 730 } |
| 731 |
| 732 void EnsureMarkingDequeIsCommitted(size_t max_size); |
| 733 void EnsureMarkingDequeIsReserved(); |
| 724 | 734 |
| 725 void InitializeMarkingDeque(); | 735 void InitializeMarkingDeque(); |
| 726 | 736 |
| 727 void UncommitMarkingDeque(); | |
| 728 | |
| 729 // The following four methods can just be called after marking, when the | 737 // The following four methods can just be called after marking, when the |
| 730 // whole transitive closure is known. They must be called before sweeping | 738 // whole transitive closure is known. They must be called before sweeping |
| 731 // when mark bits are still intact. | 739 // when mark bits are still intact. |
| 732 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); | 740 bool IsSlotInBlackObject(Page* p, Address slot, HeapObject** out_object); |
| 733 bool IsSlotInBlackObjectSlow(Page* p, Address slot); | 741 bool IsSlotInBlackObjectSlow(Page* p, Address slot); |
| 734 bool IsSlotInLiveObject(Address slot); | 742 bool IsSlotInLiveObject(Address slot); |
| 735 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); | 743 void VerifyIsSlotInLiveObject(Address slot, HeapObject* object); |
| 736 | 744 |
| 737 private: | 745 private: |
| 738 class SweeperTask; | 746 class SweeperTask; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 #ifdef DEBUG | 955 #ifdef DEBUG |
| 948 friend class MarkObjectVisitor; | 956 friend class MarkObjectVisitor; |
| 949 static void VisitObject(HeapObject* obj); | 957 static void VisitObject(HeapObject* obj); |
| 950 | 958 |
| 951 friend class UnmarkObjectVisitor; | 959 friend class UnmarkObjectVisitor; |
| 952 static void UnmarkObject(HeapObject* obj); | 960 static void UnmarkObject(HeapObject* obj); |
| 953 #endif | 961 #endif |
| 954 | 962 |
| 955 Heap* heap_; | 963 Heap* heap_; |
| 956 base::VirtualMemory* marking_deque_memory_; | 964 base::VirtualMemory* marking_deque_memory_; |
| 957 bool marking_deque_memory_committed_; | 965 size_t marking_deque_memory_committed_; |
| 958 MarkingDeque marking_deque_; | 966 MarkingDeque marking_deque_; |
| 959 CodeFlusher* code_flusher_; | 967 CodeFlusher* code_flusher_; |
| 960 bool have_code_to_deoptimize_; | 968 bool have_code_to_deoptimize_; |
| 961 | 969 |
| 962 List<Page*> evacuation_candidates_; | 970 List<Page*> evacuation_candidates_; |
| 963 List<Code*> invalidated_code_; | 971 List<Code*> invalidated_code_; |
| 964 | 972 |
| 965 SmartPointer<FreeList> free_list_old_space_; | 973 SmartPointer<FreeList> free_list_old_space_; |
| 966 | 974 |
| 967 friend class Heap; | 975 friend class Heap; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 private: | 1029 private: |
| 1022 MarkCompactCollector* collector_; | 1030 MarkCompactCollector* collector_; |
| 1023 }; | 1031 }; |
| 1024 | 1032 |
| 1025 | 1033 |
| 1026 const char* AllocationSpaceName(AllocationSpace space); | 1034 const char* AllocationSpaceName(AllocationSpace space); |
| 1027 } | 1035 } |
| 1028 } // namespace v8::internal | 1036 } // namespace v8::internal |
| 1029 | 1037 |
| 1030 #endif // V8_HEAP_MARK_COMPACT_H_ | 1038 #endif // V8_HEAP_MARK_COMPACT_H_ |
| OLD | NEW |