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