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