Home | History | Annotate | Download | only in objects
      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_DESCRIPTOR_ARRAY_H_
      6 #define V8_OBJECTS_DESCRIPTOR_ARRAY_H_
      7 
      8 #include "src/objects.h"
      9 #include "src/objects/fixed-array.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 template <typename T>
     18 class Handle;
     19 
     20 class Isolate;
     21 
     22 // An EnumCache is a pair used to hold keys and indices caches.
     23 class EnumCache : public Tuple2 {
     24  public:
     25   DECL_ACCESSORS(keys, FixedArray)
     26   DECL_ACCESSORS(indices, FixedArray)
     27 
     28   DECL_CAST(EnumCache)
     29 
     30   // Layout description.
     31   static const int kKeysOffset = kValue1Offset;
     32   static const int kIndicesOffset = kValue2Offset;
     33 
     34  private:
     35   DISALLOW_IMPLICIT_CONSTRUCTORS(EnumCache);
     36 };
     37 
     38 // A DescriptorArray is a fixed array used to hold instance descriptors.
     39 // The format of these objects is:
     40 //   [0]: Number of descriptors
     41 //   [1]: Enum cache.
     42 //   [2]: first key (and internalized String)
     43 //   [3]: first descriptor details (see PropertyDetails)
     44 //   [4]: first value for constants | Smi(1) when not used
     45 //
     46 //   [2 + number of descriptors * 3]: start of slack
     47 // The "value" fields store either values or field types. A field type is either
     48 // FieldType::None(), FieldType::Any() or a weak reference to a Map. All other
     49 // references are strong.
     50 class DescriptorArray : public WeakFixedArray {
     51  public:
     52   // Returns the number of descriptors in the array.
     53   inline int number_of_descriptors() const;
     54   inline int number_of_descriptors_storage() const;
     55   inline int NumberOfSlackDescriptors() const;
     56 
     57   inline void SetNumberOfDescriptors(int number_of_descriptors);
     58   inline int number_of_entries() const;
     59 
     60   inline EnumCache* GetEnumCache();
     61 
     62   void ClearEnumCache();
     63   inline void CopyEnumCacheFrom(DescriptorArray* array);
     64   // Initialize or change the enum cache,
     65   static void SetEnumCache(Handle<DescriptorArray> descriptors,
     66                            Isolate* isolate, Handle<FixedArray> keys,
     67                            Handle<FixedArray> indices);
     68 
     69   // Accessors for fetching instance descriptor at descriptor number.
     70   inline Name* GetKey(int descriptor_number);
     71   inline Object** GetKeySlot(int descriptor_number);
     72   inline Object* GetStrongValue(int descriptor_number);
     73   inline void SetValue(int descriptor_number, Object* value);
     74   inline MaybeObject* GetValue(int descriptor_number);
     75   inline MaybeObject** GetValueSlot(int descriptor_number);
     76   static inline int GetValueOffset(int descriptor_number);
     77   inline MaybeObject** GetDescriptorStartSlot(int descriptor_number);
     78   inline MaybeObject** GetDescriptorEndSlot(int descriptor_number);
     79   inline PropertyDetails GetDetails(int descriptor_number);
     80   inline int GetFieldIndex(int descriptor_number);
     81   inline FieldType* GetFieldType(int descriptor_number);
     82 
     83   inline Name* GetSortedKey(int descriptor_number);
     84   inline int GetSortedKeyIndex(int descriptor_number);
     85   inline void SetSortedKey(int pointer, int descriptor_number);
     86 
     87   // Accessor for complete descriptor.
     88   inline void Set(int descriptor_number, Descriptor* desc);
     89   inline void Set(int descriptor_number, Name* key, MaybeObject* value,
     90                   PropertyDetails details);
     91   void Replace(int descriptor_number, Descriptor* descriptor);
     92 
     93   // Generalizes constness, representation and field type of all field
     94   // descriptors.
     95   void GeneralizeAllFields();
     96 
     97   // Append automatically sets the enumeration index. This should only be used
     98   // to add descriptors in bulk at the end, followed by sorting the descriptor
     99   // array.
    100   inline void Append(Descriptor* desc);
    101 
    102   static Handle<DescriptorArray> CopyUpTo(Isolate* isolate,
    103                                           Handle<DescriptorArray> desc,
    104                                           int enumeration_index, int slack = 0);
    105 
    106   static Handle<DescriptorArray> CopyUpToAddAttributes(
    107       Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
    108       PropertyAttributes attributes, int slack = 0);
    109 
    110   static Handle<DescriptorArray> CopyForFastObjectClone(
    111       Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
    112       int slack = 0);
    113 
    114   // Sort the instance descriptors by the hash codes of their keys.
    115   void Sort();
    116 
    117   // Search the instance descriptors for given name.
    118   V8_INLINE int Search(Name* name, int number_of_own_descriptors);
    119   V8_INLINE int Search(Name* name, Map* map);
    120 
    121   // As the above, but uses DescriptorLookupCache and updates it when
    122   // necessary.
    123   V8_INLINE int SearchWithCache(Isolate* isolate, Name* name, Map* map);
    124 
    125   bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
    126 
    127   // Allocates a DescriptorArray, but returns the singleton
    128   // empty descriptor array object if number_of_descriptors is 0.
    129   static Handle<DescriptorArray> Allocate(
    130       Isolate* isolate, int number_of_descriptors, int slack,
    131       PretenureFlag pretenure = NOT_TENURED);
    132 
    133   DECL_CAST(DescriptorArray)
    134 
    135   // Constant for denoting key was not found.
    136   static const int kNotFound = -1;
    137 
    138   static const int kDescriptorLengthIndex = 0;
    139   static const int kEnumCacheIndex = 1;
    140   static const int kFirstIndex = 2;
    141 
    142   // Layout description.
    143   static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
    144   static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
    145   static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
    146 
    147   // Layout of descriptor.
    148   // Naming is consistent with Dictionary classes for easy templating.
    149   static const int kEntryKeyIndex = 0;
    150   static const int kEntryDetailsIndex = 1;
    151   static const int kEntryValueIndex = 2;
    152   static const int kEntrySize = 3;
    153 
    154   // Print all the descriptors.
    155   void PrintDescriptors(std::ostream& os);
    156   void PrintDescriptorDetails(std::ostream& os, int descriptor,
    157                               PropertyDetails::PrintMode mode);
    158 
    159   DECL_PRINTER(DescriptorArray)
    160   DECL_VERIFIER(DescriptorArray)
    161 
    162 #ifdef DEBUG
    163   // Is the descriptor array sorted and without duplicates?
    164   bool IsSortedNoDuplicates(int valid_descriptors = -1);
    165 
    166   // Are two DescriptorArrays equal?
    167   bool IsEqualTo(DescriptorArray* other);
    168 #endif
    169 
    170   // Returns the fixed array length required to hold number_of_descriptors
    171   // descriptors.
    172   static constexpr int LengthFor(int number_of_descriptors) {
    173     return ToKeyIndex(number_of_descriptors);
    174   }
    175 
    176   static constexpr int ToDetailsIndex(int descriptor_number) {
    177     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryDetailsIndex;
    178   }
    179 
    180   // Conversion from descriptor number to array indices.
    181   static constexpr int ToKeyIndex(int descriptor_number) {
    182     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
    183   }
    184 
    185   static constexpr int ToValueIndex(int descriptor_number) {
    186     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryValueIndex;
    187   }
    188 
    189  private:
    190   inline MaybeObject* get(int index) const;
    191   inline void set(int index, MaybeObject* value);
    192 
    193   // Transfer a complete descriptor from the src descriptor array to this
    194   // descriptor array.
    195   void CopyFrom(int index, DescriptorArray* src);
    196 
    197   // Swap first and second descriptor.
    198   inline void SwapSortedKeys(int first, int second);
    199 
    200   DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
    201 };
    202 
    203 }  // namespace internal
    204 }  // namespace v8
    205 
    206 #include "src/objects/object-macros-undef.h"
    207 
    208 #endif  // V8_OBJECTS_DESCRIPTOR_ARRAY_H_
    209