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