Line data Source code
1 : // Copyright 2012 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 : #include "src/interface-descriptors.h"
6 :
7 : #include "src/macro-assembler.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 :
12 14580912 : void CallInterfaceDescriptorData::InitializePlatformSpecific(
13 : int register_parameter_count, const Register* registers) {
14 : DCHECK(!IsInitializedPlatformIndependent());
15 :
16 14885952 : register_param_count_ = register_parameter_count;
17 :
18 : // UBSan doesn't like creating zero-length arrays.
19 14580912 : if (register_parameter_count == 0) return;
20 :
21 : // InterfaceDescriptor owns a copy of the registers array.
22 27575616 : register_params_ = NewArray<Register>(register_parameter_count, no_reg);
23 87485472 : for (int i = 0; i < register_parameter_count; i++) {
24 : // The value of the root register must be reserved, thus any uses
25 : // within the calling convention are disallowed.
26 : DCHECK_NE(registers[i], kRootRegister);
27 36848832 : register_params_[i] = registers[i];
28 : }
29 : }
30 :
31 14885952 : void CallInterfaceDescriptorData::InitializePlatformIndependent(
32 : Flags flags, int return_count, int parameter_count,
33 : const MachineType* machine_types, int machine_types_length) {
34 : DCHECK(IsInitializedPlatformSpecific());
35 :
36 14885952 : flags_ = flags;
37 14885952 : return_count_ = return_count;
38 14885952 : param_count_ = parameter_count;
39 14885952 : const int types_length = return_count_ + param_count_;
40 :
41 : // Machine types are either fully initialized or null.
42 14885952 : if (machine_types == nullptr) {
43 : machine_types_ =
44 21596832 : NewArray<MachineType>(types_length, MachineType::AnyTagged());
45 : } else {
46 : DCHECK_EQ(machine_types_length, types_length);
47 4087536 : machine_types_ = NewArray<MachineType>(types_length);
48 19461552 : for (int i = 0; i < types_length; i++) machine_types_[i] = machine_types[i];
49 : }
50 :
51 : if (!(flags_ & kNoStackScan)) DCHECK(AllStackParametersAreTagged());
52 14885952 : }
53 :
54 : #ifdef DEBUG
55 : bool CallInterfaceDescriptorData::AllStackParametersAreTagged() const {
56 : DCHECK(IsInitialized());
57 : const int types_length = return_count_ + param_count_;
58 : const int first_stack_param = return_count_ + register_param_count_;
59 : for (int i = first_stack_param; i < types_length; i++) {
60 : if (!machine_types_[i].IsTagged()) return false;
61 : }
62 : return true;
63 : }
64 : #endif // DEBUG
65 :
66 14616332 : void CallInterfaceDescriptorData::Reset() {
67 14616332 : delete[] machine_types_;
68 14616332 : machine_types_ = nullptr;
69 14616332 : delete[] register_params_;
70 14616332 : register_params_ = nullptr;
71 14616332 : }
72 :
73 : // static
74 : CallInterfaceDescriptorData
75 : CallDescriptors::call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
76 :
77 61008 : void CallDescriptors::InitializeOncePerProcess() {
78 : #define INTERFACE_DESCRIPTOR(name, ...) \
79 : name##Descriptor().Initialize(&call_descriptor_data_[CallDescriptors::name]);
80 17204256 : INTERFACE_DESCRIPTOR_LIST(INTERFACE_DESCRIPTOR)
81 : #undef INTERFACE_DESCRIPTOR
82 :
83 : DCHECK(ContextOnlyDescriptor{}.HasContextParameter());
84 : DCHECK(!NoContextDescriptor{}.HasContextParameter());
85 : DCHECK(!AllocateDescriptor{}.HasContextParameter());
86 : DCHECK(!AllocateHeapNumberDescriptor{}.HasContextParameter());
87 : DCHECK(!AbortDescriptor{}.HasContextParameter());
88 61008 : }
89 :
90 59903 : void CallDescriptors::TearDown() {
91 29292567 : for (CallInterfaceDescriptorData& data : call_descriptor_data_) {
92 14616332 : data.Reset();
93 : }
94 59903 : }
95 :
96 183024 : void CallInterfaceDescriptor::JSDefaultInitializePlatformSpecific(
97 : CallInterfaceDescriptorData* data, int non_js_register_parameter_count) {
98 : DCHECK_LE(static_cast<unsigned>(non_js_register_parameter_count), 1);
99 :
100 : // 3 is for kTarget, kNewTarget and kActualArgumentsCount
101 183024 : int register_parameter_count = 3 + non_js_register_parameter_count;
102 :
103 : DCHECK(!AreAliased(
104 : kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
105 : kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register));
106 :
107 : const Register default_js_stub_registers[] = {
108 : kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
109 183024 : kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register};
110 :
111 183024 : CHECK_LE(static_cast<size_t>(register_parameter_count),
112 : arraysize(default_js_stub_registers));
113 : data->InitializePlatformSpecific(register_parameter_count,
114 183024 : default_js_stub_registers);
115 183024 : }
116 :
117 3290425 : const char* CallInterfaceDescriptor::DebugName() const {
118 3290425 : CallDescriptors::Key key = CallDescriptors::GetKey(data_);
119 3290425 : switch (key) {
120 : #define DEF_CASE(name, ...) \
121 : case CallDescriptors::name: \
122 : return #name " Descriptor";
123 114221 : INTERFACE_DESCRIPTOR_LIST(DEF_CASE)
124 : #undef DEF_CASE
125 : case CallDescriptors::NUMBER_OF_DESCRIPTORS:
126 : break;
127 : }
128 0 : return "";
129 : }
130 :
131 : #if !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64)
132 0 : bool CallInterfaceDescriptor::IsValidFloatParameterRegister(Register reg) {
133 0 : return true;
134 : }
135 : #endif
136 :
137 61008 : void VoidDescriptor::InitializePlatformSpecific(
138 : CallInterfaceDescriptorData* data) {
139 : data->InitializePlatformSpecific(0, nullptr);
140 61008 : }
141 :
142 61008 : void AllocateDescriptor::InitializePlatformSpecific(
143 : CallInterfaceDescriptorData* data) {
144 61008 : Register registers[] = {kAllocateSizeRegister};
145 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
146 61008 : }
147 :
148 61008 : void CEntry1ArgvOnStackDescriptor::InitializePlatformSpecific(
149 : CallInterfaceDescriptorData* data) {
150 : Register registers[] = {kRuntimeCallArgCountRegister,
151 61008 : kRuntimeCallFunctionRegister};
152 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
153 61008 : }
154 :
155 : namespace {
156 :
157 : void InterpreterCEntryDescriptor_InitializePlatformSpecific(
158 : CallInterfaceDescriptorData* data) {
159 : Register registers[] = {kRuntimeCallArgCountRegister,
160 : kRuntimeCallArgvRegister,
161 122016 : kRuntimeCallFunctionRegister};
162 122016 : data->InitializePlatformSpecific(arraysize(registers), registers);
163 : }
164 :
165 : } // namespace
166 :
167 61008 : void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
168 : CallInterfaceDescriptorData* data) {
169 : InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
170 61008 : }
171 :
172 61008 : void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
173 : CallInterfaceDescriptorData* data) {
174 : InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
175 61008 : }
176 :
177 61008 : void FastNewFunctionContextDescriptor::InitializePlatformSpecific(
178 : CallInterfaceDescriptorData* data) {
179 61008 : Register registers[] = {ScopeInfoRegister(), SlotsRegister()};
180 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
181 61008 : }
182 :
183 61008 : void FastNewObjectDescriptor::InitializePlatformSpecific(
184 : CallInterfaceDescriptorData* data) {
185 61008 : Register registers[] = {TargetRegister(), NewTargetRegister()};
186 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
187 61008 : }
188 :
189 0 : const Register FastNewObjectDescriptor::TargetRegister() {
190 0 : return kJSFunctionRegister;
191 : }
192 :
193 0 : const Register FastNewObjectDescriptor::NewTargetRegister() {
194 0 : return kJavaScriptCallNewTargetRegister;
195 : }
196 :
197 :
198 61008 : void LoadDescriptor::InitializePlatformSpecific(
199 : CallInterfaceDescriptorData* data) {
200 61008 : Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
201 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
202 61008 : }
203 :
204 61008 : void LoadGlobalDescriptor::InitializePlatformSpecific(
205 : CallInterfaceDescriptorData* data) {
206 122016 : Register registers[] = {NameRegister(), SlotRegister()};
207 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
208 61008 : }
209 :
210 61008 : void LoadGlobalWithVectorDescriptor::InitializePlatformSpecific(
211 : CallInterfaceDescriptorData* data) {
212 183024 : Register registers[] = {NameRegister(), SlotRegister(), VectorRegister()};
213 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
214 61008 : }
215 :
216 61008 : void StoreGlobalDescriptor::InitializePlatformSpecific(
217 : CallInterfaceDescriptorData* data) {
218 183024 : Register registers[] = {NameRegister(), ValueRegister(), SlotRegister()};
219 :
220 : int len = arraysize(registers) - kStackArgumentsCount;
221 61008 : data->InitializePlatformSpecific(len, registers);
222 61008 : }
223 :
224 61008 : void StoreGlobalWithVectorDescriptor::InitializePlatformSpecific(
225 : CallInterfaceDescriptorData* data) {
226 : Register registers[] = {NameRegister(), ValueRegister(), SlotRegister(),
227 244032 : VectorRegister()};
228 : int len = arraysize(registers) - kStackArgumentsCount;
229 61008 : data->InitializePlatformSpecific(len, registers);
230 61008 : }
231 :
232 61008 : void StoreDescriptor::InitializePlatformSpecific(
233 : CallInterfaceDescriptorData* data) {
234 : Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
235 61008 : SlotRegister()};
236 :
237 : int len = arraysize(registers) - kStackArgumentsCount;
238 61008 : data->InitializePlatformSpecific(len, registers);
239 61008 : }
240 :
241 61008 : void StoreTransitionDescriptor::InitializePlatformSpecific(
242 : CallInterfaceDescriptorData* data) {
243 : Register registers[] = {
244 : ReceiverRegister(), NameRegister(), MapRegister(),
245 : ValueRegister(), SlotRegister(), VectorRegister(),
246 61008 : };
247 : int len = arraysize(registers) - kStackArgumentsCount;
248 61008 : data->InitializePlatformSpecific(len, registers);
249 61008 : }
250 :
251 61008 : void StringAtDescriptor::InitializePlatformSpecific(
252 : CallInterfaceDescriptorData* data) {
253 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
254 61008 : }
255 :
256 61008 : void StringSubstringDescriptor::InitializePlatformSpecific(
257 : CallInterfaceDescriptorData* data) {
258 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
259 61008 : }
260 :
261 61008 : void TypeConversionDescriptor::InitializePlatformSpecific(
262 : CallInterfaceDescriptorData* data) {
263 61008 : Register registers[] = {ArgumentRegister()};
264 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
265 61008 : }
266 :
267 61008 : void TypeConversionStackParameterDescriptor::InitializePlatformSpecific(
268 : CallInterfaceDescriptorData* data) {
269 : data->InitializePlatformSpecific(0, nullptr);
270 61008 : }
271 :
272 61008 : void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific(
273 : CallInterfaceDescriptorData* data) {
274 : data->InitializePlatformSpecific(0, nullptr);
275 61008 : }
276 :
277 61008 : void LoadWithVectorDescriptor::InitializePlatformSpecific(
278 : CallInterfaceDescriptorData* data) {
279 : Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
280 61008 : VectorRegister()};
281 : // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
282 : // to allow no_reg entries.
283 : // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), SlotRegister(),
284 : // VectorRegister(), kRootRegister));
285 : int len = arraysize(registers) - kStackArgumentsCount;
286 61008 : data->InitializePlatformSpecific(len, registers);
287 61008 : }
288 :
289 61008 : void StoreWithVectorDescriptor::InitializePlatformSpecific(
290 : CallInterfaceDescriptorData* data) {
291 : Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
292 61008 : SlotRegister(), VectorRegister()};
293 : // TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
294 : // to allow no_reg entries.
295 : // DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), kRootRegister));
296 : int len = arraysize(registers) - kStackArgumentsCount;
297 61008 : data->InitializePlatformSpecific(len, registers);
298 61008 : }
299 :
300 56 : const Register ApiGetterDescriptor::ReceiverRegister() {
301 61064 : return LoadDescriptor::ReceiverRegister();
302 : }
303 :
304 61008 : void ApiGetterDescriptor::InitializePlatformSpecific(
305 : CallInterfaceDescriptorData* data) {
306 : Register registers[] = {ReceiverRegister(), HolderRegister(),
307 61008 : CallbackRegister()};
308 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
309 61008 : }
310 :
311 61008 : void ContextOnlyDescriptor::InitializePlatformSpecific(
312 : CallInterfaceDescriptorData* data) {
313 : data->InitializePlatformSpecific(0, nullptr);
314 61008 : }
315 :
316 61008 : void NoContextDescriptor::InitializePlatformSpecific(
317 : CallInterfaceDescriptorData* data) {
318 : data->InitializePlatformSpecific(0, nullptr);
319 61008 : }
320 :
321 61008 : void GrowArrayElementsDescriptor::InitializePlatformSpecific(
322 : CallInterfaceDescriptorData* data) {
323 61008 : Register registers[] = {ObjectRegister(), KeyRegister()};
324 61008 : data->InitializePlatformSpecific(arraysize(registers), registers);
325 61008 : }
326 :
327 61008 : void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
328 : CallInterfaceDescriptorData* data) {
329 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
330 61008 : }
331 :
332 61008 : void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
333 : CallInterfaceDescriptorData* data) {
334 : // This descriptor must use the same set of registers as the
335 : // ArrayNArgumentsConstructorDescriptor.
336 : ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
337 61008 : }
338 :
339 61008 : void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
340 : CallInterfaceDescriptorData* data) {
341 : // This descriptor must use the same set of registers as the
342 : // ArrayNArgumentsConstructorDescriptor.
343 : ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
344 61008 : }
345 :
346 61008 : void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
347 : CallInterfaceDescriptorData* data) {
348 : // Keep the arguments on the same registers as they were in
349 : // ArrayConstructorDescriptor to avoid unnecessary register moves.
350 : // kFunction, kAllocationSite, kActualArgumentsCount
351 : Register registers[] = {kJavaScriptCallTargetRegister,
352 : kJavaScriptCallExtraArg1Register,
353 183024 : kJavaScriptCallArgCountRegister};
354 183024 : data->InitializePlatformSpecific(arraysize(registers), registers);
355 61008 : }
356 :
357 61008 : void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
358 : CallInterfaceDescriptorData* data) {
359 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
360 61008 : }
361 :
362 61008 : void WasmTableGetDescriptor::InitializePlatformSpecific(
363 : CallInterfaceDescriptorData* data) {
364 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
365 61008 : }
366 :
367 61008 : void WasmTableSetDescriptor::InitializePlatformSpecific(
368 : CallInterfaceDescriptorData* data) {
369 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
370 61008 : }
371 :
372 61008 : void WasmThrowDescriptor::InitializePlatformSpecific(
373 : CallInterfaceDescriptorData* data) {
374 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
375 61008 : }
376 :
377 61008 : void WasmAtomicNotifyDescriptor::InitializePlatformSpecific(
378 : CallInterfaceDescriptorData* data) {
379 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
380 61008 : }
381 :
382 : #if !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64)
383 61008 : void WasmI32AtomicWaitDescriptor::InitializePlatformSpecific(
384 : CallInterfaceDescriptorData* data) {
385 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
386 61008 : }
387 :
388 61008 : void WasmI64AtomicWaitDescriptor::InitializePlatformSpecific(
389 : CallInterfaceDescriptorData* data) {
390 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
391 61008 : }
392 : #endif
393 :
394 61008 : void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
395 : CallInterfaceDescriptorData* data) {
396 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
397 61008 : }
398 :
399 : // static
400 56 : Register RunMicrotasksDescriptor::MicrotaskQueueRegister() {
401 : return CallDescriptors::call_descriptor_data(CallDescriptors::RunMicrotasks)
402 56 : ->register_param(0);
403 : }
404 :
405 61008 : void RunMicrotasksDescriptor::InitializePlatformSpecific(
406 : CallInterfaceDescriptorData* data) {
407 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
408 61008 : }
409 :
410 61008 : void I64ToBigIntDescriptor::InitializePlatformSpecific(
411 : CallInterfaceDescriptorData* data) {
412 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
413 61008 : }
414 :
415 61008 : void BigIntToI64Descriptor::InitializePlatformSpecific(
416 : CallInterfaceDescriptorData* data) {
417 61008 : DefaultInitializePlatformSpecific(data, kParameterCount);
418 61008 : }
419 :
420 : } // namespace internal
421 122036 : } // namespace v8
|