Line data Source code
1 : // Copyright 2014 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_INTERFACE_DESCRIPTORS_H_
6 : #define V8_INTERFACE_DESCRIPTORS_H_
7 :
8 : #include <memory>
9 :
10 : #include "src/globals.h"
11 : #include "src/isolate.h"
12 : #include "src/machine-type.h"
13 : #include "src/register-arch.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : #define INTERFACE_DESCRIPTOR_LIST(V) \
19 : V(Abort) \
20 : V(Allocate) \
21 : V(AllocateHeapNumber) \
22 : V(ApiCallback) \
23 : V(ApiGetter) \
24 : V(ArgumentsAdaptor) \
25 : V(ArrayConstructor) \
26 : V(ArrayNArgumentsConstructor) \
27 : V(ArrayNoArgumentConstructor) \
28 : V(ArraySingleArgumentConstructor) \
29 : V(AsyncFunctionStackParameter) \
30 : V(BigIntToI64) \
31 : V(I64ToBigInt) \
32 : V(BinaryOp) \
33 : V(CallForwardVarargs) \
34 : V(CallFunctionTemplate) \
35 : V(CallTrampoline) \
36 : V(CallVarargs) \
37 : V(CallWithArrayLike) \
38 : V(CallWithSpread) \
39 : V(CEntry1ArgvOnStack) \
40 : V(CloneObjectWithVector) \
41 : V(Compare) \
42 : V(ConstructForwardVarargs) \
43 : V(ConstructStub) \
44 : V(ConstructVarargs) \
45 : V(ConstructWithArrayLike) \
46 : V(ConstructWithSpread) \
47 : V(ContextOnly) \
48 : V(CppBuiltinAdaptor) \
49 : V(FastNewFunctionContext) \
50 : V(FastNewObject) \
51 : V(FrameDropperTrampoline) \
52 : V(GetProperty) \
53 : V(GrowArrayElements) \
54 : V(InterpreterCEntry1) \
55 : V(InterpreterCEntry2) \
56 : V(InterpreterDispatch) \
57 : V(InterpreterPushArgsThenCall) \
58 : V(InterpreterPushArgsThenConstruct) \
59 : V(JSTrampoline) \
60 : V(Load) \
61 : V(LoadGlobal) \
62 : V(LoadGlobalWithVector) \
63 : V(LoadWithVector) \
64 : V(NewArgumentsElements) \
65 : V(NoContext) \
66 : V(RecordWrite) \
67 : V(ResumeGenerator) \
68 : V(RunMicrotasksEntry) \
69 : V(RunMicrotasks) \
70 : V(Store) \
71 : V(StoreGlobal) \
72 : V(StoreGlobalWithVector) \
73 : V(StoreTransition) \
74 : V(StoreWithVector) \
75 : V(StringAt) \
76 : V(StringSubstring) \
77 : V(TypeConversion) \
78 : V(TypeConversionStackParameter) \
79 : V(Typeof) \
80 : V(Void) \
81 : V(WasmAtomicNotify) \
82 : V(WasmI32AtomicWait) \
83 : V(WasmI64AtomicWait) \
84 : V(WasmMemoryGrow) \
85 : V(WasmTableGet) \
86 : V(WasmTableSet) \
87 : V(WasmThrow) \
88 : BUILTIN_LIST_TFS(V)
89 :
90 : class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
91 : public:
92 : enum Flag {
93 : kNoFlags = 0u,
94 : kNoContext = 1u << 0,
95 :
96 : // This indicates that the code uses a special frame that does not scan the
97 : // stack arguments, e.g. EntryFrame. And this allows the code to use
98 : // untagged stack arguments.
99 : kNoStackScan = 1u << 1,
100 : };
101 : typedef base::Flags<Flag> Flags;
102 :
103 : CallInterfaceDescriptorData() = default;
104 :
105 : // A copy of the passed in registers and param_representations is made
106 : // and owned by the CallInterfaceDescriptorData.
107 :
108 : void InitializePlatformSpecific(int register_parameter_count,
109 : const Register* registers);
110 :
111 : // if machine_types is null, then an array of size
112 : // (return_count + parameter_count) will be created with
113 : // MachineType::AnyTagged() for each member.
114 : //
115 : // if machine_types is not null, then it should be of the size
116 : // (return_count + parameter_count). Those members of the parameter array will
117 : // be initialized from {machine_types}, and the rest initialized to
118 : // MachineType::AnyTagged().
119 : void InitializePlatformIndependent(Flags flags, int return_count,
120 : int parameter_count,
121 : const MachineType* machine_types,
122 : int machine_types_length);
123 :
124 : void Reset();
125 :
126 : bool IsInitialized() const {
127 : return IsInitializedPlatformSpecific() &&
128 : IsInitializedPlatformIndependent();
129 : }
130 :
131 : Flags flags() const { return flags_; }
132 : int return_count() const { return return_count_; }
133 2688 : int param_count() const { return param_count_; }
134 0 : int register_param_count() const { return register_param_count_; }
135 8911695 : Register register_param(int index) const { return register_params_[index]; }
136 : Register* register_params() const { return register_params_; }
137 : MachineType return_type(int index) const {
138 : DCHECK_LT(index, return_count_);
139 3483060 : return machine_types_[index];
140 : }
141 : MachineType param_type(int index) const {
142 : DCHECK_LT(index, param_count_);
143 7766291 : return machine_types_[return_count_ + index];
144 : }
145 :
146 : void RestrictAllocatableRegisters(const Register* registers, int num) {
147 : DCHECK_EQ(allocatable_registers_, 0);
148 661078 : for (int i = 0; i < num; ++i) {
149 600980 : allocatable_registers_ |= registers[i].bit();
150 : }
151 : DCHECK_GT(NumRegs(allocatable_registers_), 0);
152 : }
153 :
154 : RegList allocatable_registers() const { return allocatable_registers_; }
155 :
156 : private:
157 : bool IsInitializedPlatformSpecific() const {
158 : const bool initialized =
159 : (register_param_count_ == 0 && register_params_ == nullptr) ||
160 : (register_param_count_ > 0 && register_params_ != nullptr);
161 : // Platform-specific initialization happens before platform-independent.
162 : return initialized;
163 : }
164 : bool IsInitializedPlatformIndependent() const {
165 : const bool initialized =
166 : return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
167 : // Platform-specific initialization happens before platform-independent.
168 : return initialized;
169 : }
170 :
171 : #ifdef DEBUG
172 : bool AllStackParametersAreTagged() const;
173 : #endif // DEBUG
174 :
175 : int register_param_count_ = -1;
176 : int return_count_ = -1;
177 : int param_count_ = -1;
178 : Flags flags_ = kNoFlags;
179 :
180 : // Specifying the set of registers that could be used by the register
181 : // allocator. Currently, it's only used by RecordWrite code stub.
182 : RegList allocatable_registers_ = 0;
183 :
184 : // |registers_params_| defines registers that are used for parameter passing.
185 : // |machine_types_| defines machine types for resulting values and incomping
186 : // parameters.
187 : // Both arrays are allocated dynamically by the InterfaceDescriptor and
188 : // freed on destruction. This is because static arrays cause creation of
189 : // runtime static initializers which we don't want.
190 : Register* register_params_ = nullptr;
191 : MachineType* machine_types_ = nullptr;
192 :
193 : DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
194 : };
195 :
196 : class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
197 : public:
198 : enum Key {
199 : #define DEF_ENUM(name, ...) name,
200 : INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
201 : #undef DEF_ENUM
202 : NUMBER_OF_DESCRIPTORS
203 : };
204 :
205 : static void InitializeOncePerProcess();
206 : static void TearDown();
207 :
208 93856 : static CallInterfaceDescriptorData* call_descriptor_data(
209 : CallDescriptors::Key key) {
210 2980906 : return &call_descriptor_data_[key];
211 : }
212 :
213 : static Key GetKey(const CallInterfaceDescriptorData* data) {
214 3482878 : ptrdiff_t index = data - call_descriptor_data_;
215 : DCHECK_LE(0, index);
216 : DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
217 : return static_cast<CallDescriptors::Key>(index);
218 : }
219 :
220 : private:
221 : static CallInterfaceDescriptorData
222 : call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
223 : };
224 :
225 11631419 : class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
226 : public:
227 : typedef CallInterfaceDescriptorData::Flags Flags;
228 :
229 : CallInterfaceDescriptor() : data_(nullptr) {}
230 26415108 : virtual ~CallInterfaceDescriptor() = default;
231 :
232 93856 : explicit CallInterfaceDescriptor(CallDescriptors::Key key)
233 14959408 : : data_(CallDescriptors::call_descriptor_data(key)) {}
234 :
235 : Flags flags() const { return data()->flags(); }
236 :
237 : bool HasContextParameter() const {
238 : return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
239 : }
240 :
241 : int GetReturnCount() const { return data()->return_count(); }
242 :
243 : MachineType GetReturnType(int index) const {
244 : DCHECK_LT(index, data()->return_count());
245 : return data()->return_type(index);
246 : }
247 :
248 2688 : int GetParameterCount() const { return data()->param_count(); }
249 :
250 : int GetRegisterParameterCount() const {
251 : return data()->register_param_count();
252 : }
253 :
254 : int GetStackParameterCount() const {
255 2714502 : return data()->param_count() - data()->register_param_count();
256 : }
257 :
258 : Register GetRegisterParameter(int index) const {
259 : return data()->register_param(index);
260 : }
261 :
262 : MachineType GetParameterType(int index) const {
263 : DCHECK_LT(index, data()->param_count());
264 : return data()->param_type(index);
265 : }
266 :
267 : RegList allocatable_registers() const {
268 : return data()->allocatable_registers();
269 : }
270 :
271 : static const Register ContextRegister();
272 :
273 : const char* DebugName() const;
274 :
275 : protected:
276 2688 : const CallInterfaceDescriptorData* data() const { return data_; }
277 :
278 0 : virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
279 0 : UNREACHABLE();
280 : }
281 :
282 120196 : virtual void InitializePlatformIndependent(
283 : CallInterfaceDescriptorData* data) {
284 : // Default descriptor configuration: one result, all parameters are passed
285 : // in registers and all parameters have MachineType::AnyTagged() type.
286 120196 : data->InitializePlatformIndependent(CallInterfaceDescriptorData::kNoFlags,
287 : 1, data->register_param_count(),
288 120196 : nullptr, 0);
289 120196 : }
290 :
291 : // Initializes |data| using the platform dependent default set of registers.
292 : // It is intended to be used for TurboFan stubs when particular set of
293 : // registers does not matter.
294 : static void DefaultInitializePlatformSpecific(
295 : CallInterfaceDescriptorData* data, int register_parameter_count);
296 :
297 : // Initializes |data| using the platform dependent default set of registers
298 : // for JavaScript-compatible calling convention.
299 : // It is intended to be used for TurboFan stubs being called with JavaScript
300 : // linkage + additional parameters on registers and stack.
301 : static void JSDefaultInitializePlatformSpecific(
302 : CallInterfaceDescriptorData* data, int non_js_register_parameter_count);
303 :
304 : // Checks if float parameters are not assigned invalid registers.
305 : bool CheckFloatingPointParameters(CallInterfaceDescriptorData* data) {
306 : for (int i = 0; i < data->register_param_count(); i++) {
307 : if (IsFloatingPoint(data->param_type(i).representation())) {
308 : if (!IsValidFloatParameterRegister(data->register_param(i))) {
309 : return false;
310 : }
311 : }
312 : }
313 : return true;
314 : }
315 :
316 : bool IsValidFloatParameterRegister(Register reg);
317 :
318 : private:
319 : // {CallDescriptors} is allowed to call the private {Initialize} method.
320 : friend class CallDescriptors;
321 :
322 : const CallInterfaceDescriptorData* data_;
323 :
324 2223626 : void Initialize(CallInterfaceDescriptorData* data) {
325 : // The passed pointer should be a modifiable pointer to our own data.
326 : DCHECK_EQ(data, data_);
327 : DCHECK(!data->IsInitialized());
328 14603814 : InitializePlatformSpecific(data);
329 14603814 : InitializePlatformIndependent(data);
330 : DCHECK(data->IsInitialized());
331 : DCHECK(CheckFloatingPointParameters(data));
332 2223626 : }
333 : };
334 :
335 : #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
336 : public: \
337 : explicit name() : base(key()) {} \
338 : static inline CallDescriptors::Key key();
339 :
340 : #if defined(V8_TARGET_ARCH_IA32)
341 : // To support all possible cases, we must limit the number of register args for
342 : // TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
343 : // as the context register and ebx is the root register. One register must
344 : // remain available to store the jump/call target. Thus 3 registers remain for
345 : // arguments. The reason this applies to TFS builtins specifically is because
346 : // this becomes relevant for builtins used as targets of Torque function
347 : // pointers (which must have a register available to store the target).
348 : // TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
349 : // that comes with its own set of complications. It's possible, but requires
350 : // refactoring the calling convention of other existing stubs.
351 : constexpr int kMaxBuiltinRegisterParams = 4;
352 : constexpr int kMaxTFSBuiltinRegisterParams = 3;
353 : #else
354 : constexpr int kMaxBuiltinRegisterParams = 5;
355 : constexpr int kMaxTFSBuiltinRegisterParams = kMaxBuiltinRegisterParams;
356 : #endif
357 : STATIC_ASSERT(kMaxTFSBuiltinRegisterParams <= kMaxBuiltinRegisterParams);
358 :
359 : #define DECLARE_DEFAULT_DESCRIPTOR(name, base) \
360 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
361 : protected: \
362 : static const int kRegisterParams = \
363 : kParameterCount > kMaxTFSBuiltinRegisterParams \
364 : ? kMaxTFSBuiltinRegisterParams \
365 : : kParameterCount; \
366 : static const int kStackParams = kParameterCount - kRegisterParams; \
367 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
368 : override { \
369 : DefaultInitializePlatformSpecific(data, kRegisterParams); \
370 : } \
371 : void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
372 : override { \
373 : data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
374 : kParameterCount, nullptr, 0); \
375 : } \
376 : name(CallDescriptors::Key key) : base(key) {} \
377 : \
378 : public:
379 :
380 : #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base, \
381 : non_js_reg_parameters_count) \
382 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
383 : protected: \
384 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
385 : override { \
386 : JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
387 : } \
388 : name(CallDescriptors::Key key) : base(key) {} \
389 : \
390 : public:
391 :
392 : #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
393 : static constexpr int kDescriptorFlags = \
394 : CallInterfaceDescriptorData::kNoFlags; \
395 : static constexpr int kReturnCount = return_count; \
396 : enum ParameterIndices { \
397 : __dummy = -1, /* to be able to pass zero arguments */ \
398 : ##__VA_ARGS__, \
399 : \
400 : kParameterCount, \
401 : kContext = kParameterCount /* implicit parameter */ \
402 : };
403 :
404 : #define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \
405 : static constexpr int kDescriptorFlags = \
406 : CallInterfaceDescriptorData::kNoContext; \
407 : static constexpr int kReturnCount = return_count; \
408 : enum ParameterIndices { \
409 : __dummy = -1, /* to be able to pass zero arguments */ \
410 : ##__VA_ARGS__, \
411 : \
412 : kParameterCount \
413 : };
414 :
415 : // This is valid only for builtins that use EntryFrame, which does not scan
416 : // stack arguments on GC.
417 : #define DEFINE_PARAMETERS_ENTRY(...) \
418 : static constexpr int kDescriptorFlags = \
419 : CallInterfaceDescriptorData::kNoContext | \
420 : CallInterfaceDescriptorData::kNoStackScan; \
421 : static constexpr int kReturnCount = 1; \
422 : enum ParameterIndices { \
423 : __dummy = -1, /* to be able to pass zero arguments */ \
424 : ##__VA_ARGS__, \
425 : \
426 : kParameterCount \
427 : };
428 :
429 : #define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
430 :
431 : #define DEFINE_PARAMETERS_NO_CONTEXT(...) \
432 : DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(1, ##__VA_ARGS__)
433 :
434 : #define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
435 : void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
436 : override { \
437 : MachineType machine_types[] = {__VA_ARGS__}; \
438 : static_assert( \
439 : kReturnCount + kParameterCount == arraysize(machine_types), \
440 : "Parameter names definition is not consistent with parameter types"); \
441 : data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
442 : kParameterCount, machine_types, \
443 : arraysize(machine_types)); \
444 : }
445 :
446 : #define DEFINE_PARAMETER_TYPES(...) \
447 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
448 : ##__VA_ARGS__)
449 :
450 : #define DEFINE_JS_PARAMETERS(...) \
451 : static constexpr int kDescriptorFlags = \
452 : CallInterfaceDescriptorData::kNoFlags; \
453 : static constexpr int kReturnCount = 1; \
454 : enum ParameterIndices { \
455 : kTarget, \
456 : kNewTarget, \
457 : kActualArgumentsCount, \
458 : ##__VA_ARGS__, \
459 : \
460 : kParameterCount, \
461 : kContext = kParameterCount /* implicit parameter */ \
462 : };
463 :
464 : #define DEFINE_JS_PARAMETER_TYPES(...) \
465 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */ \
466 : MachineType::AnyTagged(), /* kNewTarget */ \
467 : MachineType::Int32(), /* kActualArgumentsCount */ \
468 : ##__VA_ARGS__)
469 :
470 : #define DECLARE_DESCRIPTOR(name, base) \
471 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
472 : protected: \
473 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
474 : name(CallDescriptors::Key key) : base(key) {} \
475 : \
476 : public:
477 :
478 120293 : class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
479 : public:
480 : DEFINE_PARAMETERS()
481 120196 : DEFINE_PARAMETER_TYPES()
482 60195 : DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
483 : };
484 :
485 : // Dummy descriptor used to mark builtins that don't yet have their proper
486 : // descriptor associated.
487 : typedef VoidDescriptor DummyDescriptor;
488 :
489 : // Dummy descriptor that marks builtins with C calling convention.
490 : typedef VoidDescriptor CCallDescriptor;
491 :
492 378332 : class AllocateDescriptor : public CallInterfaceDescriptor {
493 : public:
494 : DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
495 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
496 : MachineType::IntPtr()) // kRequestedSize
497 189164 : DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
498 : };
499 :
500 : // This descriptor defines the JavaScript calling convention that can be used
501 : // by stubs: target, new.target, argc (not including the receiver) and context
502 : // are passed in registers while receiver and the rest of the JS arguments are
503 : // passed on the stack.
504 120700 : class JSTrampolineDescriptor : public CallInterfaceDescriptor {
505 : public:
506 : DEFINE_JS_PARAMETERS()
507 120196 : DEFINE_JS_PARAMETER_TYPES()
508 :
509 120700 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
510 : CallInterfaceDescriptor, 0)
511 : };
512 :
513 120196 : class ContextOnlyDescriptor : public CallInterfaceDescriptor {
514 : public:
515 : DEFINE_PARAMETERS()
516 120196 : DEFINE_PARAMETER_TYPES()
517 60098 : DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
518 : };
519 :
520 144876 : class NoContextDescriptor : public CallInterfaceDescriptor {
521 : public:
522 : DEFINE_PARAMETERS_NO_CONTEXT()
523 120196 : DEFINE_PARAMETER_TYPES()
524 72457 : DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
525 : };
526 :
527 : // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
528 241817 : class LoadDescriptor : public CallInterfaceDescriptor {
529 : public:
530 : DEFINE_PARAMETERS(kReceiver, kName, kSlot)
531 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
532 : MachineType::AnyTagged(), // kName
533 : MachineType::TaggedSigned()) // kSlot
534 121596 : DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
535 :
536 : static const Register ReceiverRegister();
537 : static const Register NameRegister();
538 : static const Register SlotRegister();
539 : };
540 :
541 240392 : class LoadGlobalDescriptor : public CallInterfaceDescriptor {
542 : public:
543 : DEFINE_PARAMETERS(kName, kSlot)
544 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
545 : MachineType::TaggedSigned()) // kSlot
546 120196 : DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
547 :
548 : static const Register NameRegister() {
549 120196 : return LoadDescriptor::NameRegister();
550 : }
551 :
552 : static const Register SlotRegister() {
553 120196 : return LoadDescriptor::SlotRegister();
554 : }
555 : };
556 :
557 360987 : class StoreDescriptor : public CallInterfaceDescriptor {
558 : public:
559 : DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
560 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
561 : MachineType::AnyTagged(), // kName
562 : MachineType::AnyTagged(), // kValue
563 : MachineType::TaggedSigned()) // kSlot
564 180686 : DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
565 :
566 : static const Register ReceiverRegister();
567 : static const Register NameRegister();
568 : static const Register ValueRegister();
569 : static const Register SlotRegister();
570 :
571 : #if V8_TARGET_ARCH_IA32
572 : static const bool kPassLastArgsOnStack = true;
573 : #else
574 : static const bool kPassLastArgsOnStack = false;
575 : #endif
576 :
577 : // Pass value and slot through the stack.
578 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
579 : };
580 :
581 120310 : class StoreTransitionDescriptor : public StoreDescriptor {
582 : public:
583 : DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
584 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
585 : MachineType::AnyTagged(), // kName
586 : MachineType::AnyTagged(), // kMap
587 : MachineType::AnyTagged(), // kValue
588 : MachineType::TaggedSigned(), // kSlot
589 : MachineType::AnyTagged()) // kVector
590 60210 : DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
591 :
592 : static const Register MapRegister();
593 : static const Register SlotRegister();
594 : static const Register VectorRegister();
595 :
596 : // Pass value, slot and vector through the stack.
597 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
598 : };
599 :
600 120481 : class StoreWithVectorDescriptor : public StoreDescriptor {
601 : public:
602 : DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
603 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
604 : MachineType::AnyTagged(), // kName
605 : MachineType::AnyTagged(), // kValue
606 : MachineType::TaggedSigned(), // kSlot
607 : MachineType::AnyTagged()) // kVector
608 60378 : DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
609 :
610 : static const Register VectorRegister();
611 :
612 : // Pass value, slot and vector through the stack.
613 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
614 : };
615 :
616 240392 : class StoreGlobalDescriptor : public CallInterfaceDescriptor {
617 : public:
618 : DEFINE_PARAMETERS(kName, kValue, kSlot)
619 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
620 : MachineType::AnyTagged(), // kValue
621 : MachineType::TaggedSigned()) // kSlot
622 120196 : DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
623 :
624 : static const bool kPassLastArgsOnStack =
625 : StoreDescriptor::kPassLastArgsOnStack;
626 : // Pass value and slot through the stack.
627 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
628 :
629 : static const Register NameRegister() {
630 120196 : return StoreDescriptor::NameRegister();
631 : }
632 :
633 : static const Register ValueRegister() {
634 120196 : return StoreDescriptor::ValueRegister();
635 : }
636 :
637 : static const Register SlotRegister() {
638 120196 : return StoreDescriptor::SlotRegister();
639 : }
640 : };
641 :
642 120196 : class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
643 : public:
644 : DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
645 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
646 : MachineType::AnyTagged(), // kValue
647 : MachineType::TaggedSigned(), // kSlot
648 : MachineType::AnyTagged()) // kVector
649 60098 : DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
650 :
651 : static const Register VectorRegister() {
652 60098 : return StoreWithVectorDescriptor::VectorRegister();
653 : }
654 :
655 : // Pass value, slot and vector through the stack.
656 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
657 : };
658 :
659 121621 : class LoadWithVectorDescriptor : public LoadDescriptor {
660 : public:
661 : DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
662 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
663 : MachineType::AnyTagged(), // kName
664 : MachineType::TaggedSigned(), // kSlot
665 : MachineType::AnyTagged()) // kVector
666 61498 : DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
667 :
668 : static const Register VectorRegister();
669 :
670 : #if V8_TARGET_ARCH_IA32
671 : static const bool kPassLastArgsOnStack = true;
672 : #else
673 : static const bool kPassLastArgsOnStack = false;
674 : #endif
675 :
676 : // Pass vector through the stack.
677 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
678 : };
679 :
680 120196 : class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
681 : public:
682 : DEFINE_PARAMETERS(kName, kSlot, kVector)
683 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
684 : MachineType::TaggedSigned(), // kSlot
685 : MachineType::AnyTagged()) // kVector
686 60098 : DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
687 :
688 : #if V8_TARGET_ARCH_IA32
689 : // On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
690 : // need to choose a new register here.
691 : static const Register VectorRegister() { return edx; }
692 : #else
693 : static const Register VectorRegister() {
694 60098 : return LoadWithVectorDescriptor::VectorRegister();
695 : }
696 : #endif
697 : };
698 :
699 120196 : class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor {
700 : public:
701 : DEFINE_PARAMETERS(kScopeInfo, kSlots)
702 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kScopeInfo
703 : MachineType::Int32()) // kSlots
704 60098 : DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor)
705 :
706 : static const Register ScopeInfoRegister();
707 : static const Register SlotsRegister();
708 : };
709 :
710 120196 : class FastNewObjectDescriptor : public CallInterfaceDescriptor {
711 : public:
712 : DEFINE_PARAMETERS(kTarget, kNewTarget)
713 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
714 : MachineType::AnyTagged()) // kNewTarget
715 60098 : DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
716 : static const Register TargetRegister();
717 : static const Register NewTargetRegister();
718 : };
719 :
720 120253 : class RecordWriteDescriptor final : public CallInterfaceDescriptor {
721 : public:
722 : DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
723 120196 : DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
724 : MachineType::Pointer(), // kSlot
725 : MachineType::TaggedSigned(), // kRememberedSet
726 : MachineType::TaggedSigned()) // kFPMode
727 :
728 60154 : DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
729 : };
730 :
731 287609 : class TypeConversionDescriptor final : public CallInterfaceDescriptor {
732 : public:
733 : DEFINE_PARAMETERS(kArgument)
734 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
735 143830 : DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
736 :
737 : static const Register ArgumentRegister();
738 : };
739 :
740 120196 : class TypeConversionStackParameterDescriptor final
741 : : public CallInterfaceDescriptor {
742 : public:
743 : DEFINE_PARAMETERS(kArgument)
744 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
745 60098 : DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor,
746 : CallInterfaceDescriptor)
747 : };
748 :
749 120196 : class AsyncFunctionStackParameterDescriptor final
750 : : public CallInterfaceDescriptor {
751 : public:
752 : DEFINE_PARAMETERS(kPromise, kResult)
753 120196 : DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
754 60098 : DECLARE_DESCRIPTOR(AsyncFunctionStackParameterDescriptor,
755 : CallInterfaceDescriptor)
756 : };
757 :
758 120196 : class GetPropertyDescriptor final : public CallInterfaceDescriptor {
759 : public:
760 : DEFINE_PARAMETERS(kObject, kKey)
761 240392 : DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
762 : };
763 :
764 120196 : class TypeofDescriptor : public CallInterfaceDescriptor {
765 : public:
766 : DEFINE_PARAMETERS(kObject)
767 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
768 60098 : DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
769 : };
770 :
771 123921 : class CallTrampolineDescriptor : public CallInterfaceDescriptor {
772 : public:
773 : DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
774 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
775 : MachineType::Int32()) // kActualArgumentsCount
776 62098 : DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
777 : };
778 :
779 120196 : class CallVarargsDescriptor : public CallInterfaceDescriptor {
780 : public:
781 : DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsLength,
782 : kArgumentsList)
783 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
784 : MachineType::Int32(), // kActualArgumentsCount
785 : MachineType::Int32(), // kArgumentsLength
786 : MachineType::AnyTagged()) // kArgumentsList
787 60098 : DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
788 : };
789 :
790 120196 : class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
791 : public:
792 : DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kStartIndex)
793 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
794 : MachineType::Int32(), // kActualArgumentsCount
795 : MachineType::Int32()) // kStartIndex
796 60098 : DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
797 : };
798 :
799 120196 : class CallFunctionTemplateDescriptor : public CallInterfaceDescriptor {
800 : public:
801 : DEFINE_PARAMETERS(kFunctionTemplateInfo, kArgumentsCount)
802 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunctionTemplateInfo
803 : MachineType::IntPtr()) // kArgumentsCount
804 60098 : DECLARE_DESCRIPTOR(CallFunctionTemplateDescriptor, CallInterfaceDescriptor)
805 : };
806 :
807 120196 : class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
808 : public:
809 : DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread)
810 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
811 : MachineType::Int32(), // kArgumentsCount
812 : MachineType::AnyTagged()) // kSpread
813 60098 : DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
814 : };
815 :
816 120196 : class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
817 : public:
818 : DEFINE_PARAMETERS(kTarget, kArgumentsList)
819 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
820 : MachineType::AnyTagged()) // kArgumentsList
821 60098 : DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
822 : };
823 :
824 120196 : class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
825 : public:
826 : DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
827 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(), // kArgumentsLength
828 : MachineType::AnyTagged()) // kArgumentsList
829 :
830 60098 : DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
831 : };
832 :
833 120196 : class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
834 : public:
835 : DEFINE_JS_PARAMETERS(kStartIndex)
836 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
837 60098 : DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
838 : };
839 :
840 120196 : class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
841 : public:
842 : DEFINE_JS_PARAMETERS(kSpread)
843 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
844 60098 : DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
845 : };
846 :
847 120196 : class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
848 : public:
849 : DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
850 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
851 : MachineType::AnyTagged(), // kNewTarget
852 : MachineType::AnyTagged()) // kArgumentsList
853 60098 : DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
854 : };
855 :
856 : // TODO(ishell): consider merging this with ArrayConstructorDescriptor
857 122511 : class ConstructStubDescriptor : public CallInterfaceDescriptor {
858 : public:
859 : // TODO(jgruber): Remove the unused allocation site parameter.
860 : DEFINE_JS_PARAMETERS(kAllocationSite)
861 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
862 :
863 : // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
864 62413 : DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
865 : };
866 :
867 120196 : class AbortDescriptor : public CallInterfaceDescriptor {
868 : public:
869 : DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
870 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
871 60098 : DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
872 : };
873 :
874 174068 : class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
875 : public:
876 : DEFINE_PARAMETERS_NO_CONTEXT()
877 120196 : DEFINE_PARAMETER_TYPES()
878 87310 : DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
879 : };
880 :
881 120434 : class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
882 : public:
883 : DEFINE_JS_PARAMETERS(kAllocationSite)
884 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
885 :
886 120315 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
887 : CallInterfaceDescriptor, 1)
888 : };
889 :
890 361386 : class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
891 : public:
892 : // This descriptor declares only register arguments while respective number
893 : // of JS arguments stay on the expression stack.
894 : // The ArrayNArgumentsConstructor builtin does not access stack arguments
895 : // directly it just forwards them to the runtime function.
896 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
897 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction,
898 : MachineType::AnyTagged(), // kAllocationSite
899 : MachineType::Int32()) // kActualArgumentsCount
900 181078 : DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
901 : CallInterfaceDescriptor)
902 : };
903 :
904 120196 : class ArrayNoArgumentConstructorDescriptor
905 : : public ArrayNArgumentsConstructorDescriptor {
906 : public:
907 : // This descriptor declares same register arguments as the parent
908 : // ArrayNArgumentsConstructorDescriptor and it declares indices for
909 : // JS arguments passed on the expression stack.
910 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
911 : kFunctionParameter)
912 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
913 : MachineType::AnyTagged(), // kAllocationSite
914 : MachineType::Int32(), // kActualArgumentsCount
915 : MachineType::AnyTagged()) // kFunctionParameter
916 60098 : DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
917 : ArrayNArgumentsConstructorDescriptor)
918 : };
919 :
920 120196 : class ArraySingleArgumentConstructorDescriptor
921 : : public ArrayNArgumentsConstructorDescriptor {
922 : public:
923 : // This descriptor declares same register arguments as the parent
924 : // ArrayNArgumentsConstructorDescriptor and it declares indices for
925 : // JS arguments passed on the expression stack.
926 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
927 : kFunctionParameter, kArraySizeSmiParameter)
928 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
929 : MachineType::AnyTagged(), // kAllocationSite
930 : MachineType::Int32(), // kActualArgumentsCount
931 : MachineType::AnyTagged(), // kFunctionParameter
932 : MachineType::AnyTagged()) // kArraySizeSmiParameter
933 60098 : DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
934 : ArrayNArgumentsConstructorDescriptor)
935 : };
936 :
937 120196 : class CompareDescriptor : public CallInterfaceDescriptor {
938 : public:
939 : DEFINE_PARAMETERS(kLeft, kRight)
940 60098 : DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
941 : };
942 :
943 :
944 120196 : class BinaryOpDescriptor : public CallInterfaceDescriptor {
945 : public:
946 : DEFINE_PARAMETERS(kLeft, kRight)
947 60098 : DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
948 : };
949 :
950 : // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
951 : // as they all have the same interface.
952 120196 : class StringAtDescriptor final : public CallInterfaceDescriptor {
953 : public:
954 : DEFINE_PARAMETERS(kReceiver, kPosition)
955 : // TODO(turbofan): Return untagged value here.
956 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(), // result 1
957 : MachineType::AnyTagged(), // kReceiver
958 : MachineType::IntPtr()) // kPosition
959 60098 : DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
960 : };
961 :
962 120196 : class StringSubstringDescriptor final : public CallInterfaceDescriptor {
963 : public:
964 : DEFINE_PARAMETERS(kString, kFrom, kTo)
965 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kString
966 : MachineType::IntPtr(), // kFrom
967 : MachineType::IntPtr()) // kTo
968 :
969 : // TODO(turbofan): Allow builtins to return untagged values.
970 60098 : DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
971 : };
972 :
973 121472 : class ArgumentsAdaptorDescriptor : public CallInterfaceDescriptor {
974 : public:
975 : DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
976 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
977 60736 : DECLARE_DESCRIPTOR(ArgumentsAdaptorDescriptor, CallInterfaceDescriptor)
978 : };
979 :
980 120196 : class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
981 : public:
982 : DEFINE_JS_PARAMETERS(kCFunction)
983 120196 : DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
984 120196 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
985 : CallInterfaceDescriptor, 1)
986 : };
987 :
988 120310 : class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
989 : public:
990 : DEFINE_PARAMETERS(kArity, // register argument
991 : kCFunction, // register argument
992 : kPadding, // stack argument 1 (just padding)
993 : kArgcSmi, // stack argument 2
994 : kTargetCopy, // stack argument 3
995 : kNewTargetCopy) // stack argument 4
996 120196 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kArity
997 : MachineType::Pointer(), // kCFunction
998 : MachineType::AnyTagged(), // kPadding
999 : MachineType::AnyTagged(), // kArgcSmi
1000 : MachineType::AnyTagged(), // kTargetCopy
1001 : MachineType::AnyTagged()) // kNewTargetCopy
1002 60210 : DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
1003 : };
1004 :
1005 120196 : class ApiCallbackDescriptor : public CallInterfaceDescriptor {
1006 : public:
1007 : DEFINE_PARAMETERS(kApiFunctionAddress, kActualArgumentsCount, kCallData,
1008 : kHolder)
1009 : // receiver is implicit stack argument 1
1010 : // argv are implicit stack arguments [2, 2 + kArgc[
1011 120196 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kApiFunctionAddress
1012 : MachineType::IntPtr(), // kActualArgumentsCount
1013 : MachineType::AnyTagged(), // kCallData
1014 : MachineType::AnyTagged()) // kHolder
1015 60098 : DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
1016 : };
1017 :
1018 120196 : class ApiGetterDescriptor : public CallInterfaceDescriptor {
1019 : public:
1020 : DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
1021 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1022 : MachineType::AnyTagged(), // kHolder
1023 : MachineType::AnyTagged()) // kCallback
1024 60098 : DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
1025 :
1026 : static const Register ReceiverRegister();
1027 : static const Register HolderRegister();
1028 : static const Register CallbackRegister();
1029 : };
1030 :
1031 : // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
1032 120196 : class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
1033 : public:
1034 : DEFINE_PARAMETERS(kObject, kKey)
1035 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kObject
1036 : MachineType::AnyTagged()) // kKey
1037 60098 : DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
1038 :
1039 : static const Register ObjectRegister();
1040 : static const Register KeyRegister();
1041 : };
1042 :
1043 120196 : class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
1044 : public:
1045 : DEFINE_PARAMETERS(kFrame, kLength, kMappedCount)
1046 120196 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kFrame
1047 : MachineType::TaggedSigned(), // kLength
1048 : MachineType::TaggedSigned()) // kMappedCount
1049 60098 : DECLARE_DESCRIPTOR(NewArgumentsElementsDescriptor, CallInterfaceDescriptor)
1050 : };
1051 :
1052 193120 : class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
1053 : : public CallInterfaceDescriptor {
1054 : public:
1055 : DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
1056 : kDispatchTable)
1057 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kAccumulator
1058 : MachineType::IntPtr(), // kBytecodeOffset
1059 : MachineType::AnyTagged(), // kBytecodeArray
1060 : MachineType::IntPtr()) // kDispatchTable
1061 131768 : DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
1062 : };
1063 :
1064 120196 : class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
1065 : public:
1066 : DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
1067 120196 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
1068 : MachineType::Pointer(), // kFirstArgument
1069 : MachineType::AnyTagged()) // kFunction
1070 60098 : DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
1071 : CallInterfaceDescriptor)
1072 : };
1073 :
1074 120196 : class InterpreterPushArgsThenConstructDescriptor
1075 : : public CallInterfaceDescriptor {
1076 : public:
1077 : DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
1078 : kNewTarget, kFeedbackElement)
1079 120196 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
1080 : MachineType::Pointer(), // kFirstArgument
1081 : MachineType::AnyTagged(), // kConstructor
1082 : MachineType::AnyTagged(), // kNewTarget
1083 : MachineType::AnyTagged()) // kFeedbackElement
1084 60098 : DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
1085 : CallInterfaceDescriptor)
1086 :
1087 : #if V8_TARGET_ARCH_IA32
1088 : static const bool kPassLastArgsOnStack = true;
1089 : #else
1090 : static const bool kPassLastArgsOnStack = false;
1091 : #endif
1092 :
1093 : // Pass constructor, new target and feedback element through the stack.
1094 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
1095 : };
1096 :
1097 120196 : class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
1098 : public:
1099 : DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
1100 : kFunctionEntry)
1101 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1102 : MachineType::Int32(), // kNumberOfArguments
1103 : MachineType::Pointer(), // kFirstArgument
1104 : MachineType::Pointer()) // kFunctionEntry
1105 60098 : DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
1106 : };
1107 :
1108 120196 : class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
1109 : public:
1110 : DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
1111 : kFunctionEntry)
1112 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1113 : MachineType::AnyTagged(), // result 2
1114 : MachineType::Int32(), // kNumberOfArguments
1115 : MachineType::Pointer(), // kFirstArgument
1116 : MachineType::Pointer()) // kFunctionEntry
1117 60098 : DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
1118 : };
1119 :
1120 120196 : class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
1121 : public:
1122 : DEFINE_PARAMETERS(kValue, kGenerator)
1123 120196 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
1124 : MachineType::AnyTagged()) // kGenerator
1125 60098 : DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
1126 : };
1127 :
1128 120196 : class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
1129 : public:
1130 : DEFINE_PARAMETERS(kRestartFp)
1131 120196 : DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1132 60098 : DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
1133 : };
1134 :
1135 120196 : class RunMicrotasksEntryDescriptor final : public CallInterfaceDescriptor {
1136 : public:
1137 : DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
1138 120196 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kRootRegisterValue
1139 : MachineType::Pointer()) // kMicrotaskQueue
1140 60098 : DECLARE_DESCRIPTOR(RunMicrotasksEntryDescriptor, CallInterfaceDescriptor)
1141 : };
1142 :
1143 120196 : class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
1144 : public:
1145 : DEFINE_PARAMETERS(kMicrotaskQueue)
1146 120196 : DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1147 60098 : DECLARE_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)
1148 :
1149 : static Register MicrotaskQueueRegister();
1150 : };
1151 :
1152 121328 : class WasmMemoryGrowDescriptor final : public CallInterfaceDescriptor {
1153 : public:
1154 : DEFINE_PARAMETERS_NO_CONTEXT(kNumPages)
1155 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(), // result 1
1156 : MachineType::Int32()) // kNumPages
1157 61230 : DECLARE_DESCRIPTOR(WasmMemoryGrowDescriptor, CallInterfaceDescriptor)
1158 : };
1159 :
1160 120260 : class WasmTableGetDescriptor final : public CallInterfaceDescriptor {
1161 : public:
1162 : DEFINE_PARAMETERS_NO_CONTEXT(kTableIndex, kEntryIndex)
1163 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1164 : MachineType::TaggedSigned(), // kTableIndex
1165 : MachineType::Int32()) // kEntryIndex
1166 60162 : DECLARE_DESCRIPTOR(WasmTableGetDescriptor, CallInterfaceDescriptor)
1167 : };
1168 :
1169 120228 : class WasmTableSetDescriptor final : public CallInterfaceDescriptor {
1170 : public:
1171 : DEFINE_PARAMETERS_NO_CONTEXT(kTableIndex, kEntryIndex, kValue)
1172 120196 : DEFINE_PARAMETER_TYPES(MachineType::TaggedSigned(), // kTableIndex
1173 : MachineType::Int32(), // kEntryIndex
1174 : MachineType::AnyTagged()) // kValue
1175 60130 : DECLARE_DESCRIPTOR(WasmTableSetDescriptor, CallInterfaceDescriptor)
1176 : };
1177 :
1178 121177 : class WasmThrowDescriptor final : public CallInterfaceDescriptor {
1179 : public:
1180 : DEFINE_PARAMETERS_NO_CONTEXT(kException)
1181 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1182 : MachineType::AnyTagged()) // kException
1183 61081 : DECLARE_DESCRIPTOR(WasmThrowDescriptor, CallInterfaceDescriptor)
1184 : };
1185 :
1186 120285 : class I64ToBigIntDescriptor final : public CallInterfaceDescriptor {
1187 : public:
1188 : DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
1189 120196 : DEFINE_PARAMETER_TYPES(MachineType::Int64()) // kArgument
1190 60186 : DECLARE_DESCRIPTOR(I64ToBigIntDescriptor, CallInterfaceDescriptor)
1191 : };
1192 :
1193 120269 : class BigIntToI64Descriptor final : public CallInterfaceDescriptor {
1194 : public:
1195 : DEFINE_PARAMETERS(kArgument)
1196 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(), // result 1
1197 : MachineType::AnyTagged()) // kArgument
1198 60170 : DECLARE_DESCRIPTOR(BigIntToI64Descriptor, CallInterfaceDescriptor)
1199 : };
1200 :
1201 120612 : class WasmAtomicNotifyDescriptor final : public CallInterfaceDescriptor {
1202 : public:
1203 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kCount)
1204 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
1205 : MachineType::Uint32(), // kAddress
1206 : MachineType::Uint32()) // kCount
1207 60306 : DECLARE_DESCRIPTOR(WasmAtomicNotifyDescriptor, CallInterfaceDescriptor)
1208 : };
1209 :
1210 120812 : class WasmI32AtomicWaitDescriptor final : public CallInterfaceDescriptor {
1211 : public:
1212 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
1213 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
1214 : MachineType::Uint32(), // kAddress
1215 : MachineType::Int32(), // kExpectedValue
1216 : MachineType::Float64()) // kTimeout
1217 60406 : DECLARE_DESCRIPTOR(WasmI32AtomicWaitDescriptor, CallInterfaceDescriptor)
1218 : };
1219 :
1220 120940 : class WasmI64AtomicWaitDescriptor final : public CallInterfaceDescriptor {
1221 : public:
1222 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValueHigh, kExpectedValueLow,
1223 : kTimeout)
1224 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(
1225 : MachineType::Uint32(), // result 1
1226 : MachineType::Uint32(), // kAddress
1227 : MachineType::Uint32(), // kExpectedValueHigh
1228 : MachineType::Uint32(), // kExpectedValueLow
1229 : MachineType::Float64()) // kTimeout
1230 60469 : DECLARE_DESCRIPTOR(WasmI64AtomicWaitDescriptor, CallInterfaceDescriptor)
1231 : };
1232 :
1233 120196 : class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
1234 : public:
1235 : DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
1236 120196 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
1237 : MachineType::AnyTagged(), // kSource
1238 : MachineType::TaggedSigned(), // kFlags
1239 : MachineType::TaggedSigned(), // kSlot
1240 : MachineType::AnyTagged()) // kVector
1241 60098 : DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
1242 : };
1243 :
1244 : #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...) \
1245 : class Name##Descriptor : public CallInterfaceDescriptor { \
1246 : public: \
1247 : DEFINE_PARAMETERS(__VA_ARGS__) \
1248 : DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
1249 : };
1250 62682214 : BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
1251 : #undef DEFINE_TFS_BUILTIN_DESCRIPTOR
1252 :
1253 : #undef DECLARE_DEFAULT_DESCRIPTOR
1254 : #undef DECLARE_DESCRIPTOR_WITH_BASE
1255 : #undef DECLARE_DESCRIPTOR
1256 : #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
1257 : #undef DEFINE_RESULT_AND_PARAMETERS
1258 : #undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT
1259 : #undef DEFINE_PARAMETERS
1260 : #undef DEFINE_PARAMETERS_NO_CONTEXT
1261 : #undef DEFINE_RESULT_AND_PARAMETER_TYPES
1262 : #undef DEFINE_PARAMETER_TYPES
1263 : #undef DEFINE_JS_PARAMETERS
1264 : #undef DEFINE_JS_PARAMETER_TYPES
1265 :
1266 : // We define the association between CallDescriptors::Key and the specialized
1267 : // descriptor here to reduce boilerplate and mistakes.
1268 : #define DEF_KEY(name, ...) \
1269 : CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
1270 73976 : INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
1271 : #undef DEF_KEY
1272 : } // namespace internal
1273 : } // namespace v8
1274 :
1275 : #endif // V8_INTERFACE_DESCRIPTORS_H_
|