v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
dictionary-inl.h
Go to the documentation of this file.
1// Copyright 2018 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_INL_H_
6#define V8_OBJECTS_DICTIONARY_INL_H_
7
9// Include the non-inl header before the rest of the headers.
10
11#include <optional>
12
17#include "src/objects/oddball.h"
19
20// Has to be the last include (doesn't have include guards):
22
23namespace v8::internal {
24
25template <typename Derived, typename Shape>
26Tagged<Object> Dictionary<Derived, Shape>::ValueAt(InternalIndex entry) {
27 PtrComprCageBase cage_base = GetPtrComprCageBase();
28 return ValueAt(cage_base, entry);
29}
30
31template <typename Derived, typename Shape>
32Tagged<Object> Dictionary<Derived, Shape>::ValueAt(PtrComprCageBase cage_base,
33 InternalIndex entry) {
34 return this->get(DerivedHashTable::EntryToIndex(entry) +
35 Derived::kEntryValueIndex);
36}
37
38template <typename Derived, typename Shape>
39Tagged<Object> Dictionary<Derived, Shape>::ValueAt(InternalIndex entry,
40 SeqCstAccessTag tag) {
41 PtrComprCageBase cage_base = GetPtrComprCageBase();
42 return ValueAt(cage_base, entry, tag);
43}
44
45template <typename Derived, typename Shape>
46Tagged<Object> Dictionary<Derived, Shape>::ValueAt(PtrComprCageBase cage_base,
47 InternalIndex entry,
48 SeqCstAccessTag tag) {
49 return this->get(
50 DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex, tag);
51}
52
53template <typename Derived, typename Shape>
54std::optional<Tagged<Object>> Dictionary<Derived, Shape>::TryValueAt(
55 InternalIndex entry) {
56#if DEBUG
57 Isolate* isolate;
58 GetIsolateFromHeapObject(this, &isolate);
59 DCHECK_NE(isolate, nullptr);
60 SLOW_DCHECK(!isolate->heap()->IsPendingAllocation(Tagged(this)));
61#endif // DEBUG
62 // We can read length() in a non-atomic way since we are reading an
63 // initialized object which is not pending allocation.
64 if (DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex >=
65 this->length()) {
66 return {};
67 }
68 return ValueAt(entry);
69}
70
71template <typename Derived, typename Shape>
72void Dictionary<Derived, Shape>::ValueAtPut(InternalIndex entry,
73 Tagged<Object> value) {
74 this->set(DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex,
75 value);
76}
77
78template <typename Derived, typename Shape>
79void Dictionary<Derived, Shape>::ValueAtPut(InternalIndex entry,
80 Tagged<Object> value,
81 SeqCstAccessTag tag) {
82 this->set(DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex,
83 value, tag);
84}
85
86template <typename Derived, typename Shape>
87Tagged<Object> Dictionary<Derived, Shape>::ValueAtSwap(InternalIndex entry,
88 Tagged<Object> value,
89 SeqCstAccessTag tag) {
90 return this->swap(
91 DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex, value,
92 tag);
93}
94
95template <typename Derived, typename Shape>
96Tagged<Object> Dictionary<Derived, Shape>::ValueAtCompareAndSwap(
97 InternalIndex entry, Tagged<Object> expected, Tagged<Object> value,
98 SeqCstAccessTag tag) {
99 return this->compare_and_swap(
100 DerivedHashTable::EntryToIndex(entry) + Derived::kEntryValueIndex,
101 expected, value, tag);
102}
103
104template <typename Derived, typename Shape>
105PropertyDetails Dictionary<Derived, Shape>::DetailsAt(InternalIndex entry) {
106 return Shape::DetailsAt(Cast<Derived>(this), entry);
107}
108
109template <typename Derived, typename Shape>
110void Dictionary<Derived, Shape>::DetailsAtPut(InternalIndex entry,
111 PropertyDetails value) {
112 Shape::DetailsAtPut(Cast<Derived>(this), entry, value);
113}
114
115template <typename Derived, typename Shape>
116void BaseNameDictionary<Derived, Shape>::set_next_enumeration_index(int index) {
117 DCHECK_LT(0, index);
118 this->set(kNextEnumerationIndexIndex, Smi::FromInt(index));
119}
120
121template <typename Derived, typename Shape>
122int BaseNameDictionary<Derived, Shape>::next_enumeration_index() {
123 return Smi::ToInt(this->get(kNextEnumerationIndexIndex));
124}
125
126template <typename Derived, typename Shape>
127void BaseNameDictionary<Derived, Shape>::SetHash(int hash) {
129 this->set(kObjectHashIndex, Smi::FromInt(hash));
130}
131
132template <typename Derived, typename Shape>
133int BaseNameDictionary<Derived, Shape>::Hash() const {
134 Tagged<Object> hash_obj = this->get(kObjectHashIndex);
135 int hash = Smi::ToInt(hash_obj);
137 return hash;
138}
139
141 Tagged<Object> max_index_object = get(kMaxNumberKeyIndex);
142 if (!IsSmi(max_index_object)) return false;
143 return 0 != (Smi::ToInt(max_index_object) & kRequiresSlowElementsMask);
144}
145
148 Tagged<Object> max_index_object = get(kMaxNumberKeyIndex);
149 if (!IsSmi(max_index_object)) return 0;
150 uint32_t value = static_cast<uint32_t>(Smi::ToInt(max_index_object));
152}
153
157
158template <typename Derived, typename Shape>
159void Dictionary<Derived, Shape>::ClearEntry(InternalIndex entry) {
160 Tagged<Object> the_hole = GetReadOnlyRoots().the_hole_value();
162 Cast<Derived>(this)->SetEntry(entry, the_hole, the_hole, details);
163}
164
165template <typename Derived, typename Shape>
166void Dictionary<Derived, Shape>::SetEntry(InternalIndex entry,
168 Tagged<Object> value,
169 PropertyDetails details) {
170 DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3);
171 DCHECK(!IsName(key) || details.dictionary_index() > 0);
172 int index = DerivedHashTable::EntryToIndex(entry);
174 WriteBarrierMode mode = this->GetWriteBarrierMode(no_gc);
175 this->set(index + Derived::kEntryKeyIndex, key, mode);
176 this->set(index + Derived::kEntryValueIndex, value, mode);
177 if (Shape::kHasDetails) DetailsAtPut(entry, details);
178}
179
180template <typename Derived, typename Shape>
181ObjectSlot Dictionary<Derived, Shape>::RawFieldOfValueAt(InternalIndex entry) {
182 return this->RawFieldOfElementAt(DerivedHashTable::EntryToIndex(entry) +
183 Derived::kEntryValueIndex);
184}
185
186template <typename Key>
187template <typename Dictionary>
189 InternalIndex entry) {
190 static_assert(Dictionary::kEntrySize == 3);
191 DCHECK(entry.is_found());
192 return PropertyDetails(Cast<Smi>(dict->get(Dictionary::EntryToIndex(entry) +
193 Dictionary::kEntryDetailsIndex)));
194}
195
196template <typename Key>
197template <typename Dictionary>
199 InternalIndex entry,
200 PropertyDetails value) {
201 static_assert(Dictionary::kEntrySize == 3);
202 dict->set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex,
203 value.AsSmi());
204}
205
209
211 return roots.global_dictionary_map();
212}
213
216 return NameAt(cage_base, entry);
217}
218
220 InternalIndex entry) {
221 return Cast<Name>(KeyAt(cage_base, entry));
222}
223
225 return roots.name_dictionary_map();
226}
227
228uint32_t NameDictionary::flags() const {
229 return Smi::ToInt(this->get(kFlagsIndex));
230}
231
232void NameDictionary::set_flags(uint32_t flags) {
233 this->set(kFlagsIndex, Smi::FromInt(flags));
234}
235
236BIT_FIELD_ACCESSORS(NameDictionary, flags, may_have_interesting_properties,
238
241 return CellAt(cage_base, entry);
242}
243
245 InternalIndex entry) {
246 DCHECK(IsPropertyCell(KeyAt(cage_base, entry), cage_base));
247 return Cast<PropertyCell>(KeyAt(cage_base, entry));
248}
249
252 return NameAt(cage_base, entry);
253}
254
256 InternalIndex entry) {
257 return CellAt(cage_base, entry)->name(cage_base);
258}
259
262 return ValueAt(cage_base, entry);
263}
264
266 InternalIndex entry) {
267 return CellAt(cage_base, entry)->value(cage_base);
268}
269
271 Tagged<Object> value, PropertyDetails details) {
273 set(EntryToIndex(entry) + kEntryKeyIndex, value);
274 DetailsAtPut(entry, details);
275}
276
278 Tagged<Hole> the_hole = GetReadOnlyRoots().the_hole_value();
279 set(EntryToIndex(entry) + kEntryKeyIndex, the_hole);
280}
281
283 set(EntryToIndex(entry), value);
284}
285
287 return key == static_cast<uint32_t>(Object::NumberValue(Cast<Number>(other)));
288}
289
291 return ComputeSeededHash(key, HashSeed(roots));
292}
293
295 Tagged<Object> other) {
296 DCHECK(IsNumber(other));
297 return ComputeSeededHash(
298 static_cast<uint32_t>(Object::NumberValue(Cast<Number>(other))),
299 HashSeed(roots));
300}
301
302template <AllocationType allocation>
304 uint32_t key) {
305 return isolate->factory()->NewNumberFromUint<allocation>(key);
306}
307
308template <AllocationType allocation>
310 uint32_t key) {
311 return isolate->factory()->NewNumberFromUint<allocation>(key);
312}
313
315 return roots.number_dictionary_map();
316}
317
319 return roots.simple_number_dictionary_map();
320}
321
323 Tagged<Object> other) {
324 DCHECK(IsTheHole(other) || IsUniqueName(Cast<Name>(other)));
326 return *key == other;
327}
328
332 return key->hash();
333}
334
336 Tagged<Object> other) {
337 DCHECK(IsUniqueName(other));
338 return Cast<Name>(other)->hash();
339}
340
347
349 Tagged<Object> other) {
350 return Cast<PropertyCell>(other)->name()->hash();
351}
352
353template <AllocationType allocation>
359
360template <AllocationType allocation>
366
367template <typename Dictionary>
369 InternalIndex entry) {
370 DCHECK(entry.is_found());
371 return dict->CellAt(entry)->property_details();
372}
373
374template <typename Dictionary>
376 InternalIndex entry,
377 PropertyDetails value) {
378 DCHECK(entry.is_found());
379 dict->CellAt(entry)->UpdatePropertyDetailsExceptCellType(value);
380}
381
382} // namespace v8::internal
383
385
386#endif // V8_OBJECTS_DICTIONARY_INL_H_
#define SLOW_DCHECK(condition)
Definition checks.h:21
static constexpr bool is_valid(T value)
Definition bit-field.h:50
static void DetailsAtPut(Tagged< Dictionary > dict, InternalIndex entry, PropertyDetails value)
static PropertyDetails DetailsAt(Tagged< Dictionary > dict, InternalIndex entry)
static bool IsMatch(DirectHandle< Name > key, Tagged< Object > other)
static uint32_t HashForObject(ReadOnlyRoots roots, Tagged< Object > object)
static DirectHandle< Object > AsHandle(Isolate *isolate, DirectHandle< Name > key)
static uint32_t Hash(ReadOnlyRoots roots, DirectHandle< Name > key)
static Tagged< Object > Unwrap(Tagged< Object > key)
static void DetailsAtPut(Tagged< Dictionary > dict, InternalIndex entry, PropertyDetails value)
static uint32_t HashForObject(ReadOnlyRoots roots, Tagged< Object > object)
static bool IsMatch(DirectHandle< Name > key, Tagged< Object > other)
static PropertyDetails DetailsAt(Tagged< Dictionary > dict, InternalIndex entry)
Tagged< Name > NameAt(InternalIndex entry)
void ClearEntry(InternalIndex entry)
Tagged< PropertyCell > CellAt(InternalIndex entry)
void ValueAtPut(InternalIndex entry, Tagged< Object > value)
void SetEntry(InternalIndex entry, Tagged< Object > key, Tagged< Object > value, PropertyDetails details)
Tagged< Object > ValueAt(InternalIndex entry)
static DirectHandle< Map > GetMap(RootsTable &roots)
Tagged< Name > NameAt(InternalIndex entry)
static const int kFlagsIndex
Definition dictionary.h:247
void set_flags(uint32_t flags)
static DirectHandle< Map > GetMap(RootsTable &roots)
static DirectHandle< Object > AsHandle(Isolate *isolate, uint32_t key)
static uint32_t HashForObject(ReadOnlyRoots roots, Tagged< Object > object)
static uint32_t Hash(ReadOnlyRoots roots, uint32_t key)
static bool IsMatch(uint32_t key, Tagged< Object > other)
static const int kMaxNumberKeyIndex
Definition dictionary.h:410
static DirectHandle< Map > GetMap(RootsTable &roots)
static const int kRequiresSlowElementsTagSize
Definition dictionary.h:435
static const int kRequiresSlowElementsMask
Definition dictionary.h:434
static double NumberValue(Tagged< Number > obj)
static constexpr PropertyDetails Empty(PropertyCellType cell_type=PropertyCellType::kNoCell)
static DirectHandle< Map > GetMap(RootsTable &roots)
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
Isolate * isolate
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
SlotTraits::TObjectSlot ObjectSlot
Definition globals.h:1243
bool IsNumber(Tagged< Object > obj)
ReadOnlyRoots GetReadOnlyRoots()
Definition roots-inl.h:86
Tagged(T object) -> Tagged< T >
V8_INLINE bool GetIsolateFromHeapObject(Tagged< HeapObject > object, Isolate **isolate)
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
Definition objects.h:665
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
V8_INLINE PtrComprCageBase GetPtrComprCageBase()
return ComputeSeededHash(static_cast< uint32_t >(key), HashSeed(isolate))
bool IsUniqueName(Tagged< Name > obj)
uint64_t HashSeed(Isolate *isolate)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define BIT_FIELD_ACCESSORS(holder, field, name, BitField)
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485