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/objects.h"
9
10 // Has to be the last include (doesn't have include guards):
11 #include "src/objects/object-macros.h"
12
13 namespace v8 {
14 namespace internal {
15
16 class WeakArrayBodyDescriptor;
17
18 #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
19 V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE) \
20 V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE) \
21 V(CODE_STUBS_TABLE_SUB_TYPE) \
22 V(COMPILATION_CACHE_TABLE_SUB_TYPE) \
23 V(CONTEXT_SUB_TYPE) \
24 V(COPY_ON_WRITE_SUB_TYPE) \
25 V(DEOPTIMIZATION_DATA_SUB_TYPE) \
26 V(DESCRIPTOR_ARRAY_SUB_TYPE) \
27 V(EMBEDDED_OBJECT_SUB_TYPE) \
28 V(ENUM_CACHE_SUB_TYPE) \
29 V(ENUM_INDICES_CACHE_SUB_TYPE) \
30 V(DEPENDENT_CODE_SUB_TYPE) \
31 V(DICTIONARY_ELEMENTS_SUB_TYPE) \
32 V(DICTIONARY_PROPERTIES_SUB_TYPE) \
33 V(EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE) \
34 V(PACKED_ELEMENTS_SUB_TYPE) \
35 V(FAST_PROPERTIES_SUB_TYPE) \
36 V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
37 V(HANDLER_TABLE_SUB_TYPE) \
38 V(JS_COLLECTION_SUB_TYPE) \
39 V(JS_WEAK_COLLECTION_SUB_TYPE) \
40 V(NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE) \
41 V(NUMBER_STRING_CACHE_SUB_TYPE) \
42 V(OBJECT_TO_CODE_SUB_TYPE) \
43 V(OPTIMIZED_CODE_LITERALS_SUB_TYPE) \
44 V(OPTIMIZED_CODE_MAP_SUB_TYPE) \
45 V(PROTOTYPE_USERS_SUB_TYPE) \
46 V(REGEXP_MULTIPLE_CACHE_SUB_TYPE) \
47 V(RETAINED_MAPS_SUB_TYPE) \
48 V(SCOPE_INFO_SUB_TYPE) \
49 V(SCRIPT_LIST_SUB_TYPE) \
50 V(SERIALIZED_OBJECTS_SUB_TYPE) \
51 V(SHARED_FUNCTION_INFOS_SUB_TYPE) \
52 V(SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE) \
53 V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
54 V(STRING_SPLIT_CACHE_SUB_TYPE) \
55 V(STRING_TABLE_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 // Common superclass for FixedArrays that allow implementations to share
68 // common accessors and some code paths.
69 class FixedArrayBase : public HeapObject {
70 public:
71 // [length]: length of the array.
72 inline int length() const;
73 inline void set_length(int value);
74
75 // Get and set the length using acquire loads and release stores.
76 inline int synchronized_length() const;
77 inline void synchronized_set_length(int value);
78
79 inline Object* unchecked_synchronized_length() const;
80
81 DECL_CAST(FixedArrayBase)
82
83 static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
84
85 bool IsCowArray() const;
86
87 // Layout description.
88 // Length is smi tagged when it is stored.
89 static const int kLengthOffset = HeapObject::kHeaderSize;
90 static const int kHeaderSize = kLengthOffset + kPointerSize;
91 };
92
93 // FixedArray describes fixed-sized arrays with element type Object*.
94 class FixedArray : public FixedArrayBase {
95 public:
96 // Setter and getter for elements.
97 inline Object* get(int index) const;
98 static inline Handle<Object> get(FixedArray* array, int index,
99 Isolate* isolate);
100 template <class T>
101 MaybeHandle<T> GetValue(Isolate* isolate, int index) const;
102
103 template <class T>
104 Handle<T> GetValueChecked(Isolate* isolate, int index) const;
105
106 // Return a grown copy if the index is bigger than the array's length.
107 static Handle<FixedArray> SetAndGrow(Handle<FixedArray> array, int index,
108 Handle<Object> value,
109 PretenureFlag pretenure = NOT_TENURED);
110
111 // Setter that uses write barrier.
112 inline void set(int index, Object* value);
113 inline bool is_the_hole(Isolate* isolate, int index);
114
115 // Setter that doesn't need write barrier.
116 inline void set(int index, Smi* value);
117 // Setter with explicit barrier mode.
118 inline void set(int index, Object* value, WriteBarrierMode mode);
119
120 // Setters for frequently used oddballs located in old space.
121 inline void set_undefined(int index);
122 inline void set_undefined(Isolate* isolate, int index);
123 inline void set_null(int index);
124 inline void set_null(Isolate* isolate, int index);
125 inline void set_the_hole(int index);
126 inline void set_the_hole(Isolate* isolate, int index);
127
128 inline Object** GetFirstElementAddress();
129 inline bool ContainsOnlySmisOrHoles();
130 // Returns true iff the elements are Numbers and sorted ascending.
131 bool ContainsSortedNumbers();
132
133 // Gives access to raw memory which stores the array's data.
134 inline Object** data_start();
135
136 inline void FillWithHoles(int from, int to);
137
138 // Shrink length and insert filler objects.
139 void Shrink(int length);
140
141 // Copy a sub array from the receiver to dest.
142 void CopyTo(int pos, FixedArray* dest, int dest_pos, int len) const;
143
144 // Garbage collection support.
SizeFor(int length)145 static constexpr int SizeFor(int length) {
146 return kHeaderSize + length * kPointerSize;
147 }
148
149 // Code Generation support.
OffsetOfElementAt(int index)150 static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
151
152 // Garbage collection support.
153 inline Object** RawFieldOfElementAt(int index);
154
155 DECL_CAST(FixedArray)
156
157 // Maximal allowed size, in bytes, of a single FixedArray.
158 // Prevents overflowing size computations, as well as extreme memory
159 // consumption.
160 static const int kMaxSize = 128 * MB * kPointerSize;
161 // Maximally allowed length of a FixedArray.
162 static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
163 // Maximally allowed length for regular (non large object space) object.
164 STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
165 static const int kMaxRegularLength =
166 (kMaxRegularHeapObjectSize - kHeaderSize) / kPointerSize;
167
168 // Dispatched behavior.
169 DECL_PRINTER(FixedArray)
170 DECL_VERIFIER(FixedArray)
171 #ifdef DEBUG
172 // Checks if two FixedArrays have identical contents.
173 bool IsEqualTo(FixedArray* other);
174 #endif
175
176 typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
177 // No weak fields.
178 typedef BodyDescriptor BodyDescriptorWeak;
179
180 protected:
181 // Set operation on FixedArray without using write barriers. Can
182 // only be used for storing old space objects or smis.
183 static inline void NoWriteBarrierSet(FixedArray* array, int index,
184 Object* value);
185
186 private:
187 STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
188
189 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
190 };
191
192 // FixedArray alias added only because of IsFixedArrayExact() predicate, which
193 // checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
194 // check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
195 class FixedArrayExact final : public FixedArray {
196 public:
197 DECL_CAST(FixedArrayExact)
198 };
199
200 // FixedDoubleArray describes fixed-sized arrays with element type double.
201 class FixedDoubleArray : public FixedArrayBase {
202 public:
203 // Setter and getter for elements.
204 inline double get_scalar(int index);
205 inline uint64_t get_representation(int index);
206 static inline Handle<Object> get(FixedDoubleArray* array, int index,
207 Isolate* isolate);
208 inline void set(int index, double value);
209 inline void set_the_hole(Isolate* isolate, int index);
210 inline void set_the_hole(int index);
211
212 // Checking for the hole.
213 inline bool is_the_hole(Isolate* isolate, int index);
214 inline bool is_the_hole(int index);
215
216 // Garbage collection support.
SizeFor(int length)217 inline static int SizeFor(int length) {
218 return kHeaderSize + length * kDoubleSize;
219 }
220
221 // Gives access to raw memory which stores the array's data.
222 inline double* data_start();
223
224 inline void FillWithHoles(int from, int to);
225
226 // Code Generation support.
OffsetOfElementAt(int index)227 static int OffsetOfElementAt(int index) { return SizeFor(index); }
228
229 DECL_CAST(FixedDoubleArray)
230
231 // Maximal allowed size, in bytes, of a single FixedDoubleArray.
232 // Prevents overflowing size computations, as well as extreme memory
233 // consumption.
234 static const int kMaxSize = 512 * MB;
235 // Maximally allowed length of a FixedArray.
236 static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
237
238 // Dispatched behavior.
239 DECL_PRINTER(FixedDoubleArray)
240 DECL_VERIFIER(FixedDoubleArray)
241
242 class BodyDescriptor;
243 // No weak fields.
244 typedef BodyDescriptor BodyDescriptorWeak;
245
246 private:
247 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
248 };
249
250 // WeakFixedArray describes fixed-sized arrays with element type
251 // MaybeObject*.
252 class WeakFixedArray : public HeapObject {
253 public:
254 DECL_CAST(WeakFixedArray)
255
256 inline MaybeObject* Get(int index) const;
257
258 // Setter that uses write barrier.
259 inline void Set(int index, MaybeObject* value);
260
261 // Setter with explicit barrier mode.
262 inline void Set(int index, MaybeObject* value, WriteBarrierMode mode);
263
SizeFor(int length)264 static constexpr int SizeFor(int length) {
265 return kHeaderSize + length * kPointerSize;
266 }
267
268 DECL_INT_ACCESSORS(length)
269
270 // Get and set the length using acquire loads and release stores.
271 inline int synchronized_length() const;
272 inline void synchronized_set_length(int value);
273
274 // Gives access to raw memory which stores the array's data.
275 inline MaybeObject** data_start();
276
277 inline MaybeObject** RawFieldOfElementAt(int index);
278
279 // Shrink length and insert filler objects.
280 void Shrink(int new_length);
281
282 DECL_PRINTER(WeakFixedArray)
283 DECL_VERIFIER(WeakFixedArray)
284
285 typedef WeakArrayBodyDescriptor BodyDescriptor;
286 typedef BodyDescriptor BodyDescriptorWeak;
287
288 static const int kLengthOffset = HeapObject::kHeaderSize;
289 static const int kHeaderSize = kLengthOffset + kPointerSize;
290
291 static const int kMaxLength =
292 (FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
293
294 private:
OffsetOfElementAt(int index)295 static int OffsetOfElementAt(int index) {
296 return kHeaderSize + index * kPointerSize;
297 }
298
299 friend class Heap;
300
301 static const int kFirstIndex = 1;
302
303 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
304 };
305
306 // WeakArrayList is like a WeakFixedArray with static convenience methods for
307 // adding more elements. length() returns the number of elements in the list and
308 // capacity() returns the allocated size. The number of elements is stored at
309 // kLengthOffset and is updated with every insertion. The array grows
310 // dynamically with O(1) amortized insertion.
311 class WeakArrayList : public HeapObject {
312 public:
313 DECL_CAST(WeakArrayList)
314 DECL_VERIFIER(WeakArrayList)
315 DECL_PRINTER(WeakArrayList)
316
317 static Handle<WeakArrayList> Add(Handle<WeakArrayList> array,
318 Handle<HeapObject> obj1, Smi* obj2);
319
320 inline MaybeObject* Get(int index) const;
321
322 // Set the element at index to obj. The underlying array must be large enough.
323 // If you need to grow the WeakArrayList, use the static Add() methods
324 // instead.
325 inline void Set(int index, MaybeObject* value,
326 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
327
SizeForCapacity(int capacity)328 static constexpr int SizeForCapacity(int capacity) {
329 return kHeaderSize + capacity * kPointerSize;
330 }
331
332 // Gives access to raw memory which stores the array's data.
333 inline MaybeObject** data_start();
334
335 bool IsFull();
336
337 DECL_INT_ACCESSORS(capacity)
338 DECL_INT_ACCESSORS(length)
339
340 // Get and set the capacity using acquire loads and release stores.
341 inline int synchronized_capacity() const;
342 inline void synchronized_set_capacity(int value);
343
344 typedef WeakArrayBodyDescriptor BodyDescriptor;
345 typedef BodyDescriptor BodyDescriptorWeak;
346
347 static const int kCapacityOffset = HeapObject::kHeaderSize;
348 static const int kLengthOffset = kCapacityOffset + kPointerSize;
349 static const int kHeaderSize = kLengthOffset + kPointerSize;
350
351 static const int kMaxCapacity =
352 (FixedArray::kMaxSize - kHeaderSize) / kPointerSize;
353
354 private:
OffsetOfElementAt(int index)355 static int OffsetOfElementAt(int index) {
356 return kHeaderSize + index * kPointerSize;
357 }
358
359 static Handle<WeakArrayList> EnsureSpace(Handle<WeakArrayList> array,
360 int length);
361
362 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakArrayList);
363 };
364
365 // Deprecated. Use WeakFixedArray instead.
366 class FixedArrayOfWeakCells : public FixedArray {
367 public:
368 // If |maybe_array| is not a FixedArrayOfWeakCells, a fresh one will be
369 // allocated. This function does not check if the value exists already,
370 // callers must ensure this themselves if necessary.
371 static Handle<FixedArrayOfWeakCells> Add(Handle<Object> maybe_array,
372 Handle<HeapObject> value,
373 int* assigned_index = nullptr);
374
375 // Returns true if an entry was found and removed.
376 bool Remove(Handle<HeapObject> value);
377
378 class NullCallback {
379 public:
Callback(Object * value,int old_index,int new_index)380 static void Callback(Object* value, int old_index, int new_index) {}
381 };
382
383 template <class CompactionCallback>
384 void Compact();
385
386 inline Object* Get(int index) const;
387 inline void Clear(int index);
388 inline int Length() const;
389
390 inline bool IsEmptySlot(int index) const;
Empty()391 static Object* Empty() { return Smi::kZero; }
392
393 class Iterator {
394 public:
Iterator(Object * maybe_array)395 explicit Iterator(Object* maybe_array) : list_(nullptr) {
396 Reset(maybe_array);
397 }
398 void Reset(Object* maybe_array);
399
400 template <class T>
401 inline T* Next();
402
403 private:
404 int index_;
405 FixedArrayOfWeakCells* list_;
406 #ifdef DEBUG
407 int last_used_index_;
408 DisallowHeapAllocation no_gc_;
409 #endif // DEBUG
410 DISALLOW_COPY_AND_ASSIGN(Iterator);
411 };
412
413 DECL_CAST(FixedArrayOfWeakCells)
414
415 private:
416 static const int kLastUsedIndexIndex = 0;
417 static const int kFirstIndex = 1;
418
419 static Handle<FixedArrayOfWeakCells> Allocate(
420 Isolate* isolate, int size,
421 Handle<FixedArrayOfWeakCells> initialize_from);
422
423 static void Set(Handle<FixedArrayOfWeakCells> array, int index,
424 Handle<HeapObject> value);
425 inline void clear(int index);
426
427 inline int last_used_index() const;
428 inline void set_last_used_index(int index);
429
430 // Disallow inherited setters.
431 void set(int index, Smi* value);
432 void set(int index, Object* value);
433 void set(int index, Object* value, WriteBarrierMode mode);
434 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArrayOfWeakCells);
435 };
436
437 // Generic array grows dynamically with O(1) amortized insertion.
438 //
439 // ArrayList is a FixedArray with static convenience methods for adding more
440 // elements. The Length() method returns the number of elements in the list, not
441 // the allocated size. The number of elements is stored at kLengthIndex and is
442 // updated with every insertion. The elements of the ArrayList are stored in the
443 // underlying FixedArray starting at kFirstIndex.
444 class ArrayList : public FixedArray {
445 public:
446 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj);
447 static Handle<ArrayList> Add(Handle<ArrayList> array, Handle<Object> obj1,
448 Handle<Object> obj2);
449 static Handle<ArrayList> New(Isolate* isolate, int size);
450
451 // Returns the number of elements in the list, not the allocated size, which
452 // is length(). Lower and upper case length() return different results!
453 inline int Length() const;
454
455 // Sets the Length() as used by Elements(). Does not change the underlying
456 // storage capacity, i.e., length().
457 inline void SetLength(int length);
458 inline Object* Get(int index) const;
459 inline Object** Slot(int index);
460
461 // Set the element at index to obj. The underlying array must be large enough.
462 // If you need to grow the ArrayList, use the static Add() methods instead.
463 inline void Set(int index, Object* obj,
464 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
465
466 // Set the element at index to undefined. This does not change the Length().
467 inline void Clear(int index, Object* undefined);
468
469 // Return a copy of the list of size Length() without the first entry. The
470 // number returned by Length() is stored in the first entry.
471 static Handle<FixedArray> Elements(Handle<ArrayList> array);
472 bool IsFull();
473 DECL_CAST(ArrayList)
474
475 private:
476 static Handle<ArrayList> EnsureSpace(Handle<ArrayList> array, int length);
477 static const int kLengthIndex = 0;
478 static const int kFirstIndex = 1;
479 DISALLOW_IMPLICIT_CONSTRUCTORS(ArrayList);
480 };
481
482 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
483
484 template <SearchMode search_mode, typename T>
485 inline int Search(T* array, Name* name, int valid_entries = 0,
486 int* out_insertion_index = nullptr);
487
488 // ByteArray represents fixed sized byte arrays. Used for the relocation info
489 // that is attached to code objects.
490 class ByteArray : public FixedArrayBase {
491 public:
492 inline int Size();
493
494 // Setter and getter.
495 inline byte get(int index) const;
496 inline void set(int index, byte value);
497
498 // Copy in / copy out whole byte slices.
499 inline void copy_out(int index, byte* buffer, int length);
500 inline void copy_in(int index, const byte* buffer, int length);
501
502 // Treat contents as an int array.
503 inline int get_int(int index) const;
504 inline void set_int(int index, int value);
505
506 inline uint32_t get_uint32(int index) const;
507 inline void set_uint32(int index, uint32_t value);
508
509 // Clear uninitialized padding space. This ensures that the snapshot content
510 // is deterministic.
511 inline void clear_padding();
512
SizeFor(int length)513 static int SizeFor(int length) {
514 return OBJECT_POINTER_ALIGN(kHeaderSize + length);
515 }
516 // We use byte arrays for free blocks in the heap. Given a desired size in
517 // bytes that is a multiple of the word size and big enough to hold a byte
518 // array, this function returns the number of elements a byte array should
519 // have.
LengthFor(int size_in_bytes)520 static int LengthFor(int size_in_bytes) {
521 DCHECK(IsAligned(size_in_bytes, kPointerSize));
522 DCHECK_GE(size_in_bytes, kHeaderSize);
523 return size_in_bytes - kHeaderSize;
524 }
525
526 // Returns data start address.
527 inline byte* GetDataStartAddress();
528
529 inline int DataSize() const;
530
531 // Returns a pointer to the ByteArray object for a given data start address.
532 static inline ByteArray* FromDataStartAddress(Address address);
533
534 DECL_CAST(ByteArray)
535
536 // Dispatched behavior.
537 inline int ByteArraySize();
538 DECL_PRINTER(ByteArray)
539 DECL_VERIFIER(ByteArray)
540
541 // Layout description.
542 static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
543
544 // Maximal memory consumption for a single ByteArray.
545 static const int kMaxSize = 512 * MB;
546 // Maximal length of a single ByteArray.
547 static const int kMaxLength = kMaxSize - kHeaderSize;
548
549 class BodyDescriptor;
550 // No weak fields.
551 typedef BodyDescriptor BodyDescriptorWeak;
552
553 private:
554 DISALLOW_IMPLICIT_CONSTRUCTORS(ByteArray);
555 };
556
557 // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
558 // as they can be copied with memcpy.
559 template <class T>
560 class PodArray : public ByteArray {
561 public:
562 static Handle<PodArray<T>> New(Isolate* isolate, int length,
563 PretenureFlag pretenure = NOT_TENURED);
copy_out(int index,T * result)564 void copy_out(int index, T* result) {
565 ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
566 sizeof(T));
567 }
get(int index)568 T get(int index) {
569 T result;
570 copy_out(index, &result);
571 return result;
572 }
set(int index,const T & value)573 void set(int index, const T& value) {
574 copy_in(index * sizeof(T), reinterpret_cast<const byte*>(&value),
575 sizeof(T));
576 }
length()577 int length() { return ByteArray::length() / sizeof(T); }
578 DECL_CAST(PodArray<T>)
579
580 private:
581 DISALLOW_IMPLICIT_CONSTRUCTORS(PodArray<T>);
582 };
583
584 // V has parameters (Type, type, TYPE, C type, element_size)
585 #define TYPED_ARRAYS(V) \
586 V(Uint8, uint8, UINT8, uint8_t, 1) \
587 V(Int8, int8, INT8, int8_t, 1) \
588 V(Uint16, uint16, UINT16, uint16_t, 2) \
589 V(Int16, int16, INT16, int16_t, 2) \
590 V(Uint32, uint32, UINT32, uint32_t, 4) \
591 V(Int32, int32, INT32, int32_t, 4) \
592 V(Float32, float32, FLOAT32, float, 4) \
593 V(Float64, float64, FLOAT64, double, 8) \
594 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1) \
595 V(BigUint64, biguint64, BIGUINT64, uint64_t, 8) \
596 V(BigInt64, bigint64, BIGINT64, int64_t, 8)
597
598 class FixedTypedArrayBase : public FixedArrayBase {
599 public:
600 // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
601 DECL_ACCESSORS(base_pointer, Object)
602
603 // [external_pointer]: Contains the offset between base_pointer and the start
604 // of the data. If the base_pointer is a nullptr, the external_pointer
605 // therefore points to the actual backing store.
606 DECL_ACCESSORS(external_pointer, void)
607
608 // Dispatched behavior.
609 DECL_CAST(FixedTypedArrayBase)
610
611 static const int kBasePointerOffset = FixedArrayBase::kHeaderSize;
612 static const int kExternalPointerOffset = kBasePointerOffset + kPointerSize;
613 static const int kHeaderSize =
614 DOUBLE_POINTER_ALIGN(kExternalPointerOffset + kPointerSize);
615
616 static const int kDataOffset = kHeaderSize;
617
618 static const int kMaxElementSize = 8;
619
620 #ifdef V8_HOST_ARCH_32_BIT
621 static const size_t kMaxByteLength = std::numeric_limits<size_t>::max();
622 #else
623 static const size_t kMaxByteLength =
624 static_cast<size_t>(Smi::kMaxValue) * kMaxElementSize;
625 #endif // V8_HOST_ARCH_32_BIT
626
627 static const size_t kMaxLength = Smi::kMaxValue;
628
629 class BodyDescriptor;
630 // No weak fields.
631 typedef BodyDescriptor BodyDescriptorWeak;
632
633 inline int size() const;
634
635 static inline int TypedArraySize(InstanceType type, int length);
636 inline int TypedArraySize(InstanceType type) const;
637
638 // Use with care: returns raw pointer into heap.
639 inline void* DataPtr();
640
641 inline int DataSize() const;
642
643 inline size_t ByteLength() const;
644
645 private:
646 static inline int ElementSize(InstanceType type);
647
648 inline int DataSize(InstanceType type) const;
649
650 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArrayBase);
651 };
652
653 template <class Traits>
654 class FixedTypedArray : public FixedTypedArrayBase {
655 public:
656 typedef typename Traits::ElementType ElementType;
657 static const InstanceType kInstanceType = Traits::kInstanceType;
658
659 DECL_CAST(FixedTypedArray<Traits>)
660
661 static inline ElementType get_scalar_from_data_ptr(void* data_ptr, int index);
662 inline ElementType get_scalar(int index);
663 static inline Handle<Object> get(FixedTypedArray* array, int index);
664 inline void set(int index, ElementType value);
665
666 static inline ElementType from(int value);
667 static inline ElementType from(uint32_t value);
668 static inline ElementType from(double value);
669 static inline ElementType from(int64_t value);
670 static inline ElementType from(uint64_t value);
671
672 static inline ElementType FromHandle(Handle<Object> value,
673 bool* lossless = nullptr);
674
675 // This accessor applies the correct conversion from Smi, HeapNumber
676 // and undefined.
677 inline void SetValue(uint32_t index, Object* value);
678
679 DECL_PRINTER(FixedTypedArray)
680 DECL_VERIFIER(FixedTypedArray)
681
682 private:
683 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedTypedArray);
684 };
685
686 #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType, size) \
687 STATIC_ASSERT(size <= FixedTypedArrayBase::kMaxElementSize); \
688 class Type##ArrayTraits { \
689 public: /* NOLINT */ \
690 typedef elementType ElementType; \
691 static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
692 static const char* Designator() { return #type " array"; } \
693 static inline Handle<Object> ToHandle(Isolate* isolate, \
694 elementType scalar); \
695 static inline elementType defaultValue(); \
696 }; \
697 \
698 typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
699
TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)700 TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
701
702 #undef FIXED_TYPED_ARRAY_TRAITS
703
704 class TemplateList : public FixedArray {
705 public:
706 static Handle<TemplateList> New(Isolate* isolate, int size);
707 inline int length() const;
708 inline Object* get(int index) const;
709 inline void set(int index, Object* value);
710 static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
711 Handle<Object> value);
712 DECL_CAST(TemplateList)
713 private:
714 static const int kLengthIndex = 0;
715 static const int kFirstElementIndex = kLengthIndex + 1;
716 DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateList);
717 };
718
719 } // namespace internal
720 } // namespace v8
721
722 #include "src/objects/object-macros-undef.h"
723
724 #endif // V8_OBJECTS_FIXED_ARRAY_H_
725