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_DESCRIPTOR_ARRAY_INL_H_ 6#define V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ 7 8#include "src/execution/isolate.h" 9#include "src/handles/maybe-handles-inl.h" 10#include "src/heap/heap-write-barrier.h" 11#include "src/heap/heap.h" 12#include "src/objects/descriptor-array.h" 13#include "src/objects/field-type.h" 14#include "src/objects/heap-object-inl.h" 15#include "src/objects/lookup-cache-inl.h" 16#include "src/objects/maybe-object-inl.h" 17#include "src/objects/property.h" 18#include "src/objects/struct-inl.h" 19 20// Has to be the last include (doesn't have include guards): 21#include "src/objects/object-macros.h" 22 23namespace v8 { 24namespace internal { 25 26#include "torque-generated/src/objects/descriptor-array-tq-inl.inc" 27 28TQ_OBJECT_CONSTRUCTORS_IMPL(DescriptorArray) 29TQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache) 30 31RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors, 32 kNumberOfAllDescriptorsOffset) 33RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors, 34 kNumberOfDescriptorsOffset) 35RELAXED_INT16_ACCESSORS(DescriptorArray, raw_number_of_marked_descriptors, 36 kRawNumberOfMarkedDescriptorsOffset) 37RELAXED_INT16_ACCESSORS(DescriptorArray, filler16bits, kFiller16BitsOffset) 38 39inline int16_t DescriptorArray::number_of_slack_descriptors() const { 40 return number_of_all_descriptors() - number_of_descriptors(); 41} 42 43inline int DescriptorArray::number_of_entries() const { 44 return number_of_descriptors(); 45} 46 47inline int16_t DescriptorArray::CompareAndSwapRawNumberOfMarkedDescriptors( 48 int16_t expected, int16_t value) { 49 return base::Relaxed_CompareAndSwap( 50 reinterpret_cast<base::Atomic16*>( 51 FIELD_ADDR(*this, kRawNumberOfMarkedDescriptorsOffset)), 52 expected, value); 53} 54 55void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) { 56 set_enum_cache(array.enum_cache()); 57} 58 59InternalIndex DescriptorArray::Search(Name name, int valid_descriptors, 60 bool concurrent_search) { 61 DCHECK(name.IsUniqueName()); 62 return InternalIndex(internal::Search<VALID_ENTRIES>( 63 this, name, valid_descriptors, nullptr, concurrent_search)); 64} 65 66InternalIndex DescriptorArray::Search(Name name, Map map, 67 bool concurrent_search) { 68 DCHECK(name.IsUniqueName()); 69 int number_of_own_descriptors = map.NumberOfOwnDescriptors(); 70 if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); 71 return Search(name, number_of_own_descriptors, concurrent_search); 72} 73 74InternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name, 75 Map map) { 76 DCHECK(name.IsUniqueName()); 77 int number_of_own_descriptors = map.NumberOfOwnDescriptors(); 78 if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); 79 80 DescriptorLookupCache* cache = isolate->descriptor_lookup_cache(); 81 int number = cache->Lookup(map, name); 82 83 if (number == DescriptorLookupCache::kAbsent) { 84 InternalIndex result = Search(name, number_of_own_descriptors); 85 number = result.is_found() ? result.as_int() : DescriptorArray::kNotFound; 86 cache->Update(map, name, number); 87 } 88 if (number == DescriptorArray::kNotFound) return InternalIndex::NotFound(); 89 return InternalIndex(number); 90} 91 92ObjectSlot DescriptorArray::GetFirstPointerSlot() { 93 static_assert(kEndOfStrongFieldsOffset == kStartOfWeakFieldsOffset, 94 "Weak and strong fields are continuous."); 95 static_assert(kEndOfWeakFieldsOffset == kHeaderSize, 96 "Weak fields extend up to the end of the header."); 97 return RawField(DescriptorArray::kStartOfStrongFieldsOffset); 98} 99 100ObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) { 101 // Allow descriptor == number_of_all_descriptors() for computing the slot 102 // address that comes after the last descriptor (for iterating). 103 DCHECK_LE(descriptor, number_of_all_descriptors()); 104 return RawField(OffsetOfDescriptorAt(descriptor)); 105} 106 107Name DescriptorArray::GetKey(InternalIndex descriptor_number) const { 108 PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 109 return GetKey(cage_base, descriptor_number); 110} 111 112Name DescriptorArray::GetKey(PtrComprCageBase cage_base, 113 InternalIndex descriptor_number) const { 114 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 115 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 116 return Name::cast( 117 EntryKeyField::Relaxed_Load(cage_base, *this, entry_offset)); 118} 119 120void DescriptorArray::SetKey(InternalIndex descriptor_number, Name key) { 121 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 122 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 123 EntryKeyField::Relaxed_Store(*this, entry_offset, key); 124 WRITE_BARRIER(*this, entry_offset + kEntryKeyOffset, key); 125} 126 127int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { 128 return GetDetails(InternalIndex(descriptor_number)).pointer(); 129} 130 131Name DescriptorArray::GetSortedKey(int descriptor_number) { 132 PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 133 return GetSortedKey(cage_base, descriptor_number); 134} 135 136Name DescriptorArray::GetSortedKey(PtrComprCageBase cage_base, 137 int descriptor_number) { 138 return GetKey(cage_base, InternalIndex(GetSortedKeyIndex(descriptor_number))); 139} 140 141void DescriptorArray::SetSortedKey(int descriptor_number, int pointer) { 142 PropertyDetails details = GetDetails(InternalIndex(descriptor_number)); 143 SetDetails(InternalIndex(descriptor_number), details.set_pointer(pointer)); 144} 145 146Object DescriptorArray::GetStrongValue(InternalIndex descriptor_number) { 147 PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 148 return GetStrongValue(cage_base, descriptor_number); 149} 150 151Object DescriptorArray::GetStrongValue(PtrComprCageBase cage_base, 152 InternalIndex descriptor_number) { 153 return GetValue(cage_base, descriptor_number).cast<Object>(); 154} 155 156void DescriptorArray::SetValue(InternalIndex descriptor_number, 157 MaybeObject value) { 158 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 159 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 160 EntryValueField::Relaxed_Store(*this, entry_offset, value); 161 WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value); 162} 163 164MaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) { 165 PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 166 return GetValue(cage_base, descriptor_number); 167} 168 169MaybeObject DescriptorArray::GetValue(PtrComprCageBase cage_base, 170 InternalIndex descriptor_number) { 171 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 172 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 173 return EntryValueField::Relaxed_Load(cage_base, *this, entry_offset); 174} 175 176PropertyDetails DescriptorArray::GetDetails(InternalIndex descriptor_number) { 177 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 178 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 179 Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset); 180 return PropertyDetails(details); 181} 182 183void DescriptorArray::SetDetails(InternalIndex descriptor_number, 184 PropertyDetails details) { 185 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 186 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 187 EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi()); 188} 189 190int DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) { 191 DCHECK_EQ(GetDetails(descriptor_number).location(), PropertyLocation::kField); 192 return GetDetails(descriptor_number).field_index(); 193} 194 195FieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) { 196 PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 197 return GetFieldType(cage_base, descriptor_number); 198} 199 200FieldType DescriptorArray::GetFieldType(PtrComprCageBase cage_base, 201 InternalIndex descriptor_number) { 202 DCHECK_EQ(GetDetails(descriptor_number).location(), PropertyLocation::kField); 203 MaybeObject wrapped_type = GetValue(cage_base, descriptor_number); 204 return Map::UnwrapFieldType(wrapped_type); 205} 206 207void DescriptorArray::Set(InternalIndex descriptor_number, Name key, 208 MaybeObject value, PropertyDetails details) { 209 SetKey(descriptor_number, key); 210 SetDetails(descriptor_number, details); 211 SetValue(descriptor_number, value); 212} 213 214void DescriptorArray::Set(InternalIndex descriptor_number, Descriptor* desc) { 215 Name key = *desc->GetKey(); 216 MaybeObject value = *desc->GetValue(); 217 Set(descriptor_number, key, value, desc->GetDetails()); 218} 219 220void DescriptorArray::Append(Descriptor* desc) { 221 DisallowGarbageCollection no_gc; 222 int descriptor_number = number_of_descriptors(); 223 DCHECK_LE(descriptor_number + 1, number_of_all_descriptors()); 224 set_number_of_descriptors(descriptor_number + 1); 225 Set(InternalIndex(descriptor_number), desc); 226 227 uint32_t hash = desc->GetKey()->hash(); 228 229 int insertion; 230 231 for (insertion = descriptor_number; insertion > 0; --insertion) { 232 Name key = GetSortedKey(insertion - 1); 233 if (key.hash() <= hash) break; 234 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); 235 } 236 237 SetSortedKey(insertion, descriptor_number); 238} 239 240void DescriptorArray::SwapSortedKeys(int first, int second) { 241 int first_key = GetSortedKeyIndex(first); 242 SetSortedKey(first, GetSortedKeyIndex(second)); 243 SetSortedKey(second, first_key); 244} 245 246} // namespace internal 247} // namespace v8 248 249#include "src/objects/object-macros-undef.h" 250 251#endif // V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ 252