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_OBJECTS_VISITING_H_ | 5 #ifndef V8_OBJECTS_VISITING_H_ |
6 #define V8_OBJECTS_VISITING_H_ | 6 #define V8_OBJECTS_VISITING_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/heap/heap.h" | 9 #include "src/heap/heap.h" |
10 #include "src/heap/spaces.h" | 10 #include "src/heap/spaces.h" |
(...skipping 170 matching lines...) Loading... |
181 RegisterSpecialization<Visitor, base, generic, 8>(); | 181 RegisterSpecialization<Visitor, base, generic, 8>(); |
182 RegisterSpecialization<Visitor, base, generic, 9>(); | 182 RegisterSpecialization<Visitor, base, generic, 9>(); |
183 Register(generic, &Visitor::Visit); | 183 Register(generic, &Visitor::Visit); |
184 } | 184 } |
185 | 185 |
186 private: | 186 private: |
187 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; | 187 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; |
188 }; | 188 }; |
189 | 189 |
190 | 190 |
191 template <typename StaticVisitor> | |
192 class BodyVisitorBase : public AllStatic { | |
193 public: | |
194 INLINE(static void IteratePointers(Heap* heap, HeapObject* object, | |
195 int start_offset, int end_offset)) { | |
196 DCHECK(!FLAG_unbox_double_fields || object->map()->HasFastPointerLayout()); | |
197 IterateRawPointers(heap, object, start_offset, end_offset); | |
198 } | |
199 | |
200 INLINE(static void IterateBody(Heap* heap, HeapObject* object, | |
201 int start_offset, int end_offset)) { | |
202 if (!FLAG_unbox_double_fields || object->map()->HasFastPointerLayout()) { | |
203 IterateRawPointers(heap, object, start_offset, end_offset); | |
204 } else { | |
205 IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset); | |
206 } | |
207 } | |
208 | |
209 private: | |
210 INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object, | |
211 int start_offset, int end_offset)) { | |
212 StaticVisitor::VisitPointers(heap, object, | |
213 HeapObject::RawField(object, start_offset), | |
214 HeapObject::RawField(object, end_offset)); | |
215 } | |
216 | |
217 static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object, | |
218 int start_offset, | |
219 int end_offset) { | |
220 DCHECK(FLAG_unbox_double_fields); | |
221 DCHECK(IsAligned(start_offset, kPointerSize) && | |
222 IsAligned(end_offset, kPointerSize)); | |
223 | |
224 LayoutDescriptorHelper helper(object->map()); | |
225 DCHECK(!helper.all_fields_tagged()); | |
226 for (int offset = start_offset; offset < end_offset;) { | |
227 int end_of_region_offset; | |
228 if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) { | |
229 IterateRawPointers(heap, object, offset, end_of_region_offset); | |
230 } | |
231 offset = end_of_region_offset; | |
232 } | |
233 } | |
234 }; | |
235 | |
236 | |
237 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 191 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
238 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 192 class FlexibleBodyVisitor : public AllStatic { |
239 public: | 193 public: |
240 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 194 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
241 int object_size = BodyDescriptor::SizeOf(map, object); | 195 int object_size = BodyDescriptor::SizeOf(map, object); |
242 BodyVisitorBase<StaticVisitor>::IterateBody( | 196 BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size); |
243 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); | |
244 return static_cast<ReturnType>(object_size); | 197 return static_cast<ReturnType>(object_size); |
245 } | 198 } |
246 | 199 |
| 200 // This specialization is only suitable for objects containing pointer fields. |
247 template <int object_size> | 201 template <int object_size> |
248 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { | 202 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { |
249 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); | 203 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); |
250 BodyVisitorBase<StaticVisitor>::IteratePointers( | 204 DCHECK(!FLAG_unbox_double_fields || map->HasFastPointerLayout()); |
251 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); | 205 StaticVisitor::VisitPointers( |
| 206 object->GetHeap(), object, |
| 207 HeapObject::RawField(object, BodyDescriptor::kStartOffset), |
| 208 HeapObject::RawField(object, object_size)); |
252 return static_cast<ReturnType>(object_size); | 209 return static_cast<ReturnType>(object_size); |
253 } | 210 } |
254 }; | 211 }; |
255 | 212 |
256 | 213 |
257 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 214 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
258 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 215 class FixedBodyVisitor : public AllStatic { |
259 public: | 216 public: |
260 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 217 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
261 BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object, | 218 BodyDescriptor::template IterateBody<StaticVisitor>(object); |
262 BodyDescriptor::kStartOffset, | |
263 BodyDescriptor::kEndOffset); | |
264 return static_cast<ReturnType>(BodyDescriptor::kSize); | 219 return static_cast<ReturnType>(BodyDescriptor::kSize); |
265 } | 220 } |
266 }; | 221 }; |
267 | 222 |
268 | 223 |
269 // Base class for visitors used for a linear new space iteration. | 224 // Base class for visitors used for a linear new space iteration. |
270 // IterateBody returns size of visited object. | 225 // IterateBody returns size of visited object. |
271 // Certain types of objects (i.e. Code objects) are not handled | 226 // Certain types of objects (i.e. Code objects) are not handled |
272 // by dispatch table of this visitor because they cannot appear | 227 // by dispatch table of this visitor because they cannot appear |
273 // in the new space. | 228 // in the new space. |
(...skipping 214 matching lines...) Loading... |
488 // the next element. Given the head of the list, this function removes dead | 443 // the next element. Given the head of the list, this function removes dead |
489 // elements from the list and if requested records slots for next-element | 444 // elements from the list and if requested records slots for next-element |
490 // pointers. The template parameter T is a WeakListVisitor that defines how to | 445 // pointers. The template parameter T is a WeakListVisitor that defines how to |
491 // access the next-element pointers. | 446 // access the next-element pointers. |
492 template <class T> | 447 template <class T> |
493 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); | 448 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); |
494 } // namespace internal | 449 } // namespace internal |
495 } // namespace v8 | 450 } // namespace v8 |
496 | 451 |
497 #endif // V8_OBJECTS_VISITING_H_ | 452 #endif // V8_OBJECTS_VISITING_H_ |
OLD | NEW |