LCOV - code coverage report
Current view: top level - src/objects - fixed-array.h (source / functions) Hit Total Coverage
Test: app.info Lines: 27 27 100.0 %
Date: 2019-03-21 Functions: 13 13 100.0 %

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

Generated by: LCOV version 1.10