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