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 14952564 : void CallInterfaceDescriptorData::InitializePlatformSpecific(
13 : int register_parameter_count, const Register* registers) {
14 : DCHECK(!IsInitializedPlatformIndependent());
15 :
16 14952564 : register_param_count_ = register_parameter_count;
17 :
18 : // UBSan doesn't like creating zero-length arrays.
19 29905128 : if (register_parameter_count == 0) return;
20 :
21 : // InterfaceDescriptor owns a copy of the registers array.
22 13849506 : register_params_ = NewArray<Register>(register_parameter_count, no_reg);
23 51966288 : 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 38116782 : register_params_[i] = registers[i];
28 : }
29 : }
30 :
31 14952564 : 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 14952564 : flags_ = flags;
37 14952564 : return_count_ = return_count;
38 14952564 : param_count_ = parameter_count;
39 14952564 : const int types_length = return_count_ + param_count_;
40 :
41 : // Machine types are either fully initialized or null.
42 14952564 : if (machine_types == nullptr) {
43 : machine_types_ =
44 11091861 : NewArray<MachineType>(types_length, MachineType::AnyTagged());
45 : } else {
46 : DCHECK_EQ(machine_types_length, types_length);
47 3860703 : machine_types_ = NewArray<MachineType>(types_length);
48 3860703 : for (int i = 0; i < types_length; i++) machine_types_[i] = machine_types[i];
49 : }
50 :
51 : if (!(flags_ & kNoStackScan)) DCHECK(AllStackParametersAreTagged());
52 14952564 : }
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 7778232 : void CallInterfaceDescriptorData::Reset() {
67 7778232 : delete[] machine_types_;
68 7778232 : machine_types_ = nullptr;
69 7778232 : delete[] register_params_;
70 7778232 : register_params_ = nullptr;
71 7778232 : }
72 :
73 : // static
74 : CallInterfaceDescriptorData
75 15015805 : CallDescriptors::call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
76 :
77 61281 : void CallDescriptors::InitializeOncePerProcess() {
78 : #define INTERFACE_DESCRIPTOR(name, ...) \
79 : name##Descriptor().Initialize(&call_descriptor_data_[CallDescriptors::name]);
80 17281242 : 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 61281 : }
89 :
90 31878 : void CallDescriptors::TearDown() {
91 7810110 : for (CallInterfaceDescriptorData& data : call_descriptor_data_) {
92 7778232 : data.Reset();
93 : }
94 31878 : }
95 :
96 183843 : 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 183843 : 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 183843 : kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register};
110 :
111 183843 : CHECK_LE(static_cast<size_t>(register_parameter_count),
112 : arraysize(default_js_stub_registers));
113 : data->InitializePlatformSpecific(register_parameter_count,
114 183843 : default_js_stub_registers);
115 183843 : }
116 :
117 2757382 : const char* CallInterfaceDescriptor::DebugName() const {
118 2757382 : CallDescriptors::Key key = CallDescriptors::GetKey(data_);
119 2757382 : switch (key) {
120 : #define DEF_CASE(name, ...) \
121 : case CallDescriptors::name: \
122 : return #name " Descriptor";
123 112129 : 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 61281 : void VoidDescriptor::InitializePlatformSpecific(
138 : CallInterfaceDescriptorData* data) {
139 61281 : data->InitializePlatformSpecific(0, nullptr);
140 61281 : }
141 :
142 61281 : void AllocateDescriptor::InitializePlatformSpecific(
143 : CallInterfaceDescriptorData* data) {
144 61281 : Register registers[] = {kAllocateSizeRegister};
145 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
146 61281 : }
147 :
148 61281 : void CEntry1ArgvOnStackDescriptor::InitializePlatformSpecific(
149 : CallInterfaceDescriptorData* data) {
150 : Register registers[] = {kRuntimeCallArgCountRegister,
151 61281 : kRuntimeCallFunctionRegister};
152 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
153 61281 : }
154 :
155 : namespace {
156 :
157 : void InterpreterCEntryDescriptor_InitializePlatformSpecific(
158 : CallInterfaceDescriptorData* data) {
159 : Register registers[] = {kRuntimeCallArgCountRegister,
160 : kRuntimeCallArgvRegister,
161 122562 : kRuntimeCallFunctionRegister};
162 122562 : data->InitializePlatformSpecific(arraysize(registers), registers);
163 : }
164 :
165 : } // namespace
166 :
167 61281 : void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
168 : CallInterfaceDescriptorData* data) {
169 : InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
170 61281 : }
171 :
172 61281 : void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
173 : CallInterfaceDescriptorData* data) {
174 : InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
175 61281 : }
176 :
177 61281 : void FastNewFunctionContextDescriptor::InitializePlatformSpecific(
178 : CallInterfaceDescriptorData* data) {
179 61281 : Register registers[] = {ScopeInfoRegister(), SlotsRegister()};
180 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
181 61281 : }
182 :
183 61281 : void FastNewObjectDescriptor::InitializePlatformSpecific(
184 : CallInterfaceDescriptorData* data) {
185 61281 : Register registers[] = {TargetRegister(), NewTargetRegister()};
186 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
187 61281 : }
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 61281 : void LoadDescriptor::InitializePlatformSpecific(
199 : CallInterfaceDescriptorData* data) {
200 61281 : Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
201 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
202 61281 : }
203 :
204 61281 : void LoadGlobalDescriptor::InitializePlatformSpecific(
205 : CallInterfaceDescriptorData* data) {
206 122562 : Register registers[] = {NameRegister(), SlotRegister()};
207 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
208 61281 : }
209 :
210 61281 : void LoadGlobalWithVectorDescriptor::InitializePlatformSpecific(
211 : CallInterfaceDescriptorData* data) {
212 183843 : Register registers[] = {NameRegister(), SlotRegister(), VectorRegister()};
213 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
214 61281 : }
215 :
216 61281 : void StoreGlobalDescriptor::InitializePlatformSpecific(
217 : CallInterfaceDescriptorData* data) {
218 183843 : Register registers[] = {NameRegister(), ValueRegister(), SlotRegister()};
219 :
220 : int len = arraysize(registers) - kStackArgumentsCount;
221 61281 : data->InitializePlatformSpecific(len, registers);
222 61281 : }
223 :
224 61281 : void StoreGlobalWithVectorDescriptor::InitializePlatformSpecific(
225 : CallInterfaceDescriptorData* data) {
226 : Register registers[] = {NameRegister(), ValueRegister(), SlotRegister(),
227 245124 : VectorRegister()};
228 : int len = arraysize(registers) - kStackArgumentsCount;
229 61281 : data->InitializePlatformSpecific(len, registers);
230 61281 : }
231 :
232 61281 : void StoreDescriptor::InitializePlatformSpecific(
233 : CallInterfaceDescriptorData* data) {
234 : Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
235 61281 : SlotRegister()};
236 :
237 : int len = arraysize(registers) - kStackArgumentsCount;
238 61281 : data->InitializePlatformSpecific(len, registers);
239 61281 : }
240 :
241 61281 : void StoreTransitionDescriptor::InitializePlatformSpecific(
242 : CallInterfaceDescriptorData* data) {
243 : Register registers[] = {
244 : ReceiverRegister(), NameRegister(), MapRegister(),
245 : ValueRegister(), SlotRegister(), VectorRegister(),
246 61281 : };
247 : int len = arraysize(registers) - kStackArgumentsCount;
248 61281 : data->InitializePlatformSpecific(len, registers);
249 61281 : }
250 :
251 61281 : void StringAtDescriptor::InitializePlatformSpecific(
252 : CallInterfaceDescriptorData* data) {
253 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
254 61281 : }
255 :
256 61281 : void StringSubstringDescriptor::InitializePlatformSpecific(
257 : CallInterfaceDescriptorData* data) {
258 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
259 61281 : }
260 :
261 61281 : void TypeConversionDescriptor::InitializePlatformSpecific(
262 : CallInterfaceDescriptorData* data) {
263 61281 : Register registers[] = {ArgumentRegister()};
264 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
265 61281 : }
266 :
267 61281 : void TypeConversionStackParameterDescriptor::InitializePlatformSpecific(
268 : CallInterfaceDescriptorData* data) {
269 61281 : data->InitializePlatformSpecific(0, nullptr);
270 61281 : }
271 :
272 61281 : void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific(
273 : CallInterfaceDescriptorData* data) {
274 61281 : data->InitializePlatformSpecific(0, nullptr);
275 61281 : }
276 :
277 61281 : void LoadWithVectorDescriptor::InitializePlatformSpecific(
278 : CallInterfaceDescriptorData* data) {
279 : Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
280 61281 : 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 61281 : data->InitializePlatformSpecific(len, registers);
287 61281 : }
288 :
289 61281 : void StoreWithVectorDescriptor::InitializePlatformSpecific(
290 : CallInterfaceDescriptorData* data) {
291 : Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
292 61281 : 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 61281 : data->InitializePlatformSpecific(len, registers);
298 61281 : }
299 :
300 56 : const Register ApiGetterDescriptor::ReceiverRegister() {
301 61337 : return LoadDescriptor::ReceiverRegister();
302 : }
303 :
304 61281 : void ApiGetterDescriptor::InitializePlatformSpecific(
305 : CallInterfaceDescriptorData* data) {
306 : Register registers[] = {ReceiverRegister(), HolderRegister(),
307 61281 : CallbackRegister()};
308 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
309 61281 : }
310 :
311 61281 : void ContextOnlyDescriptor::InitializePlatformSpecific(
312 : CallInterfaceDescriptorData* data) {
313 61281 : data->InitializePlatformSpecific(0, nullptr);
314 61281 : }
315 :
316 61281 : void NoContextDescriptor::InitializePlatformSpecific(
317 : CallInterfaceDescriptorData* data) {
318 61281 : data->InitializePlatformSpecific(0, nullptr);
319 61281 : }
320 :
321 61281 : void GrowArrayElementsDescriptor::InitializePlatformSpecific(
322 : CallInterfaceDescriptorData* data) {
323 61281 : Register registers[] = {ObjectRegister(), KeyRegister()};
324 61281 : data->InitializePlatformSpecific(arraysize(registers), registers);
325 61281 : }
326 :
327 61281 : void NewArgumentsElementsDescriptor::InitializePlatformSpecific(
328 : CallInterfaceDescriptorData* data) {
329 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
330 61281 : }
331 :
332 61281 : 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 61281 : }
338 :
339 61281 : 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 61281 : }
345 :
346 61281 : 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 183843 : kJavaScriptCallArgCountRegister};
354 183843 : data->InitializePlatformSpecific(arraysize(registers), registers);
355 61281 : }
356 :
357 61281 : void WasmMemoryGrowDescriptor::InitializePlatformSpecific(
358 : CallInterfaceDescriptorData* data) {
359 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
360 61281 : }
361 :
362 61281 : void WasmThrowDescriptor::InitializePlatformSpecific(
363 : CallInterfaceDescriptorData* data) {
364 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
365 61281 : }
366 :
367 61281 : void WasmAtomicWakeDescriptor::InitializePlatformSpecific(
368 : CallInterfaceDescriptorData* data) {
369 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
370 61281 : }
371 :
372 : #if !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64)
373 61281 : void WasmI32AtomicWaitDescriptor::InitializePlatformSpecific(
374 : CallInterfaceDescriptorData* data) {
375 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
376 61281 : }
377 :
378 61281 : void WasmI64AtomicWaitDescriptor::InitializePlatformSpecific(
379 : CallInterfaceDescriptorData* data) {
380 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
381 61281 : }
382 : #endif
383 :
384 61281 : void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
385 : CallInterfaceDescriptorData* data) {
386 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
387 61281 : }
388 :
389 : // static
390 56 : Register RunMicrotasksDescriptor::MicrotaskQueueRegister() {
391 : return CallDescriptors::call_descriptor_data(CallDescriptors::RunMicrotasks)
392 112 : ->register_param(0);
393 : }
394 :
395 61281 : void RunMicrotasksDescriptor::InitializePlatformSpecific(
396 : CallInterfaceDescriptorData* data) {
397 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
398 61281 : }
399 :
400 61281 : void BigIntToWasmI64Descriptor::InitializePlatformSpecific(
401 : CallInterfaceDescriptorData* data) {
402 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
403 61281 : }
404 :
405 61281 : void BigIntToI64Descriptor::InitializePlatformSpecific(
406 : CallInterfaceDescriptorData* data) {
407 61281 : DefaultInitializePlatformSpecific(data, kParameterCount);
408 61281 : }
409 :
410 : } // namespace internal
411 183867 : } // namespace v8
|