• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
6 #define V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
7 
8 #include "src/objects-body-descriptors.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 template <int start_offset>
SizeOf(Map * map,HeapObject * object)14 int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) {
15   return object->SizeFromMap(map);
16 }
17 
18 
IsValidSlotImpl(HeapObject * obj,int offset)19 bool BodyDescriptorBase::IsValidSlotImpl(HeapObject* obj, int offset) {
20   if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
21     return true;
22   } else {
23     DCHECK(FLAG_unbox_double_fields);
24     DCHECK(IsAligned(offset, kPointerSize));
25 
26     LayoutDescriptorHelper helper(obj->map());
27     DCHECK(!helper.all_fields_tagged());
28     return helper.IsTagged(offset);
29   }
30 }
31 
32 template <typename ObjectVisitor>
IterateBodyImpl(HeapObject * obj,int start_offset,int end_offset,ObjectVisitor * v)33 void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset,
34                                          int end_offset, ObjectVisitor* v) {
35   if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
36     IteratePointers(obj, start_offset, end_offset, v);
37   } else {
38     DCHECK(FLAG_unbox_double_fields);
39     DCHECK(IsAligned(start_offset, kPointerSize) &&
40            IsAligned(end_offset, kPointerSize));
41 
42     LayoutDescriptorHelper helper(obj->map());
43     DCHECK(!helper.all_fields_tagged());
44     for (int offset = start_offset; offset < end_offset;) {
45       int end_of_region_offset;
46       if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
47         IteratePointers(obj, offset, end_of_region_offset, v);
48       }
49       offset = end_of_region_offset;
50     }
51   }
52 }
53 
54 
55 template <typename StaticVisitor>
IterateBodyImpl(Heap * heap,HeapObject * obj,int start_offset,int end_offset)56 void BodyDescriptorBase::IterateBodyImpl(Heap* heap, HeapObject* obj,
57                                          int start_offset, int end_offset) {
58   if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
59     IteratePointers<StaticVisitor>(heap, obj, start_offset, end_offset);
60   } else {
61     DCHECK(FLAG_unbox_double_fields);
62     DCHECK(IsAligned(start_offset, kPointerSize) &&
63            IsAligned(end_offset, kPointerSize));
64 
65     LayoutDescriptorHelper helper(obj->map());
66     DCHECK(!helper.all_fields_tagged());
67     for (int offset = start_offset; offset < end_offset;) {
68       int end_of_region_offset;
69       if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
70         IteratePointers<StaticVisitor>(heap, obj, offset, end_of_region_offset);
71       }
72       offset = end_of_region_offset;
73     }
74   }
75 }
76 
77 
78 template <typename ObjectVisitor>
IteratePointers(HeapObject * obj,int start_offset,int end_offset,ObjectVisitor * v)79 void BodyDescriptorBase::IteratePointers(HeapObject* obj, int start_offset,
80                                          int end_offset, ObjectVisitor* v) {
81   v->VisitPointers(HeapObject::RawField(obj, start_offset),
82                    HeapObject::RawField(obj, end_offset));
83 }
84 
85 
86 template <typename StaticVisitor>
IteratePointers(Heap * heap,HeapObject * obj,int start_offset,int end_offset)87 void BodyDescriptorBase::IteratePointers(Heap* heap, HeapObject* obj,
88                                          int start_offset, int end_offset) {
89   StaticVisitor::VisitPointers(heap, obj,
90                                HeapObject::RawField(obj, start_offset),
91                                HeapObject::RawField(obj, end_offset));
92 }
93 
94 
95 template <typename ObjectVisitor>
IteratePointer(HeapObject * obj,int offset,ObjectVisitor * v)96 void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
97                                         ObjectVisitor* v) {
98   v->VisitPointer(HeapObject::RawField(obj, offset));
99 }
100 
101 
102 template <typename StaticVisitor>
IteratePointer(Heap * heap,HeapObject * obj,int offset)103 void BodyDescriptorBase::IteratePointer(Heap* heap, HeapObject* obj,
104                                         int offset) {
105   StaticVisitor::VisitPointer(heap, obj, HeapObject::RawField(obj, offset));
106 }
107 
108 
109 // Iterates the function object according to the visiting policy.
110 template <JSFunction::BodyVisitingPolicy body_visiting_policy>
111 class JSFunction::BodyDescriptorImpl final : public BodyDescriptorBase {
112  public:
113   STATIC_ASSERT(kNonWeakFieldsEndOffset == kCodeEntryOffset);
114   STATIC_ASSERT(kCodeEntryOffset + kPointerSize == kNextFunctionLinkOffset);
115   STATIC_ASSERT(kNextFunctionLinkOffset + kPointerSize == kSize);
116 
IsValidSlot(HeapObject * obj,int offset)117   static bool IsValidSlot(HeapObject* obj, int offset) {
118     if (offset < kSize) return true;
119     return IsValidSlotImpl(obj, offset);
120   }
121 
122   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)123   static inline void IterateBody(HeapObject* obj, int object_size,
124                                  ObjectVisitor* v) {
125     IteratePointers(obj, kPropertiesOffset, kNonWeakFieldsEndOffset, v);
126 
127     if (body_visiting_policy & kVisitCodeEntry) {
128       v->VisitCodeEntry(obj->address() + kCodeEntryOffset);
129     }
130 
131     if (body_visiting_policy & kVisitNextFunction) {
132       IteratePointers(obj, kNextFunctionLinkOffset, kSize, v);
133     }
134     IterateBodyImpl(obj, kSize, object_size, v);
135   }
136 
137   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)138   static inline void IterateBody(HeapObject* obj, int object_size) {
139     Heap* heap = obj->GetHeap();
140     IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset,
141                                    kNonWeakFieldsEndOffset);
142 
143     if (body_visiting_policy & kVisitCodeEntry) {
144       StaticVisitor::VisitCodeEntry(heap, obj,
145                                     obj->address() + kCodeEntryOffset);
146     }
147 
148     if (body_visiting_policy & kVisitNextFunction) {
149       IteratePointers<StaticVisitor>(heap, obj, kNextFunctionLinkOffset, kSize);
150     }
151     IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size);
152   }
153 
SizeOf(Map * map,HeapObject * object)154   static inline int SizeOf(Map* map, HeapObject* object) {
155     return map->instance_size();
156   }
157 };
158 
159 
160 class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
161  public:
162   STATIC_ASSERT(kByteLengthOffset + kPointerSize == kBackingStoreOffset);
163   STATIC_ASSERT(kBackingStoreOffset + kPointerSize == kBitFieldSlot);
164   STATIC_ASSERT(kBitFieldSlot + kPointerSize == kSize);
165 
IsValidSlot(HeapObject * obj,int offset)166   static bool IsValidSlot(HeapObject* obj, int offset) {
167     if (offset < kBackingStoreOffset) return true;
168     if (offset < kSize) return false;
169     return IsValidSlotImpl(obj, offset);
170   }
171 
172   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)173   static inline void IterateBody(HeapObject* obj, int object_size,
174                                  ObjectVisitor* v) {
175     IteratePointers(obj, kPropertiesOffset, kBackingStoreOffset, v);
176     IterateBodyImpl(obj, kSize, object_size, v);
177   }
178 
179   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)180   static inline void IterateBody(HeapObject* obj, int object_size) {
181     Heap* heap = obj->GetHeap();
182     IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset,
183                                    kBackingStoreOffset);
184     IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size);
185   }
186 
SizeOf(Map * map,HeapObject * object)187   static inline int SizeOf(Map* map, HeapObject* object) {
188     return map->instance_size();
189   }
190 };
191 
192 
193 class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
194  public:
IsValidSlot(HeapObject * obj,int offset)195   static bool IsValidSlot(HeapObject* obj, int offset) {
196     return offset >= kConstantPoolOffset &&
197            offset <= kSourcePositionTableOffset;
198   }
199 
200   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)201   static inline void IterateBody(HeapObject* obj, int object_size,
202                                  ObjectVisitor* v) {
203     IteratePointer(obj, kConstantPoolOffset, v);
204     IteratePointer(obj, kHandlerTableOffset, v);
205     IteratePointer(obj, kSourcePositionTableOffset, v);
206   }
207 
208   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)209   static inline void IterateBody(HeapObject* obj, int object_size) {
210     Heap* heap = obj->GetHeap();
211     IteratePointer<StaticVisitor>(heap, obj, kConstantPoolOffset);
212     IteratePointer<StaticVisitor>(heap, obj, kHandlerTableOffset);
213     IteratePointer<StaticVisitor>(heap, obj, kSourcePositionTableOffset);
214   }
215 
SizeOf(Map * map,HeapObject * obj)216   static inline int SizeOf(Map* map, HeapObject* obj) {
217     return reinterpret_cast<BytecodeArray*>(obj)->BytecodeArraySize();
218   }
219 };
220 
221 
222 class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
223  public:
IsValidSlot(HeapObject * obj,int offset)224   static bool IsValidSlot(HeapObject* obj, int offset) {
225     return offset == kBasePointerOffset;
226   }
227 
228   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)229   static inline void IterateBody(HeapObject* obj, int object_size,
230                                  ObjectVisitor* v) {
231     IteratePointer(obj, kBasePointerOffset, v);
232   }
233 
234   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)235   static inline void IterateBody(HeapObject* obj, int object_size) {
236     Heap* heap = obj->GetHeap();
237     IteratePointer<StaticVisitor>(heap, obj, kBasePointerOffset);
238   }
239 
SizeOf(Map * map,HeapObject * object)240   static inline int SizeOf(Map* map, HeapObject* object) {
241     return reinterpret_cast<FixedTypedArrayBase*>(object)->size();
242   }
243 };
244 
245 
246 template <JSWeakCollection::BodyVisitingPolicy body_visiting_policy>
247 class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
248  public:
249   STATIC_ASSERT(kTableOffset + kPointerSize == kNextOffset);
250   STATIC_ASSERT(kNextOffset + kPointerSize == kSize);
251 
IsValidSlot(HeapObject * obj,int offset)252   static bool IsValidSlot(HeapObject* obj, int offset) {
253     return IsValidSlotImpl(obj, offset);
254   }
255 
256   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)257   static inline void IterateBody(HeapObject* obj, int object_size,
258                                  ObjectVisitor* v) {
259     if (body_visiting_policy == kVisitStrong) {
260       IterateBodyImpl(obj, kPropertiesOffset, object_size, v);
261     } else {
262       IteratePointers(obj, kPropertiesOffset, kTableOffset, v);
263       IterateBodyImpl(obj, kSize, object_size, v);
264     }
265   }
266 
267   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)268   static inline void IterateBody(HeapObject* obj, int object_size) {
269     Heap* heap = obj->GetHeap();
270     if (body_visiting_policy == kVisitStrong) {
271       IterateBodyImpl<StaticVisitor>(heap, obj, kPropertiesOffset, object_size);
272     } else {
273       IteratePointers<StaticVisitor>(heap, obj, kPropertiesOffset,
274                                      kTableOffset);
275       IterateBodyImpl<StaticVisitor>(heap, obj, kSize, object_size);
276     }
277   }
278 
SizeOf(Map * map,HeapObject * object)279   static inline int SizeOf(Map* map, HeapObject* object) {
280     return map->instance_size();
281   }
282 };
283 
284 
285 class Foreign::BodyDescriptor final : public BodyDescriptorBase {
286  public:
IsValidSlot(HeapObject * obj,int offset)287   static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
288 
289   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)290   static inline void IterateBody(HeapObject* obj, int object_size,
291                                  ObjectVisitor* v) {
292     v->VisitExternalReference(reinterpret_cast<Address*>(
293         HeapObject::RawField(obj, kForeignAddressOffset)));
294   }
295 
296   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)297   static inline void IterateBody(HeapObject* obj, int object_size) {
298     StaticVisitor::VisitExternalReference(reinterpret_cast<Address*>(
299         HeapObject::RawField(obj, kForeignAddressOffset)));
300   }
301 
SizeOf(Map * map,HeapObject * object)302   static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
303 };
304 
305 
306 class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
307  public:
IsValidSlot(HeapObject * obj,int offset)308   static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
309 
310   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)311   static inline void IterateBody(HeapObject* obj, int object_size,
312                                  ObjectVisitor* v) {
313     typedef v8::String::ExternalOneByteStringResource Resource;
314     v->VisitExternalOneByteString(reinterpret_cast<Resource**>(
315         HeapObject::RawField(obj, kResourceOffset)));
316   }
317 
318   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)319   static inline void IterateBody(HeapObject* obj, int object_size) {
320     typedef v8::String::ExternalOneByteStringResource Resource;
321     StaticVisitor::VisitExternalOneByteString(reinterpret_cast<Resource**>(
322         HeapObject::RawField(obj, kResourceOffset)));
323   }
324 
SizeOf(Map * map,HeapObject * object)325   static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
326 };
327 
328 
329 class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
330  public:
IsValidSlot(HeapObject * obj,int offset)331   static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
332 
333   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)334   static inline void IterateBody(HeapObject* obj, int object_size,
335                                  ObjectVisitor* v) {
336     typedef v8::String::ExternalStringResource Resource;
337     v->VisitExternalTwoByteString(reinterpret_cast<Resource**>(
338         HeapObject::RawField(obj, kResourceOffset)));
339   }
340 
341   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)342   static inline void IterateBody(HeapObject* obj, int object_size) {
343     typedef v8::String::ExternalStringResource Resource;
344     StaticVisitor::VisitExternalTwoByteString(reinterpret_cast<Resource**>(
345         HeapObject::RawField(obj, kResourceOffset)));
346   }
347 
SizeOf(Map * map,HeapObject * object)348   static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
349 };
350 
351 
352 class Code::BodyDescriptor final : public BodyDescriptorBase {
353  public:
354   STATIC_ASSERT(kRelocationInfoOffset + kPointerSize == kHandlerTableOffset);
355   STATIC_ASSERT(kHandlerTableOffset + kPointerSize ==
356                 kDeoptimizationDataOffset);
357   STATIC_ASSERT(kDeoptimizationDataOffset + kPointerSize ==
358                 kTypeFeedbackInfoOffset);
359   STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize == kNextCodeLinkOffset);
360 
IsValidSlot(HeapObject * obj,int offset)361   static bool IsValidSlot(HeapObject* obj, int offset) {
362     // Slots in code can't be invalid because we never trim code objects.
363     return true;
364   }
365 
366   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,ObjectVisitor * v)367   static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
368     int mode_mask = RelocInfo::kCodeTargetMask |
369                     RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
370                     RelocInfo::ModeMask(RelocInfo::CELL) |
371                     RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
372                     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
373                     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
374                     RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
375                     RelocInfo::kDebugBreakSlotMask;
376 
377     IteratePointers(obj, kRelocationInfoOffset, kNextCodeLinkOffset, v);
378     v->VisitNextCodeLink(HeapObject::RawField(obj, kNextCodeLinkOffset));
379 
380     RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask);
381     Isolate* isolate = obj->GetIsolate();
382     for (; !it.done(); it.next()) {
383       it.rinfo()->Visit(isolate, v);
384     }
385   }
386 
387   template <typename ObjectVisitor>
IterateBody(HeapObject * obj,int object_size,ObjectVisitor * v)388   static inline void IterateBody(HeapObject* obj, int object_size,
389                                  ObjectVisitor* v) {
390     IterateBody(obj, v);
391   }
392 
393   template <typename StaticVisitor>
IterateBody(HeapObject * obj)394   static inline void IterateBody(HeapObject* obj) {
395     int mode_mask = RelocInfo::kCodeTargetMask |
396                     RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
397                     RelocInfo::ModeMask(RelocInfo::CELL) |
398                     RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
399                     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
400                     RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
401                     RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
402                     RelocInfo::kDebugBreakSlotMask;
403 
404     Heap* heap = obj->GetHeap();
405     IteratePointers<StaticVisitor>(heap, obj, kRelocationInfoOffset,
406                                    kNextCodeLinkOffset);
407     StaticVisitor::VisitNextCodeLink(
408         heap, HeapObject::RawField(obj, kNextCodeLinkOffset));
409 
410     RelocIterator it(reinterpret_cast<Code*>(obj), mode_mask);
411     for (; !it.done(); it.next()) {
412       it.rinfo()->template Visit<StaticVisitor>(heap);
413     }
414   }
415 
416   template <typename StaticVisitor>
IterateBody(HeapObject * obj,int object_size)417   static inline void IterateBody(HeapObject* obj, int object_size) {
418     IterateBody<StaticVisitor>(obj);
419   }
420 
SizeOf(Map * map,HeapObject * object)421   static inline int SizeOf(Map* map, HeapObject* object) {
422     return reinterpret_cast<Code*>(object)->CodeSize();
423   }
424 };
425 
426 
427 template <typename Op, typename ReturnType, typename T1, typename T2,
428           typename T3>
BodyDescriptorApply(InstanceType type,T1 p1,T2 p2,T3 p3)429 ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
430   if (type < FIRST_NONSTRING_TYPE) {
431     switch (type & kStringRepresentationMask) {
432       case kSeqStringTag:
433         return ReturnType();
434       case kConsStringTag:
435         return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3);
436       case kSlicedStringTag:
437         return Op::template apply<SlicedString::BodyDescriptor>(p1, p2, p3);
438       case kExternalStringTag:
439         if ((type & kStringEncodingMask) == kOneByteStringTag) {
440           return Op::template apply<ExternalOneByteString::BodyDescriptor>(
441               p1, p2, p3);
442         } else {
443           return Op::template apply<ExternalTwoByteString::BodyDescriptor>(
444               p1, p2, p3);
445         }
446     }
447     UNREACHABLE();
448     return ReturnType();
449   }
450 
451   switch (type) {
452     case FIXED_ARRAY_TYPE:
453       return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3);
454     case FIXED_DOUBLE_ARRAY_TYPE:
455       return ReturnType();
456     case TRANSITION_ARRAY_TYPE:
457       return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3);
458     case JS_OBJECT_TYPE:
459     case JS_ERROR_TYPE:
460     case JS_ARGUMENTS_TYPE:
461     case JS_PROMISE_TYPE:
462     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
463     case JS_GENERATOR_OBJECT_TYPE:
464     case JS_MODULE_TYPE:
465     case JS_VALUE_TYPE:
466     case JS_DATE_TYPE:
467     case JS_ARRAY_TYPE:
468     case JS_TYPED_ARRAY_TYPE:
469     case JS_DATA_VIEW_TYPE:
470     case JS_SET_TYPE:
471     case JS_MAP_TYPE:
472     case JS_SET_ITERATOR_TYPE:
473     case JS_MAP_ITERATOR_TYPE:
474     case JS_REGEXP_TYPE:
475     case JS_GLOBAL_PROXY_TYPE:
476     case JS_GLOBAL_OBJECT_TYPE:
477     case JS_API_OBJECT_TYPE:
478     case JS_SPECIAL_API_OBJECT_TYPE:
479     case JS_MESSAGE_OBJECT_TYPE:
480     case JS_BOUND_FUNCTION_TYPE:
481       return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3);
482     case JS_WEAK_MAP_TYPE:
483     case JS_WEAK_SET_TYPE:
484       return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3);
485     case JS_ARRAY_BUFFER_TYPE:
486       return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3);
487     case JS_FUNCTION_TYPE:
488       return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3);
489     case ODDBALL_TYPE:
490       return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3);
491     case JS_PROXY_TYPE:
492       return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3);
493     case FOREIGN_TYPE:
494       return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3);
495     case MAP_TYPE:
496       return Op::template apply<Map::BodyDescriptor>(p1, p2, p3);
497     case CODE_TYPE:
498       return Op::template apply<Code::BodyDescriptor>(p1, p2, p3);
499     case CELL_TYPE:
500       return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3);
501     case PROPERTY_CELL_TYPE:
502       return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3);
503     case WEAK_CELL_TYPE:
504       return Op::template apply<WeakCell::BodyDescriptor>(p1, p2, p3);
505     case SYMBOL_TYPE:
506       return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3);
507     case BYTECODE_ARRAY_TYPE:
508       return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3);
509 
510     case HEAP_NUMBER_TYPE:
511     case MUTABLE_HEAP_NUMBER_TYPE:
512     case SIMD128_VALUE_TYPE:
513     case FILLER_TYPE:
514     case BYTE_ARRAY_TYPE:
515     case FREE_SPACE_TYPE:
516       return ReturnType();
517 
518 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
519   case FIXED_##TYPE##_ARRAY_TYPE:                       \
520     return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3);
521       TYPED_ARRAYS(TYPED_ARRAY_CASE)
522 #undef TYPED_ARRAY_CASE
523 
524     case SHARED_FUNCTION_INFO_TYPE: {
525       return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3);
526     }
527 
528 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
529       STRUCT_LIST(MAKE_STRUCT_CASE)
530 #undef MAKE_STRUCT_CASE
531       if (type == ALLOCATION_SITE_TYPE) {
532         return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3);
533       } else {
534         return Op::template apply<StructBodyDescriptor>(p1, p2, p3);
535       }
536     default:
537       PrintF("Unknown type: %d\n", type);
538       UNREACHABLE();
539       return ReturnType();
540   }
541 }
542 
543 
544 template <typename ObjectVisitor>
IterateFast(ObjectVisitor * v)545 void HeapObject::IterateFast(ObjectVisitor* v) {
546   BodyDescriptorBase::IteratePointer(this, kMapOffset, v);
547   IterateBodyFast(v);
548 }
549 
550 
551 template <typename ObjectVisitor>
IterateBodyFast(ObjectVisitor * v)552 void HeapObject::IterateBodyFast(ObjectVisitor* v) {
553   Map* m = map();
554   IterateBodyFast(m->instance_type(), SizeFromMap(m), v);
555 }
556 
557 
558 struct CallIterateBody {
559   template <typename BodyDescriptor, typename ObjectVisitor>
applyCallIterateBody560   static void apply(HeapObject* obj, int object_size, ObjectVisitor* v) {
561     BodyDescriptor::IterateBody(obj, object_size, v);
562   }
563 };
564 
565 template <typename ObjectVisitor>
IterateBodyFast(InstanceType type,int object_size,ObjectVisitor * v)566 void HeapObject::IterateBodyFast(InstanceType type, int object_size,
567                                  ObjectVisitor* v) {
568   BodyDescriptorApply<CallIterateBody, void>(type, this, object_size, v);
569 }
570 }  // namespace internal
571 }  // namespace v8
572 
573 #endif  // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
574