• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 namespace v8 {
24 namespace internal {
25 
26 #include "torque-generated/src/objects/descriptor-array-tq-inl.inc"
27 
28 TQ_OBJECT_CONSTRUCTORS_IMPL(DescriptorArray)
TQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache)29 TQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache)
30 
31 RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
32                         kNumberOfAllDescriptorsOffset)
33 RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors,
34                         kNumberOfDescriptorsOffset)
35 RELAXED_INT16_ACCESSORS(DescriptorArray, raw_number_of_marked_descriptors,
36                         kRawNumberOfMarkedDescriptorsOffset)
37 RELAXED_INT16_ACCESSORS(DescriptorArray, filler16bits, kFiller16BitsOffset)
38 
39 inline int16_t DescriptorArray::number_of_slack_descriptors() const {
40   return number_of_all_descriptors() - number_of_descriptors();
41 }
42 
number_of_entries()43 inline int DescriptorArray::number_of_entries() const {
44   return number_of_descriptors();
45 }
46 
CompareAndSwapRawNumberOfMarkedDescriptors(int16_t expected,int16_t value)47 inline 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 
CopyEnumCacheFrom(DescriptorArray array)55 void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) {
56   set_enum_cache(array.enum_cache());
57 }
58 
Search(Name name,int valid_descriptors,bool concurrent_search)59 InternalIndex 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 
Search(Name name,Map map,bool concurrent_search)66 InternalIndex 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 
SearchWithCache(Isolate * isolate,Name name,Map map)74 InternalIndex 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 
GetFirstPointerSlot()92 ObjectSlot 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 
GetDescriptorSlot(int descriptor)100 ObjectSlot 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 
GetKey(InternalIndex descriptor_number)107 Name DescriptorArray::GetKey(InternalIndex descriptor_number) const {
108   PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
109   return GetKey(cage_base, descriptor_number);
110 }
111 
GetKey(PtrComprCageBase cage_base,InternalIndex descriptor_number)112 Name 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 
SetKey(InternalIndex descriptor_number,Name key)120 void 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 
GetSortedKeyIndex(int descriptor_number)127 int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
128   return GetDetails(InternalIndex(descriptor_number)).pointer();
129 }
130 
GetSortedKey(int descriptor_number)131 Name DescriptorArray::GetSortedKey(int descriptor_number) {
132   PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
133   return GetSortedKey(cage_base, descriptor_number);
134 }
135 
GetSortedKey(PtrComprCageBase cage_base,int descriptor_number)136 Name DescriptorArray::GetSortedKey(PtrComprCageBase cage_base,
137                                    int descriptor_number) {
138   return GetKey(cage_base, InternalIndex(GetSortedKeyIndex(descriptor_number)));
139 }
140 
SetSortedKey(int descriptor_number,int pointer)141 void 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 
GetStrongValue(InternalIndex descriptor_number)146 Object DescriptorArray::GetStrongValue(InternalIndex descriptor_number) {
147   PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
148   return GetStrongValue(cage_base, descriptor_number);
149 }
150 
GetStrongValue(PtrComprCageBase cage_base,InternalIndex descriptor_number)151 Object DescriptorArray::GetStrongValue(PtrComprCageBase cage_base,
152                                        InternalIndex descriptor_number) {
153   return GetValue(cage_base, descriptor_number).cast<Object>();
154 }
155 
SetValue(InternalIndex descriptor_number,MaybeObject value)156 void 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 
GetValue(InternalIndex descriptor_number)164 MaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) {
165   PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
166   return GetValue(cage_base, descriptor_number);
167 }
168 
GetValue(PtrComprCageBase cage_base,InternalIndex descriptor_number)169 MaybeObject 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 
GetDetails(InternalIndex descriptor_number)176 PropertyDetails 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 
SetDetails(InternalIndex descriptor_number,PropertyDetails details)183 void 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 
GetFieldIndex(InternalIndex descriptor_number)190 int DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) {
191   DCHECK_EQ(GetDetails(descriptor_number).location(), PropertyLocation::kField);
192   return GetDetails(descriptor_number).field_index();
193 }
194 
GetFieldType(InternalIndex descriptor_number)195 FieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) {
196   PtrComprCageBase cage_base = GetPtrComprCageBase(*this);
197   return GetFieldType(cage_base, descriptor_number);
198 }
199 
GetFieldType(PtrComprCageBase cage_base,InternalIndex descriptor_number)200 FieldType 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 
Set(InternalIndex descriptor_number,Name key,MaybeObject value,PropertyDetails details)207 void 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 
Set(InternalIndex descriptor_number,Descriptor * desc)214 void 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 
Append(Descriptor * desc)220 void 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 
SwapSortedKeys(int first,int second)240 void 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