blob: cfa945dd6ff72b5d88355de2337b74bbf8d62122 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
10namespace v8 {
11namespace internal {
12
13template <int start_offset>
14int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) {
15 return object->SizeFromMap(map);
16}
17
18
19bool 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
32template <typename ObjectVisitor>
33void 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
55template <typename StaticVisitor>
56void 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
78template <typename ObjectVisitor>
79void 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
86template <typename StaticVisitor>
87void 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
95template <typename ObjectVisitor>
96void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
97 ObjectVisitor* v) {
98 v->VisitPointer(HeapObject::RawField(obj, offset));
99}
100
101
102template <typename StaticVisitor>
103void 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.
110template <JSFunction::BodyVisitingPolicy body_visiting_policy>
111class 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
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>
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>
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
154 static inline int SizeOf(Map* map, HeapObject* object) {
155 return map->instance_size();
156 }
157};
158
159
160class 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
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>
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>
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
187 static inline int SizeOf(Map* map, HeapObject* object) {
188 return map->instance_size();
189 }
190};
191
192
193class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
194 public:
195 static bool IsValidSlot(HeapObject* obj, int offset) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100196 return offset >= kConstantPoolOffset &&
197 offset <= kSourcePositionTableOffset;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198 }
199
200 template <typename ObjectVisitor>
201 static inline void IterateBody(HeapObject* obj, int object_size,
202 ObjectVisitor* v) {
203 IteratePointer(obj, kConstantPoolOffset, v);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100204 IteratePointer(obj, kHandlerTableOffset, v);
205 IteratePointer(obj, kSourcePositionTableOffset, v);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 }
207
208 template <typename StaticVisitor>
209 static inline void IterateBody(HeapObject* obj, int object_size) {
210 Heap* heap = obj->GetHeap();
211 IteratePointer<StaticVisitor>(heap, obj, kConstantPoolOffset);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100212 IteratePointer<StaticVisitor>(heap, obj, kHandlerTableOffset);
213 IteratePointer<StaticVisitor>(heap, obj, kSourcePositionTableOffset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 }
215
216 static inline int SizeOf(Map* map, HeapObject* obj) {
217 return reinterpret_cast<BytecodeArray*>(obj)->BytecodeArraySize();
218 }
219};
220
221
222class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
223 public:
224 static bool IsValidSlot(HeapObject* obj, int offset) {
225 return offset == kBasePointerOffset;
226 }
227
228 template <typename ObjectVisitor>
229 static inline void IterateBody(HeapObject* obj, int object_size,
230 ObjectVisitor* v) {
231 IteratePointer(obj, kBasePointerOffset, v);
232 }
233
234 template <typename StaticVisitor>
235 static inline void IterateBody(HeapObject* obj, int object_size) {
236 Heap* heap = obj->GetHeap();
237 IteratePointer<StaticVisitor>(heap, obj, kBasePointerOffset);
238 }
239
240 static inline int SizeOf(Map* map, HeapObject* object) {
241 return reinterpret_cast<FixedTypedArrayBase*>(object)->size();
242 }
243};
244
245
246template <JSWeakCollection::BodyVisitingPolicy body_visiting_policy>
247class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
248 public:
249 STATIC_ASSERT(kTableOffset + kPointerSize == kNextOffset);
250 STATIC_ASSERT(kNextOffset + kPointerSize == kSize);
251
252 static bool IsValidSlot(HeapObject* obj, int offset) {
253 return IsValidSlotImpl(obj, offset);
254 }
255
256 template <typename ObjectVisitor>
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>
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
279 static inline int SizeOf(Map* map, HeapObject* object) {
280 return map->instance_size();
281 }
282};
283
284
285class Foreign::BodyDescriptor final : public BodyDescriptorBase {
286 public:
287 static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
288
289 template <typename ObjectVisitor>
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>
297 static inline void IterateBody(HeapObject* obj, int object_size) {
298 StaticVisitor::VisitExternalReference(reinterpret_cast<Address*>(
299 HeapObject::RawField(obj, kForeignAddressOffset)));
300 }
301
302 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
303};
304
305
306class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
307 public:
308 static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
309
310 template <typename ObjectVisitor>
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>
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
325 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
326};
327
328
329class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
330 public:
331 static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
332
333 template <typename ObjectVisitor>
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>
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
348 static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
349};
350
351
352class 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
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>
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>
388 static inline void IterateBody(HeapObject* obj, int object_size,
389 ObjectVisitor* v) {
390 IterateBody(obj, v);
391 }
392
393 template <typename StaticVisitor>
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>
417 static inline void IterateBody(HeapObject* obj, int object_size) {
418 IterateBody<StaticVisitor>(obj);
419 }
420
421 static inline int SizeOf(Map* map, HeapObject* object) {
422 return reinterpret_cast<Code*>(object)->CodeSize();
423 }
424};
425
426
427template <typename Op, typename ReturnType, typename T1, typename T2,
428 typename T3>
429ReturnType 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:
Ben Murdoch61f157c2016-09-16 13:49:30 +0100459 case JS_ERROR_TYPE:
460 case JS_ARGUMENTS_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000461 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:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000474 case JS_REGEXP_TYPE:
475 case JS_GLOBAL_PROXY_TYPE:
476 case JS_GLOBAL_OBJECT_TYPE:
Ben Murdochc5610432016-08-08 18:44:38 +0100477 case JS_API_OBJECT_TYPE:
Ben Murdochda12d292016-06-02 14:46:10 +0100478 case JS_SPECIAL_API_OBJECT_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000479 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
544template <typename ObjectVisitor>
545void HeapObject::IterateFast(ObjectVisitor* v) {
546 BodyDescriptorBase::IteratePointer(this, kMapOffset, v);
547 IterateBodyFast(v);
548}
549
550
551template <typename ObjectVisitor>
552void HeapObject::IterateBodyFast(ObjectVisitor* v) {
553 Map* m = map();
554 IterateBodyFast(m->instance_type(), SizeFromMap(m), v);
555}
556
557
558struct CallIterateBody {
559 template <typename BodyDescriptor, typename ObjectVisitor>
560 static void apply(HeapObject* obj, int object_size, ObjectVisitor* v) {
561 BodyDescriptor::IterateBody(obj, object_size, v);
562 }
563};
564
565template <typename ObjectVisitor>
566void 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_