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