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_ORDERED_HASH_TABLE_INL_H_
6 #define V8_OBJECTS_ORDERED_HASH_TABLE_INL_H_
7
8 #include "src/objects/ordered-hash-table.h"
9
10 #include "src/heap/heap.h"
11 #include "src/objects/compressed-slots.h"
12 #include "src/objects/fixed-array-inl.h"
13 #include "src/objects/js-collection-iterator.h"
14 #include "src/objects/objects-inl.h"
15 #include "src/objects/slots.h"
16
17 // Has to be the last include (doesn't have include guards):
18 #include "src/objects/object-macros.h"
19
20 namespace v8 {
21 namespace internal {
22
23 CAST_ACCESSOR(OrderedNameDictionary)
CAST_ACCESSOR(SmallOrderedNameDictionary)24 CAST_ACCESSOR(SmallOrderedNameDictionary)
25 CAST_ACCESSOR(OrderedHashMap)
26 CAST_ACCESSOR(OrderedHashSet)
27 CAST_ACCESSOR(SmallOrderedHashMap)
28 CAST_ACCESSOR(SmallOrderedHashSet)
29
30 template <class Derived, int entrysize>
31 OrderedHashTable<Derived, entrysize>::OrderedHashTable(Address ptr)
32 : FixedArray(ptr) {}
33
34 template <class Derived, int entrysize>
IsKey(ReadOnlyRoots roots,Object k)35 bool OrderedHashTable<Derived, entrysize>::IsKey(ReadOnlyRoots roots,
36 Object k) {
37 return k != roots.the_hole_value();
38 }
39
OrderedHashSet(Address ptr)40 OrderedHashSet::OrderedHashSet(Address ptr)
41 : OrderedHashTable<OrderedHashSet, 1>(ptr) {
42 SLOW_DCHECK(IsOrderedHashSet());
43 }
44
OrderedHashMap(Address ptr)45 OrderedHashMap::OrderedHashMap(Address ptr)
46 : OrderedHashTable<OrderedHashMap, 2>(ptr) {
47 SLOW_DCHECK(IsOrderedHashMap());
48 }
49
OrderedNameDictionary(Address ptr)50 OrderedNameDictionary::OrderedNameDictionary(Address ptr)
51 : OrderedHashTable<OrderedNameDictionary, 3>(ptr) {
52 SLOW_DCHECK(IsOrderedNameDictionary());
53 }
54
55 template <class Derived>
SmallOrderedHashTable(Address ptr)56 SmallOrderedHashTable<Derived>::SmallOrderedHashTable(Address ptr)
57 : HeapObject(ptr) {}
58
59 template <class Derived>
KeyAt(InternalIndex entry)60 Object SmallOrderedHashTable<Derived>::KeyAt(InternalIndex entry) const {
61 DCHECK_LT(entry.as_int(), Capacity());
62 Offset entry_offset = GetDataEntryOffset(entry.as_int(), Derived::kKeyIndex);
63 return TaggedField<Object>::load(*this, entry_offset);
64 }
65
66 template <class Derived>
GetDataEntry(int entry,int relative_index)67 Object SmallOrderedHashTable<Derived>::GetDataEntry(int entry,
68 int relative_index) {
69 DCHECK_LT(entry, Capacity());
70 DCHECK_LE(static_cast<unsigned>(relative_index), Derived::kEntrySize);
71 Offset entry_offset = GetDataEntryOffset(entry, relative_index);
72 return TaggedField<Object>::load(*this, entry_offset);
73 }
74
OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet,SmallOrderedHashTable<SmallOrderedHashSet>)75 OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashSet,
76 SmallOrderedHashTable<SmallOrderedHashSet>)
77 OBJECT_CONSTRUCTORS_IMPL(SmallOrderedHashMap,
78 SmallOrderedHashTable<SmallOrderedHashMap>)
79 OBJECT_CONSTRUCTORS_IMPL(SmallOrderedNameDictionary,
80 SmallOrderedHashTable<SmallOrderedNameDictionary>)
81
82 Handle<Map> OrderedHashSet::GetMap(ReadOnlyRoots roots) {
83 return roots.ordered_hash_set_map_handle();
84 }
85
GetMap(ReadOnlyRoots roots)86 Handle<Map> OrderedHashMap::GetMap(ReadOnlyRoots roots) {
87 return roots.ordered_hash_map_map_handle();
88 }
89
GetMap(ReadOnlyRoots roots)90 Handle<Map> OrderedNameDictionary::GetMap(ReadOnlyRoots roots) {
91 return roots.ordered_name_dictionary_map_handle();
92 }
93
GetMap(ReadOnlyRoots roots)94 Handle<Map> SmallOrderedNameDictionary::GetMap(ReadOnlyRoots roots) {
95 return roots.small_ordered_name_dictionary_map_handle();
96 }
97
GetMap(ReadOnlyRoots roots)98 Handle<Map> SmallOrderedHashMap::GetMap(ReadOnlyRoots roots) {
99 return roots.small_ordered_hash_map_map_handle();
100 }
101
GetMap(ReadOnlyRoots roots)102 Handle<Map> SmallOrderedHashSet::GetMap(ReadOnlyRoots roots) {
103 return roots.small_ordered_hash_set_map_handle();
104 }
105
ValueAt(InternalIndex entry)106 inline Object OrderedHashMap::ValueAt(InternalIndex entry) {
107 DCHECK_LT(entry.as_int(), UsedCapacity());
108 return get(EntryToIndex(entry) + kValueOffset);
109 }
110
ValueAt(InternalIndex entry)111 inline Object OrderedNameDictionary::ValueAt(InternalIndex entry) {
112 DCHECK_LT(entry.as_int(), UsedCapacity());
113 return get(EntryToIndex(entry) + kValueOffset);
114 }
115
NameAt(InternalIndex entry)116 Name OrderedNameDictionary::NameAt(InternalIndex entry) {
117 return Name::cast(KeyAt(entry));
118 }
119
120 // Set the value for entry.
ValueAtPut(InternalIndex entry,Object value)121 inline void OrderedNameDictionary::ValueAtPut(InternalIndex entry,
122 Object value) {
123 DCHECK_LT(entry.as_int(), UsedCapacity());
124 this->set(EntryToIndex(entry) + kValueOffset, value);
125 }
126
127 // Returns the property details for the property at entry.
DetailsAt(InternalIndex entry)128 inline PropertyDetails OrderedNameDictionary::DetailsAt(InternalIndex entry) {
129 DCHECK_LT(entry.as_int(), this->UsedCapacity());
130 // TODO(gsathya): Optimize the cast away.
131 return PropertyDetails(
132 Smi::cast(get(EntryToIndex(entry) + kPropertyDetailsOffset)));
133 }
134
DetailsAtPut(InternalIndex entry,PropertyDetails value)135 inline void OrderedNameDictionary::DetailsAtPut(InternalIndex entry,
136 PropertyDetails value) {
137 DCHECK_LT(entry.as_int(), this->UsedCapacity());
138 // TODO(gsathya): Optimize the cast away.
139 this->set(EntryToIndex(entry) + kPropertyDetailsOffset, value.AsSmi());
140 }
141
ValueAt(InternalIndex entry)142 inline Object SmallOrderedNameDictionary::ValueAt(InternalIndex entry) {
143 return this->GetDataEntry(entry.as_int(), kValueIndex);
144 }
145
146 // Set the value for entry.
ValueAtPut(InternalIndex entry,Object value)147 inline void SmallOrderedNameDictionary::ValueAtPut(InternalIndex entry,
148 Object value) {
149 this->SetDataEntry(entry.as_int(), kValueIndex, value);
150 }
151
152 // Returns the property details for the property at entry.
DetailsAt(InternalIndex entry)153 inline PropertyDetails SmallOrderedNameDictionary::DetailsAt(
154 InternalIndex entry) {
155 // TODO(gsathya): Optimize the cast away. And store this in the data table.
156 return PropertyDetails(
157 Smi::cast(this->GetDataEntry(entry.as_int(), kPropertyDetailsIndex)));
158 }
159
160 // Set the details for entry.
DetailsAtPut(InternalIndex entry,PropertyDetails value)161 inline void SmallOrderedNameDictionary::DetailsAtPut(InternalIndex entry,
162 PropertyDetails value) {
163 // TODO(gsathya): Optimize the cast away. And store this in the data table.
164 this->SetDataEntry(entry.as_int(), kPropertyDetailsIndex, value.AsSmi());
165 }
166
Is(Handle<HeapObject> table)167 inline bool OrderedHashSet::Is(Handle<HeapObject> table) {
168 return table->IsOrderedHashSet();
169 }
170
Is(Handle<HeapObject> table)171 inline bool OrderedHashMap::Is(Handle<HeapObject> table) {
172 return table->IsOrderedHashMap();
173 }
174
Is(Handle<HeapObject> table)175 inline bool OrderedNameDictionary::Is(Handle<HeapObject> table) {
176 return table->IsOrderedNameDictionary();
177 }
178
Is(Handle<HeapObject> table)179 inline bool SmallOrderedHashSet::Is(Handle<HeapObject> table) {
180 return table->IsSmallOrderedHashSet();
181 }
182
Is(Handle<HeapObject> table)183 inline bool SmallOrderedNameDictionary::Is(Handle<HeapObject> table) {
184 return table->IsSmallOrderedNameDictionary();
185 }
186
Is(Handle<HeapObject> table)187 inline bool SmallOrderedHashMap::Is(Handle<HeapObject> table) {
188 return table->IsSmallOrderedHashMap();
189 }
190
191 template <class Derived>
SetDataEntry(int entry,int relative_index,Object value)192 void SmallOrderedHashTable<Derived>::SetDataEntry(int entry, int relative_index,
193 Object value) {
194 DCHECK_NE(kNotFound, entry);
195 int entry_offset = GetDataEntryOffset(entry, relative_index);
196 RELAXED_WRITE_FIELD(*this, entry_offset, value);
197 WRITE_BARRIER(*this, entry_offset, value);
198 }
199
200 template <class Derived, class TableType>
CurrentKey()201 Object OrderedHashTableIterator<Derived, TableType>::CurrentKey() {
202 TableType table = TableType::cast(this->table());
203 int index = Smi::ToInt(this->index());
204 DCHECK_LE(0, index);
205 InternalIndex entry(index);
206 Object key = table.KeyAt(entry);
207 DCHECK(!key.IsTheHole());
208 return key;
209 }
210
SetHash(int hash)211 inline void SmallOrderedNameDictionary::SetHash(int hash) {
212 DCHECK(PropertyArray::HashField::is_valid(hash));
213 WriteField<int>(PrefixOffset(), hash);
214 }
215
Hash()216 inline int SmallOrderedNameDictionary::Hash() {
217 int hash = ReadField<int>(PrefixOffset());
218 DCHECK(PropertyArray::HashField::is_valid(hash));
219 return hash;
220 }
221
SetHash(int hash)222 inline void OrderedNameDictionary::SetHash(int hash) {
223 DCHECK(PropertyArray::HashField::is_valid(hash));
224 this->set(PrefixIndex(), Smi::FromInt(hash));
225 }
226
Hash()227 inline int OrderedNameDictionary::Hash() {
228 Object hash_obj = this->get(PrefixIndex());
229 int hash = Smi::ToInt(hash_obj);
230 DCHECK(PropertyArray::HashField::is_valid(hash));
231 return hash;
232 }
233
234 } // namespace internal
235 } // namespace v8
236
237 #include "src/objects/object-macros-undef.h"
238
239 #endif // V8_OBJECTS_ORDERED_HASH_TABLE_INL_H_
240