Line data Source code
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 :
8 : #include "src/objects/dictionary.h"
9 :
10 : #include "src/hash-seed-inl.h"
11 : #include "src/objects/hash-table-inl.h"
12 : #include "src/objects/oddball.h"
13 : #include "src/objects/property-cell-inl.h"
14 :
15 : // Has to be the last include (doesn't have include guards):
16 : #include "src/objects/object-macros.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 269058047 : CAST_ACCESSOR(GlobalDictionary)
22 112946363 : CAST_ACCESSOR(NameDictionary)
23 : CAST_ACCESSOR(NumberDictionary)
24 : CAST_ACCESSOR(SimpleNumberDictionary)
25 :
26 : template <typename Derived, typename Shape>
27 0 : Dictionary<Derived, Shape>::Dictionary(Address ptr)
28 0 : : HashTable<Derived, Shape>(ptr) {}
29 :
30 : template <typename Derived, typename Shape>
31 : BaseNameDictionary<Derived, Shape>::BaseNameDictionary(Address ptr)
32 : : Dictionary<Derived, Shape>(ptr) {}
33 :
34 269057960 : GlobalDictionary::GlobalDictionary(Address ptr)
35 : : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>(ptr) {
36 : SLOW_DCHECK(IsGlobalDictionary());
37 269057960 : }
38 :
39 112946363 : NameDictionary::NameDictionary(Address ptr)
40 : : BaseNameDictionary<NameDictionary, NameDictionaryShape>(ptr) {
41 : SLOW_DCHECK(IsNameDictionary());
42 112946363 : }
43 :
44 : NumberDictionary::NumberDictionary(Address ptr)
45 : : Dictionary<NumberDictionary, NumberDictionaryShape>(ptr) {
46 : SLOW_DCHECK(IsNumberDictionary());
47 : }
48 :
49 : SimpleNumberDictionary::SimpleNumberDictionary(Address ptr)
50 : : Dictionary<SimpleNumberDictionary, SimpleNumberDictionaryShape>(ptr) {
51 : SLOW_DCHECK(IsSimpleNumberDictionary());
52 : }
53 :
54 2445672 : bool NumberDictionary::requires_slow_elements() {
55 : Object max_index_object = get(kMaxNumberKeyIndex);
56 2445672 : if (!max_index_object->IsSmi()) return false;
57 2057951 : return 0 != (Smi::ToInt(max_index_object) & kRequiresSlowElementsMask);
58 : }
59 :
60 1327874 : uint32_t NumberDictionary::max_number_key() {
61 : DCHECK(!requires_slow_elements());
62 : Object max_index_object = get(kMaxNumberKeyIndex);
63 1327874 : if (!max_index_object->IsSmi()) return 0;
64 1326730 : uint32_t value = static_cast<uint32_t>(Smi::ToInt(max_index_object));
65 1326730 : return value >> kRequiresSlowElementsTagSize;
66 : }
67 :
68 56 : void NumberDictionary::set_requires_slow_elements() {
69 56 : set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
70 56 : }
71 :
72 : template <typename Derived, typename Shape>
73 47412 : void Dictionary<Derived, Shape>::ClearEntry(Isolate* isolate, int entry) {
74 47412 : Object the_hole = this->GetReadOnlyRoots().the_hole_value();
75 47412 : PropertyDetails details = PropertyDetails::Empty();
76 47412 : Derived::cast(*this)->SetEntry(isolate, entry, the_hole, the_hole, details);
77 47412 : }
78 :
79 : template <typename Derived, typename Shape>
80 8599379 : void Dictionary<Derived, Shape>::SetEntry(Isolate* isolate, int entry,
81 : Object key, Object value,
82 : PropertyDetails details) {
83 : DCHECK(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3);
84 : DCHECK(!key->IsName() || details.dictionary_index() > 0);
85 : int index = DerivedHashTable::EntryToIndex(entry);
86 : DisallowHeapAllocation no_gc;
87 : WriteBarrierMode mode = this->GetWriteBarrierMode(no_gc);
88 8599379 : this->set(index + Derived::kEntryKeyIndex, key, mode);
89 8599379 : this->set(index + Derived::kEntryValueIndex, value, mode);
90 4521625 : if (Shape::kHasDetails) DetailsAtPut(isolate, entry, details);
91 8599379 : }
92 :
93 : Object GlobalDictionaryShape::Unwrap(Object object) {
94 : return PropertyCell::cast(object)->name();
95 : }
96 :
97 : RootIndex GlobalDictionaryShape::GetMapRootIndex() {
98 : return RootIndex::kGlobalDictionaryMap;
99 : }
100 :
101 4098804 : Name NameDictionary::NameAt(int entry) { return Name::cast(KeyAt(entry)); }
102 :
103 : RootIndex NameDictionaryShape::GetMapRootIndex() {
104 : return RootIndex::kNameDictionaryMap;
105 : }
106 :
107 : PropertyCell GlobalDictionary::CellAt(int entry) {
108 : DCHECK(KeyAt(entry)->IsPropertyCell());
109 : return PropertyCell::cast(KeyAt(entry));
110 : }
111 :
112 : bool GlobalDictionaryShape::IsLive(ReadOnlyRoots roots, Object k) {
113 : DCHECK_NE(roots.the_hole_value(), k);
114 : return k != roots.undefined_value();
115 : }
116 :
117 : bool GlobalDictionaryShape::IsKey(ReadOnlyRoots roots, Object k) {
118 62135099 : return IsLive(roots, k) && !PropertyCell::cast(k)->value()->IsTheHole(roots);
119 : }
120 :
121 15301216 : Name GlobalDictionary::NameAt(int entry) { return CellAt(entry)->name(); }
122 14390812 : Object GlobalDictionary::ValueAt(int entry) { return CellAt(entry)->value(); }
123 :
124 : void GlobalDictionary::SetEntry(Isolate* isolate, int entry, Object key,
125 : Object value, PropertyDetails details) {
126 : DCHECK_EQ(key, PropertyCell::cast(value)->name());
127 8220066 : set(EntryToIndex(entry) + kEntryKeyIndex, value);
128 8220067 : DetailsAtPut(isolate, entry, details);
129 : }
130 :
131 : void GlobalDictionary::ValueAtPut(int entry, Object value) {
132 20008 : set(EntryToIndex(entry), value);
133 : }
134 :
135 : bool NumberDictionaryBaseShape::IsMatch(uint32_t key, Object other) {
136 : DCHECK(other->IsNumber());
137 56860571 : return key == static_cast<uint32_t>(other->Number());
138 : }
139 :
140 : uint32_t NumberDictionaryBaseShape::Hash(Isolate* isolate, uint32_t key) {
141 : return ComputeSeededHash(key, HashSeed(isolate));
142 : }
143 :
144 1786117 : uint32_t NumberDictionaryBaseShape::HashForObject(ReadOnlyRoots roots,
145 : Object other) {
146 : DCHECK(other->IsNumber());
147 1786117 : return ComputeSeededHash(static_cast<uint32_t>(other->Number()),
148 1786117 : HashSeed(roots));
149 : }
150 :
151 : Handle<Object> NumberDictionaryBaseShape::AsHandle(Isolate* isolate,
152 : uint32_t key) {
153 3841419 : return isolate->factory()->NewNumberFromUint(key);
154 : }
155 :
156 : RootIndex NumberDictionaryShape::GetMapRootIndex() {
157 : return RootIndex::kNumberDictionaryMap;
158 : }
159 :
160 : RootIndex SimpleNumberDictionaryShape::GetMapRootIndex() {
161 : return RootIndex::kSimpleNumberDictionaryMap;
162 : }
163 :
164 : bool NameDictionaryShape::IsMatch(Handle<Name> key, Object other) {
165 : DCHECK(other->IsTheHole() || Name::cast(other)->IsUniqueName());
166 : DCHECK(key->IsUniqueName());
167 : return *key == other;
168 : }
169 :
170 : uint32_t NameDictionaryShape::Hash(Isolate* isolate, Handle<Name> key) {
171 59120068 : return key->Hash();
172 : }
173 :
174 : uint32_t NameDictionaryShape::HashForObject(ReadOnlyRoots roots, Object other) {
175 4788530 : return Name::cast(other)->Hash();
176 : }
177 :
178 : bool GlobalDictionaryShape::IsMatch(Handle<Name> key, Object other) {
179 : DCHECK(PropertyCell::cast(other)->name()->IsUniqueName());
180 : return *key == PropertyCell::cast(other)->name();
181 : }
182 :
183 35485398 : uint32_t GlobalDictionaryShape::HashForObject(ReadOnlyRoots roots,
184 : Object other) {
185 35485398 : return PropertyCell::cast(other)->name()->Hash();
186 : }
187 :
188 : Handle<Object> NameDictionaryShape::AsHandle(Isolate* isolate,
189 : Handle<Name> key) {
190 : DCHECK(key->IsUniqueName());
191 : return key;
192 : }
193 :
194 : template <typename Dictionary>
195 173731926 : PropertyDetails GlobalDictionaryShape::DetailsAt(Dictionary dict, int entry) {
196 : DCHECK_LE(0, entry); // Not found is -1, which is not caught by get().
197 173746703 : return dict->CellAt(entry)->property_details();
198 : }
199 :
200 : template <typename Dictionary>
201 8229347 : void GlobalDictionaryShape::DetailsAtPut(Isolate* isolate, Dictionary dict,
202 : int entry, PropertyDetails value) {
203 : DCHECK_LE(0, entry); // Not found is -1, which is not caught by get().
204 8229347 : PropertyCell cell = dict->CellAt(entry);
205 8229347 : if (cell->property_details().IsReadOnly() != value.IsReadOnly()) {
206 8029 : cell->dependent_code()->DeoptimizeDependentCodeGroup(
207 : isolate, DependentCode::kPropertyCellChangedGroup);
208 : }
209 : cell->set_property_details(value);
210 8229345 : }
211 :
212 : } // namespace internal
213 : } // namespace v8
214 :
215 : #include "src/objects/object-macros-undef.h"
216 :
217 : #endif // V8_OBJECTS_DICTIONARY_INL_H_
|