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