V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
objects-body-descriptors-inl.h
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/objects/js-collection.h"
13 #include "src/objects/js-weak-refs.h"
14 #include "src/objects/slots.h"
15 #include "src/transitions.h"
16 #include "src/wasm/wasm-objects-inl.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 template <int start_offset>
22 int FlexibleBodyDescriptor<start_offset>::SizeOf(Map map, HeapObject* object) {
23  return object->SizeFromMap(map);
24 }
25 
26 template <int start_offset>
27 int FlexibleWeakBodyDescriptor<start_offset>::SizeOf(Map map,
28  HeapObject* object) {
29  return object->SizeFromMap(map);
30 }
31 
32 bool BodyDescriptorBase::IsValidSlotImpl(Map map, HeapObject* obj, int offset) {
33  if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
34  return true;
35  } else {
36  DCHECK(FLAG_unbox_double_fields);
37  DCHECK(IsAligned(offset, kPointerSize));
38 
39  LayoutDescriptorHelper helper(map);
40  DCHECK(!helper.all_fields_tagged());
41  return helper.IsTagged(offset);
42  }
43 }
44 
45 template <typename ObjectVisitor>
46 void BodyDescriptorBase::IterateBodyImpl(Map map, HeapObject* obj,
47  int start_offset, int end_offset,
48  ObjectVisitor* v) {
49  if (!FLAG_unbox_double_fields || map->HasFastPointerLayout()) {
50  IteratePointers(obj, start_offset, end_offset, v);
51  } else {
52  DCHECK(FLAG_unbox_double_fields);
53  DCHECK(IsAligned(start_offset, kPointerSize) &&
54  IsAligned(end_offset, kPointerSize));
55 
56  LayoutDescriptorHelper helper(map);
57  DCHECK(!helper.all_fields_tagged());
58  for (int offset = start_offset; offset < end_offset;) {
59  int end_of_region_offset;
60  if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
61  IteratePointers(obj, offset, end_of_region_offset, v);
62  }
63  offset = end_of_region_offset;
64  }
65  }
66 }
67 
68 template <typename ObjectVisitor>
69 DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(HeapObject* obj,
70  int start_offset,
71  int end_offset,
72  ObjectVisitor* v) {
73  v->VisitPointers(obj, HeapObject::RawField(obj, start_offset),
74  HeapObject::RawField(obj, end_offset));
75 }
76 
77 template <typename ObjectVisitor>
78 void BodyDescriptorBase::IteratePointer(HeapObject* obj, int offset,
79  ObjectVisitor* v) {
80  v->VisitPointer(obj, HeapObject::RawField(obj, offset));
81 }
82 
83 template <typename ObjectVisitor>
84 DISABLE_CFI_PERF void BodyDescriptorBase::IterateMaybeWeakPointers(
85  HeapObject* obj, int start_offset, int end_offset, ObjectVisitor* v) {
86  v->VisitPointers(obj, HeapObject::RawMaybeWeakField(obj, start_offset),
87  HeapObject::RawMaybeWeakField(obj, end_offset));
88 }
89 
90 template <typename ObjectVisitor>
91 void BodyDescriptorBase::IterateMaybeWeakPointer(HeapObject* obj, int offset,
92  ObjectVisitor* v) {
93  v->VisitPointer(obj, HeapObject::RawMaybeWeakField(obj, offset));
94 }
95 
96 template <typename ObjectVisitor>
97 DISABLE_CFI_PERF void BodyDescriptorBase::IterateCustomWeakPointers(
98  HeapObject* obj, int start_offset, int end_offset, ObjectVisitor* v) {
99  v->VisitCustomWeakPointers(obj, HeapObject::RawField(obj, start_offset),
100  HeapObject::RawField(obj, end_offset));
101 }
102 
103 template <typename ObjectVisitor>
104 void BodyDescriptorBase::IterateCustomWeakPointer(HeapObject* obj, int offset,
105  ObjectVisitor* v) {
106  v->VisitCustomWeakPointer(obj, HeapObject::RawField(obj, offset));
107 }
108 
110  public:
111  static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
112 
113  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
114  if (offset < kStartOffset) return false;
115  return IsValidSlotImpl(map, obj, offset);
116  }
117 
118  template <typename ObjectVisitor>
119  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
120  ObjectVisitor* v) {
121  IterateBodyImpl(map, obj, kStartOffset, object_size, v);
122  }
123 
124  static inline int SizeOf(Map map, HeapObject* object) {
125  return map->instance_size();
126  }
127 };
128 
130  public:
131  static const int kStartOffset = JSReceiver::kPropertiesOrHashOffset;
132 
133  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
134  return offset >= kStartOffset;
135  }
136 
137  template <typename ObjectVisitor>
138  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
139  ObjectVisitor* v) {
140  IteratePointers(obj, kStartOffset, object_size, v);
141  }
142 
143  static inline int SizeOf(Map map, HeapObject* object) {
144  return map->instance_size();
145  }
146 };
147 
149  public:
150  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
151  if (offset < kSizeWithoutPrototype) return true;
152  if (offset < kSizeWithPrototype && map->has_prototype_slot()) {
153  return true;
154  }
155  return IsValidSlotImpl(map, obj, offset);
156  }
157 
158  template <typename ObjectVisitor>
159  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
160  ObjectVisitor* v) {
161  int header_size = JSFunction::GetHeaderSize(map->has_prototype_slot());
162  DCHECK_EQ(header_size, JSObject::GetHeaderSize(map));
163  IteratePointers(obj, kPropertiesOrHashOffset, header_size, v);
164  IterateBodyImpl(map, obj, header_size, object_size, v);
165  }
166 
167  static inline int SizeOf(Map map, HeapObject* object) {
168  return map->instance_size();
169  }
170 };
171 
173  public:
174  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
175  return JSObject::BodyDescriptor::IsValidSlot(map, obj, offset);
176  }
177 
178  template <typename ObjectVisitor>
179  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
180  ObjectVisitor* v) {
181  IteratePointers(obj, JSReceiver::kPropertiesOrHashOffset, kTargetOffset, v);
182  IterateCustomWeakPointer(obj, kTargetOffset, v);
183  IteratePointers(obj, kTargetOffset + kPointerSize, object_size, v);
184  }
185 
186  static inline int SizeOf(Map map, HeapObject* object) {
187  return map->instance_size();
188  }
189 };
190 
192  public:
193  STATIC_ASSERT(AllocationSite::kCommonPointerFieldEndOffset ==
194  AllocationSite::kPretenureDataOffset);
195  STATIC_ASSERT(AllocationSite::kPretenureDataOffset + kInt32Size ==
196  AllocationSite::kPretenureCreateCountOffset);
197  STATIC_ASSERT(AllocationSite::kPretenureCreateCountOffset + kInt32Size ==
198  AllocationSite::kWeakNextOffset);
199 
200  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
201  if (offset >= AllocationSite::kStartOffset &&
202  offset < AllocationSite::kCommonPointerFieldEndOffset) {
203  return true;
204  }
205  // check for weak_next offset
206  if (map->instance_size() == AllocationSite::kSizeWithWeakNext &&
207  offset == AllocationSite::kWeakNextOffset) {
208  return true;
209  }
210  return false;
211  }
212 
213  template <typename ObjectVisitor>
214  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
215  ObjectVisitor* v) {
216  // Iterate over all the common pointer fields
217  IteratePointers(obj, AllocationSite::kStartOffset,
218  AllocationSite::kCommonPointerFieldEndOffset, v);
219  // Skip PretenureDataOffset and PretenureCreateCount which are Int32 fields.
220  // Visit weak_next only if it has weak_next field.
221  if (object_size == AllocationSite::kSizeWithWeakNext) {
222  IterateCustomWeakPointers(obj, AllocationSite::kWeakNextOffset,
223  AllocationSite::kSizeWithWeakNext, v);
224  }
225  }
226 
227  static inline int SizeOf(Map map, HeapObject* object) {
228  return map->instance_size();
229  }
230 };
231 
233  public:
234  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
235  if (offset < kEndOfTaggedFieldsOffset) return true;
236  if (offset < kHeaderSize) return false;
237  return IsValidSlotImpl(map, obj, offset);
238  }
239 
240  template <typename ObjectVisitor>
241  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
242  ObjectVisitor* v) {
243  // JSArrayBuffer instances contain raw data that the GC does not know about.
244  IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
245  IterateBodyImpl(map, obj, kHeaderSize, object_size, v);
246  }
247 
248  static inline int SizeOf(Map map, HeapObject* object) {
249  return map->instance_size();
250  }
251 };
252 
254  public:
255  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
256  if (offset < kEndOfTaggedFieldsOffset) return true;
257  if (offset < kHeaderSize) return false;
258  return IsValidSlotImpl(map, obj, offset);
259  }
260 
261  template <typename ObjectVisitor>
262  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
263  ObjectVisitor* v) {
264  // JSArrayBufferView contains raw data that the GC does not know about.
265  IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
266  IterateBodyImpl(map, obj, kHeaderSize, object_size, v);
267  }
268 
269  static inline int SizeOf(Map map, HeapObject* object) {
270  return map->instance_size();
271  }
272 };
273 
274 template <typename Derived>
276  : public BodyDescriptorBase {
277  public:
278  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
279  Derived table = Derived::cast(obj);
280  if (offset < kDataTableStartOffset) return false;
281  if (offset >= table->GetBucketsStartOffset()) return false;
282  return IsValidSlotImpl(map, obj, offset);
283  }
284 
285  template <typename ObjectVisitor>
286  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
287  ObjectVisitor* v) {
288  Derived table = Derived::cast(obj);
289 
290  int offset = kDataTableStartOffset;
291  int entry = 0;
292  for (int i = 0; i < table->Capacity(); i++) {
293  for (int j = 0; j < Derived::kEntrySize; j++) {
294  IteratePointer(obj, offset + (entry * kPointerSize), v);
295  entry++;
296  }
297  }
298  }
299 
300  static inline int SizeOf(Map map, HeapObject* obj) {
301  Derived table = Derived::cast(obj);
302  return table->SizeFor(table->Capacity());
303  }
304 };
305 
307  public:
308  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
309  return false;
310  }
311 
312  template <typename ObjectVisitor>
313  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
314  ObjectVisitor* v) {}
315 
316  static inline int SizeOf(Map map, HeapObject* obj) {
317  return ByteArray::SizeFor(ByteArray::cast(obj)->synchronized_length());
318  }
319 };
320 
322  public:
323  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
324  return offset >= kConstantPoolOffset &&
325  offset <= kSourcePositionTableOffset;
326  }
327 
328  template <typename ObjectVisitor>
329  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
330  ObjectVisitor* v) {
331  IteratePointer(obj, kConstantPoolOffset, v);
332  IteratePointer(obj, kHandlerTableOffset, v);
333  IteratePointer(obj, kSourcePositionTableOffset, v);
334  }
335 
336  static inline int SizeOf(Map map, HeapObject* obj) {
337  return BytecodeArray::SizeFor(
338  BytecodeArray::cast(obj)->synchronized_length());
339  }
340 };
341 
343  public:
344  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
345  return false;
346  }
347 
348  template <typename ObjectVisitor>
349  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
350  ObjectVisitor* v) {}
351 
352  static inline int SizeOf(Map map, HeapObject* obj) {
353  return BigInt::SizeFor(BigInt::cast(obj)->synchronized_length());
354  }
355 };
356 
358  public:
359  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
360  return false;
361  }
362 
363  template <typename ObjectVisitor>
364  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
365  ObjectVisitor* v) {}
366 
367  static inline int SizeOf(Map map, HeapObject* obj) {
368  return FixedDoubleArray::SizeFor(
369  FixedDoubleArray::cast(obj)->synchronized_length());
370  }
371 };
372 
374  public:
375  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
376  return offset == kBasePointerOffset;
377  }
378 
379  template <typename ObjectVisitor>
380  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
381  ObjectVisitor* v) {
382  IteratePointer(obj, kBasePointerOffset, v);
383  }
384 
385  static inline int SizeOf(Map map, HeapObject* object) {
386  return FixedTypedArrayBase::cast(object)->size();
387  }
388 };
389 
391  public:
392  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
393  return false;
394  }
395 
396  template <typename ObjectVisitor>
397  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
398  ObjectVisitor* v) {}
399 
400  static inline int SizeOf(Map map, HeapObject* obj) {
401  return FeedbackMetadata::SizeFor(
402  FeedbackMetadata::cast(obj)->synchronized_slot_count());
403  }
404 };
405 
407  public:
408  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
409  return offset == kSharedFunctionInfoOffset ||
410  offset == kOptimizedCodeOffset || offset >= kFeedbackSlotsOffset;
411  }
412 
413  template <typename ObjectVisitor>
414  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
415  ObjectVisitor* v) {
416  IteratePointer(obj, kSharedFunctionInfoOffset, v);
417  IterateMaybeWeakPointer(obj, kOptimizedCodeOffset, v);
418  IterateMaybeWeakPointers(obj, kFeedbackSlotsOffset, object_size, v);
419  }
420 
421  static inline int SizeOf(Map map, HeapObject* obj) {
422  return FeedbackVector::SizeFor(FeedbackVector::cast(obj)->length());
423  }
424 };
425 
427  public:
428  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
429  return offset == kScopeDataOffset || offset >= kChildDataStartOffset;
430  }
431 
432  template <typename ObjectVisitor>
433  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
434  ObjectVisitor* v) {
435  IteratePointer(obj, kScopeDataOffset, v);
436  IteratePointers(obj, kChildDataStartOffset, object_size, v);
437  }
438 
439  static inline int SizeOf(Map map, HeapObject* obj) {
440  return PreParsedScopeData::SizeFor(PreParsedScopeData::cast(obj)->length());
441  }
442 };
443 
445  public:
446  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
447  return offset >= HeapObject::kHeaderSize;
448  }
449 
450  template <typename ObjectVisitor>
451  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
452  ObjectVisitor* v) {
453  IteratePointers(obj, HeapObject::kHeaderSize, kObjectCreateMapOffset, v);
454  IterateMaybeWeakPointer(obj, kObjectCreateMapOffset, v);
455  IteratePointers(obj, kObjectCreateMapOffset + kPointerSize, object_size, v);
456  }
457 
458  static inline int SizeOf(Map map, HeapObject* obj) {
459  return obj->SizeFromMap(map);
460  }
461 };
462 
464  public:
465  STATIC_ASSERT(kTableOffset + kPointerSize == kSize);
466 
467  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
468  return IsValidSlotImpl(map, obj, offset);
469  }
470 
471  template <typename ObjectVisitor>
472  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
473  ObjectVisitor* v) {
474  IterateBodyImpl(map, obj, kPropertiesOrHashOffset, object_size, v);
475  }
476 
477  static inline int SizeOf(Map map, HeapObject* object) {
478  return map->instance_size();
479  }
480 };
481 
483  public:
484  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
485  return false;
486  }
487 
488  template <typename ObjectVisitor>
489  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
490  ObjectVisitor* v) {
491  v->VisitExternalReference(
492  Foreign::cast(obj),
493  reinterpret_cast<Address*>(
494  HeapObject::RawField(obj, kForeignAddressOffset).address()));
495  }
496 
497  static inline int SizeOf(Map map, HeapObject* object) { return kSize; }
498 };
499 
501  public:
502  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
503  return false;
504  }
505 
506  template <typename ObjectVisitor>
507  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
508  ObjectVisitor* v) {}
509 
510  static inline int SizeOf(Map map, HeapObject* object) { return kSize; }
511 };
512 
514  public:
515  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
516  return false;
517  }
518 
519  template <typename ObjectVisitor>
520  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
521  ObjectVisitor* v) {}
522 
523  static inline int SizeOf(Map map, HeapObject* object) { return kSize; }
524 };
525 
527  public:
528  STATIC_ASSERT(kRelocationInfoOffset + kPointerSize ==
529  kDeoptimizationDataOffset);
530  STATIC_ASSERT(kDeoptimizationDataOffset + kPointerSize ==
531  kSourcePositionTableOffset);
532  STATIC_ASSERT(kSourcePositionTableOffset + kPointerSize ==
533  kCodeDataContainerOffset);
534  STATIC_ASSERT(kCodeDataContainerOffset + kPointerSize == kDataStart);
535 
536  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
537  // Slots in code can't be invalid because we never trim code objects.
538  return true;
539  }
540 
541  template <typename ObjectVisitor>
542  static inline void IterateBody(Map map, HeapObject* obj, ObjectVisitor* v) {
543  int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
544  RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
545  RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
546  RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
547  RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) |
548  RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
549  RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
550 
551  // GC does not visit data/code in the header and in the body directly.
552  IteratePointers(obj, kRelocationInfoOffset, kDataStart, v);
553 
554  RelocIterator it(Code::cast(obj), mode_mask);
555  v->VisitRelocInfo(&it);
556  }
557 
558  template <typename ObjectVisitor>
559  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
560  ObjectVisitor* v) {
561  IterateBody(map, obj, v);
562  }
563 
564  static inline int SizeOf(Map map, HeapObject* object) {
565  return Code::unchecked_cast(object)->CodeSize();
566  }
567 };
568 
570  public:
571  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
572  return false;
573  }
574 
575  template <typename ObjectVisitor>
576  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
577  ObjectVisitor* v) {}
578 
579  static inline int SizeOf(Map map, HeapObject* obj) {
580  SeqOneByteString string = SeqOneByteString::cast(obj);
581  return string->SizeFor(string->synchronized_length());
582  }
583 };
584 
586  public:
587  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
588  return false;
589  }
590 
591  template <typename ObjectVisitor>
592  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
593  ObjectVisitor* v) {}
594 
595  static inline int SizeOf(Map map, HeapObject* obj) {
596  SeqTwoByteString string = SeqTwoByteString::cast(obj);
597  return string->SizeFor(string->synchronized_length());
598  }
599 };
600 
602  public:
603  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
604  if (offset < kMemoryStartOffset) return true;
605  if (offset < kModuleObjectOffset) return false;
606  return IsValidSlotImpl(map, obj, offset);
607  }
608 
609  template <typename ObjectVisitor>
610  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
611  ObjectVisitor* v) {
612  IteratePointers(obj, kPropertiesOrHashOffset, kFirstUntaggedOffset, v);
613  IterateBodyImpl(map, obj, kSize, object_size, v);
614  }
615 
616  static inline int SizeOf(Map map, HeapObject* object) {
617  return map->instance_size();
618  }
619 };
620 
622  public:
623  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
624  return offset >= Map::kPointerFieldsBeginOffset &&
625  offset < Map::kPointerFieldsEndOffset;
626  }
627 
628  template <typename ObjectVisitor>
629  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
630  ObjectVisitor* v) {
631  IteratePointers(obj, Map::kPointerFieldsBeginOffset,
632  Map::kTransitionsOrPrototypeInfoOffset, v);
633  IterateMaybeWeakPointer(obj, kTransitionsOrPrototypeInfoOffset, v);
634  IteratePointers(obj, Map::kTransitionsOrPrototypeInfoOffset + kPointerSize,
635  Map::kPointerFieldsEndOffset, v);
636  }
637 
638  static inline int SizeOf(Map map, HeapObject* obj) { return Map::kSize; }
639 };
640 
642  public:
643  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
644  return offset >= HeapObject::kHeaderSize;
645  }
646 
647  template <typename ObjectVisitor>
648  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
649  ObjectVisitor* v) {
650  static_assert(kSmiHandlerOffset < kData1Offset,
651  "Field order must be in sync with this iteration code");
652  static_assert(kData1Offset < kSizeWithData1,
653  "Field order must be in sync with this iteration code");
654  IteratePointers(obj, kSmiHandlerOffset, kData1Offset, v);
655  IterateMaybeWeakPointers(obj, kData1Offset, object_size, v);
656  }
657 
658  static inline int SizeOf(Map map, HeapObject* object) {
659  return object->SizeFromMap(map);
660  }
661 };
662 
664  public:
665  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
666  return offset < NativeContext::kEndOfTaggedFieldsOffset;
667  }
668 
669  template <typename ObjectVisitor>
670  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
671  ObjectVisitor* v) {
672  IteratePointers(obj, NativeContext::kStartOfStrongFieldsOffset,
673  NativeContext::kEndOfStrongFieldsOffset, v);
674  IterateCustomWeakPointers(obj, NativeContext::kStartOfWeakFieldsOffset,
675  NativeContext::kEndOfWeakFieldsOffset, v);
676  }
677 
678  static inline int SizeOf(Map map, HeapObject* object) {
679  return NativeContext::kSize;
680  }
681 };
682 
684  public:
685  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
686  return offset >= CodeDataContainer::kHeaderSize &&
687  offset < CodeDataContainer::kSize;
688  }
689 
690  template <typename ObjectVisitor>
691  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
692  ObjectVisitor* v) {
693  IteratePointers(obj, CodeDataContainer::kHeaderSize,
694  CodeDataContainer::kPointerFieldsStrongEndOffset, v);
695  IterateCustomWeakPointers(
696  obj, CodeDataContainer::kPointerFieldsStrongEndOffset,
697  CodeDataContainer::kPointerFieldsWeakEndOffset, v);
698  }
699 
700  static inline int SizeOf(Map map, HeapObject* object) {
701  return CodeDataContainer::kSize;
702  }
703 };
704 
706  public:
707  static bool IsValidSlot(Map map, HeapObject* obj, int offset) {
708  // We store raw aligned pointers as Smis, so it's safe to iterate the whole
709  // array.
710  return true;
711  }
712 
713  template <typename ObjectVisitor>
714  static inline void IterateBody(Map map, HeapObject* obj, int object_size,
715  ObjectVisitor* v) {
716  // We store raw aligned pointers as Smis, so it's safe to iterate the whole
717  // array.
718  IteratePointers(obj, EmbedderDataArray::kHeaderSize, object_size, v);
719  }
720 
721  static inline int SizeOf(Map map, HeapObject* object) {
722  return object->SizeFromMap(map);
723  }
724 };
725 
726 template <typename Op, typename ReturnType, typename T1, typename T2,
727  typename T3, typename T4>
728 ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
729  if (type < FIRST_NONSTRING_TYPE) {
730  switch (type & kStringRepresentationMask) {
731  case kSeqStringTag:
732  return ReturnType();
733  case kConsStringTag:
734  return Op::template apply<ConsString::BodyDescriptor>(p1, p2, p3, p4);
735  case kThinStringTag:
736  return Op::template apply<ThinString::BodyDescriptor>(p1, p2, p3, p4);
737  case kSlicedStringTag:
738  return Op::template apply<SlicedString::BodyDescriptor>(p1, p2, p3, p4);
739  case kExternalStringTag:
740  if ((type & kStringEncodingMask) == kOneByteStringTag) {
741  return Op::template apply<ExternalOneByteString::BodyDescriptor>(
742  p1, p2, p3, p4);
743  } else {
744  return Op::template apply<ExternalTwoByteString::BodyDescriptor>(
745  p1, p2, p3, p4);
746  }
747  }
748  UNREACHABLE();
749  }
750 
751  switch (type) {
752  case EMBEDDER_DATA_ARRAY_TYPE:
753  return Op::template apply<EmbedderDataArray::BodyDescriptor>(p1, p2, p3,
754  p4);
755  case FIXED_ARRAY_TYPE:
756  case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
757  case HASH_TABLE_TYPE:
758  case ORDERED_HASH_MAP_TYPE:
759  case ORDERED_HASH_SET_TYPE:
760  case ORDERED_NAME_DICTIONARY_TYPE:
761  case NAME_DICTIONARY_TYPE:
762  case GLOBAL_DICTIONARY_TYPE:
763  case NUMBER_DICTIONARY_TYPE:
764  case SIMPLE_NUMBER_DICTIONARY_TYPE:
765  case STRING_TABLE_TYPE:
766  case EPHEMERON_HASH_TABLE_TYPE:
767  case SCOPE_INFO_TYPE:
768  case SCRIPT_CONTEXT_TABLE_TYPE:
769  return Op::template apply<FixedArray::BodyDescriptor>(p1, p2, p3, p4);
770  case AWAIT_CONTEXT_TYPE:
771  case BLOCK_CONTEXT_TYPE:
772  case CATCH_CONTEXT_TYPE:
773  case DEBUG_EVALUATE_CONTEXT_TYPE:
774  case EVAL_CONTEXT_TYPE:
775  case FUNCTION_CONTEXT_TYPE:
776  case MODULE_CONTEXT_TYPE:
777  case SCRIPT_CONTEXT_TYPE:
778  case WITH_CONTEXT_TYPE:
779  return Op::template apply<Context::BodyDescriptor>(p1, p2, p3, p4);
780  case NATIVE_CONTEXT_TYPE:
781  return Op::template apply<NativeContext::BodyDescriptor>(p1, p2, p3, p4);
782  case WEAK_FIXED_ARRAY_TYPE:
783  return Op::template apply<WeakFixedArray::BodyDescriptor>(p1, p2, p3, p4);
784  case WEAK_ARRAY_LIST_TYPE:
785  return Op::template apply<WeakArrayList::BodyDescriptor>(p1, p2, p3, p4);
786  case FIXED_DOUBLE_ARRAY_TYPE:
787  return ReturnType();
788  case FEEDBACK_METADATA_TYPE:
789  return Op::template apply<FeedbackMetadata::BodyDescriptor>(p1, p2, p3,
790  p4);
791  case PROPERTY_ARRAY_TYPE:
792  return Op::template apply<PropertyArray::BodyDescriptor>(p1, p2, p3, p4);
793  case DESCRIPTOR_ARRAY_TYPE:
794  return Op::template apply<DescriptorArray::BodyDescriptor>(p1, p2, p3,
795  p4);
796  case TRANSITION_ARRAY_TYPE:
797  return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3,
798  p4);
799  case FEEDBACK_CELL_TYPE:
800  return Op::template apply<FeedbackCell::BodyDescriptor>(p1, p2, p3, p4);
801  case FEEDBACK_VECTOR_TYPE:
802  return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3, p4);
803  case JS_OBJECT_TYPE:
804  case JS_ERROR_TYPE:
805  case JS_ARGUMENTS_TYPE:
806  case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
807  case JS_PROMISE_TYPE:
808  case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
809  case JS_GENERATOR_OBJECT_TYPE:
810  case JS_ASYNC_FUNCTION_OBJECT_TYPE:
811  case JS_ASYNC_GENERATOR_OBJECT_TYPE:
812  case JS_VALUE_TYPE:
813  case JS_DATE_TYPE:
814  case JS_ARRAY_TYPE:
815  case JS_ARRAY_ITERATOR_TYPE:
816  case JS_MODULE_NAMESPACE_TYPE:
817  case JS_SET_TYPE:
818  case JS_MAP_TYPE:
819  case JS_SET_KEY_VALUE_ITERATOR_TYPE:
820  case JS_SET_VALUE_ITERATOR_TYPE:
821  case JS_MAP_KEY_ITERATOR_TYPE:
822  case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
823  case JS_MAP_VALUE_ITERATOR_TYPE:
824  case JS_STRING_ITERATOR_TYPE:
825  case JS_REGEXP_STRING_ITERATOR_TYPE:
826  case JS_REGEXP_TYPE:
827  case JS_GLOBAL_PROXY_TYPE:
828  case JS_GLOBAL_OBJECT_TYPE:
829  case JS_API_OBJECT_TYPE:
830  case JS_SPECIAL_API_OBJECT_TYPE:
831  case JS_MESSAGE_OBJECT_TYPE:
832  case JS_BOUND_FUNCTION_TYPE:
833  case JS_WEAK_FACTORY_CLEANUP_ITERATOR_TYPE:
834  case JS_WEAK_FACTORY_TYPE:
835 #ifdef V8_INTL_SUPPORT
836  case JS_INTL_V8_BREAK_ITERATOR_TYPE:
837  case JS_INTL_COLLATOR_TYPE:
838  case JS_INTL_DATE_TIME_FORMAT_TYPE:
839  case JS_INTL_LIST_FORMAT_TYPE:
840  case JS_INTL_LOCALE_TYPE:
841  case JS_INTL_NUMBER_FORMAT_TYPE:
842  case JS_INTL_PLURAL_RULES_TYPE:
843  case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
844  case JS_INTL_SEGMENT_ITERATOR_TYPE:
845  case JS_INTL_SEGMENTER_TYPE:
846 #endif // V8_INTL_SUPPORT
847  case WASM_EXCEPTION_TYPE:
848  case WASM_GLOBAL_TYPE:
849  case WASM_MEMORY_TYPE:
850  case WASM_MODULE_TYPE:
851  case WASM_TABLE_TYPE:
852  return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4);
853  case WASM_INSTANCE_TYPE:
854  return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3,
855  p4);
856  case JS_WEAK_MAP_TYPE:
857  case JS_WEAK_SET_TYPE:
858  return Op::template apply<JSWeakCollection::BodyDescriptor>(p1, p2, p3,
859  p4);
860  case JS_ARRAY_BUFFER_TYPE:
861  return Op::template apply<JSArrayBuffer::BodyDescriptor>(p1, p2, p3, p4);
862  case JS_DATA_VIEW_TYPE:
863  return Op::template apply<JSDataView::BodyDescriptor>(p1, p2, p3, p4);
864  case JS_TYPED_ARRAY_TYPE:
865  return Op::template apply<JSTypedArray::BodyDescriptor>(p1, p2, p3, p4);
866  case JS_FUNCTION_TYPE:
867  return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3, p4);
868  case JS_WEAK_CELL_TYPE:
869  case JS_WEAK_REF_TYPE:
870  return Op::template apply<JSWeakCell::BodyDescriptor>(p1, p2, p3, p4);
871  case ODDBALL_TYPE:
872  return Op::template apply<Oddball::BodyDescriptor>(p1, p2, p3, p4);
873  case JS_PROXY_TYPE:
874  return Op::template apply<JSProxy::BodyDescriptor>(p1, p2, p3, p4);
875  case FOREIGN_TYPE:
876  return Op::template apply<Foreign::BodyDescriptor>(p1, p2, p3, p4);
877  case MAP_TYPE:
878  return Op::template apply<Map::BodyDescriptor>(p1, p2, p3, p4);
879  case CODE_TYPE:
880  return Op::template apply<Code::BodyDescriptor>(p1, p2, p3, p4);
881  case CELL_TYPE:
882  return Op::template apply<Cell::BodyDescriptor>(p1, p2, p3, p4);
883  case PROPERTY_CELL_TYPE:
884  return Op::template apply<PropertyCell::BodyDescriptor>(p1, p2, p3, p4);
885  case SYMBOL_TYPE:
886  return Op::template apply<Symbol::BodyDescriptor>(p1, p2, p3, p4);
887  case BYTECODE_ARRAY_TYPE:
888  return Op::template apply<BytecodeArray::BodyDescriptor>(p1, p2, p3, p4);
889  case SMALL_ORDERED_HASH_SET_TYPE:
890  return Op::template apply<
891  SmallOrderedHashTable<SmallOrderedHashSet>::BodyDescriptor>(p1, p2,
892  p3, p4);
893  case SMALL_ORDERED_HASH_MAP_TYPE:
894  return Op::template apply<
895  SmallOrderedHashTable<SmallOrderedHashMap>::BodyDescriptor>(p1, p2,
896  p3, p4);
897  case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
898  return Op::template apply<
899  SmallOrderedHashTable<SmallOrderedNameDictionary>::BodyDescriptor>(
900  p1, p2, p3, p4);
901  case CODE_DATA_CONTAINER_TYPE:
902  return Op::template apply<CodeDataContainer::BodyDescriptor>(p1, p2, p3,
903  p4);
904  case PRE_PARSED_SCOPE_DATA_TYPE:
905  return Op::template apply<PreParsedScopeData::BodyDescriptor>(p1, p2, p3,
906  p4);
907  case UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE:
908  return Op::template apply<
909  UncompiledDataWithoutPreParsedScope::BodyDescriptor>(p1, p2, p3, p4);
910  case UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE:
911  return Op::template apply<
912  UncompiledDataWithPreParsedScope::BodyDescriptor>(p1, p2, p3, p4);
913  case HEAP_NUMBER_TYPE:
914  case MUTABLE_HEAP_NUMBER_TYPE:
915  case FILLER_TYPE:
916  case BYTE_ARRAY_TYPE:
917  case FREE_SPACE_TYPE:
918  case BIGINT_TYPE:
919  return ReturnType();
920 
921 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
922  case FIXED_##TYPE##_ARRAY_TYPE: \
923  return Op::template apply<FixedTypedArrayBase::BodyDescriptor>(p1, p2, p3, \
924  p4);
925  TYPED_ARRAYS(TYPED_ARRAY_CASE)
926 #undef TYPED_ARRAY_CASE
927 
928  case SHARED_FUNCTION_INFO_TYPE: {
929  return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3,
930  p4);
931  }
932  case ALLOCATION_SITE_TYPE:
933  return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3, p4);
934 
935 #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
936  STRUCT_LIST(MAKE_STRUCT_CASE)
937 #undef MAKE_STRUCT_CASE
938  if (type == PROTOTYPE_INFO_TYPE) {
939  return Op::template apply<PrototypeInfo::BodyDescriptor>(p1, p2, p3,
940  p4);
941  } else {
942  return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
943  }
944  case CALL_HANDLER_INFO_TYPE:
945  return Op::template apply<StructBodyDescriptor>(p1, p2, p3, p4);
946  case LOAD_HANDLER_TYPE:
947  case STORE_HANDLER_TYPE:
948  return Op::template apply<DataHandler::BodyDescriptor>(p1, p2, p3, p4);
949  default:
950  PrintF("Unknown type: %d\n", type);
951  UNREACHABLE();
952  }
953 }
954 
955 
956 template <typename ObjectVisitor>
957 void HeapObject::IterateFast(ObjectVisitor* v) {
958  BodyDescriptorBase::IteratePointer(this, kMapOffset, v);
959  IterateBodyFast(v);
960 }
961 
962 
963 template <typename ObjectVisitor>
964 void HeapObject::IterateBodyFast(ObjectVisitor* v) {
965  Map m = map();
966  IterateBodyFast(m, SizeFromMap(m), v);
967 }
968 
969 
971  template <typename BodyDescriptor, typename ObjectVisitor>
972  static void apply(Map map, HeapObject* obj, int object_size,
973  ObjectVisitor* v) {
974  BodyDescriptor::IterateBody(map, obj, object_size, v);
975  }
976 };
977 
978 template <typename ObjectVisitor>
979 void HeapObject::IterateBodyFast(Map map, int object_size, ObjectVisitor* v) {
980  BodyDescriptorApply<CallIterateBody, void>(map->instance_type(), map, this,
981  object_size, v);
982 }
983 } // namespace internal
984 } // namespace v8
985 
986 #endif // V8_OBJECTS_BODY_DESCRIPTORS_INL_H_
Definition: libplatform.h:13