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