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