V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
dictionary.h
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_DICTIONARY_H_
6 #define V8_OBJECTS_DICTIONARY_H_
7 
8 #include "src/base/export-template.h"
9 #include "src/globals.h"
10 #include "src/objects/hash-table.h"
11 #include "src/objects/property-array.h"
12 #include "src/objects/smi.h"
13 
14 // Has to be the last include (doesn't have include guards):
15 #include "src/objects/object-macros.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 template <typename T>
21 class Handle;
22 
23 class Isolate;
24 
25 template <typename Derived, typename Shape>
26 class Dictionary : public HashTable<Derived, Shape> {
28 
29  public:
30  typedef typename Shape::Key Key;
31  // Returns the value at entry.
32  Object* ValueAt(int entry) {
33  return this->get(DerivedHashTable::EntryToIndex(entry) + 1);
34  }
35 
36  // Set the value for entry.
37  void ValueAtPut(int entry, Object* value) {
38  this->set(DerivedHashTable::EntryToIndex(entry) + 1, value);
39  }
40 
41  // Returns the property details for the property at entry.
42  PropertyDetails DetailsAt(int entry) {
43  return Shape::DetailsAt(Derived::cast(*this), entry);
44  }
45 
46  // Set the details for entry.
47  void DetailsAtPut(Isolate* isolate, int entry, PropertyDetails value) {
48  Shape::DetailsAtPut(isolate, Derived::cast(*this), entry, value);
49  }
50 
51  // Delete a property from the dictionary.
52  V8_WARN_UNUSED_RESULT static Handle<Derived> DeleteEntry(
53  Isolate* isolate, Handle<Derived> dictionary, int entry);
54 
55  // Attempt to shrink the dictionary after deletion of key.
56  V8_WARN_UNUSED_RESULT static inline Handle<Derived> Shrink(
57  Isolate* isolate, Handle<Derived> dictionary) {
58  return DerivedHashTable::Shrink(isolate, dictionary);
59  }
60 
61  int NumberOfEnumerableProperties();
62 
63 #ifdef OBJECT_PRINT
64  // For our gdb macros, we should perhaps change these in the future.
65  void Print();
66 
67  void Print(std::ostream& os); // NOLINT
68 #endif
69  // Returns the key (slow).
70  Object* SlowReverseLookup(Object* value);
71 
72  // Sets the entry to (key, value) pair.
73  inline void ClearEntry(Isolate* isolate, int entry);
74  inline void SetEntry(Isolate* isolate, int entry, Object* key, Object* value,
75  PropertyDetails details);
76 
77  V8_WARN_UNUSED_RESULT static Handle<Derived> Add(
78  Isolate* isolate, Handle<Derived> dictionary, Key key,
79  Handle<Object> value, PropertyDetails details, int* entry_out = nullptr);
80 
81  protected:
82  // Generic at put operation.
83  V8_WARN_UNUSED_RESULT static Handle<Derived> AtPut(Isolate* isolate,
84  Handle<Derived> dictionary,
85  Key key,
86  Handle<Object> value,
87  PropertyDetails details);
88 
89  OBJECT_CONSTRUCTORS(Dictionary, HashTable<Derived, Shape>)
90 };
91 
92 template <typename Key>
93 class BaseDictionaryShape : public BaseShape<Key> {
94  public:
95  static const bool kHasDetails = true;
96  template <typename Dictionary>
97  static inline PropertyDetails DetailsAt(Dictionary dict, int entry) {
98  STATIC_ASSERT(Dictionary::kEntrySize == 3);
99  DCHECK_GE(entry, 0); // Not found is -1, which is not caught by get().
100  return PropertyDetails(Smi::cast(dict->get(
101  Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex)));
102  }
103 
104  template <typename Dictionary>
105  static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry,
106  PropertyDetails value) {
107  STATIC_ASSERT(Dictionary::kEntrySize == 3);
108  dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
109  value.AsSmi());
110  }
111 };
112 
113 class NameDictionaryShape : public BaseDictionaryShape<Handle<Name>> {
114  public:
115  static inline bool IsMatch(Handle<Name> key, Object* other);
116  static inline uint32_t Hash(Isolate* isolate, Handle<Name> key);
117  static inline uint32_t HashForObject(Isolate* isolate, Object* object);
118  static inline Handle<Object> AsHandle(Isolate* isolate, Handle<Name> key);
119  static inline RootIndex GetMapRootIndex();
120  static const int kPrefixSize = 2;
121  static const int kEntrySize = 3;
122  static const int kEntryValueIndex = 1;
123  static const bool kNeedsHoleCheck = false;
124 };
125 
126 template <typename Derived, typename Shape>
127 class BaseNameDictionary : public Dictionary<Derived, Shape> {
128  typedef typename Shape::Key Key;
129 
130  public:
131  static const int kNextEnumerationIndexIndex =
132  HashTableBase::kPrefixStartIndex;
133  static const int kObjectHashIndex = kNextEnumerationIndexIndex + 1;
134  static const int kEntryValueIndex = 1;
135 
136  // Accessors for next enumeration index.
137  void SetNextEnumerationIndex(int index) {
138  DCHECK_NE(0, index);
139  this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
140  }
141 
142  int NextEnumerationIndex() {
143  return Smi::ToInt(this->get(kNextEnumerationIndexIndex));
144  }
145 
146  void SetHash(int hash) {
147  DCHECK(PropertyArray::HashField::is_valid(hash));
148  this->set(kObjectHashIndex, Smi::FromInt(hash));
149  }
150 
151  int Hash() const {
152  Object* hash_obj = this->get(kObjectHashIndex);
153  int hash = Smi::ToInt(hash_obj);
154  DCHECK(PropertyArray::HashField::is_valid(hash));
155  return hash;
156  }
157 
158  // Creates a new dictionary.
159  V8_WARN_UNUSED_RESULT static Handle<Derived> New(
160  Isolate* isolate, int at_least_space_for,
161  PretenureFlag pretenure = NOT_TENURED,
162  MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
163 
164  // Collect the keys into the given KeyAccumulator, in ascending chronological
165  // order of property creation.
166  static void CollectKeysTo(Handle<Derived> dictionary, KeyAccumulator* keys);
167 
168  // Return the key indices sorted by its enumeration index.
169  static Handle<FixedArray> IterationIndices(Isolate* isolate,
170  Handle<Derived> dictionary);
171 
172  // Copies enumerable keys to preallocated fixed array.
173  // Does not throw for uninitialized exports in module namespace objects, so
174  // this has to be checked separately.
175  static void CopyEnumKeysTo(Isolate* isolate, Handle<Derived> dictionary,
176  Handle<FixedArray> storage, KeyCollectionMode mode,
177  KeyAccumulator* accumulator);
178 
179  // Ensure enough space for n additional elements.
180  static Handle<Derived> EnsureCapacity(Isolate* isolate,
181  Handle<Derived> dictionary, int n);
182 
183  V8_WARN_UNUSED_RESULT static Handle<Derived> AddNoUpdateNextEnumerationIndex(
184  Isolate* isolate, Handle<Derived> dictionary, Key key,
185  Handle<Object> value, PropertyDetails details, int* entry_out = nullptr);
186 
187  V8_WARN_UNUSED_RESULT static Handle<Derived> Add(
188  Isolate* isolate, Handle<Derived> dictionary, Key key,
189  Handle<Object> value, PropertyDetails details, int* entry_out = nullptr);
190 
191  OBJECT_CONSTRUCTORS(BaseNameDictionary, Dictionary<Derived, Shape>)
192 };
193 
195  : public BaseNameDictionary<NameDictionary, NameDictionaryShape> {
196  public:
197  DECL_CAST2(NameDictionary)
198 
199  static const int kEntryDetailsIndex = 2;
200  static const int kInitialCapacity = 2;
201 
202  inline Name NameAt(int entry);
203  inline void set_hash(int hash);
204  inline int hash() const;
205 
206  OBJECT_CONSTRUCTORS(NameDictionary,
208 };
209 
211  public:
212  static inline bool IsMatch(Handle<Name> key, Object* other);
213  static inline uint32_t HashForObject(Isolate* isolate, Object* object);
214 
215  static const int kEntrySize = 1; // Overrides NameDictionaryShape::kEntrySize
216 
217  template <typename Dictionary>
218  static inline PropertyDetails DetailsAt(Dictionary dict, int entry);
219 
220  template <typename Dictionary>
221  static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry,
222  PropertyDetails value);
223 
224  static inline Object* Unwrap(Object* key);
225  static inline bool IsKey(ReadOnlyRoots roots, Object* k);
226  static inline bool IsLive(ReadOnlyRoots roots, Object* key);
227  static inline RootIndex GetMapRootIndex();
228 };
229 
231  : public BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape> {
232  public:
233  DECL_CAST2(GlobalDictionary)
234 
235  inline Object* ValueAt(int entry);
236  inline PropertyCell* CellAt(int entry);
237  inline void SetEntry(Isolate* isolate, int entry, Object* key, Object* value,
238  PropertyDetails details);
239  inline Name NameAt(int entry);
240  inline void ValueAtPut(int entry, Object* value);
241 
242  OBJECT_CONSTRUCTORS(
245 };
246 
248  public:
249  static inline bool IsMatch(uint32_t key, Object* other);
250  static inline Handle<Object> AsHandle(Isolate* isolate, uint32_t key);
251 
252  static inline uint32_t Hash(Isolate* isolate, uint32_t key);
253  static inline uint32_t HashForObject(Isolate* isolate, Object* object);
254 };
255 
257  public:
258  static const int kPrefixSize = 1;
259  static const int kEntrySize = 3;
260 
261  static inline RootIndex GetMapRootIndex();
262 };
263 
265  public:
266  static const bool kHasDetails = false;
267  static const int kPrefixSize = 0;
268  static const int kEntrySize = 2;
269 
270  template <typename Dictionary>
271  static inline PropertyDetails DetailsAt(Dictionary dict, int entry) {
272  UNREACHABLE();
273  }
274 
275  template <typename Dictionary>
276  static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry,
277  PropertyDetails value) {
278  UNREACHABLE();
279  }
280 
281  static inline RootIndex GetMapRootIndex();
282 };
283 
284 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
286 
287 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
289 
290 // SimpleNumberDictionary is used to map number to an entry.
293  public:
294  DECL_CAST2(SimpleNumberDictionary)
295  // Type specific at put (default NONE attributes is used when adding).
296  V8_WARN_UNUSED_RESULT static Handle<SimpleNumberDictionary> Set(
297  Isolate* isolate, Handle<SimpleNumberDictionary> dictionary, uint32_t key,
298  Handle<Object> value);
299 
300  static const int kEntryValueIndex = 1;
301 
302  OBJECT_CONSTRUCTORS(
305 };
306 
307 extern template class EXPORT_TEMPLATE_DECLARE(
309 
310 extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
312 
313 // NumberDictionary is used as elements backing store and provides a bitfield
314 // and stores property details for every entry.
317  public:
318  DECL_CAST2(NumberDictionary)
319  DECL_PRINTER(NumberDictionary)
320 
321  // Type specific at put (default NONE attributes is used when adding).
322  V8_WARN_UNUSED_RESULT static Handle<NumberDictionary> Set(
323  Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t key,
324  Handle<Object> value,
325  Handle<JSObject> dictionary_holder = Handle<JSObject>::null(),
326  PropertyDetails details = PropertyDetails::Empty());
327 
328  static const int kMaxNumberKeyIndex = kPrefixStartIndex;
329  void UpdateMaxNumberKey(uint32_t key, Handle<JSObject> dictionary_holder);
330 
331  // Returns true if the dictionary contains any elements that are non-writable,
332  // non-configurable, non-enumerable, or have getters/setters.
333  bool HasComplexElements();
334 
335  // Sorting support
336  void CopyValuesTo(FixedArray elements);
337 
338  // If slow elements are required we will never go back to fast-case
339  // for the elements kept in this dictionary. We require slow
340  // elements if an element has been added at an index larger than
341  // kRequiresSlowElementsLimit or set_requires_slow_elements() has been called
342  // when defining a getter or setter with a number key.
343  inline bool requires_slow_elements();
344  inline void set_requires_slow_elements();
345 
346  // Get the value of the max number key that has been added to this
347  // dictionary. max_number_key can only be called if
348  // requires_slow_elements returns false.
349  inline uint32_t max_number_key();
350 
351  static const int kEntryValueIndex = 1;
352  static const int kEntryDetailsIndex = 2;
353 
354  // Bit masks.
355  static const int kRequiresSlowElementsMask = 1;
356  static const int kRequiresSlowElementsTagSize = 1;
357  static const uint32_t kRequiresSlowElementsLimit = (1 << 29) - 1;
358 
359  // JSObjects prefer dictionary elements if the dictionary saves this much
360  // memory compared to a fast elements backing store.
361  static const uint32_t kPreferFastElementsSizeFactor = 3;
362 
363  OBJECT_CONSTRUCTORS(NumberDictionary,
365 };
366 
367 } // namespace internal
368 } // namespace v8
369 
370 #include "src/objects/object-macros-undef.h"
371 
372 #endif // V8_OBJECTS_DICTIONARY_H_
Definition: libplatform.h:13
Definition: v8.h:3740