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/feedback-vector.h"
10 : #include "src/objects-body-descriptors.h"
11 : #include "src/objects/hash-table.h"
12 : #include "src/transitions.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : template <int start_offset>
18 26741143 : int FlexibleBodyDescriptor<start_offset>::SizeOf(Map* map, HeapObject* object) {
19 27135515 : return object->SizeFromMap(map);
20 : }
21 :
22 202 : bool BodyDescriptorBase::IsValidSlotImpl(HeapObject* obj, int offset) {
23 202 : if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
24 : return true;
25 : } else {
26 : DCHECK(FLAG_unbox_double_fields);
27 : DCHECK(IsAligned(offset, kPointerSize));
28 :
29 12 : LayoutDescriptorHelper helper(obj->map());
30 : DCHECK(!helper.all_fields_tagged());
31 12 : return helper.IsTagged(offset);
32 : }
33 : }
34 :
35 : template <typename ObjectVisitor>
36 91452345 : void BodyDescriptorBase::IterateBodyImpl(HeapObject* obj, int start_offset,
37 : int end_offset, ObjectVisitor* v) {
38 91452345 : if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
39 41360860 : IteratePointers(obj, start_offset, end_offset, v);
40 : } else {
41 : DCHECK(FLAG_unbox_double_fields);
42 : DCHECK(IsAligned(start_offset, kPointerSize) &&
43 : IsAligned(end_offset, kPointerSize));
44 :
45 243379 : LayoutDescriptorHelper helper(obj->map());
46 : DCHECK(!helper.all_fields_tagged());
47 1002989 : for (int offset = start_offset; offset < end_offset;) {
48 : int end_of_region_offset;
49 516519 : if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
50 280444 : IteratePointers(obj, offset, end_of_region_offset, v);
51 : }
52 516649 : offset = end_of_region_offset;
53 : }
54 : }
55 91395069 : }
56 :
57 : template <typename ObjectVisitor>
58 217216769 : DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(HeapObject* obj,
59 : int start_offset,
60 : int end_offset,
61 : ObjectVisitor* v) {
62 294015567 : v->VisitPointers(obj, HeapObject::RawField(obj, start_offset),
63 : HeapObject::RawField(obj, end_offset));
64 217311458 : }
65 :
66 : template <typename ObjectVisitor>
67 5992031 : void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
68 : ObjectVisitor* v) {
69 62430376 : v->VisitPointer(obj, HeapObject::RawField(obj, offset));
70 5992031 : }
71 :
72 : class JSObject::BodyDescriptor final : public BodyDescriptorBase {
73 : public:
74 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
75 :
76 : static bool IsValidSlot(HeapObject* obj, int offset) {
77 204 : if (offset < kStartOffset) return false;
78 204 : return IsValidSlotImpl(obj, offset);
79 : }
80 :
81 : template <typename ObjectVisitor>
82 38657428 : static inline void IterateBody(HeapObject* obj, int object_size,
83 : ObjectVisitor* v) {
84 85955719 : IterateBodyImpl(obj, kStartOffset, object_size, v);
85 38657333 : }
86 :
87 38657895 : static inline int SizeOf(Map* map, HeapObject* object) {
88 38657895 : return map->instance_size();
89 : }
90 : };
91 :
92 : class JSObject::FastBodyDescriptor final : public BodyDescriptorBase {
93 : public:
94 : static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
95 :
96 : static bool IsValidSlot(HeapObject* obj, int offset) {
97 : return offset >= kStartOffset;
98 : }
99 :
100 : template <typename ObjectVisitor>
101 15592934 : static inline void IterateBody(HeapObject* obj, int object_size,
102 : ObjectVisitor* v) {
103 15592934 : IteratePointers(obj, kStartOffset, object_size, v);
104 15557835 : }
105 :
106 15595852 : static inline int SizeOf(Map* map, HeapObject* object) {
107 15595852 : return map->instance_size();
108 : }
109 : };
110 :
111 : class JSFunction::BodyDescriptor final : public BodyDescriptorBase {
112 : public:
113 0 : static bool IsValidSlot(HeapObject* obj, int offset) {
114 0 : if (offset < kSizeWithoutPrototype) return true;
115 0 : if (offset < kSizeWithPrototype && obj->map()->has_prototype_slot()) {
116 : return true;
117 : }
118 0 : return IsValidSlotImpl(obj, offset);
119 : }
120 :
121 : template <typename ObjectVisitor>
122 5393792 : static inline void IterateBody(HeapObject* obj, int object_size,
123 : ObjectVisitor* v) {
124 5393792 : int header_size = JSFunction::cast(obj)->GetHeaderSize();
125 1185546 : IteratePointers(obj, kPropertiesOrHashOffset, header_size, v);
126 5392330 : IterateBodyImpl(obj, header_size, object_size, v);
127 5392924 : }
128 :
129 : static inline int SizeOf(Map* map, HeapObject* object) {
130 : return map->instance_size();
131 : }
132 : };
133 :
134 : class JSArrayBuffer::BodyDescriptor final : public BodyDescriptorBase {
135 : public:
136 : STATIC_ASSERT(kByteLengthOffset + kPointerSize == kBackingStoreOffset);
137 : STATIC_ASSERT(kAllocationLengthOffset + kPointerSize == kBitFieldSlot);
138 : STATIC_ASSERT(kBitFieldSlot + kPointerSize == kSize);
139 :
140 : static bool IsValidSlot(HeapObject* obj, int offset) {
141 0 : if (offset < kAllocationLengthOffset) return true;
142 0 : if (offset < kSize) return false;
143 0 : return IsValidSlotImpl(obj, offset);
144 : }
145 :
146 : template <typename ObjectVisitor>
147 75733 : static inline void IterateBody(HeapObject* obj, int object_size,
148 : ObjectVisitor* v) {
149 : // Array buffers contain raw pointers that the GC does not know about. These
150 : // are stored at kBackStoreOffset and later, so we do not iterate over
151 : // those.
152 22924 : IteratePointers(obj, kPropertiesOrHashOffset, kBackingStoreOffset, v);
153 75697 : IterateBodyImpl(obj, kSize, object_size, v);
154 75724 : }
155 :
156 47291 : static inline int SizeOf(Map* map, HeapObject* object) {
157 47291 : return map->instance_size();
158 : }
159 : };
160 :
161 : template <typename Derived>
162 : class SmallOrderedHashTable<Derived>::BodyDescriptor final
163 : : public BodyDescriptorBase {
164 : public:
165 0 : static bool IsValidSlot(HeapObject* obj, int offset) {
166 : Derived* table = reinterpret_cast<Derived*>(obj);
167 0 : if (offset < table->GetDataTableStartOffset()) return false;
168 0 : return IsValidSlotImpl(obj, offset);
169 : }
170 :
171 : template <typename ObjectVisitor>
172 0 : static inline void IterateBody(HeapObject* obj, int object_size,
173 : ObjectVisitor* v) {
174 : Derived* table = reinterpret_cast<Derived*>(obj);
175 : int start = table->GetDataTableStartOffset();
176 0 : for (int i = 0; i < table->Capacity(); i++) {
177 0 : IteratePointer(obj, start + (i * kPointerSize), v);
178 : }
179 0 : }
180 :
181 0 : static inline int SizeOf(Map* map, HeapObject* obj) {
182 : Derived* table = reinterpret_cast<Derived*>(obj);
183 0 : return table->Size();
184 : }
185 : };
186 :
187 : class ByteArray::BodyDescriptor final : public BodyDescriptorBase {
188 : public:
189 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
190 :
191 : template <typename ObjectVisitor>
192 64126882 : static inline void IterateBody(HeapObject* obj, int object_size,
193 64126882 : ObjectVisitor* v) {}
194 :
195 71476756 : static inline int SizeOf(Map* map, HeapObject* obj) {
196 71476756 : return ByteArray::SizeFor(ByteArray::cast(obj)->synchronized_length());
197 : }
198 : };
199 :
200 : class BytecodeArray::BodyDescriptor final : public BodyDescriptorBase {
201 : public:
202 : static bool IsValidSlot(HeapObject* obj, int offset) {
203 0 : return offset >= kConstantPoolOffset &&
204 0 : offset <= kSourcePositionTableOffset;
205 : }
206 :
207 : template <typename ObjectVisitor>
208 1698990 : static inline void IterateBody(HeapObject* obj, int object_size,
209 : ObjectVisitor* v) {
210 475305 : IteratePointer(obj, kConstantPoolOffset, v);
211 475305 : IteratePointer(obj, kHandlerTableOffset, v);
212 475305 : IteratePointer(obj, kSourcePositionTableOffset, v);
213 1699247 : }
214 :
215 475305 : static inline int SizeOf(Map* map, HeapObject* obj) {
216 : return BytecodeArray::SizeFor(
217 475305 : BytecodeArray::cast(obj)->synchronized_length());
218 : }
219 : };
220 :
221 : class BigInt::BodyDescriptor final : public BodyDescriptorBase {
222 : public:
223 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
224 :
225 : template <typename ObjectVisitor>
226 58 : static inline void IterateBody(HeapObject* obj, int object_size,
227 58 : ObjectVisitor* v) {}
228 :
229 21 : static inline int SizeOf(Map* map, HeapObject* obj) {
230 21 : return BigInt::SizeFor(BigInt::cast(obj)->length());
231 : }
232 : };
233 :
234 : class FixedDoubleArray::BodyDescriptor final : public BodyDescriptorBase {
235 : public:
236 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
237 :
238 : template <typename ObjectVisitor>
239 41695 : static inline void IterateBody(HeapObject* obj, int object_size,
240 41695 : ObjectVisitor* v) {}
241 :
242 43244 : static inline int SizeOf(Map* map, HeapObject* obj) {
243 : return FixedDoubleArray::SizeFor(
244 43244 : FixedDoubleArray::cast(obj)->synchronized_length());
245 : }
246 : };
247 :
248 : class FixedTypedArrayBase::BodyDescriptor final : public BodyDescriptorBase {
249 : public:
250 : static bool IsValidSlot(HeapObject* obj, int offset) {
251 0 : return offset == kBasePointerOffset;
252 : }
253 :
254 : template <typename ObjectVisitor>
255 670099 : static inline void IterateBody(HeapObject* obj, int object_size,
256 : ObjectVisitor* v) {
257 89232 : IteratePointer(obj, kBasePointerOffset, v);
258 670091 : }
259 :
260 670248 : static inline int SizeOf(Map* map, HeapObject* object) {
261 670251 : return FixedTypedArrayBase::cast(object)->size();
262 : }
263 : };
264 :
265 : class FeedbackVector::BodyDescriptor final : public BodyDescriptorBase {
266 : public:
267 : static bool IsValidSlot(HeapObject* obj, int offset) {
268 0 : return offset == kSharedFunctionInfoOffset ||
269 0 : offset == kOptimizedCodeOffset || offset >= kFeedbackSlotsOffset;
270 : }
271 :
272 : template <typename ObjectVisitor>
273 7789308 : static inline void IterateBody(HeapObject* obj, int object_size,
274 : ObjectVisitor* v) {
275 2238442 : IteratePointer(obj, kSharedFunctionInfoOffset, v);
276 2238442 : IteratePointer(obj, kOptimizedCodeOffset, v);
277 2311295 : IteratePointers(obj, kFeedbackSlotsOffset, object_size, v);
278 7789104 : }
279 :
280 7444595 : static inline int SizeOf(Map* map, HeapObject* obj) {
281 7444595 : return FeedbackVector::SizeFor(FeedbackVector::cast(obj)->length());
282 : }
283 : };
284 :
285 : template <JSWeakCollection::BodyVisitingPolicy body_visiting_policy>
286 : class JSWeakCollection::BodyDescriptorImpl final : public BodyDescriptorBase {
287 : public:
288 : STATIC_ASSERT(kTableOffset + kPointerSize == kNextOffset);
289 : STATIC_ASSERT(kNextOffset + kPointerSize == kSize);
290 :
291 : static bool IsValidSlot(HeapObject* obj, int offset) {
292 0 : return IsValidSlotImpl(obj, offset);
293 : }
294 :
295 : template <typename ObjectVisitor>
296 16976 : static inline void IterateBody(HeapObject* obj, int object_size,
297 : ObjectVisitor* v) {
298 : if (body_visiting_policy == kIgnoreWeakness) {
299 17934 : IterateBodyImpl(obj, kPropertiesOrHashOffset, object_size, v);
300 : } else {
301 9425 : IteratePointers(obj, kPropertiesOrHashOffset, kTableOffset, v);
302 9425 : IterateBodyImpl(obj, kSize, object_size, v);
303 : }
304 16978 : }
305 :
306 16976 : static inline int SizeOf(Map* map, HeapObject* object) {
307 16976 : return map->instance_size();
308 : }
309 : };
310 :
311 : class Foreign::BodyDescriptor final : public BodyDescriptorBase {
312 : public:
313 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
314 :
315 : template <typename ObjectVisitor>
316 : static inline void IterateBody(HeapObject* obj, int object_size,
317 : ObjectVisitor* v) {
318 2541934 : v->VisitExternalReference(Foreign::cast(obj),
319 : reinterpret_cast<Address*>(HeapObject::RawField(
320 1270967 : obj, kForeignAddressOffset)));
321 : }
322 :
323 : static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
324 : };
325 :
326 : class ExternalOneByteString::BodyDescriptor final : public BodyDescriptorBase {
327 : public:
328 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
329 :
330 : template <typename ObjectVisitor>
331 : static inline void IterateBody(HeapObject* obj, int object_size,
332 : ObjectVisitor* v) {
333 : }
334 :
335 : static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
336 : };
337 :
338 : class ExternalTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
339 : public:
340 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
341 :
342 : template <typename ObjectVisitor>
343 : static inline void IterateBody(HeapObject* obj, int object_size,
344 : ObjectVisitor* v) {
345 : }
346 :
347 : static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
348 : };
349 :
350 : class Code::BodyDescriptor final : public BodyDescriptorBase {
351 : public:
352 : STATIC_ASSERT(kRelocationInfoOffset + kPointerSize == kHandlerTableOffset);
353 : STATIC_ASSERT(kHandlerTableOffset + kPointerSize ==
354 : kDeoptimizationDataOffset);
355 : STATIC_ASSERT(kDeoptimizationDataOffset + kPointerSize ==
356 : kSourcePositionTableOffset);
357 : STATIC_ASSERT(kSourcePositionTableOffset + kPointerSize ==
358 : kTypeFeedbackInfoOffset);
359 : STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize ==
360 : kNextCodeLinkOffset);
361 :
362 : static bool IsValidSlot(HeapObject* obj, int offset) {
363 : // Slots in code can't be invalid because we never trim code objects.
364 : return true;
365 : }
366 :
367 : template <typename ObjectVisitor>
368 57401796 : static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
369 : int mode_mask = RelocInfo::kCodeTargetMask |
370 : RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
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 :
376 55600809 : IteratePointers(obj, kRelocationInfoOffset, kNextCodeLinkOffset, v);
377 1802180 : v->VisitNextCodeLink(Code::cast(obj),
378 : HeapObject::RawField(obj, kNextCodeLinkOffset));
379 :
380 : // GC does not visit data/code in the header and in the body directly.
381 : STATIC_ASSERT(Code::kNextCodeLinkOffset + kPointerSize == kDataStart);
382 :
383 57401725 : RelocIterator it(Code::cast(obj), mode_mask);
384 : Isolate* isolate = obj->GetIsolate();
385 497676561 : for (; !it.done(); it.next()) {
386 440275657 : it.rinfo()->Visit(isolate, v);
387 : }
388 57401763 : }
389 :
390 : template <typename ObjectVisitor>
391 55599613 : static inline void IterateBody(HeapObject* obj, int object_size,
392 : ObjectVisitor* v) {
393 57401406 : IterateBody(obj, v);
394 55599582 : }
395 :
396 55599613 : static inline int SizeOf(Map* map, HeapObject* object) {
397 55599610 : return reinterpret_cast<Code*>(object)->CodeSize();
398 : }
399 : };
400 :
401 : class SeqOneByteString::BodyDescriptor final : public BodyDescriptorBase {
402 : public:
403 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
404 :
405 : template <typename ObjectVisitor>
406 21015286 : static inline void IterateBody(HeapObject* obj, int object_size,
407 21015286 : ObjectVisitor* v) {}
408 :
409 25234060 : static inline int SizeOf(Map* map, HeapObject* obj) {
410 : SeqOneByteString* string = SeqOneByteString::cast(obj);
411 25234060 : return string->SizeFor(string->synchronized_length());
412 : }
413 : };
414 :
415 : class SeqTwoByteString::BodyDescriptor final : public BodyDescriptorBase {
416 : public:
417 : static bool IsValidSlot(HeapObject* obj, int offset) { return false; }
418 :
419 : template <typename ObjectVisitor>
420 4372541 : static inline void IterateBody(HeapObject* obj, int object_size,
421 4372541 : ObjectVisitor* v) {}
422 :
423 7136621 : static inline int SizeOf(Map* map, HeapObject* obj) {
424 : SeqTwoByteString* string = SeqTwoByteString::cast(obj);
425 7136621 : return string->SizeFor(string->synchronized_length());
426 : }
427 : };
428 :
429 : template <typename Op, typename ReturnType, typename T1, typename T2,
430 : typename T3>
431 97577241 : ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
432 97577241 : if (type < FIRST_NONSTRING_TYPE) {
433 46767123 : switch (type & kStringRepresentationMask) {
434 : case kSeqStringTag:
435 : return ReturnType();
436 : case kConsStringTag:
437 0 : return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3);
438 : case kThinStringTag:
439 0 : return Op::template apply<ThinString::BodyDescriptor>(p1, p2, p3);
440 : case kSlicedStringTag:
441 0 : 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 0 : UNREACHABLE();
452 : }
453 :
454 50810118 : switch (type) {
455 : case HASH_TABLE_TYPE:
456 : case FIXED_ARRAY_TYPE:
457 0 : return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3);
458 : case FIXED_DOUBLE_ARRAY_TYPE:
459 : return ReturnType();
460 : case PROPERTY_ARRAY_TYPE:
461 0 : return Op::template apply<PropertyArray::BodyDescriptor>(p1, p2, p3);
462 : case TRANSITION_ARRAY_TYPE:
463 0 : return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3);
464 : case FEEDBACK_VECTOR_TYPE:
465 0 : return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3);
466 : case JS_OBJECT_TYPE:
467 : case JS_ERROR_TYPE:
468 : case JS_ARGUMENTS_TYPE:
469 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
470 : case JS_PROMISE_TYPE:
471 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
472 : case JS_GENERATOR_OBJECT_TYPE:
473 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
474 : case JS_VALUE_TYPE:
475 : case JS_DATE_TYPE:
476 : case JS_ARRAY_TYPE:
477 : case JS_MODULE_NAMESPACE_TYPE:
478 : case JS_TYPED_ARRAY_TYPE:
479 : case JS_DATA_VIEW_TYPE:
480 : case JS_SET_TYPE:
481 : case JS_MAP_TYPE:
482 : case JS_SET_KEY_VALUE_ITERATOR_TYPE:
483 : case JS_SET_VALUE_ITERATOR_TYPE:
484 : case JS_MAP_KEY_ITERATOR_TYPE:
485 : case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
486 : case JS_MAP_VALUE_ITERATOR_TYPE:
487 : case JS_STRING_ITERATOR_TYPE:
488 :
489 : #define ARRAY_ITERATOR_CASE(type) case type:
490 : ARRAY_ITERATOR_TYPE_LIST(ARRAY_ITERATOR_CASE)
491 : #undef ARRAY_ITERATOR_CASE
492 :
493 : case JS_REGEXP_TYPE:
494 : case JS_GLOBAL_PROXY_TYPE:
495 : case JS_GLOBAL_OBJECT_TYPE:
496 : case JS_API_OBJECT_TYPE:
497 : case JS_SPECIAL_API_OBJECT_TYPE:
498 : case JS_MESSAGE_OBJECT_TYPE:
499 : case JS_BOUND_FUNCTION_TYPE:
500 : case WASM_INSTANCE_TYPE:
501 : case WASM_MEMORY_TYPE:
502 : case WASM_MODULE_TYPE:
503 : case WASM_TABLE_TYPE:
504 203 : return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3);
505 : case JS_WEAK_MAP_TYPE:
506 : case JS_WEAK_SET_TYPE:
507 0 : return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3);
508 : case JS_ARRAY_BUFFER_TYPE:
509 0 : return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3);
510 : case JS_FUNCTION_TYPE:
511 0 : return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3);
512 : case ODDBALL_TYPE:
513 0 : return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3);
514 : case JS_PROXY_TYPE:
515 0 : return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3);
516 : case FOREIGN_TYPE:
517 : return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3);
518 : case MAP_TYPE:
519 0 : return Op::template apply<Map::BodyDescriptor>(p1, p2, p3);
520 : case CODE_TYPE:
521 0 : return Op::template apply<Code::BodyDescriptor>(p1, p2, p3);
522 : case CELL_TYPE:
523 0 : return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3);
524 : case PROPERTY_CELL_TYPE:
525 0 : return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3);
526 : case WEAK_CELL_TYPE:
527 0 : return Op::template apply<WeakCell::BodyDescriptor>(p1, p2, p3);
528 : case SYMBOL_TYPE:
529 0 : return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3);
530 : case BYTECODE_ARRAY_TYPE:
531 0 : return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3);
532 : case SMALL_ORDERED_HASH_SET_TYPE:
533 : return Op::template apply<
534 : SmallOrderedHashTable<SmallOrderedHashSet>::BodyDescriptor>(p1, p2,
535 0 : p3);
536 : case SMALL_ORDERED_HASH_MAP_TYPE:
537 : return Op::template apply<
538 : SmallOrderedHashTable<SmallOrderedHashMap>::BodyDescriptor>(p1, p2,
539 0 : p3);
540 : case HEAP_NUMBER_TYPE:
541 : case MUTABLE_HEAP_NUMBER_TYPE:
542 : case FILLER_TYPE:
543 : case BYTE_ARRAY_TYPE:
544 : case FREE_SPACE_TYPE:
545 : case BIGINT_TYPE:
546 : return ReturnType();
547 :
548 : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
549 : case FIXED_##TYPE##_ARRAY_TYPE: \
550 : return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3);
551 0 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
552 : #undef TYPED_ARRAY_CASE
553 :
554 : case SHARED_FUNCTION_INFO_TYPE: {
555 0 : return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3);
556 : }
557 :
558 : #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
559 : STRUCT_LIST(MAKE_STRUCT_CASE)
560 : #undef MAKE_STRUCT_CASE
561 704635 : if (type == ALLOCATION_SITE_TYPE) {
562 0 : return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3);
563 : } else {
564 0 : return Op::template apply<StructBodyDescriptor>(p1, p2, p3);
565 : }
566 : default:
567 0 : PrintF("Unknown type: %d\n", type);
568 0 : UNREACHABLE();
569 : }
570 : }
571 :
572 :
573 : template <typename ObjectVisitor>
574 19937875 : void HeapObject::IterateFast(ObjectVisitor* v) {
575 : BodyDescriptorBase::IteratePointer(this, kMapOffset, v);
576 19937875 : IterateBodyFast(v);
577 19937875 : }
578 :
579 :
580 : template <typename ObjectVisitor>
581 28614223 : void HeapObject::IterateBodyFast(ObjectVisitor* v) {
582 : Map* m = map();
583 28614223 : IterateBodyFast(m->instance_type(), SizeFromMap(m), v);
584 28536811 : }
585 :
586 :
587 : struct CallIterateBody {
588 : template <typename BodyDescriptor, typename ObjectVisitor>
589 : static void apply(HeapObject* obj, int object_size, ObjectVisitor* v) {
590 456002 : BodyDescriptor::IterateBody(obj, object_size, v);
591 : }
592 : };
593 :
594 : template <typename ObjectVisitor>
595 : void HeapObject::IterateBodyFast(InstanceType type, int object_size,
596 : ObjectVisitor* v) {
597 96815389 : BodyDescriptorApply<CallIterateBody, void>(type, this, object_size, v);
598 : }
599 : } // namespace internal
600 : } // namespace v8
601 :
602 : #endif // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
|