• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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_FIXED_ARRAY_H_
6 #define V8_OBJECTS_FIXED_ARRAY_H_
7 
8 #include "src/handles/maybe-handles.h"
9 #include "src/objects/instance-type.h"
10 #include "src/objects/objects.h"
11 #include "src/objects/smi.h"
12 
13 // Has to be the last include (doesn't have include guards):
14 #include "src/objects/object-macros.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V)    \
20   V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE)       \
21   V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE)       \
22   V(CODE_STUBS_TABLE_SUB_TYPE)                   \
23   V(COMPILATION_CACHE_TABLE_SUB_TYPE)            \
24   V(CONTEXT_SUB_TYPE)                            \
25   V(COPY_ON_WRITE_SUB_TYPE)                      \
26   V(DEOPTIMIZATION_DATA_SUB_TYPE)                \
27   V(DESCRIPTOR_ARRAY_SUB_TYPE)                   \
28   V(EMBEDDED_OBJECT_SUB_TYPE)                    \
29   V(ENUM_CACHE_SUB_TYPE)                         \
30   V(ENUM_INDICES_CACHE_SUB_TYPE)                 \
31   V(DEPENDENT_CODE_SUB_TYPE)                     \
32   V(DICTIONARY_ELEMENTS_SUB_TYPE)                \
33   V(DICTIONARY_PROPERTIES_SUB_TYPE)              \
34   V(EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE)        \
35   V(PACKED_ELEMENTS_SUB_TYPE)                    \
36   V(FAST_PROPERTIES_SUB_TYPE)                    \
37   V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
38   V(HANDLER_TABLE_SUB_TYPE)                      \
39   V(JS_COLLECTION_SUB_TYPE)                      \
40   V(JS_WEAK_COLLECTION_SUB_TYPE)                 \
41   V(NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE)     \
42   V(NUMBER_STRING_CACHE_SUB_TYPE)                \
43   V(OBJECT_TO_CODE_SUB_TYPE)                     \
44   V(OPTIMIZED_CODE_LITERALS_SUB_TYPE)            \
45   V(OPTIMIZED_CODE_MAP_SUB_TYPE)                 \
46   V(PROTOTYPE_USERS_SUB_TYPE)                    \
47   V(REGEXP_MULTIPLE_CACHE_SUB_TYPE)              \
48   V(RETAINED_MAPS_SUB_TYPE)                      \
49   V(SCOPE_INFO_SUB_TYPE)                         \
50   V(SCRIPT_LIST_SUB_TYPE)                        \
51   V(SERIALIZED_OBJECTS_SUB_TYPE)                 \
52   V(SHARED_FUNCTION_INFOS_SUB_TYPE)              \
53   V(SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE)      \
54   V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
55   V(STRING_SPLIT_CACHE_SUB_TYPE)                 \
56   V(TEMPLATE_INFO_SUB_TYPE)                      \
57   V(FEEDBACK_METADATA_SUB_TYPE)                  \
58   V(WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE)
59 
60 enum FixedArraySubInstanceType {
61 #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
62   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
63 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
64       LAST_FIXED_ARRAY_SUB_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE
65 };
66 
67 #include "torque-generated/src/objects/fixed-array-tq.inc"
68 
69 // Common superclass for FixedArrays that allow implementations to share
70 // common accessors and some code paths.
71 class FixedArrayBase
72     : public TorqueGeneratedFixedArrayBase<FixedArrayBase, HeapObject> {
73  public:
74   // Forward declare the non-atomic (set_)length defined in torque.
75   using TorqueGeneratedFixedArrayBase::length;
76   using TorqueGeneratedFixedArrayBase::set_length;
77   DECL_RELEASE_ACQUIRE_INT_ACCESSORS(length)
78 
79   inline Object unchecked_length(AcquireLoadTag) const;
80 
81   static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
82 
83   V8_EXPORT_PRIVATE bool IsCowArray() const;
84 
85   // Maximal allowed size, in bytes, of a single FixedArrayBase.
86   // Prevents overflowing size computations, as well as extreme memory
87   // consumption. It's either (512Mb - kTaggedSize) or (1024Mb - kTaggedSize).
88   // -kTaggedSize is here to ensure that this max size always fits into Smi
89   // which is necessary for being able to create a free space filler for the
90   // whole array of kMaxSize.
91   static const int kMaxSize = 128 * kTaggedSize * MB - kTaggedSize;
92   STATIC_ASSERT(Smi::IsValid(kMaxSize));
93 
94  protected:
95   TQ_OBJECT_CONSTRUCTORS(FixedArrayBase)
96   inline FixedArrayBase(Address ptr,
97                         HeapObject::AllowInlineSmiStorage allow_smi);
98 };
99 
100 // FixedArray describes fixed-sized arrays with element type Object.
101 class FixedArray
102     : public TorqueGeneratedFixedArray<FixedArray, FixedArrayBase> {
103  public:
104   // Setter and getter for elements.
105   inline Object get(int index) const;
106   inline Object get(PtrComprCageBase cage_base, int index) const;
107 
108   static inline Handle<Object> get(FixedArray array, int index,
109                                    Isolate* isolate);
110 
111   // Return a grown copy if the index is bigger than the array's length.
112   V8_EXPORT_PRIVATE static Handle<FixedArray> SetAndGrow(
113       Isolate* isolate, Handle<FixedArray> array, int index,
114       Handle<Object> value);
115 
116   // Relaxed accessors.
117   inline Object get(int index, RelaxedLoadTag) const;
118   inline Object get(PtrComprCageBase cage_base, int index,
119                     RelaxedLoadTag) const;
120   inline void set(int index, Object value, RelaxedStoreTag,
121                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
122   inline void set(int index, Smi value, RelaxedStoreTag);
123 
124   // Acquire/release accessors.
125   inline Object get(int index, AcquireLoadTag) const;
126   inline Object get(PtrComprCageBase cage_base, int index,
127                     AcquireLoadTag) const;
128   inline void set(int index, Object value, ReleaseStoreTag,
129                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
130   inline void set(int index, Smi value, ReleaseStoreTag);
131 
132   // Setter that uses write barrier.
133   inline void set(int index, Object value);
134   inline bool is_the_hole(Isolate* isolate, int index);
135 
136   // Setter that doesn't need write barrier.
137 #if !defined(_WIN32) || (defined(_WIN64) && _MSC_VER < 1930 && __cplusplus < 201703L)
138   inline void set(int index, Smi value);
139 #else
set(int index,Smi value)140   inline void set(int index, Smi value) {
141 #if !defined(_WIN32)
142     DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
143 #endif
144     DCHECK_LT(static_cast<unsigned>(index), static_cast<unsigned>(length()));
145     DCHECK(Object(value).IsSmi());
146     int offset = OffsetOfElementAt(index);
147     RELAXED_WRITE_FIELD(*this, offset, value);
148   }
149 #endif
150 
151   // Setter with explicit barrier mode.
152   inline void set(int index, Object value, WriteBarrierMode mode);
153 
154   // Setters for frequently used oddballs located in old space.
155   inline void set_undefined(int index);
156   inline void set_undefined(Isolate* isolate, int index);
157   inline void set_undefined(ReadOnlyRoots ro_roots, int index);
158   inline void set_null(int index);
159   inline void set_null(Isolate* isolate, int index);
160   inline void set_null(ReadOnlyRoots ro_roots, int index);
161   inline void set_the_hole(int index);
162   inline void set_the_hole(Isolate* isolate, int index);
163   inline void set_the_hole(ReadOnlyRoots ro_roots, int index);
164 
165   inline ObjectSlot GetFirstElementAddress();
166   inline bool ContainsOnlySmisOrHoles();
167 
168   // Gives access to raw memory which stores the array's data.
169   inline ObjectSlot data_start();
170 
171   inline void MoveElements(Isolate* isolate, int dst_index, int src_index,
172                            int len, WriteBarrierMode mode);
173 
174   inline void CopyElements(Isolate* isolate, int dst_index, FixedArray src,
175                            int src_index, int len, WriteBarrierMode mode);
176 
177   inline void FillWithHoles(int from, int to);
178 
179   // Shrink the array and insert filler objects. {new_length} must be > 0.
180   V8_EXPORT_PRIVATE void Shrink(Isolate* isolate, int new_length);
181   // If {new_length} is 0, return the canonical empty FixedArray. Otherwise
182   // like above.
183   static Handle<FixedArray> ShrinkOrEmpty(Isolate* isolate,
184                                           Handle<FixedArray> array,
185                                           int new_length);
186 
187   // Copy a sub array from the receiver to dest.
188   V8_EXPORT_PRIVATE void CopyTo(int pos, FixedArray dest, int dest_pos,
189                                 int len) const;
190 
191   // Garbage collection support.
SizeFor(int length)192   static constexpr int SizeFor(int length) {
193     return kHeaderSize + length * kTaggedSize;
194   }
195 
196   // Code Generation support.
OffsetOfElementAt(int index)197   static constexpr int OffsetOfElementAt(int index) {
198     STATIC_ASSERT(kObjectsOffset == SizeFor(0));
199     return SizeFor(index);
200   }
201 
202   // Garbage collection support.
203   inline ObjectSlot RawFieldOfElementAt(int index);
204 
205   // Maximally allowed length of a FixedArray.
206   static const int kMaxLength = (kMaxSize - kHeaderSize) / kTaggedSize;
207   static_assert(Internals::IsValidSmi(kMaxLength),
208                 "FixedArray maxLength not a Smi");
209 
210   // Maximally allowed length for regular (non large object space) object.
211   STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
212   static const int kMaxRegularLength =
213       (kMaxRegularHeapObjectSize - kHeaderSize) / kTaggedSize;
214 
215   // Dispatched behavior.
216   DECL_PRINTER(FixedArray)
217   DECL_VERIFIER(FixedArray)
218 
219   int AllocatedSize();
220 
221   class BodyDescriptor;
222 
223   static constexpr int kObjectsOffset = kHeaderSize;
224 
225  protected:
226   // Set operation on FixedArray without using write barriers. Can
227   // only be used for storing old space objects or smis.
228   static inline void NoWriteBarrierSet(FixedArray array, int index,
229                                        Object value);
230 
231  private:
232   STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
233 
234   TQ_OBJECT_CONSTRUCTORS(FixedArray)
235 };
236 
237 // FixedArray alias added only because of IsFixedArrayExact() predicate, which
238 // checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
239 // check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
240 class FixedArrayExact final : public FixedArray {};
241 
242 // FixedDoubleArray describes fixed-sized arrays with element type double.
243 class FixedDoubleArray
244     : public TorqueGeneratedFixedDoubleArray<FixedDoubleArray, FixedArrayBase> {
245  public:
246   // Setter and getter for elements.
247   inline double get_scalar(int index);
248   inline uint64_t get_representation(int index);
249   static inline Handle<Object> get(FixedDoubleArray array, int index,
250                                    Isolate* isolate);
251   inline void set(int index, double value);
252   inline void set_the_hole(Isolate* isolate, int index);
253   inline void set_the_hole(int index);
254 
255   // Checking for the hole.
256   inline bool is_the_hole(Isolate* isolate, int index);
257   inline bool is_the_hole(int index);
258 
259   // Garbage collection support.
SizeFor(int length)260   inline static int SizeFor(int length) {
261     return kHeaderSize + length * kDoubleSize;
262   }
263 
264   inline void MoveElements(Isolate* isolate, int dst_index, int src_index,
265                            int len, WriteBarrierMode mode);
266 
267   inline void FillWithHoles(int from, int to);
268 
269   // Code Generation support.
OffsetOfElementAt(int index)270   static int OffsetOfElementAt(int index) { return SizeFor(index); }
271 
272   // Start offset of elements.
273   static constexpr int kFloatsOffset = kHeaderSize;
274 
275   // Maximally allowed length of a FixedDoubleArray.
276   static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
277   static_assert(Internals::IsValidSmi(kMaxLength),
278                 "FixedDoubleArray maxLength not a Smi");
279 
280   // Dispatched behavior.
281   DECL_PRINTER(FixedDoubleArray)
282   DECL_VERIFIER(FixedDoubleArray)
283 
284   class BodyDescriptor;
285 
286   TQ_OBJECT_CONSTRUCTORS(FixedDoubleArray)
287 };
288 
289 // WeakFixedArray describes fixed-sized arrays with element type
290 // MaybeObject.
291 class WeakFixedArray
292     : public TorqueGeneratedWeakFixedArray<WeakFixedArray, HeapObject> {
293  public:
294   inline MaybeObject Get(int index) const;
295   inline MaybeObject Get(PtrComprCageBase cage_base, int index) const;
296 
297   inline void Set(
298       int index, MaybeObject value,
299       WriteBarrierMode mode = WriteBarrierMode::UPDATE_WRITE_BARRIER);
300 
301   static inline Handle<WeakFixedArray> EnsureSpace(Isolate* isolate,
302                                                    Handle<WeakFixedArray> array,
303                                                    int length);
304 
305   // Forward declare the non-atomic (set_)length defined in torque.
306   using TorqueGeneratedWeakFixedArray::length;
307   using TorqueGeneratedWeakFixedArray::set_length;
308   DECL_RELEASE_ACQUIRE_INT_ACCESSORS(length)
309 
310   // Gives access to raw memory which stores the array's data.
311   inline MaybeObjectSlot data_start();
312 
313   inline MaybeObjectSlot RawFieldOfElementAt(int index);
314 
315   inline void CopyElements(Isolate* isolate, int dst_index, WeakFixedArray src,
316                            int src_index, int len, WriteBarrierMode mode);
317 
318   DECL_PRINTER(WeakFixedArray)
319   DECL_VERIFIER(WeakFixedArray)
320 
321   class BodyDescriptor;
322 
323   static const int kMaxLength =
324       (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
325   static_assert(Internals::IsValidSmi(kMaxLength),
326                 "WeakFixedArray maxLength not a Smi");
327 
328   int AllocatedSize();
329 
OffsetOfElementAt(int index)330   static int OffsetOfElementAt(int index) {
331     STATIC_ASSERT(kObjectsOffset == SizeFor(0));
332     return SizeFor(index);
333   }
334 
335  private:
336   friend class Heap;
337 
338   static const int kFirstIndex = 1;
339 
340   TQ_OBJECT_CONSTRUCTORS(WeakFixedArray)
341 };
342 
343 // WeakArrayList is like a WeakFixedArray with static convenience methods for
344 // adding more elements. length() returns the number of elements in the list and
345 // capacity() returns the allocated size. The number of elements is stored at
346 // kLengthOffset and is updated with every insertion. The array grows
347 // dynamically with O(1) amortized insertion.
348 class WeakArrayList
349     : public TorqueGeneratedWeakArrayList<WeakArrayList, HeapObject> {
350  public:
351   NEVER_READ_ONLY_SPACE
352   DECL_PRINTER(WeakArrayList)
353 
354   V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd(
355       Isolate* isolate, Handle<WeakArrayList> array,
356       const MaybeObjectHandle& value);
357 
358   // A version that adds to elements. This ensures that the elements are
359   // inserted atomically w.r.t GC.
360   V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd(
361       Isolate* isolate, Handle<WeakArrayList> array,
362       const MaybeObjectHandle& value1, const MaybeObjectHandle& value2);
363 
364   // Appends an element to the array and possibly compacts and shrinks live weak
365   // references to the start of the collection. Only use this method when
366   // indices to elements can change.
367   static Handle<WeakArrayList> Append(
368       Isolate* isolate, Handle<WeakArrayList> array,
369       const MaybeObjectHandle& value,
370       AllocationType allocation = AllocationType::kYoung);
371 
372   // Compact weak references to the beginning of the array.
373   V8_EXPORT_PRIVATE void Compact(Isolate* isolate);
374 
375   inline MaybeObject Get(int index) const;
376   inline MaybeObject Get(PtrComprCageBase cage_base, int index) const;
377 
378   // Set the element at index to obj. The underlying array must be large enough.
379   // If you need to grow the WeakArrayList, use the static AddToEnd() method
380   // instead.
381   inline void Set(int index, MaybeObject value,
382                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
383   inline void Set(int index, Smi value);
384 
SizeForCapacity(int capacity)385   static constexpr int SizeForCapacity(int capacity) {
386     return SizeFor(capacity);
387   }
388 
CapacityForLength(int length)389   static constexpr int CapacityForLength(int length) {
390     return length + std::max(length / 2, 2);
391   }
392 
393   // Gives access to raw memory which stores the array's data.
394   inline MaybeObjectSlot data_start();
395 
396   inline void CopyElements(Isolate* isolate, int dst_index, WeakArrayList src,
397                            int src_index, int len, WriteBarrierMode mode);
398 
399   V8_EXPORT_PRIVATE bool IsFull() const;
400 
401   int AllocatedSize();
402 
403   class BodyDescriptor;
404 
405   static const int kMaxCapacity =
406       (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
407 
408   static Handle<WeakArrayList> EnsureSpace(
409       Isolate* isolate, Handle<WeakArrayList> array, int length,
410       AllocationType allocation = AllocationType::kYoung);
411 
412   // Returns the number of non-cleaned weak references in the array.
413   int CountLiveWeakReferences() const;
414 
415   // Returns the number of non-cleaned elements in the array.
416   int CountLiveElements() const;
417 
418   // Returns whether an entry was found and removed. Will move the elements
419   // around in the array - this method can only be used in cases where the user
420   // doesn't care about the indices! Users should make sure there are no
421   // duplicates.
422   V8_EXPORT_PRIVATE bool RemoveOne(const MaybeObjectHandle& value);
423 
424   class Iterator;
425 
426  private:
OffsetOfElementAt(int index)427   static int OffsetOfElementAt(int index) {
428     return kHeaderSize + index * kTaggedSize;
429   }
430 
431   TQ_OBJECT_CONSTRUCTORS(WeakArrayList)
432 };
433 
434 class WeakArrayList::Iterator {
435  public:
Iterator(WeakArrayList array)436   explicit Iterator(WeakArrayList array) : index_(0), array_(array) {}
437   Iterator(const Iterator&) = delete;
438   Iterator& operator=(const Iterator&) = delete;
439 
440   inline HeapObject Next();
441 
442  private:
443   int index_;
444   WeakArrayList array_;
445   DISALLOW_GARBAGE_COLLECTION(no_gc_)
446 };
447 
448 // Generic array grows dynamically with O(1) amortized insertion.
449 //
450 // ArrayList is a FixedArray with static convenience methods for adding more
451 // elements. The Length() method returns the number of elements in the list, not
452 // the allocated size. The number of elements is stored at kLengthIndex and is
453 // updated with every insertion. The elements of the ArrayList are stored in the
454 // underlying FixedArray starting at kFirstIndex.
455 class ArrayList : public TorqueGeneratedArrayList<ArrayList, FixedArray> {
456  public:
457   V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
458                                                  Handle<ArrayList> array,
459                                                  Handle<Object> obj);
460   V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
461                                                  Handle<ArrayList> array,
462                                                  Handle<Object> obj1,
463                                                  Handle<Object> obj2);
464   V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
465                                                  Handle<ArrayList> array,
466                                                  Handle<Object> obj1, Smi obj2,
467                                                  Smi obj3, Smi obj4);
468   static Handle<ArrayList> New(Isolate* isolate, int size);
469 
470   // Returns the number of elements in the list, not the allocated size, which
471   // is length(). Lower and upper case length() return different results!
472   inline int Length() const;
473 
474   // Sets the Length() as used by Elements(). Does not change the underlying
475   // storage capacity, i.e., length().
476   inline void SetLength(int length);
477   inline Object Get(int index) const;
478   inline Object Get(PtrComprCageBase cage_base, int index) const;
479   inline ObjectSlot Slot(int index);
480 
481   // Set the element at index to obj. The underlying array must be large enough.
482   // If you need to grow the ArrayList, use the static Add() methods instead.
483   inline void Set(int index, Object obj,
484                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
485 
486   inline void Set(int index, Smi obj);
487 
488   // Set the element at index to undefined. This does not change the Length().
489   inline void Clear(int index, Object undefined);
490 
491   // Return a copy of the list of size Length() without the first entry. The
492   // number returned by Length() is stored in the first entry.
493   static Handle<FixedArray> Elements(Isolate* isolate, Handle<ArrayList> array);
494 
495   static const int kHeaderFields = 1;
496 
497   static const int kLengthIndex = 0;
498   static const int kFirstIndex = 1;
499   STATIC_ASSERT(kHeaderFields == kFirstIndex);
500 
501   DECL_VERIFIER(ArrayList)
502 
503  private:
504   static Handle<ArrayList> EnsureSpace(Isolate* isolate,
505                                        Handle<ArrayList> array, int length);
506   TQ_OBJECT_CONSTRUCTORS(ArrayList)
507 };
508 
509 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
510 
511 template <SearchMode search_mode, typename T>
512 inline int Search(T* array, Name name, int valid_entries = 0,
513                   int* out_insertion_index = nullptr,
514                   bool concurrent_search = false);
515 
516 // ByteArray represents fixed sized byte arrays.  Used for the relocation info
517 // that is attached to code objects.
518 class ByteArray : public TorqueGeneratedByteArray<ByteArray, FixedArrayBase> {
519  public:
520   inline int Size();
521 
522   // Setter and getter.
523   inline byte get(int index) const;
524   inline void set(int index, byte value);
525 
526   // Copy in / copy out whole byte slices.
527   inline void copy_out(int index, byte* buffer, int slice_length);
528   inline void copy_in(int index, const byte* buffer, int slice_length);
529 
530   // Treat contents as an int array.
531   inline int get_int(int index) const;
532   inline void set_int(int index, int value);
533 
534   inline uint32_t get_uint32(int index) const;
535   inline void set_uint32(int index, uint32_t value);
536 
537   inline uint32_t get_uint32_relaxed(int index) const;
538   inline void set_uint32_relaxed(int index, uint32_t value);
539 
540   inline uint16_t get_uint16(int index) const;
541   inline void set_uint16(int index, uint16_t value);
542 
543   // Clear uninitialized padding space. This ensures that the snapshot content
544   // is deterministic.
545   inline void clear_padding();
546 
SizeFor(int length)547   static int SizeFor(int length) {
548     return OBJECT_POINTER_ALIGN(kHeaderSize + length);
549   }
550   // We use byte arrays for free blocks in the heap.  Given a desired size in
551   // bytes that is a multiple of the word size and big enough to hold a byte
552   // array, this function returns the number of elements a byte array should
553   // have.
LengthFor(int size_in_bytes)554   static int LengthFor(int size_in_bytes) {
555     DCHECK(IsAligned(size_in_bytes, kTaggedSize));
556     DCHECK_GE(size_in_bytes, kHeaderSize);
557     return size_in_bytes - kHeaderSize;
558   }
559 
560   // Returns data start address.
561   inline byte* GetDataStartAddress();
562   // Returns address of the past-the-end element.
563   inline byte* GetDataEndAddress();
564 
565   inline int DataSize() const;
566 
567   // Returns a pointer to the ByteArray object for a given data start address.
568   static inline ByteArray FromDataStartAddress(Address address);
569 
570   // Dispatched behavior.
571   inline int ByteArraySize();
572   DECL_PRINTER(ByteArray)
573 
574   // Layout description.
575   static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
576 
577   // Maximal length of a single ByteArray.
578   static const int kMaxLength = kMaxSize - kHeaderSize;
579   static_assert(Internals::IsValidSmi(kMaxLength),
580                 "ByteArray maxLength not a Smi");
581 
582   class BodyDescriptor;
583 
584  protected:
585   TQ_OBJECT_CONSTRUCTORS(ByteArray)
586   inline ByteArray(Address ptr, HeapObject::AllowInlineSmiStorage allow_smi);
587 };
588 
589 // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
590 // as they can be copied with memcpy.
591 template <class T>
592 class PodArray : public ByteArray {
593  public:
594   static Handle<PodArray<T>> New(
595       Isolate* isolate, int length,
596       AllocationType allocation = AllocationType::kYoung);
copy_out(int index,T * result,int length)597   void copy_out(int index, T* result, int length) {
598     ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
599                         length * sizeof(T));
600   }
601 
copy_in(int index,const T * buffer,int length)602   void copy_in(int index, const T* buffer, int length) {
603     ByteArray::copy_in(index * sizeof(T), reinterpret_cast<const byte*>(buffer),
604                        length * sizeof(T));
605   }
606 
matches(const T * buffer,int length)607   bool matches(const T* buffer, int length) {
608     DCHECK_LE(length, this->length());
609     return memcmp(GetDataStartAddress(), buffer, length * sizeof(T)) == 0;
610   }
611 
matches(int offset,const T * buffer,int length)612   bool matches(int offset, const T* buffer, int length) {
613     DCHECK_LE(offset, this->length());
614     DCHECK_LE(offset + length, this->length());
615     return memcmp(GetDataStartAddress() + sizeof(T) * offset, buffer,
616                   length * sizeof(T)) == 0;
617   }
618 
get(int index)619   T get(int index) {
620     T result;
621     copy_out(index, &result, 1);
622     return result;
623   }
624 
set(int index,const T & value)625   void set(int index, const T& value) { copy_in(index, &value, 1); }
626 
627   inline int length() const;
628   DECL_CAST(PodArray<T>)
629 
630   OBJECT_CONSTRUCTORS(PodArray<T>, ByteArray);
631 };
632 
633 class TemplateList
634     : public TorqueGeneratedTemplateList<TemplateList, FixedArray> {
635  public:
636   static Handle<TemplateList> New(Isolate* isolate, int size);
637   inline int length() const;
638   inline Object get(int index) const;
639   inline Object get(PtrComprCageBase cage_base, int index) const;
640   inline void set(int index, Object value);
641   static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
642                                   Handle<Object> value);
643  private:
644   static const int kLengthIndex = 0;
645   static const int kFirstElementIndex = kLengthIndex + 1;
646 
647   TQ_OBJECT_CONSTRUCTORS(TemplateList)
648 };
649 
650 }  // namespace internal
651 }  // namespace v8
652 
653 #include "src/objects/object-macros-undef.h"
654 
655 #endif  // V8_OBJECTS_FIXED_ARRAY_H_
656