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 |