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