• 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/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