• 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_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.
LengthFor(int number_of_descriptors)172   static constexpr int LengthFor(int number_of_descriptors) {
173     return ToKeyIndex(number_of_descriptors);
174   }
175 
ToDetailsIndex(int descriptor_number)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.
ToKeyIndex(int descriptor_number)181   static constexpr int ToKeyIndex(int descriptor_number) {
182     return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
183   }
184 
ToValueIndex(int descriptor_number)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