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