11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ 61cb0ef41Sopenharmony_ci#define V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 91cb0ef41Sopenharmony_ci#include "src/handles/maybe-handles-inl.h" 101cb0ef41Sopenharmony_ci#include "src/heap/heap-write-barrier.h" 111cb0ef41Sopenharmony_ci#include "src/heap/heap.h" 121cb0ef41Sopenharmony_ci#include "src/objects/descriptor-array.h" 131cb0ef41Sopenharmony_ci#include "src/objects/field-type.h" 141cb0ef41Sopenharmony_ci#include "src/objects/heap-object-inl.h" 151cb0ef41Sopenharmony_ci#include "src/objects/lookup-cache-inl.h" 161cb0ef41Sopenharmony_ci#include "src/objects/maybe-object-inl.h" 171cb0ef41Sopenharmony_ci#include "src/objects/property.h" 181cb0ef41Sopenharmony_ci#include "src/objects/struct-inl.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci// Has to be the last include (doesn't have include guards): 211cb0ef41Sopenharmony_ci#include "src/objects/object-macros.h" 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_cinamespace v8 { 241cb0ef41Sopenharmony_cinamespace internal { 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci#include "torque-generated/src/objects/descriptor-array-tq-inl.inc" 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(DescriptorArray) 291cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache) 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciRELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors, 321cb0ef41Sopenharmony_ci kNumberOfAllDescriptorsOffset) 331cb0ef41Sopenharmony_ciRELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors, 341cb0ef41Sopenharmony_ci kNumberOfDescriptorsOffset) 351cb0ef41Sopenharmony_ciRELAXED_INT16_ACCESSORS(DescriptorArray, raw_number_of_marked_descriptors, 361cb0ef41Sopenharmony_ci kRawNumberOfMarkedDescriptorsOffset) 371cb0ef41Sopenharmony_ciRELAXED_INT16_ACCESSORS(DescriptorArray, filler16bits, kFiller16BitsOffset) 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ciinline int16_t DescriptorArray::number_of_slack_descriptors() const { 401cb0ef41Sopenharmony_ci return number_of_all_descriptors() - number_of_descriptors(); 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciinline int DescriptorArray::number_of_entries() const { 441cb0ef41Sopenharmony_ci return number_of_descriptors(); 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciinline int16_t DescriptorArray::CompareAndSwapRawNumberOfMarkedDescriptors( 481cb0ef41Sopenharmony_ci int16_t expected, int16_t value) { 491cb0ef41Sopenharmony_ci return base::Relaxed_CompareAndSwap( 501cb0ef41Sopenharmony_ci reinterpret_cast<base::Atomic16*>( 511cb0ef41Sopenharmony_ci FIELD_ADDR(*this, kRawNumberOfMarkedDescriptorsOffset)), 521cb0ef41Sopenharmony_ci expected, value); 531cb0ef41Sopenharmony_ci} 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_civoid DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) { 561cb0ef41Sopenharmony_ci set_enum_cache(array.enum_cache()); 571cb0ef41Sopenharmony_ci} 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_ciInternalIndex DescriptorArray::Search(Name name, int valid_descriptors, 601cb0ef41Sopenharmony_ci bool concurrent_search) { 611cb0ef41Sopenharmony_ci DCHECK(name.IsUniqueName()); 621cb0ef41Sopenharmony_ci return InternalIndex(internal::Search<VALID_ENTRIES>( 631cb0ef41Sopenharmony_ci this, name, valid_descriptors, nullptr, concurrent_search)); 641cb0ef41Sopenharmony_ci} 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ciInternalIndex DescriptorArray::Search(Name name, Map map, 671cb0ef41Sopenharmony_ci bool concurrent_search) { 681cb0ef41Sopenharmony_ci DCHECK(name.IsUniqueName()); 691cb0ef41Sopenharmony_ci int number_of_own_descriptors = map.NumberOfOwnDescriptors(); 701cb0ef41Sopenharmony_ci if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); 711cb0ef41Sopenharmony_ci return Search(name, number_of_own_descriptors, concurrent_search); 721cb0ef41Sopenharmony_ci} 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ciInternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name, 751cb0ef41Sopenharmony_ci Map map) { 761cb0ef41Sopenharmony_ci DCHECK(name.IsUniqueName()); 771cb0ef41Sopenharmony_ci int number_of_own_descriptors = map.NumberOfOwnDescriptors(); 781cb0ef41Sopenharmony_ci if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci DescriptorLookupCache* cache = isolate->descriptor_lookup_cache(); 811cb0ef41Sopenharmony_ci int number = cache->Lookup(map, name); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci if (number == DescriptorLookupCache::kAbsent) { 841cb0ef41Sopenharmony_ci InternalIndex result = Search(name, number_of_own_descriptors); 851cb0ef41Sopenharmony_ci number = result.is_found() ? result.as_int() : DescriptorArray::kNotFound; 861cb0ef41Sopenharmony_ci cache->Update(map, name, number); 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci if (number == DescriptorArray::kNotFound) return InternalIndex::NotFound(); 891cb0ef41Sopenharmony_ci return InternalIndex(number); 901cb0ef41Sopenharmony_ci} 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ciObjectSlot DescriptorArray::GetFirstPointerSlot() { 931cb0ef41Sopenharmony_ci static_assert(kEndOfStrongFieldsOffset == kStartOfWeakFieldsOffset, 941cb0ef41Sopenharmony_ci "Weak and strong fields are continuous."); 951cb0ef41Sopenharmony_ci static_assert(kEndOfWeakFieldsOffset == kHeaderSize, 961cb0ef41Sopenharmony_ci "Weak fields extend up to the end of the header."); 971cb0ef41Sopenharmony_ci return RawField(DescriptorArray::kStartOfStrongFieldsOffset); 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ciObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) { 1011cb0ef41Sopenharmony_ci // Allow descriptor == number_of_all_descriptors() for computing the slot 1021cb0ef41Sopenharmony_ci // address that comes after the last descriptor (for iterating). 1031cb0ef41Sopenharmony_ci DCHECK_LE(descriptor, number_of_all_descriptors()); 1041cb0ef41Sopenharmony_ci return RawField(OffsetOfDescriptorAt(descriptor)); 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciName DescriptorArray::GetKey(InternalIndex descriptor_number) const { 1081cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 1091cb0ef41Sopenharmony_ci return GetKey(cage_base, descriptor_number); 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ciName DescriptorArray::GetKey(PtrComprCageBase cage_base, 1131cb0ef41Sopenharmony_ci InternalIndex descriptor_number) const { 1141cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1151cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1161cb0ef41Sopenharmony_ci return Name::cast( 1171cb0ef41Sopenharmony_ci EntryKeyField::Relaxed_Load(cage_base, *this, entry_offset)); 1181cb0ef41Sopenharmony_ci} 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_civoid DescriptorArray::SetKey(InternalIndex descriptor_number, Name key) { 1211cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1221cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1231cb0ef41Sopenharmony_ci EntryKeyField::Relaxed_Store(*this, entry_offset, key); 1241cb0ef41Sopenharmony_ci WRITE_BARRIER(*this, entry_offset + kEntryKeyOffset, key); 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciint DescriptorArray::GetSortedKeyIndex(int descriptor_number) { 1281cb0ef41Sopenharmony_ci return GetDetails(InternalIndex(descriptor_number)).pointer(); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciName DescriptorArray::GetSortedKey(int descriptor_number) { 1321cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 1331cb0ef41Sopenharmony_ci return GetSortedKey(cage_base, descriptor_number); 1341cb0ef41Sopenharmony_ci} 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ciName DescriptorArray::GetSortedKey(PtrComprCageBase cage_base, 1371cb0ef41Sopenharmony_ci int descriptor_number) { 1381cb0ef41Sopenharmony_ci return GetKey(cage_base, InternalIndex(GetSortedKeyIndex(descriptor_number))); 1391cb0ef41Sopenharmony_ci} 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_civoid DescriptorArray::SetSortedKey(int descriptor_number, int pointer) { 1421cb0ef41Sopenharmony_ci PropertyDetails details = GetDetails(InternalIndex(descriptor_number)); 1431cb0ef41Sopenharmony_ci SetDetails(InternalIndex(descriptor_number), details.set_pointer(pointer)); 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ciObject DescriptorArray::GetStrongValue(InternalIndex descriptor_number) { 1471cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 1481cb0ef41Sopenharmony_ci return GetStrongValue(cage_base, descriptor_number); 1491cb0ef41Sopenharmony_ci} 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ciObject DescriptorArray::GetStrongValue(PtrComprCageBase cage_base, 1521cb0ef41Sopenharmony_ci InternalIndex descriptor_number) { 1531cb0ef41Sopenharmony_ci return GetValue(cage_base, descriptor_number).cast<Object>(); 1541cb0ef41Sopenharmony_ci} 1551cb0ef41Sopenharmony_ci 1561cb0ef41Sopenharmony_civoid DescriptorArray::SetValue(InternalIndex descriptor_number, 1571cb0ef41Sopenharmony_ci MaybeObject value) { 1581cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1591cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1601cb0ef41Sopenharmony_ci EntryValueField::Relaxed_Store(*this, entry_offset, value); 1611cb0ef41Sopenharmony_ci WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value); 1621cb0ef41Sopenharmony_ci} 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ciMaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) { 1651cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 1661cb0ef41Sopenharmony_ci return GetValue(cage_base, descriptor_number); 1671cb0ef41Sopenharmony_ci} 1681cb0ef41Sopenharmony_ci 1691cb0ef41Sopenharmony_ciMaybeObject DescriptorArray::GetValue(PtrComprCageBase cage_base, 1701cb0ef41Sopenharmony_ci InternalIndex descriptor_number) { 1711cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1721cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1731cb0ef41Sopenharmony_ci return EntryValueField::Relaxed_Load(cage_base, *this, entry_offset); 1741cb0ef41Sopenharmony_ci} 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ciPropertyDetails DescriptorArray::GetDetails(InternalIndex descriptor_number) { 1771cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1781cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1791cb0ef41Sopenharmony_ci Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset); 1801cb0ef41Sopenharmony_ci return PropertyDetails(details); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_civoid DescriptorArray::SetDetails(InternalIndex descriptor_number, 1841cb0ef41Sopenharmony_ci PropertyDetails details) { 1851cb0ef41Sopenharmony_ci DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); 1861cb0ef41Sopenharmony_ci int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); 1871cb0ef41Sopenharmony_ci EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi()); 1881cb0ef41Sopenharmony_ci} 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ciint DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) { 1911cb0ef41Sopenharmony_ci DCHECK_EQ(GetDetails(descriptor_number).location(), PropertyLocation::kField); 1921cb0ef41Sopenharmony_ci return GetDetails(descriptor_number).field_index(); 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ciFieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) { 1961cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = GetPtrComprCageBase(*this); 1971cb0ef41Sopenharmony_ci return GetFieldType(cage_base, descriptor_number); 1981cb0ef41Sopenharmony_ci} 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ciFieldType DescriptorArray::GetFieldType(PtrComprCageBase cage_base, 2011cb0ef41Sopenharmony_ci InternalIndex descriptor_number) { 2021cb0ef41Sopenharmony_ci DCHECK_EQ(GetDetails(descriptor_number).location(), PropertyLocation::kField); 2031cb0ef41Sopenharmony_ci MaybeObject wrapped_type = GetValue(cage_base, descriptor_number); 2041cb0ef41Sopenharmony_ci return Map::UnwrapFieldType(wrapped_type); 2051cb0ef41Sopenharmony_ci} 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_civoid DescriptorArray::Set(InternalIndex descriptor_number, Name key, 2081cb0ef41Sopenharmony_ci MaybeObject value, PropertyDetails details) { 2091cb0ef41Sopenharmony_ci SetKey(descriptor_number, key); 2101cb0ef41Sopenharmony_ci SetDetails(descriptor_number, details); 2111cb0ef41Sopenharmony_ci SetValue(descriptor_number, value); 2121cb0ef41Sopenharmony_ci} 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_civoid DescriptorArray::Set(InternalIndex descriptor_number, Descriptor* desc) { 2151cb0ef41Sopenharmony_ci Name key = *desc->GetKey(); 2161cb0ef41Sopenharmony_ci MaybeObject value = *desc->GetValue(); 2171cb0ef41Sopenharmony_ci Set(descriptor_number, key, value, desc->GetDetails()); 2181cb0ef41Sopenharmony_ci} 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_civoid DescriptorArray::Append(Descriptor* desc) { 2211cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 2221cb0ef41Sopenharmony_ci int descriptor_number = number_of_descriptors(); 2231cb0ef41Sopenharmony_ci DCHECK_LE(descriptor_number + 1, number_of_all_descriptors()); 2241cb0ef41Sopenharmony_ci set_number_of_descriptors(descriptor_number + 1); 2251cb0ef41Sopenharmony_ci Set(InternalIndex(descriptor_number), desc); 2261cb0ef41Sopenharmony_ci 2271cb0ef41Sopenharmony_ci uint32_t hash = desc->GetKey()->hash(); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci int insertion; 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci for (insertion = descriptor_number; insertion > 0; --insertion) { 2321cb0ef41Sopenharmony_ci Name key = GetSortedKey(insertion - 1); 2331cb0ef41Sopenharmony_ci if (key.hash() <= hash) break; 2341cb0ef41Sopenharmony_ci SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1)); 2351cb0ef41Sopenharmony_ci } 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci SetSortedKey(insertion, descriptor_number); 2381cb0ef41Sopenharmony_ci} 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_civoid DescriptorArray::SwapSortedKeys(int first, int second) { 2411cb0ef41Sopenharmony_ci int first_key = GetSortedKeyIndex(first); 2421cb0ef41Sopenharmony_ci SetSortedKey(first, GetSortedKeyIndex(second)); 2431cb0ef41Sopenharmony_ci SetSortedKey(second, first_key); 2441cb0ef41Sopenharmony_ci} 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci} // namespace internal 2471cb0ef41Sopenharmony_ci} // namespace v8 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h" 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci#endif // V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ 252