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 IsolateRoot isolate = GetIsolateForPtrCompr(*this);
110 return GetKey(isolate, descriptor_number);
111 }
112
GetKey(IsolateRoot isolate,InternalIndex descriptor_number)113 Name DescriptorArray::GetKey(IsolateRoot isolate,
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(EntryKeyField::Relaxed_Load(isolate, *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 IsolateRoot isolate = GetIsolateForPtrCompr(*this);
133 return GetSortedKey(isolate, descriptor_number);
134 }
135
GetSortedKey(IsolateRoot isolate,int descriptor_number)136 Name DescriptorArray::GetSortedKey(IsolateRoot isolate, int descriptor_number) {
137 return GetKey(isolate, InternalIndex(GetSortedKeyIndex(descriptor_number)));
138 }
139
SetSortedKey(int descriptor_number,int pointer)140 void DescriptorArray::SetSortedKey(int descriptor_number, int pointer) {
141 PropertyDetails details = GetDetails(InternalIndex(descriptor_number));
142 SetDetails(InternalIndex(descriptor_number), details.set_pointer(pointer));
143 }
144
GetStrongValue(InternalIndex descriptor_number)145 Object DescriptorArray::GetStrongValue(InternalIndex descriptor_number) {
146 IsolateRoot isolate = GetIsolateForPtrCompr(*this);
147 return GetStrongValue(isolate, descriptor_number);
148 }
149
GetStrongValue(IsolateRoot isolate,InternalIndex descriptor_number)150 Object DescriptorArray::GetStrongValue(IsolateRoot isolate,
151 InternalIndex descriptor_number) {
152 return GetValue(isolate, descriptor_number).cast<Object>();
153 }
154
SetValue(InternalIndex descriptor_number,MaybeObject value)155 void DescriptorArray::SetValue(InternalIndex descriptor_number,
156 MaybeObject value) {
157 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
158 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
159 EntryValueField::Relaxed_Store(*this, entry_offset, value);
160 WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value);
161 }
162
GetValue(InternalIndex descriptor_number)163 MaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) {
164 IsolateRoot isolate = GetIsolateForPtrCompr(*this);
165 return GetValue(isolate, descriptor_number);
166 }
167
GetValue(IsolateRoot isolate,InternalIndex descriptor_number)168 MaybeObject DescriptorArray::GetValue(IsolateRoot isolate,
169 InternalIndex descriptor_number) {
170 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
171 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
172 return EntryValueField::Relaxed_Load(isolate, *this, entry_offset);
173 }
174
GetDetails(InternalIndex descriptor_number)175 PropertyDetails DescriptorArray::GetDetails(InternalIndex descriptor_number) {
176 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
177 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
178 Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset);
179 return PropertyDetails(details);
180 }
181
SetDetails(InternalIndex descriptor_number,PropertyDetails details)182 void DescriptorArray::SetDetails(InternalIndex descriptor_number,
183 PropertyDetails details) {
184 DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
185 int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
186 EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi());
187 }
188
GetFieldIndex(InternalIndex descriptor_number)189 int DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) {
190 DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
191 return GetDetails(descriptor_number).field_index();
192 }
193
GetFieldType(InternalIndex descriptor_number)194 FieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) {
195 IsolateRoot isolate = GetIsolateForPtrCompr(*this);
196 return GetFieldType(isolate, descriptor_number);
197 }
198
GetFieldType(IsolateRoot isolate,InternalIndex descriptor_number)199 FieldType DescriptorArray::GetFieldType(IsolateRoot isolate,
200 InternalIndex descriptor_number) {
201 DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
202 MaybeObject wrapped_type = GetValue(isolate, descriptor_number);
203 return Map::UnwrapFieldType(wrapped_type);
204 }
205
Set(InternalIndex descriptor_number,Name key,MaybeObject value,PropertyDetails details)206 void DescriptorArray::Set(InternalIndex descriptor_number, Name key,
207 MaybeObject value, PropertyDetails details) {
208 SetKey(descriptor_number, key);
209 SetDetails(descriptor_number, details);
210 SetValue(descriptor_number, value);
211 }
212
Set(InternalIndex descriptor_number,Descriptor * desc)213 void DescriptorArray::Set(InternalIndex descriptor_number, Descriptor* desc) {
214 Name key = *desc->GetKey();
215 MaybeObject value = *desc->GetValue();
216 Set(descriptor_number, key, value, desc->GetDetails());
217 }
218
Append(Descriptor * desc)219 void DescriptorArray::Append(Descriptor* desc) {
220 DisallowHeapAllocation no_gc;
221 int descriptor_number = number_of_descriptors();
222 DCHECK_LE(descriptor_number + 1, number_of_all_descriptors());
223 set_number_of_descriptors(descriptor_number + 1);
224 Set(InternalIndex(descriptor_number), desc);
225
226 uint32_t hash = desc->GetKey()->Hash();
227
228 int insertion;
229
230 for (insertion = descriptor_number; insertion > 0; --insertion) {
231 Name key = GetSortedKey(insertion - 1);
232 if (key.hash() <= hash) break;
233 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
234 }
235
236 SetSortedKey(insertion, descriptor_number);
237 }
238
SwapSortedKeys(int first,int second)239 void DescriptorArray::SwapSortedKeys(int first, int second) {
240 int first_key = GetSortedKeyIndex(first);
241 SetSortedKey(first, GetSortedKeyIndex(second));
242 SetSortedKey(second, first_key);
243 }
244
245 } // namespace internal
246 } // namespace v8
247
248 #include "src/objects/object-macros-undef.h"
249
250 #endif // V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
251