fixed-array.h 22.3 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_FIXED_ARRAY_H_
#define V8_OBJECTS_FIXED_ARRAY_H_

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 14 15 16 17

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {
18

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V)    \
  V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE)       \
  V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE)       \
  V(CODE_STUBS_TABLE_SUB_TYPE)                   \
  V(COMPILATION_CACHE_TABLE_SUB_TYPE)            \
  V(CONTEXT_SUB_TYPE)                            \
  V(COPY_ON_WRITE_SUB_TYPE)                      \
  V(DEOPTIMIZATION_DATA_SUB_TYPE)                \
  V(DESCRIPTOR_ARRAY_SUB_TYPE)                   \
  V(EMBEDDED_OBJECT_SUB_TYPE)                    \
  V(ENUM_CACHE_SUB_TYPE)                         \
  V(ENUM_INDICES_CACHE_SUB_TYPE)                 \
  V(DEPENDENT_CODE_SUB_TYPE)                     \
  V(DICTIONARY_ELEMENTS_SUB_TYPE)                \
  V(DICTIONARY_PROPERTIES_SUB_TYPE)              \
  V(EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE)        \
  V(PACKED_ELEMENTS_SUB_TYPE)                    \
  V(FAST_PROPERTIES_SUB_TYPE)                    \
  V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
  V(HANDLER_TABLE_SUB_TYPE)                      \
  V(JS_COLLECTION_SUB_TYPE)                      \
  V(JS_WEAK_COLLECTION_SUB_TYPE)                 \
  V(NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE)     \
  V(NUMBER_STRING_CACHE_SUB_TYPE)                \
  V(OBJECT_TO_CODE_SUB_TYPE)                     \
  V(OPTIMIZED_CODE_LITERALS_SUB_TYPE)            \
  V(OPTIMIZED_CODE_MAP_SUB_TYPE)                 \
  V(PROTOTYPE_USERS_SUB_TYPE)                    \
  V(REGEXP_MULTIPLE_CACHE_SUB_TYPE)              \
  V(RETAINED_MAPS_SUB_TYPE)                      \
  V(SCOPE_INFO_SUB_TYPE)                         \
  V(SCRIPT_LIST_SUB_TYPE)                        \
51
  V(SERIALIZED_OBJECTS_SUB_TYPE)                 \
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
  V(SHARED_FUNCTION_INFOS_SUB_TYPE)              \
  V(SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE)      \
  V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
  V(STRING_SPLIT_CACHE_SUB_TYPE)                 \
  V(TEMPLATE_INFO_SUB_TYPE)                      \
  V(FEEDBACK_METADATA_SUB_TYPE)                  \
  V(WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE)

enum FixedArraySubInstanceType {
#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
  FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
      LAST_FIXED_ARRAY_SUB_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE
};

67 68
#include "torque-generated/src/objects/fixed-array-tq.inc"

69 70
// Common superclass for FixedArrays that allow implementations to share
// common accessors and some code paths.
71 72
class FixedArrayBase
    : public TorqueGeneratedFixedArrayBase<FixedArrayBase, HeapObject> {
73 74
 public:
  // Get and set the length using acquire loads and release stores.
75
  DECL_SYNCHRONIZED_INT_ACCESSORS(length)
76

77
  inline Object unchecked_synchronized_length() const;
78

79 80
  static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);

81
  V8_EXPORT_PRIVATE bool IsCowArray() const;
82

83 84 85 86 87 88 89 90
  // Maximal allowed size, in bytes, of a single FixedArrayBase.
  // Prevents overflowing size computations, as well as extreme memory
  // consumption. It's either (512Mb - kTaggedSize) or (1024Mb - kTaggedSize).
  // -kTaggedSize is here to ensure that this max size always fits into Smi
  // which is necessary for being able to create a free space filler for the
  // whole array of kMaxSize.
  static const int kMaxSize = 128 * kTaggedSize * MB - kTaggedSize;
  STATIC_ASSERT(Smi::IsValid(kMaxSize));
91

92
 protected:
93 94 95
  TQ_OBJECT_CONSTRUCTORS(FixedArrayBase)
  inline FixedArrayBase(Address ptr,
                        HeapObject::AllowInlineSmiStorage allow_smi);
96 97
};

98
// FixedArray describes fixed-sized arrays with element type Object.
99 100
class FixedArray
    : public TorqueGeneratedFixedArray<FixedArray, FixedArrayBase> {
101 102
 public:
  // Setter and getter for elements.
103
  inline Object get(int index) const;
104
  inline Object get(PtrComprCageBase cage_base, int index) const;
105

106
  static inline Handle<Object> get(FixedArray array, int index,
107 108 109
                                   Isolate* isolate);

  // Return a grown copy if the index is bigger than the array's length.
110
  V8_EXPORT_PRIVATE static Handle<FixedArray> SetAndGrow(
111
      Isolate* isolate, Handle<FixedArray> array, int index,
112
      Handle<Object> value);
113

114 115
  // Relaxed accessors.
  inline Object get(int index, RelaxedLoadTag) const;
116 117
  inline Object get(PtrComprCageBase cage_base, int index,
                    RelaxedLoadTag) const;
118 119 120 121 122 123
  inline void set(int index, Object value, RelaxedStoreTag,
                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
  inline void set(int index, Smi value, RelaxedStoreTag);

  // Acquire/release accessors.
  inline Object get(int index, AcquireLoadTag) const;
124 125
  inline Object get(PtrComprCageBase cage_base, int index,
                    AcquireLoadTag) const;
126 127 128
  inline void set(int index, Object value, ReleaseStoreTag,
                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
  inline void set(int index, Smi value, ReleaseStoreTag);
129

130
  // Setter that uses write barrier.
131
  inline void set(int index, Object value);
132 133 134
  inline bool is_the_hole(Isolate* isolate, int index);

  // Setter that doesn't need write barrier.
135
  inline void set(int index, Smi value);
136
  // Setter with explicit barrier mode.
137
  inline void set(int index, Object value, WriteBarrierMode mode);
138 139 140 141 142 143 144 145 146

  // Setters for frequently used oddballs located in old space.
  inline void set_undefined(int index);
  inline void set_undefined(Isolate* isolate, int index);
  inline void set_null(int index);
  inline void set_null(Isolate* isolate, int index);
  inline void set_the_hole(int index);
  inline void set_the_hole(Isolate* isolate, int index);

147
  inline ObjectSlot GetFirstElementAddress();
148 149 150
  inline bool ContainsOnlySmisOrHoles();

  // Gives access to raw memory which stores the array's data.
151 152
  inline ObjectSlot data_start();

153 154
  inline void MoveElements(Isolate* isolate, int dst_index, int src_index,
                           int len, WriteBarrierMode mode);
155

156
  inline void CopyElements(Isolate* isolate, int dst_index, FixedArray src,
157 158
                           int src_index, int len, WriteBarrierMode mode);

159 160
  inline void FillWithHoles(int from, int to);

161
  // Shrink the array and insert filler objects. {new_length} must be > 0.
162
  V8_EXPORT_PRIVATE void Shrink(Isolate* isolate, int new_length);
163 164
  // If {new_length} is 0, return the canonical empty FixedArray. Otherwise
  // like above.
165 166
  static Handle<FixedArray> ShrinkOrEmpty(Isolate* isolate,
                                          Handle<FixedArray> array,
167
                                          int new_length);
168 169

  // Copy a sub array from the receiver to dest.
170 171
  V8_EXPORT_PRIVATE void CopyTo(int pos, FixedArray dest, int dest_pos,
                                int len) const;
172 173 174

  // Garbage collection support.
  static constexpr int SizeFor(int length) {
175
    return kHeaderSize + length * kTaggedSize;
176 177 178
  }

  // Code Generation support.
179 180 181 182
  static constexpr int OffsetOfElementAt(int index) {
    STATIC_ASSERT(kObjectsOffset == SizeFor(0));
    return SizeFor(index);
  }
183 184

  // Garbage collection support.
185
  inline ObjectSlot RawFieldOfElementAt(int index);
186 187

  // Maximally allowed length of a FixedArray.
188
  static const int kMaxLength = (kMaxSize - kHeaderSize) / kTaggedSize;
189 190 191
  static_assert(Internals::IsValidSmi(kMaxLength),
                "FixedArray maxLength not a Smi");

192 193 194
  // Maximally allowed length for regular (non large object space) object.
  STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
  static const int kMaxRegularLength =
195
      (kMaxRegularHeapObjectSize - kHeaderSize) / kTaggedSize;
196 197 198 199

  // Dispatched behavior.
  DECL_PRINTER(FixedArray)

200 201 202
  int AllocatedSize();

  class BodyDescriptor;
203

204 205
  static constexpr int kObjectsOffset = kHeaderSize;

206 207 208
 protected:
  // Set operation on FixedArray without using write barriers. Can
  // only be used for storing old space objects or smis.
209
  static inline void NoWriteBarrierSet(FixedArray array, int index,
210
                                       Object value);
211 212 213 214

 private:
  STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);

215 216 217 218
  inline void set_undefined(ReadOnlyRoots ro_roots, int index);
  inline void set_null(ReadOnlyRoots ro_roots, int index);
  inline void set_the_hole(ReadOnlyRoots ro_roots, int index);

219
  TQ_OBJECT_CONSTRUCTORS(FixedArray)
220 221
};

222 223 224
// FixedArray alias added only because of IsFixedArrayExact() predicate, which
// checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
// check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
225
class FixedArrayExact final : public FixedArray {};
226 227

// FixedDoubleArray describes fixed-sized arrays with element type double.
228 229
class FixedDoubleArray
    : public TorqueGeneratedFixedDoubleArray<FixedDoubleArray, FixedArrayBase> {
230 231 232 233
 public:
  // Setter and getter for elements.
  inline double get_scalar(int index);
  inline uint64_t get_representation(int index);
234
  static inline Handle<Object> get(FixedDoubleArray array, int index,
235 236 237 238 239 240 241 242 243 244 245 246 247 248
                                   Isolate* isolate);
  inline void set(int index, double value);
  inline void set_the_hole(Isolate* isolate, int index);
  inline void set_the_hole(int index);

  // Checking for the hole.
  inline bool is_the_hole(Isolate* isolate, int index);
  inline bool is_the_hole(int index);

  // Garbage collection support.
  inline static int SizeFor(int length) {
    return kHeaderSize + length * kDoubleSize;
  }

249 250
  inline void MoveElements(Isolate* isolate, int dst_index, int src_index,
                           int len, WriteBarrierMode mode);
251 252 253 254 255 256

  inline void FillWithHoles(int from, int to);

  // Code Generation support.
  static int OffsetOfElementAt(int index) { return SizeFor(index); }

257 258 259
  // Start offset of elements.
  static constexpr int kFloatsOffset = kHeaderSize;

260
  // Maximally allowed length of a FixedDoubleArray.
261
  static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
262 263
  static_assert(Internals::IsValidSmi(kMaxLength),
                "FixedDoubleArray maxLength not a Smi");
264 265 266 267 268 269 270

  // Dispatched behavior.
  DECL_PRINTER(FixedDoubleArray)
  DECL_VERIFIER(FixedDoubleArray)

  class BodyDescriptor;

271
  TQ_OBJECT_CONSTRUCTORS(FixedDoubleArray)
272 273
};

274
// WeakFixedArray describes fixed-sized arrays with element type
275
// MaybeObject.
276 277
class WeakFixedArray
    : public TorqueGeneratedWeakFixedArray<WeakFixedArray, HeapObject> {
278
 public:
279
  inline MaybeObject Get(int index) const;
280
  inline MaybeObject Get(PtrComprCageBase cage_base, int index) const;
281

282 283 284
  inline void Set(
      int index, MaybeObject value,
      WriteBarrierMode mode = WriteBarrierMode::UPDATE_WRITE_BARRIER);
285 286

  // Get and set the length using acquire loads and release stores.
287
  DECL_SYNCHRONIZED_INT_ACCESSORS(length)
288 289

  // Gives access to raw memory which stores the array's data.
290
  inline MaybeObjectSlot data_start();
291

292
  inline MaybeObjectSlot RawFieldOfElementAt(int index);
293

294 295 296
  inline void CopyElements(Isolate* isolate, int dst_index, WeakFixedArray src,
                           int src_index, int len, WriteBarrierMode mode);

297
  DECL_PRINTER(WeakFixedArray)
298 299
  DECL_VERIFIER(WeakFixedArray)

300
  class BodyDescriptor;
301 302

  static const int kMaxLength =
303
      (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
304 305
  static_assert(Internals::IsValidSmi(kMaxLength),
                "WeakFixedArray maxLength not a Smi");
306

307 308
  int AllocatedSize();

309
  static int OffsetOfElementAt(int index) {
310 311
    STATIC_ASSERT(kObjectsOffset == SizeFor(0));
    return SizeFor(index);
312 313
  }

314
 private:
315 316 317 318
  friend class Heap;

  static const int kFirstIndex = 1;

319
  TQ_OBJECT_CONSTRUCTORS(WeakFixedArray)
320 321
};

322 323 324 325 326
// WeakArrayList is like a WeakFixedArray with static convenience methods for
// adding more elements. length() returns the number of elements in the list and
// capacity() returns the allocated size. The number of elements is stored at
// kLengthOffset and is updated with every insertion. The array grows
// dynamically with O(1) amortized insertion.
327 328
class WeakArrayList
    : public TorqueGeneratedWeakArrayList<WeakArrayList, HeapObject> {
329
 public:
330
  NEVER_READ_ONLY_SPACE
331 332
  DECL_PRINTER(WeakArrayList)

333 334 335
  V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd(
      Isolate* isolate, Handle<WeakArrayList> array,
      const MaybeObjectHandle& value);
336

337 338 339 340 341 342
  // A version that adds to elements. This ensures that the elements are
  // inserted atomically w.r.t GC.
  V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd(
      Isolate* isolate, Handle<WeakArrayList> array,
      const MaybeObjectHandle& value1, const MaybeObjectHandle& value2);

343 344 345 346 347 348 349 350 351 352 353
  // Appends an element to the array and possibly compacts and shrinks live weak
  // references to the start of the collection. Only use this method when
  // indices to elements can change.
  static Handle<WeakArrayList> Append(
      Isolate* isolate, Handle<WeakArrayList> array,
      const MaybeObjectHandle& value,
      AllocationType allocation = AllocationType::kYoung);

  // Compact weak references to the beginning of the array.
  V8_EXPORT_PRIVATE void Compact(Isolate* isolate);

354
  inline MaybeObject Get(int index) const;
355
  inline MaybeObject Get(PtrComprCageBase cage_base, int index) const;
356 357

  // Set the element at index to obj. The underlying array must be large enough.
358
  // If you need to grow the WeakArrayList, use the static AddToEnd() method
359
  // instead.
360
  inline void Set(int index, MaybeObject value,
361 362 363
                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  static constexpr int SizeForCapacity(int capacity) {
364
    return SizeFor(capacity);
365 366
  }

367
  static constexpr int CapacityForLength(int length) {
368
    return length + std::max(length / 2, 2);
369 370
  }

371
  // Gives access to raw memory which stores the array's data.
372
  inline MaybeObjectSlot data_start();
373

374 375 376
  inline void CopyElements(Isolate* isolate, int dst_index, WeakArrayList src,
                           int src_index, int len, WriteBarrierMode mode);

377
  V8_EXPORT_PRIVATE bool IsFull();
378 379

  // Get and set the capacity using acquire loads and release stores.
380
  DECL_SYNCHRONIZED_INT_ACCESSORS(capacity)
381

382
  int AllocatedSize();
383

384
  class BodyDescriptor;
385

386
  static const int kMaxCapacity =
387
      (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
388

389 390
  static Handle<WeakArrayList> EnsureSpace(
      Isolate* isolate, Handle<WeakArrayList> array, int length,
391
      AllocationType allocation = AllocationType::kYoung);
392

393 394 395
  // Returns the number of non-cleaned weak references in the array.
  int CountLiveWeakReferences() const;

396 397 398
  // Returns the number of non-cleaned elements in the array.
  int CountLiveElements() const;

399 400 401 402
  // Returns whether an entry was found and removed. Will move the elements
  // around in the array - this method can only be used in cases where the user
  // doesn't care about the indices! Users should make sure there are no
  // duplicates.
403
  V8_EXPORT_PRIVATE bool RemoveOne(const MaybeObjectHandle& value);
404

405
  class Iterator;
406

407 408
 private:
  static int OffsetOfElementAt(int index) {
409
    return kHeaderSize + index * kTaggedSize;
410 411
  }

412
  TQ_OBJECT_CONSTRUCTORS(WeakArrayList)
413 414 415 416 417
};

class WeakArrayList::Iterator {
 public:
  explicit Iterator(WeakArrayList array) : index_(0), array_(array) {}
418 419
  Iterator(const Iterator&) = delete;
  Iterator& operator=(const Iterator&) = delete;
420

421
  inline HeapObject Next();
422 423 424 425

 private:
  int index_;
  WeakArrayList array_;
426
  DISALLOW_GARBAGE_COLLECTION(no_gc_)
427 428
};

429 430 431 432 433 434 435
// Generic array grows dynamically with O(1) amortized insertion.
//
// ArrayList is a FixedArray with static convenience methods for adding more
// elements. The Length() method returns the number of elements in the list, not
// the allocated size. The number of elements is stored at kLengthIndex and is
// updated with every insertion. The elements of the ArrayList are stored in the
// underlying FixedArray starting at kFirstIndex.
436
class ArrayList : public TorqueGeneratedArrayList<ArrayList, FixedArray> {
437
 public:
438 439 440 441 442 443 444
  V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
                                                 Handle<ArrayList> array,
                                                 Handle<Object> obj);
  V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
                                                 Handle<ArrayList> array,
                                                 Handle<Object> obj1,
                                                 Handle<Object> obj2);
445 446 447 448 449 450 451 452 453
  static Handle<ArrayList> New(Isolate* isolate, int size);

  // Returns the number of elements in the list, not the allocated size, which
  // is length(). Lower and upper case length() return different results!
  inline int Length() const;

  // Sets the Length() as used by Elements(). Does not change the underlying
  // storage capacity, i.e., length().
  inline void SetLength(int length);
454
  inline Object Get(int index) const;
455
  inline Object Get(PtrComprCageBase cage_base, int index) const;
456
  inline ObjectSlot Slot(int index);
457 458 459

  // Set the element at index to obj. The underlying array must be large enough.
  // If you need to grow the ArrayList, use the static Add() methods instead.
460
  inline void Set(int index, Object obj,
461 462 463
                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  // Set the element at index to undefined. This does not change the Length().
464
  inline void Clear(int index, Object undefined);
465 466 467

  // Return a copy of the list of size Length() without the first entry. The
  // number returned by Length() is stored in the first entry.
468
  static Handle<FixedArray> Elements(Isolate* isolate, Handle<ArrayList> array);
469

470 471
  static const int kHeaderFields = 1;

472
 private:
473 474
  static Handle<ArrayList> EnsureSpace(Isolate* isolate,
                                       Handle<ArrayList> array, int length);
475 476
  static const int kLengthIndex = 0;
  static const int kFirstIndex = 1;
477
  STATIC_ASSERT(kHeaderFields == kFirstIndex);
478
  TQ_OBJECT_CONSTRUCTORS(ArrayList)
479 480 481 482 483
};

enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };

template <SearchMode search_mode, typename T>
484
inline int Search(T* array, Name name, int valid_entries = 0,
485 486
                  int* out_insertion_index = nullptr,
                  bool concurrent_search = false);
487 488 489

// ByteArray represents fixed sized byte arrays.  Used for the relocation info
// that is attached to code objects.
490
class ByteArray : public TorqueGeneratedByteArray<ByteArray, FixedArrayBase> {
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
 public:
  inline int Size();

  // Setter and getter.
  inline byte get(int index) const;
  inline void set(int index, byte value);

  // Copy in / copy out whole byte slices.
  inline void copy_out(int index, byte* buffer, int length);
  inline void copy_in(int index, const byte* buffer, int length);

  // Treat contents as an int array.
  inline int get_int(int index) const;
  inline void set_int(int index, int value);

  inline uint32_t get_uint32(int index) const;
  inline void set_uint32(int index, uint32_t value);

509 510 511
  inline uint32_t get_uint32_relaxed(int index) const;
  inline void set_uint32_relaxed(int index, uint32_t value);

512 513 514 515 516 517 518 519 520 521 522 523
  // Clear uninitialized padding space. This ensures that the snapshot content
  // is deterministic.
  inline void clear_padding();

  static int SizeFor(int length) {
    return OBJECT_POINTER_ALIGN(kHeaderSize + length);
  }
  // We use byte arrays for free blocks in the heap.  Given a desired size in
  // bytes that is a multiple of the word size and big enough to hold a byte
  // array, this function returns the number of elements a byte array should
  // have.
  static int LengthFor(int size_in_bytes) {
524
    DCHECK(IsAligned(size_in_bytes, kTaggedSize));
525 526 527 528 529
    DCHECK_GE(size_in_bytes, kHeaderSize);
    return size_in_bytes - kHeaderSize;
  }

  // Returns data start address.
530
  inline byte* GetDataStartAddress();
531 532
  // Returns address of the past-the-end element.
  inline byte* GetDataEndAddress();
533 534 535 536

  inline int DataSize() const;

  // Returns a pointer to the ByteArray object for a given data start address.
537
  static inline ByteArray FromDataStartAddress(Address address);
538 539 540 541 542 543 544 545 546 547

  // Dispatched behavior.
  inline int ByteArraySize();
  DECL_PRINTER(ByteArray)

  // Layout description.
  static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);

  // Maximal length of a single ByteArray.
  static const int kMaxLength = kMaxSize - kHeaderSize;
548 549
  static_assert(Internals::IsValidSmi(kMaxLength),
                "ByteArray maxLength not a Smi");
550 551 552

  class BodyDescriptor;

553
 protected:
554 555
  TQ_OBJECT_CONSTRUCTORS(ByteArray)
  inline ByteArray(Address ptr, HeapObject::AllowInlineSmiStorage allow_smi);
556 557 558 559 560 561 562
};

// Wrapper class for ByteArray which can store arbitrary C++ classes, as long
// as they can be copied with memcpy.
template <class T>
class PodArray : public ByteArray {
 public:
563 564 565
  static Handle<PodArray<T>> New(
      Isolate* isolate, int length,
      AllocationType allocation = AllocationType::kYoung);
566
  void copy_out(int index, T* result, int length) {
567
    ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
568
                        length * sizeof(T));
569
  }
570 571 572 573 574 575

  void copy_in(int index, const T* buffer, int length) {
    ByteArray::copy_in(index * sizeof(T), reinterpret_cast<const byte*>(buffer),
                       length * sizeof(T));
  }

576 577 578 579 580
  bool matches(const T* buffer, int length) {
    DCHECK_LE(length, this->length());
    return memcmp(GetDataStartAddress(), buffer, length * sizeof(T)) == 0;
  }

581 582
  T get(int index) {
    T result;
583
    copy_out(index, &result, 1);
584 585
    return result;
  }
586 587 588

  void set(int index, const T& value) { copy_in(index, &value, 1); }

589
  inline int length() const;
590
  DECL_CAST(PodArray<T>)
591

592
  OBJECT_CONSTRUCTORS(PodArray<T>, ByteArray);
593 594
};

595 596
class TemplateList
    : public TorqueGeneratedTemplateList<TemplateList, FixedArray> {
597 598 599
 public:
  static Handle<TemplateList> New(Isolate* isolate, int size);
  inline int length() const;
600
  inline Object get(int index) const;
601
  inline Object get(PtrComprCageBase cage_base, int index) const;
602
  inline void set(int index, Object value);
603 604 605 606 607
  static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
                                  Handle<Object> value);
 private:
  static const int kLengthIndex = 0;
  static const int kFirstElementIndex = kLengthIndex + 1;
608

609
  TQ_OBJECT_CONSTRUCTORS(TemplateList)
610 611 612 613 614 615 616 617
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_FIXED_ARRAY_H_