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