OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 } | 118 } |
119 }; | 119 }; |
120 | 120 |
121 typedef Bitmap<BitmapStorageDescriptor> NewSpaceMarkbitsBitmap; | 121 typedef Bitmap<BitmapStorageDescriptor> NewSpaceMarkbitsBitmap; |
122 | 122 |
123 Heap* heap_; | 123 Heap* heap_; |
124 NewSpaceMarkbitsBitmap* new_space_bitmap_; | 124 NewSpaceMarkbitsBitmap* new_space_bitmap_; |
125 }; | 125 }; |
126 | 126 |
127 // ---------------------------------------------------------------------------- | 127 // ---------------------------------------------------------------------------- |
128 // Marking stack for tracing live objects. | 128 // Marking deque for tracing live objects. |
129 | 129 |
130 class MarkingStack { | 130 class MarkingDeque { |
131 public: | 131 public: |
132 MarkingStack() : low_(NULL), top_(NULL), high_(NULL), overflowed_(false) { } | 132 MarkingDeque() |
133 : array_(NULL), top_(0), bottom_(0), mask_(0), overflowed_(false) { } | |
133 | 134 |
134 void Initialize(Address low, Address high) { | 135 void Initialize(Address low, Address high) { |
135 top_ = low_ = reinterpret_cast<HeapObject**>(low); | 136 HeapObject** obj_low = reinterpret_cast<HeapObject**>(low); |
136 high_ = reinterpret_cast<HeapObject**>(high); | 137 HeapObject** obj_high = reinterpret_cast<HeapObject**>(high); |
138 array_ = obj_low; | |
139 intptr_t size = RoundUpToPowerOf2(obj_high - obj_low); | |
140 if (size > obj_high - obj_low) size >>= 1; | |
Vyacheslav Egorov (Chromium)
2011/05/04 14:46:52
(obj_high - obj_low)
| |
141 mask_ = size - 1; | |
142 top_ = bottom_ = 0; | |
137 overflowed_ = false; | 143 overflowed_ = false; |
138 } | 144 } |
139 | 145 |
140 bool is_full() const { return top_ >= high_; } | 146 inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; } |
141 | 147 |
142 bool is_empty() const { return top_ <= low_; } | 148 inline bool IsEmpty() { return top_ == bottom_; } |
143 | 149 |
144 bool overflowed() const { return overflowed_; } | 150 bool overflowed() const { return overflowed_; } |
145 | 151 |
146 void clear_overflowed() { overflowed_ = false; } | 152 void clear_overflowed() { overflowed_ = false; } |
147 | 153 |
148 // Push the (marked) object on the marking stack if there is room, | 154 // Push the (marked) object on the marking stack if there is room, |
149 // otherwise mark the object as overflowed and wait for a rescan of the | 155 // otherwise mark the object as overflowed and wait for a rescan of the |
150 // heap. | 156 // heap. |
151 void Push(HeapObject* object) { | 157 inline void Push(HeapObject* object) { |
152 CHECK(object->IsHeapObject()); | 158 ASSERT(object->IsHeapObject()); |
153 if (is_full()) { | 159 if (IsFull()) { |
154 object->SetOverflow(); | 160 object->SetOverflow(); |
155 overflowed_ = true; | 161 overflowed_ = true; |
156 } else { | 162 } else { |
157 *(top_++) = object; | 163 array_[top_] = object; |
164 top_ = ((top_ + 1) & mask_); | |
158 } | 165 } |
159 } | 166 } |
160 | 167 |
161 HeapObject* Pop() { | 168 inline HeapObject* Pop() { |
162 ASSERT(!is_empty()); | 169 ASSERT(!IsEmpty()); |
163 HeapObject* object = *(--top_); | 170 top_ = ((top_ - 1) & mask_); |
164 CHECK(object->IsHeapObject()); | 171 HeapObject* object = array_[top_]; |
172 ASSERT(object->IsHeapObject()); | |
165 return object; | 173 return object; |
166 } | 174 } |
167 | 175 |
168 HeapObject** low() { return low_; } | 176 inline void Unshift(HeapObject* object) { |
169 HeapObject** top() { return top_; } | 177 ASSERT(object->IsHeapObject()); |
170 void set_top(HeapObject** top) { top_ = top; } | 178 if (IsFull()) { |
179 object->SetOverflow(); | |
180 overflowed_ = true; | |
181 } else { | |
182 bottom_ = ((bottom_ - 1) & mask_); | |
183 array_[bottom_] = object; | |
184 } | |
185 } | |
186 | |
187 HeapObject** array() { return array_; } | |
188 intptr_t bottom() { return bottom_; } | |
189 intptr_t top() { return top_; } | |
190 intptr_t mask() { return mask_; } | |
191 void set_top(intptr_t top) { top_ = top; } | |
171 | 192 |
172 private: | 193 private: |
173 HeapObject** low_; | 194 HeapObject** array_; |
174 HeapObject** top_; | 195 // array_[(top - 1) & mask_] is the top element in the deque. The Deque is |
175 HeapObject** high_; | 196 // empty when top_ == bottom_. It is full when top_ + 1 == bottom |
197 // (mod mask + 1). | |
198 int top_; | |
199 int bottom_; | |
200 int mask_; | |
176 bool overflowed_; | 201 bool overflowed_; |
177 | 202 |
178 DISALLOW_COPY_AND_ASSIGN(MarkingStack); | 203 DISALLOW_COPY_AND_ASSIGN(MarkingDeque); |
179 }; | 204 }; |
180 | 205 |
181 | 206 |
182 // ------------------------------------------------------------------------- | 207 // ------------------------------------------------------------------------- |
183 // Mark-Compact collector | 208 // Mark-Compact collector |
184 // | 209 // |
185 // All methods are static. | 210 // All methods are static. |
186 | 211 |
187 class OverflowedObjectsScanner; | 212 class OverflowedObjectsScanner; |
188 | 213 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 // Mark objects in implicit references groups if their parent object | 396 // Mark objects in implicit references groups if their parent object |
372 // is marked. | 397 // is marked. |
373 void MarkImplicitRefGroups(); | 398 void MarkImplicitRefGroups(); |
374 | 399 |
375 // Mark all objects which are reachable due to host application | 400 // Mark all objects which are reachable due to host application |
376 // logic like object groups or implicit references' groups. | 401 // logic like object groups or implicit references' groups. |
377 void ProcessExternalMarking(); | 402 void ProcessExternalMarking(); |
378 | 403 |
379 // Mark objects reachable (transitively) from objects in the marking stack | 404 // Mark objects reachable (transitively) from objects in the marking stack |
380 // or overflowed in the heap. | 405 // or overflowed in the heap. |
381 void ProcessMarkingStack(); | 406 void ProcessMarkingDeque(); |
382 | 407 |
383 // Mark objects reachable (transitively) from objects in the marking | 408 // Mark objects reachable (transitively) from objects in the marking |
384 // stack. This function empties the marking stack, but may leave | 409 // stack. This function empties the marking stack, but may leave |
385 // overflowed objects in the heap, in which case the marking stack's | 410 // overflowed objects in the heap, in which case the marking stack's |
386 // overflow flag will be set. | 411 // overflow flag will be set. |
387 void EmptyMarkingStack(); | 412 void EmptyMarkingDeque(); |
388 | 413 |
389 // Refill the marking stack with overflowed objects from the heap. This | 414 // Refill the marking stack with overflowed objects from the heap. This |
390 // function either leaves the marking stack full or clears the overflow | 415 // function either leaves the marking stack full or clears the overflow |
391 // flag on the marking stack. | 416 // flag on the marking stack. |
392 void RefillMarkingStack(); | 417 void RefillMarkingDeque(); |
393 | 418 |
394 // Callback function for telling whether the object *p is an unmarked | 419 // Callback function for telling whether the object *p is an unmarked |
395 // heap object. | 420 // heap object. |
396 static bool IsUnmarkedHeapObject(Object** p); | 421 static bool IsUnmarkedHeapObject(Object** p); |
397 | 422 |
398 #ifdef DEBUG | 423 #ifdef DEBUG |
399 void UpdateLiveObjectCount(HeapObject* obj); | 424 void UpdateLiveObjectCount(HeapObject* obj); |
400 #endif | 425 #endif |
401 | 426 |
402 // Test whether a (possibly marked) object is a Map. | 427 // Test whether a (possibly marked) object is a Map. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 int live_bytes_; | 496 int live_bytes_; |
472 | 497 |
473 friend class MarkObjectVisitor; | 498 friend class MarkObjectVisitor; |
474 static void VisitObject(HeapObject* obj); | 499 static void VisitObject(HeapObject* obj); |
475 | 500 |
476 friend class UnmarkObjectVisitor; | 501 friend class UnmarkObjectVisitor; |
477 static void UnmarkObject(HeapObject* obj); | 502 static void UnmarkObject(HeapObject* obj); |
478 #endif | 503 #endif |
479 | 504 |
480 Heap* heap_; | 505 Heap* heap_; |
481 MarkingStack marking_stack_; | 506 MarkingDeque marking_deque_; |
482 CodeFlusher* code_flusher_; | 507 CodeFlusher* code_flusher_; |
483 | 508 |
484 friend class Heap; | 509 friend class Heap; |
485 friend class OverflowedObjectsScanner; | 510 friend class OverflowedObjectsScanner; |
486 }; | 511 }; |
487 | 512 |
488 | 513 |
489 } } // namespace v8::internal | 514 } } // namespace v8::internal |
490 | 515 |
491 #endif // V8_MARK_COMPACT_H_ | 516 #endif // V8_MARK_COMPACT_H_ |
OLD | NEW |