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