| 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |