• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CODEGEN_INTERFACE_DESCRIPTORS_H_
6 #define V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
7 
8 #include <memory>
9 
10 #include "src/codegen/machine-type.h"
11 #include "src/codegen/register-arch.h"
12 #include "src/codegen/tnode.h"
13 #include "src/common/globals.h"
14 #include "src/execution/isolate.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 #define TORQUE_BUILTIN_LIST_TFC(V)                                            \
20   BUILTIN_LIST_FROM_TORQUE(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
21                            IGNORE_BUILTIN, IGNORE_BUILTIN)
22 
23 #define INTERFACE_DESCRIPTOR_LIST(V)     \
24   V(Abort)                               \
25   V(Allocate)                            \
26   V(ApiCallback)                         \
27   V(ApiGetter)                           \
28   V(ArgumentsAdaptor)                    \
29   V(ArrayConstructor)                    \
30   V(ArrayNArgumentsConstructor)          \
31   V(ArrayNoArgumentConstructor)          \
32   V(ArraySingleArgumentConstructor)      \
33   V(AsyncFunctionStackParameter)         \
34   V(BigIntToI32Pair)                     \
35   V(BigIntToI64)                         \
36   V(BinaryOp)                            \
37   V(BinaryOp_WithFeedback)               \
38   V(CallForwardVarargs)                  \
39   V(CallFunctionTemplate)                \
40   V(CallTrampoline)                      \
41   V(CallTrampoline_WithFeedback)         \
42   V(CallVarargs)                         \
43   V(CallWithArrayLike)                   \
44   V(CallWithArrayLike_WithFeedback)      \
45   V(CallWithSpread)                      \
46   V(CallWithSpread_WithFeedback)         \
47   V(CEntry1ArgvOnStack)                  \
48   V(CloneObjectWithVector)               \
49   V(Compare)                             \
50   V(Compare_WithFeedback)                \
51   V(ConstructForwardVarargs)             \
52   V(ConstructStub)                       \
53   V(ConstructVarargs)                    \
54   V(ConstructWithArrayLike)              \
55   V(ConstructWithArrayLike_WithFeedback) \
56   V(Construct_WithFeedback)              \
57   V(ConstructWithSpread)                 \
58   V(ConstructWithSpread_WithFeedback)    \
59   V(ContextOnly)                         \
60   V(CppBuiltinAdaptor)                   \
61   V(EphemeronKeyBarrier)                 \
62   V(FastNewObject)                       \
63   V(FrameDropperTrampoline)              \
64   V(GetIteratorStackParameter)           \
65   V(GetProperty)                         \
66   V(GrowArrayElements)                   \
67   V(I32PairToBigInt)                     \
68   V(I64ToBigInt)                         \
69   V(InterpreterCEntry1)                  \
70   V(InterpreterCEntry2)                  \
71   V(InterpreterDispatch)                 \
72   V(InterpreterPushArgsThenCall)         \
73   V(InterpreterPushArgsThenConstruct)    \
74   V(JSTrampoline)                        \
75   V(Load)                                \
76   V(LoadGlobal)                          \
77   V(LoadGlobalNoFeedback)                \
78   V(LoadGlobalWithVector)                \
79   V(LoadNoFeedback)                      \
80   V(LoadWithVector)                      \
81   V(LoadWithReceiverAndVector)           \
82   V(NoContext)                           \
83   V(RecordWrite)                         \
84   V(ResumeGenerator)                     \
85   V(RunMicrotasks)                       \
86   V(RunMicrotasksEntry)                  \
87   V(Store)                               \
88   V(StoreGlobal)                         \
89   V(StoreGlobalWithVector)               \
90   V(StoreTransition)                     \
91   V(StoreWithVector)                     \
92   V(StringAt)                            \
93   V(StringAtAsString)                    \
94   V(StringSubstring)                     \
95   V(TypeConversion)                      \
96   V(TypeConversionNoContext)             \
97   V(TypeConversionStackParameter)        \
98   V(Typeof)                              \
99   V(UnaryOp_WithFeedback)                \
100   V(Void)                                \
101   V(WasmFloat32ToNumber)                 \
102   V(WasmFloat64ToNumber)                 \
103   V(WasmI32AtomicWait32)                 \
104   V(WasmI64AtomicWait32)                 \
105   BUILTIN_LIST_TFS(V)                    \
106   TORQUE_BUILTIN_LIST_TFC(V)
107 
108 enum class StackArgumentOrder {
109   kDefault,  // Arguments in the stack are pushed in the default/stub order (the
110              // first argument is pushed first).
111   kJS,  // Arguments in the stack are pushed in the same order as the one used
112         // by JS-to-JS function calls. This should be used if calling a
113         // JSFunction or if the builtin is expected to be called directly from a
114         // JSFunction. This order is reversed compared to kDefault.
115 };
116 
117 class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
118  public:
119   enum Flag {
120     kNoFlags = 0u,
121     kNoContext = 1u << 0,
122     // This indicates that the code uses a special frame that does not scan the
123     // stack arguments, e.g. EntryFrame. And this allows the code to use
124     // untagged stack arguments.
125     kNoStackScan = 1u << 1,
126     // In addition to the specified parameters, additional arguments can be
127     // passed on the stack.
128     // This does not indicate if arguments adaption is used or not.
129     kAllowVarArgs = 1u << 2,
130   };
131   using Flags = base::Flags<Flag>;
132 
133   CallInterfaceDescriptorData() = default;
134 
135   // A copy of the passed in registers and param_representations is made
136   // and owned by the CallInterfaceDescriptorData.
137 
138   void InitializePlatformSpecific(int register_parameter_count,
139                                   const Register* registers);
140 
141   // if machine_types is null, then an array of size
142   // (return_count + parameter_count) will be created with
143   // MachineType::AnyTagged() for each member.
144   //
145   // if machine_types is not null, then it should be of the size
146   // (return_count + parameter_count). Those members of the parameter array will
147   // be initialized from {machine_types}, and the rest initialized to
148   // MachineType::AnyTagged().
149   void InitializePlatformIndependent(Flags flags, int return_count,
150                                      int parameter_count,
151                                      const MachineType* machine_types,
152                                      int machine_types_length,
153                                      StackArgumentOrder stack_order);
154 
155   void Reset();
156 
IsInitialized()157   bool IsInitialized() const {
158     return IsInitializedPlatformSpecific() &&
159            IsInitializedPlatformIndependent();
160   }
161 
flags()162   Flags flags() const { return flags_; }
return_count()163   int return_count() const { return return_count_; }
param_count()164   int param_count() const { return param_count_; }
register_param_count()165   int register_param_count() const { return register_param_count_; }
register_param(int index)166   Register register_param(int index) const { return register_params_[index]; }
register_params()167   Register* register_params() const { return register_params_; }
return_type(int index)168   MachineType return_type(int index) const {
169     DCHECK_LT(index, return_count_);
170     return machine_types_[index];
171   }
param_type(int index)172   MachineType param_type(int index) const {
173     DCHECK_LT(index, param_count_);
174     return machine_types_[return_count_ + index];
175   }
stack_order()176   StackArgumentOrder stack_order() const { return stack_order_; }
177 
RestrictAllocatableRegisters(const Register * registers,int num)178   void RestrictAllocatableRegisters(const Register* registers, int num) {
179     DCHECK_EQ(allocatable_registers_, 0);
180     for (int i = 0; i < num; ++i) {
181       allocatable_registers_ |= registers[i].bit();
182     }
183     DCHECK_GT(NumRegs(allocatable_registers_), 0);
184   }
185 
allocatable_registers()186   RegList allocatable_registers() const { return allocatable_registers_; }
187 
188  private:
IsInitializedPlatformSpecific()189   bool IsInitializedPlatformSpecific() const {
190     const bool initialized =
191         (register_param_count_ == 0 && register_params_ == nullptr) ||
192         (register_param_count_ > 0 && register_params_ != nullptr);
193     // Platform-specific initialization happens before platform-independent.
194     return initialized;
195   }
IsInitializedPlatformIndependent()196   bool IsInitializedPlatformIndependent() const {
197     const bool initialized =
198         return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
199     // Platform-specific initialization happens before platform-independent.
200     return initialized;
201   }
202 
203 #ifdef DEBUG
204   bool AllStackParametersAreTagged() const;
205 #endif  // DEBUG
206 
207   int register_param_count_ = -1;
208   int return_count_ = -1;
209   int param_count_ = -1;
210   Flags flags_ = kNoFlags;
211   StackArgumentOrder stack_order_ = StackArgumentOrder::kDefault;
212 
213   // Specifying the set of registers that could be used by the register
214   // allocator. Currently, it's only used by RecordWrite code stub.
215   RegList allocatable_registers_ = 0;
216 
217   // |registers_params_| defines registers that are used for parameter passing.
218   // |machine_types_| defines machine types for resulting values and incomping
219   // parameters.
220   // Both arrays are allocated dynamically by the InterfaceDescriptor and
221   // freed on destruction. This is because static arrays cause creation of
222   // runtime static initializers which we don't want.
223   Register* register_params_ = nullptr;
224   MachineType* machine_types_ = nullptr;
225 
226   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
227 };
228 
229 class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
230  public:
231   enum Key {
232 #define DEF_ENUM(name, ...) name,
233     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
234 #undef DEF_ENUM
235         NUMBER_OF_DESCRIPTORS
236   };
237 
238   static void InitializeOncePerProcess();
239   static void TearDown();
240 
call_descriptor_data(CallDescriptors::Key key)241   static CallInterfaceDescriptorData* call_descriptor_data(
242       CallDescriptors::Key key) {
243     return &call_descriptor_data_[key];
244   }
245 
GetKey(const CallInterfaceDescriptorData * data)246   static Key GetKey(const CallInterfaceDescriptorData* data) {
247     ptrdiff_t index = data - call_descriptor_data_;
248     DCHECK_LE(0, index);
249     DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
250     return static_cast<CallDescriptors::Key>(index);
251   }
252 
253  private:
254   static CallInterfaceDescriptorData
255       call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
256 };
257 
258 class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
259  public:
260   using Flags = CallInterfaceDescriptorData::Flags;
261 
CallInterfaceDescriptor()262   CallInterfaceDescriptor() : data_(nullptr) {}
263   virtual ~CallInterfaceDescriptor() = default;
264 
CallInterfaceDescriptor(CallDescriptors::Key key)265   explicit CallInterfaceDescriptor(CallDescriptors::Key key)
266       : data_(CallDescriptors::call_descriptor_data(key)) {}
267 
flags()268   Flags flags() const { return data()->flags(); }
269 
HasContextParameter()270   bool HasContextParameter() const {
271     return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
272   }
273 
AllowVarArgs()274   bool AllowVarArgs() const {
275     return flags() & CallInterfaceDescriptorData::kAllowVarArgs;
276   }
277 
GetReturnCount()278   int GetReturnCount() const { return data()->return_count(); }
279 
GetReturnType(int index)280   MachineType GetReturnType(int index) const {
281     DCHECK_LT(index, data()->return_count());
282     return data()->return_type(index);
283   }
284 
GetParameterCount()285   int GetParameterCount() const { return data()->param_count(); }
286 
GetRegisterParameterCount()287   int GetRegisterParameterCount() const {
288     return data()->register_param_count();
289   }
290 
GetStackParameterCount()291   int GetStackParameterCount() const {
292     return data()->param_count() - data()->register_param_count();
293   }
294 
GetRegisterParameter(int index)295   Register GetRegisterParameter(int index) const {
296     return data()->register_param(index);
297   }
298 
GetParameterType(int index)299   MachineType GetParameterType(int index) const {
300     DCHECK_LT(index, data()->param_count());
301     return data()->param_type(index);
302   }
303 
allocatable_registers()304   RegList allocatable_registers() const {
305     return data()->allocatable_registers();
306   }
307 
GetStackArgumentOrder()308   StackArgumentOrder GetStackArgumentOrder() const {
309     return data()->stack_order();
310   }
311 
312   static const Register ContextRegister();
313 
314   const char* DebugName() const;
315 
316   bool operator==(const CallInterfaceDescriptor& other) const {
317     return data() == other.data();
318   }
319 
320  protected:
data()321   const CallInterfaceDescriptorData* data() const { return data_; }
322 
InitializePlatformSpecific(CallInterfaceDescriptorData * data)323   virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
324     UNREACHABLE();
325   }
326 
InitializePlatformIndependent(CallInterfaceDescriptorData * data)327   virtual void InitializePlatformIndependent(
328       CallInterfaceDescriptorData* data) {
329     // Default descriptor configuration: one result, all parameters are passed
330     // in registers and all parameters have MachineType::AnyTagged() type.
331     data->InitializePlatformIndependent(
332         CallInterfaceDescriptorData::kNoFlags, 1, data->register_param_count(),
333         nullptr, 0, StackArgumentOrder::kDefault);
334   }
335 
336   // Initializes |data| using the platform dependent default set of registers.
337   // It is intended to be used for TurboFan stubs when particular set of
338   // registers does not matter.
339   static void DefaultInitializePlatformSpecific(
340       CallInterfaceDescriptorData* data, int register_parameter_count);
341 
342   // Initializes |data| using the platform dependent default set of registers
343   // for JavaScript-compatible calling convention.
344   // It is intended to be used for TurboFan stubs being called with JavaScript
345   // linkage + additional parameters on registers and stack.
346   static void JSDefaultInitializePlatformSpecific(
347       CallInterfaceDescriptorData* data, int non_js_register_parameter_count);
348 
349   // Checks if float parameters are not assigned invalid registers.
CheckFloatingPointParameters(CallInterfaceDescriptorData * data)350   bool CheckFloatingPointParameters(CallInterfaceDescriptorData* data) {
351     for (int i = 0; i < data->register_param_count(); i++) {
352       if (IsFloatingPoint(data->param_type(i).representation())) {
353         if (!IsValidFloatParameterRegister(data->register_param(i))) {
354           return false;
355         }
356       }
357     }
358     return true;
359   }
360 
361   bool IsValidFloatParameterRegister(Register reg);
362 
363  private:
364   // {CallDescriptors} is allowed to call the private {Initialize} method.
365   friend class CallDescriptors;
366 
367   const CallInterfaceDescriptorData* data_;
368 
Initialize(CallInterfaceDescriptorData * data)369   void Initialize(CallInterfaceDescriptorData* data) {
370     // The passed pointer should be a modifiable pointer to our own data.
371     DCHECK_EQ(data, data_);
372     DCHECK(!data->IsInitialized());
373     InitializePlatformSpecific(data);
374     InitializePlatformIndependent(data);
375     DCHECK(data->IsInitialized());
376     DCHECK(CheckFloatingPointParameters(data));
377   }
378 };
379 
380 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
381  public:                                         \
382   explicit name() : base(key()) {}               \
383   static inline CallDescriptors::Key key();
384 
385 #if defined(V8_TARGET_ARCH_IA32)
386 // To support all possible cases, we must limit the number of register args for
387 // TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
388 // as the context register and ebx is the root register. One register must
389 // remain available to store the jump/call target. Thus 3 registers remain for
390 // arguments. The reason this applies to TFS builtins specifically is because
391 // this becomes relevant for builtins used as targets of Torque function
392 // pointers (which must have a register available to store the target).
393 // TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
394 // that comes with its own set of complications. It's possible, but requires
395 // refactoring the calling convention of other existing stubs.
396 constexpr int kMaxBuiltinRegisterParams = 4;
397 constexpr int kMaxTFSBuiltinRegisterParams = 3;
398 #else
399 constexpr int kMaxBuiltinRegisterParams = 5;
400 constexpr int kMaxTFSBuiltinRegisterParams = kMaxBuiltinRegisterParams;
401 #endif
402 STATIC_ASSERT(kMaxTFSBuiltinRegisterParams <= kMaxBuiltinRegisterParams);
403 
404 #define DECLARE_DEFAULT_DESCRIPTOR(name, base)                                 \
405   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
406  protected:                                                                    \
407   static const int kRegisterParams =                                           \
408       kParameterCount > kMaxTFSBuiltinRegisterParams                           \
409           ? kMaxTFSBuiltinRegisterParams                                       \
410           : kParameterCount;                                                   \
411   static const int kStackParams = kParameterCount - kRegisterParams;           \
412   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)           \
413       override {                                                               \
414     DefaultInitializePlatformSpecific(data, kRegisterParams);                  \
415   }                                                                            \
416   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)        \
417       override {                                                               \
418     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
419                                         kParameterCount, nullptr, 0,           \
420                                         kStackArgumentOrder);                  \
421   }                                                                            \
422   name(CallDescriptors::Key key) : base(key) {}                                \
423                                                                                \
424  public:
425 
426 #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base,                        \
427                                          non_js_reg_parameters_count)       \
428   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                  \
429  protected:                                                                 \
430   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)        \
431       override {                                                            \
432     JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
433   }                                                                         \
434   name(CallDescriptors::Key key) : base(key) {}                             \
435                                                                             \
436  public:
437 
438 #define DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(flags, stack_order,       \
439                                                return_count, ...)        \
440   static constexpr int kDescriptorFlags = flags;                         \
441   static constexpr int kReturnCount = return_count;                      \
442   static constexpr StackArgumentOrder kStackArgumentOrder = stack_order; \
443   enum ParameterIndices {                                                \
444     __dummy = -1, /* to be able to pass zero arguments */                \
445     ##__VA_ARGS__,                                                       \
446                                                                          \
447     kParameterCount,                                                     \
448     kContext = kParameterCount /* implicit parameter */                  \
449   };
450 
451 #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...)                    \
452   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                  \
453       CallInterfaceDescriptorData::kNoFlags, StackArgumentOrder::kDefault, \
454       return_count, ##__VA_ARGS__)
455 
456 // This is valid only for builtins that use EntryFrame, which does not scan
457 // stack arguments on GC.
458 #define DEFINE_PARAMETERS_ENTRY(...)                        \
459   static constexpr int kDescriptorFlags =                   \
460       CallInterfaceDescriptorData::kNoContext |             \
461       CallInterfaceDescriptorData::kNoStackScan;            \
462   static constexpr StackArgumentOrder kStackArgumentOrder = \
463       StackArgumentOrder::kDefault;                         \
464   static constexpr int kReturnCount = 1;                    \
465   enum ParameterIndices {                                   \
466     __dummy = -1, /* to be able to pass zero arguments */   \
467     ##__VA_ARGS__,                                          \
468                                                             \
469     kParameterCount                                         \
470   };
471 
472 #define DEFINE_PARAMETERS(...)                                                \
473   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                     \
474       CallInterfaceDescriptorData::kNoFlags, StackArgumentOrder::kDefault, 1, \
475       ##__VA_ARGS__)
476 
477 #define DEFINE_PARAMETERS_NO_CONTEXT(...)                                    \
478   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                    \
479       CallInterfaceDescriptorData::kNoContext, StackArgumentOrder::kDefault, \
480       1, ##__VA_ARGS__)
481 
482 #define DEFINE_PARAMETERS_VARARGS(...)                                        \
483   DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                     \
484       CallInterfaceDescriptorData::kAllowVarArgs, StackArgumentOrder::kJS, 1, \
485       ##__VA_ARGS__)
486 
487 #define DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(flag, ...)                \
488   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)       \
489       override {                                                              \
490     MachineType machine_types[] = {__VA_ARGS__};                              \
491     static_assert(                                                            \
492         kReturnCount + kParameterCount == arraysize(machine_types),           \
493         "Parameter names definition is not consistent with parameter types"); \
494     data->InitializePlatformIndependent(                                      \
495         Flags(flag | kDescriptorFlags), kReturnCount, kParameterCount,        \
496         machine_types, arraysize(machine_types), kStackArgumentOrder);        \
497   }
498 
499 #define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
500   DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG( \
501       CallInterfaceDescriptorData::kNoFlags, __VA_ARGS__)
502 
503 #define DEFINE_PARAMETER_TYPES(...)                                        \
504   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
505                                     ##__VA_ARGS__)
506 
507 // When the extra arguments described here are located in the stack, they are
508 // just above the return address in the frame (first arguments).
509 #define DEFINE_JS_PARAMETERS(...)                           \
510   static constexpr int kDescriptorFlags =                   \
511       CallInterfaceDescriptorData::kAllowVarArgs;           \
512   static constexpr int kReturnCount = 1;                    \
513   static constexpr StackArgumentOrder kStackArgumentOrder = \
514       StackArgumentOrder::kJS;                              \
515   enum ParameterIndices {                                   \
516     kTarget,                                                \
517     kNewTarget,                                             \
518     kActualArgumentsCount,                                  \
519     ##__VA_ARGS__,                                          \
520                                                             \
521     kParameterCount,                                        \
522     kContext = kParameterCount /* implicit parameter */     \
523   };
524 
525 #define DEFINE_JS_PARAMETER_TYPES(...)                                         \
526   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */               \
527                          MachineType::AnyTagged(), /* kNewTarget */            \
528                          MachineType::Int32(),     /* kActualArgumentsCount */ \
529                          ##__VA_ARGS__)
530 
531 #define DECLARE_DESCRIPTOR(name, base)                                         \
532   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
533  protected:                                                                    \
534   void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
535   name(CallDescriptors::Key key) : base(key) {}                                \
536                                                                                \
537  public:
538 
539 class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
540  public:
541   DEFINE_PARAMETERS()
542   DEFINE_PARAMETER_TYPES()
543   DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
544 };
545 
546 // This class is subclassed by Torque-generated call interface descriptors.
547 template <int parameter_count, bool has_context_parameter>
548 class TorqueInterfaceDescriptor : public CallInterfaceDescriptor {
549  public:
550   static constexpr int kDescriptorFlags =
551       has_context_parameter ? CallInterfaceDescriptorData::kNoFlags
552                             : CallInterfaceDescriptorData::kNoContext;
553   static constexpr int kParameterCount = parameter_count;
554   enum ParameterIndices { kContext = kParameterCount };
555   template <int i>
ParameterIndex()556   static ParameterIndices ParameterIndex() {
557     STATIC_ASSERT(0 <= i && i < kParameterCount);
558     return static_cast<ParameterIndices>(i);
559   }
560   static constexpr int kReturnCount = 1;
561 
562   using CallInterfaceDescriptor::CallInterfaceDescriptor;
563 
564  protected:
565   static const int kRegisterParams =
566       kParameterCount > kMaxTFSBuiltinRegisterParams
567           ? kMaxTFSBuiltinRegisterParams
568           : kParameterCount;
569   static const int kStackParams = kParameterCount - kRegisterParams;
570   virtual MachineType ReturnType() = 0;
571   virtual std::array<MachineType, kParameterCount> ParameterTypes() = 0;
InitializePlatformSpecific(CallInterfaceDescriptorData * data)572   void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override {
573     DefaultInitializePlatformSpecific(data, kRegisterParams);
574   }
InitializePlatformIndependent(CallInterfaceDescriptorData * data)575   void InitializePlatformIndependent(
576       CallInterfaceDescriptorData* data) override {
577     std::vector<MachineType> machine_types = {ReturnType()};
578     auto parameter_types = ParameterTypes();
579     machine_types.insert(machine_types.end(), parameter_types.begin(),
580                          parameter_types.end());
581     DCHECK_EQ(kReturnCount + kParameterCount, machine_types.size());
582     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount,
583                                         kParameterCount, machine_types.data(),
584                                         static_cast<int>(machine_types.size()),
585                                         StackArgumentOrder::kDefault);
586   }
587 };
588 
589 // Dummy descriptor used to mark builtins that don't yet have their proper
590 // descriptor associated.
591 using DummyDescriptor = VoidDescriptor;
592 
593 // Dummy descriptor that marks builtins with C calling convention.
594 using CCallDescriptor = VoidDescriptor;
595 
596 // Marks deoptimization entry builtins. Precise calling conventions currently
597 // differ based on the platform.
598 // TODO(jgruber): Once this is unified, we could create a better description
599 // here.
600 using DeoptimizationEntryDescriptor = VoidDescriptor;
601 
602 class AllocateDescriptor : public CallInterfaceDescriptor {
603  public:
604   DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
605   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
606                                     MachineType::IntPtr())  // kRequestedSize
607   DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
608 };
609 
610 // This descriptor defines the JavaScript calling convention that can be used
611 // by stubs: target, new.target, argc (not including the receiver) and context
612 // are passed in registers while receiver and the rest of the JS arguments are
613 // passed on the stack.
614 class JSTrampolineDescriptor : public CallInterfaceDescriptor {
615  public:
616   DEFINE_JS_PARAMETERS()
617   DEFINE_JS_PARAMETER_TYPES()
618 
619   DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
620                                    CallInterfaceDescriptor, 0)
621 };
622 
623 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
624  public:
625   DEFINE_PARAMETERS()
626   DEFINE_PARAMETER_TYPES()
627   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
628 };
629 
630 class NoContextDescriptor : public CallInterfaceDescriptor {
631  public:
632   DEFINE_PARAMETERS_NO_CONTEXT()
633   DEFINE_PARAMETER_TYPES()
634   DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
635 };
636 
637 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
638 class LoadDescriptor : public CallInterfaceDescriptor {
639  public:
640   DEFINE_PARAMETERS(kReceiver, kName, kSlot)
641   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
642                          MachineType::AnyTagged(),     // kName
643                          MachineType::TaggedSigned())  // kSlot
644   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
645 
646   static const Register ReceiverRegister();
647   static const Register NameRegister();
648   static const Register SlotRegister();
649 };
650 
651 class LoadGlobalNoFeedbackDescriptor : public CallInterfaceDescriptor {
652  public:
DEFINE_PARAMETERS(kName,kICKind)653   DEFINE_PARAMETERS(kName, kICKind)
654   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
655                          MachineType::TaggedSigned())  // kICKind
656   DECLARE_DESCRIPTOR(LoadGlobalNoFeedbackDescriptor, CallInterfaceDescriptor)
657 
658   static const Register NameRegister() {
659     return LoadDescriptor::NameRegister();
660   }
661 
ICKindRegister()662   static const Register ICKindRegister() {
663     return LoadDescriptor::SlotRegister();
664   }
665 };
666 
667 class LoadNoFeedbackDescriptor : public LoadGlobalNoFeedbackDescriptor {
668  public:
DEFINE_PARAMETERS(kReceiver,kName,kICKind)669   DEFINE_PARAMETERS(kReceiver, kName, kICKind)
670   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
671                          MachineType::AnyTagged(),     // kName
672                          MachineType::TaggedSigned())  // kICKind
673   DECLARE_DESCRIPTOR(LoadNoFeedbackDescriptor, LoadGlobalNoFeedbackDescriptor)
674 
675   static const Register ReceiverRegister() {
676     return LoadDescriptor::ReceiverRegister();
677   }
678 
NameRegister()679   static const Register NameRegister() {
680     return LoadGlobalNoFeedbackDescriptor::NameRegister();
681   }
682 
ICKindRegister()683   static const Register ICKindRegister() {
684     return LoadGlobalNoFeedbackDescriptor::ICKindRegister();
685   }
686 };
687 
688 class LoadGlobalDescriptor : public CallInterfaceDescriptor {
689  public:
DEFINE_PARAMETERS(kName,kSlot)690   DEFINE_PARAMETERS(kName, kSlot)
691   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
692                          MachineType::TaggedSigned())  // kSlot
693   DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
694 
695   static const Register NameRegister() {
696     return LoadDescriptor::NameRegister();
697   }
698 
SlotRegister()699   static const Register SlotRegister() {
700     return LoadDescriptor::SlotRegister();
701   }
702 };
703 
704 class StoreDescriptor : public CallInterfaceDescriptor {
705  public:
706   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
707   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
708                          MachineType::AnyTagged(),     // kName
709                          MachineType::AnyTagged(),     // kValue
710                          MachineType::TaggedSigned())  // kSlot
711   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
712 
713   static const Register ReceiverRegister();
714   static const Register NameRegister();
715   static const Register ValueRegister();
716   static const Register SlotRegister();
717 
718 #if V8_TARGET_ARCH_IA32
719   static const bool kPassLastArgsOnStack = true;
720 #else
721   static const bool kPassLastArgsOnStack = false;
722 #endif
723 
724   // Pass value and slot through the stack.
725   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
726 };
727 
728 class StoreTransitionDescriptor : public StoreDescriptor {
729  public:
730   DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
731   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
732                          MachineType::AnyTagged(),     // kName
733                          MachineType::AnyTagged(),     // kMap
734                          MachineType::AnyTagged(),     // kValue
735                          MachineType::TaggedSigned(),  // kSlot
736                          MachineType::AnyTagged())     // kVector
737   DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
738 
739   static const Register MapRegister();
740   static const Register SlotRegister();
741   static const Register VectorRegister();
742 
743   // Pass value, slot and vector through the stack.
744   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
745 };
746 
747 class StoreWithVectorDescriptor : public StoreDescriptor {
748  public:
749   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
750   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
751                          MachineType::AnyTagged(),     // kName
752                          MachineType::AnyTagged(),     // kValue
753                          MachineType::TaggedSigned(),  // kSlot
754                          MachineType::AnyTagged())     // kVector
755   DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
756 
757   static const Register VectorRegister();
758 
759   // Pass value, slot and vector through the stack.
760   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
761 };
762 
763 class StoreGlobalDescriptor : public CallInterfaceDescriptor {
764  public:
765   DEFINE_PARAMETERS(kName, kValue, kSlot)
766   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
767                          MachineType::AnyTagged(),     // kValue
768                          MachineType::TaggedSigned())  // kSlot
769   DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
770 
771   static const bool kPassLastArgsOnStack =
772       StoreDescriptor::kPassLastArgsOnStack;
773   // Pass value and slot through the stack.
774   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
775 
NameRegister()776   static const Register NameRegister() {
777     return StoreDescriptor::NameRegister();
778   }
779 
ValueRegister()780   static const Register ValueRegister() {
781     return StoreDescriptor::ValueRegister();
782   }
783 
SlotRegister()784   static const Register SlotRegister() {
785     return StoreDescriptor::SlotRegister();
786   }
787 };
788 
789 class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
790  public:
DEFINE_PARAMETERS(kName,kValue,kSlot,kVector)791   DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
792   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
793                          MachineType::AnyTagged(),     // kValue
794                          MachineType::TaggedSigned(),  // kSlot
795                          MachineType::AnyTagged())     // kVector
796   DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
797 
798   static const Register VectorRegister() {
799     return StoreWithVectorDescriptor::VectorRegister();
800   }
801 
802   // Pass value, slot and vector through the stack.
803   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
804 };
805 
806 class LoadWithVectorDescriptor : public LoadDescriptor {
807  public:
808   // TODO(v8:9497): Revert the Machine type for kSlot to the
809   // TaggedSigned once Torque can emit better call descriptors
810   DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
811   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
812                          MachineType::AnyTagged(),  // kName
813                          MachineType::AnyTagged(),  // kSlot
814                          MachineType::AnyTagged())  // kVector
815   DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
816 
817   static const Register VectorRegister();
818 
819 #if V8_TARGET_ARCH_IA32
820   static const bool kPassLastArgsOnStack = true;
821 #else
822   static const bool kPassLastArgsOnStack = false;
823 #endif
824 
825   // Pass vector through the stack.
826   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
827 };
828 
829 // Like LoadWithVectorDescriptor, except we pass the receiver (the object which
830 // should be used as the receiver for accessor function calls) and the lookup
831 // start object separately.
832 class LoadWithReceiverAndVectorDescriptor : public LoadWithVectorDescriptor {
833  public:
834   // TODO(v8:9497): Revert the Machine type for kSlot to the
835   // TaggedSigned once Torque can emit better call descriptors
836   DEFINE_PARAMETERS(kReceiver, kLookupStartObject, kName, kSlot, kVector)
837   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
838                          MachineType::AnyTagged(),  // kLookupStartObject
839                          MachineType::AnyTagged(),  // kName
840                          MachineType::AnyTagged(),  // kSlot
841                          MachineType::AnyTagged())  // kVector
842   DECLARE_DESCRIPTOR(LoadWithReceiverAndVectorDescriptor,
843                      LoadWithVectorDescriptor)
844 
845   static const Register LookupStartObjectRegister();
846 
847 #if V8_TARGET_ARCH_IA32
848   static const bool kPassLastArgsOnStack = true;
849 #else
850   static const bool kPassLastArgsOnStack = false;
851 #endif
852 
853   // Pass vector through the stack.
854   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
855 };
856 
857 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
858  public:
DEFINE_PARAMETERS(kName,kSlot,kVector)859   DEFINE_PARAMETERS(kName, kSlot, kVector)
860   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
861                          MachineType::TaggedSigned(),  // kSlot
862                          MachineType::AnyTagged())     // kVector
863   DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
864 
865 #if V8_TARGET_ARCH_IA32
866   // On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
867   // need to choose a new register here.
868   static const Register VectorRegister() { return edx; }
869 #else
870   static const Register VectorRegister() {
871     return LoadWithVectorDescriptor::VectorRegister();
872   }
873 #endif
874 };
875 
876 class FastNewObjectDescriptor : public CallInterfaceDescriptor {
877  public:
878   DEFINE_PARAMETERS(kTarget, kNewTarget)
879   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
880                          MachineType::AnyTagged())  // kNewTarget
881   DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
882   static const Register TargetRegister();
883   static const Register NewTargetRegister();
884 };
885 
886 class RecordWriteDescriptor final : public CallInterfaceDescriptor {
887  public:
888   DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
889   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
890                          MachineType::Pointer(),        // kSlot
891                          MachineType::TaggedSigned(),   // kRememberedSet
892                          MachineType::TaggedSigned())   // kFPMode
893 
894   DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
895 };
896 
897 class EphemeronKeyBarrierDescriptor final : public CallInterfaceDescriptor {
898  public:
899   DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress, kFPMode)
900   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
901                          MachineType::Pointer(),        // kSlotAddress
902                          MachineType::TaggedSigned())   // kFPMode
903 
904   DECLARE_DESCRIPTOR(EphemeronKeyBarrierDescriptor, CallInterfaceDescriptor)
905 };
906 
907 class TypeConversionDescriptor final : public CallInterfaceDescriptor {
908  public:
909   DEFINE_PARAMETERS(kArgument)
910   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
911   DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
912 
913   static const Register ArgumentRegister();
914 };
915 
916 class TypeConversionNoContextDescriptor final : public CallInterfaceDescriptor {
917  public:
918   DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
919   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
920   DECLARE_DESCRIPTOR(TypeConversionNoContextDescriptor, CallInterfaceDescriptor)
921 };
922 
923 class TypeConversionStackParameterDescriptor final
924     : public CallInterfaceDescriptor {
925  public:
926   DEFINE_PARAMETERS(kArgument)
927   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
928   DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor,
929                      CallInterfaceDescriptor)
930 };
931 
932 class AsyncFunctionStackParameterDescriptor final
933     : public CallInterfaceDescriptor {
934  public:
935   DEFINE_PARAMETERS(kPromise, kResult)
936   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
937   DECLARE_DESCRIPTOR(AsyncFunctionStackParameterDescriptor,
938                      CallInterfaceDescriptor)
939 };
940 
941 class GetIteratorStackParameterDescriptor final
942     : public CallInterfaceDescriptor {
943  public:
944   DEFINE_PARAMETERS(kReceiver, kCallSlot, kFeedback, kResult)
945   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::AnyTagged(),
946                          MachineType::AnyTagged(), MachineType::AnyTagged())
947   DECLARE_DESCRIPTOR(GetIteratorStackParameterDescriptor,
948                      CallInterfaceDescriptor)
949 };
950 
951 class GetPropertyDescriptor final : public CallInterfaceDescriptor {
952  public:
953   DEFINE_PARAMETERS(kObject, kKey)
954   DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
955 };
956 
957 class TypeofDescriptor : public CallInterfaceDescriptor {
958  public:
959   DEFINE_PARAMETERS(kObject)
960   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
961   DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
962 };
963 
964 class CallTrampolineDescriptor : public CallInterfaceDescriptor {
965  public:
966   DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount)
967   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
968                          MachineType::Int32())      // kActualArgumentsCount
969   DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
970 };
971 
972 class CallVarargsDescriptor : public CallInterfaceDescriptor {
973  public:
974   DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kArgumentsLength,
975                             kArgumentsList)
976   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
977                          MachineType::Int32(),      // kActualArgumentsCount
978                          MachineType::Int32(),      // kArgumentsLength
979                          MachineType::AnyTagged())  // kArgumentsList
980   DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
981 };
982 
983 class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
984  public:
985   DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kStartIndex)
986   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
987                          MachineType::Int32(),      // kActualArgumentsCount
988                          MachineType::Int32())      // kStartIndex
989   DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
990 };
991 
992 class CallFunctionTemplateDescriptor : public CallInterfaceDescriptor {
993  public:
994   DEFINE_PARAMETERS_VARARGS(kFunctionTemplateInfo, kArgumentsCount)
995   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunctionTemplateInfo
996                          MachineType::IntPtr())     // kArgumentsCount
997   DECLARE_DESCRIPTOR(CallFunctionTemplateDescriptor, CallInterfaceDescriptor)
998 };
999 
1000 class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
1001  public:
1002   DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread)
1003   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1004                          MachineType::Int32(),      // kArgumentsCount
1005                          MachineType::AnyTagged())  // kSpread
1006   DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
1007 };
1008 
1009 // TODO(jgruber): Pass the slot as UintPtr.
1010 class CallWithSpread_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1011  public:
1012   DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread, kSlot,
1013                             kMaybeFeedbackVector)
1014   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1015                          MachineType::Int32(),      // kArgumentsCount
1016                          MachineType::AnyTagged(),  // kSpread
1017                          MachineType::Int32(),      // kSlot
1018                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1019   DECLARE_DESCRIPTOR(CallWithSpread_WithFeedbackDescriptor,
1020                      CallInterfaceDescriptor)
1021 };
1022 
1023 class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
1024  public:
1025   DEFINE_PARAMETERS(kTarget, kArgumentsList)
1026   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1027                          MachineType::AnyTagged())  // kArgumentsList
1028   DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
1029 };
1030 
1031 // TODO(jgruber): Pass the slot as UintPtr.
1032 class CallWithArrayLike_WithFeedbackDescriptor
1033     : public CallInterfaceDescriptor {
1034  public:
1035   DEFINE_PARAMETERS(kTarget, kArgumentsList, kSlot, kMaybeFeedbackVector)
1036   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1037                          MachineType::AnyTagged(),  // kArgumentsList
1038                          MachineType::Int32(),      // kSlot
1039                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1040   DECLARE_DESCRIPTOR(CallWithArrayLike_WithFeedbackDescriptor,
1041                      CallInterfaceDescriptor)
1042 };
1043 
1044 class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
1045  public:
1046   DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
1047   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(),      // kArgumentsLength
1048                             MachineType::AnyTagged())  // kArgumentsList
1049 
1050   DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
1051 };
1052 
1053 class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
1054  public:
1055   DEFINE_JS_PARAMETERS(kStartIndex)
1056   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
1057   DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
1058 };
1059 
1060 class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
1061  public:
1062   DEFINE_JS_PARAMETERS(kSpread)
1063   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1064   DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
1065 };
1066 
1067 // TODO(jgruber): Pass the slot as UintPtr.
1068 class ConstructWithSpread_WithFeedbackDescriptor
1069     : public CallInterfaceDescriptor {
1070  public:
1071   // Note: kSlot comes before kSpread since as an untagged value it must be
1072   // passed in a register.
1073   DEFINE_JS_PARAMETERS(kSlot, kSpread, kMaybeFeedbackVector)
1074   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(),      // kSlot
1075                             MachineType::AnyTagged(),  // kSpread
1076                             MachineType::AnyTagged())  // kMaybeFeedbackVector
1077   DECLARE_DESCRIPTOR(ConstructWithSpread_WithFeedbackDescriptor,
1078                      CallInterfaceDescriptor)
1079 };
1080 
1081 class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
1082  public:
1083   DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
1084   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1085                          MachineType::AnyTagged(),  // kNewTarget
1086                          MachineType::AnyTagged())  // kArgumentsList
1087   DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
1088 };
1089 
1090 // TODO(jgruber): Pass the slot as UintPtr.
1091 class ConstructWithArrayLike_WithFeedbackDescriptor
1092     : public CallInterfaceDescriptor {
1093  public:
1094   DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList, kSlot,
1095                     kMaybeFeedbackVector)
1096   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
1097                          MachineType::AnyTagged(),  // kNewTarget
1098                          MachineType::AnyTagged(),  // kArgumentsList
1099                          MachineType::Int32(),      // kSlot
1100                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1101   DECLARE_DESCRIPTOR(ConstructWithArrayLike_WithFeedbackDescriptor,
1102                      CallInterfaceDescriptor)
1103 };
1104 
1105 // TODO(ishell): consider merging this with ArrayConstructorDescriptor
1106 class ConstructStubDescriptor : public CallInterfaceDescriptor {
1107  public:
1108   // TODO(jgruber): Remove the unused allocation site parameter.
1109   DEFINE_JS_PARAMETERS(kAllocationSite)
1110   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1111 
1112   // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
1113   DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
1114 };
1115 
1116 class AbortDescriptor : public CallInterfaceDescriptor {
1117  public:
1118   DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
1119   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1120   DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
1121 };
1122 
1123 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
1124  public:
1125   DEFINE_JS_PARAMETERS(kAllocationSite)
1126   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1127 
1128   DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
1129                                    CallInterfaceDescriptor, 1)
1130 };
1131 
1132 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
1133  public:
1134   // This descriptor declares only register arguments while respective number
1135   // of JS arguments stay on the expression stack.
1136   // The ArrayNArgumentsConstructor builtin does not access stack arguments
1137   // directly it just forwards them to the runtime function.
1138   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
1139   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction,
1140                          MachineType::AnyTagged(),  // kAllocationSite
1141                          MachineType::Int32())      // kActualArgumentsCount
1142   DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
1143                      CallInterfaceDescriptor)
1144 };
1145 
1146 class ArrayNoArgumentConstructorDescriptor
1147     : public ArrayNArgumentsConstructorDescriptor {
1148  public:
1149   // This descriptor declares same register arguments as the parent
1150   // ArrayNArgumentsConstructorDescriptor and it declares indices for
1151   // JS arguments passed on the expression stack.
1152   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1153                     kFunctionParameter)
1154   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1155                          MachineType::AnyTagged(),  // kAllocationSite
1156                          MachineType::Int32(),      // kActualArgumentsCount
1157                          MachineType::AnyTagged())  // kFunctionParameter
1158   DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
1159                      ArrayNArgumentsConstructorDescriptor)
1160 };
1161 
1162 class ArraySingleArgumentConstructorDescriptor
1163     : public ArrayNArgumentsConstructorDescriptor {
1164  public:
1165   // This descriptor declares same register arguments as the parent
1166   // ArrayNArgumentsConstructorDescriptor and it declares indices for
1167   // JS arguments passed on the expression stack.
1168   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1169                     kArraySizeSmiParameter, kReceiverParameter)
1170   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1171                          MachineType::AnyTagged(),  // kAllocationSite
1172                          MachineType::Int32(),      // kActualArgumentsCount
1173                          // JS arguments on the stack
1174                          MachineType::AnyTagged(),  // kArraySizeSmiParameter
1175                          MachineType::AnyTagged())  // kReceiverParameter
1176   DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
1177                      ArrayNArgumentsConstructorDescriptor)
1178 };
1179 
1180 class CompareDescriptor : public CallInterfaceDescriptor {
1181  public:
1182   DEFINE_PARAMETERS(kLeft, kRight)
1183   DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
1184 };
1185 
1186 class BinaryOpDescriptor : public CallInterfaceDescriptor {
1187  public:
1188   DEFINE_PARAMETERS(kLeft, kRight)
1189   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
1190 };
1191 
1192 // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
1193 // as they all have the same interface.
1194 class StringAtDescriptor final : public CallInterfaceDescriptor {
1195  public:
1196   DEFINE_PARAMETERS(kReceiver, kPosition)
1197   // TODO(turbofan): Return untagged value here.
1198   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(),  // result 1
1199                                     MachineType::AnyTagged(),     // kReceiver
1200                                     MachineType::IntPtr())        // kPosition
1201   DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
1202 };
1203 
1204 class StringAtAsStringDescriptor final : public CallInterfaceDescriptor {
1205  public:
1206   DEFINE_PARAMETERS(kReceiver, kPosition)
1207   // TODO(turbofan): Return untagged value here.
1208   DEFINE_RESULT_AND_PARAMETER_TYPES(
1209       MachineType::TaggedPointer(),  // result string
1210       MachineType::AnyTagged(),      // kReceiver
1211       MachineType::IntPtr())         // kPosition
1212   DECLARE_DESCRIPTOR(StringAtAsStringDescriptor, CallInterfaceDescriptor)
1213 };
1214 
1215 class StringSubstringDescriptor final : public CallInterfaceDescriptor {
1216  public:
1217   DEFINE_PARAMETERS(kString, kFrom, kTo)
1218   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kString
1219                          MachineType::IntPtr(),     // kFrom
1220                          MachineType::IntPtr())     // kTo
1221 
1222   // TODO(turbofan): Allow builtins to return untagged values.
1223   DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
1224 };
1225 
1226 class ArgumentsAdaptorDescriptor : public CallInterfaceDescriptor {
1227  public:
1228   DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
1229   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
1230   DECLARE_DESCRIPTOR(ArgumentsAdaptorDescriptor, CallInterfaceDescriptor)
1231 };
1232 
1233 class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
1234  public:
1235   DEFINE_JS_PARAMETERS(kCFunction)
1236   DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
1237   DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
1238                                    CallInterfaceDescriptor, 1)
1239 };
1240 
1241 class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
1242  public:
1243   DEFINE_PARAMETERS(kArity,          // register argument
1244                     kCFunction,      // register argument
1245                     kPadding,        // stack argument 1 (just padding)
1246                     kArgcSmi,        // stack argument 2
1247                     kTargetCopy,     // stack argument 3
1248                     kNewTargetCopy)  // stack argument 4
1249   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kArity
1250                          MachineType::Pointer(),    // kCFunction
1251                          MachineType::AnyTagged(),  // kPadding
1252                          MachineType::AnyTagged(),  // kArgcSmi
1253                          MachineType::AnyTagged(),  // kTargetCopy
1254                          MachineType::AnyTagged())  // kNewTargetCopy
1255   DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
1256 };
1257 
1258 class ApiCallbackDescriptor : public CallInterfaceDescriptor {
1259  public:
1260   DEFINE_PARAMETERS_VARARGS(kApiFunctionAddress, kActualArgumentsCount,
1261                             kCallData, kHolder)
1262   //                           receiver is implicit stack argument 1
1263   //                           argv are implicit stack arguments [2, 2 + kArgc[
1264   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),    // kApiFunctionAddress
1265                          MachineType::IntPtr(),     // kActualArgumentsCount
1266                          MachineType::AnyTagged(),  // kCallData
1267                          MachineType::AnyTagged())  // kHolder
1268   DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
1269 };
1270 
1271 class ApiGetterDescriptor : public CallInterfaceDescriptor {
1272  public:
1273   DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
1274   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
1275                          MachineType::AnyTagged(),  // kHolder
1276                          MachineType::AnyTagged())  // kCallback
1277   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
1278 
1279   static const Register ReceiverRegister();
1280   static const Register HolderRegister();
1281   static const Register CallbackRegister();
1282 };
1283 
1284 // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
1285 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
1286  public:
1287   DEFINE_PARAMETERS(kObject, kKey)
1288   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kObject
1289                          MachineType::AnyTagged())  // kKey
1290   DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
1291 
1292   static const Register ObjectRegister();
1293   static const Register KeyRegister();
1294 };
1295 
1296 class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
1297     : public CallInterfaceDescriptor {
1298  public:
1299   DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
1300                     kDispatchTable)
1301   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kAccumulator
1302                          MachineType::IntPtr(),     // kBytecodeOffset
1303                          MachineType::AnyTagged(),  // kBytecodeArray
1304                          MachineType::IntPtr())     // kDispatchTable
1305   DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
1306 };
1307 
1308 class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
1309  public:
1310   DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
1311   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
1312                          MachineType::Pointer(),    // kFirstArgument
1313                          MachineType::AnyTagged())  // kFunction
1314   DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
1315                      CallInterfaceDescriptor)
1316 };
1317 
1318 class InterpreterPushArgsThenConstructDescriptor
1319     : public CallInterfaceDescriptor {
1320  public:
1321   DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
1322                     kNewTarget, kFeedbackElement)
1323   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
1324                          MachineType::Pointer(),    // kFirstArgument
1325                          MachineType::AnyTagged(),  // kConstructor
1326                          MachineType::AnyTagged(),  // kNewTarget
1327                          MachineType::AnyTagged())  // kFeedbackElement
1328   DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
1329                      CallInterfaceDescriptor)
1330 
1331 #if V8_TARGET_ARCH_IA32
1332   static const bool kPassLastArgsOnStack = true;
1333 #else
1334   static const bool kPassLastArgsOnStack = false;
1335 #endif
1336 
1337   // Pass constructor, new target and feedback element through the stack.
1338   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
1339 };
1340 
1341 class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
1342  public:
1343   DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
1344                                kFunctionEntry)
1345   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1346                                     MachineType::Int32(),  // kNumberOfArguments
1347                                     MachineType::Pointer(),  // kFirstArgument
1348                                     MachineType::Pointer())  // kFunctionEntry
1349   DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
1350 };
1351 
1352 class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
1353  public:
1354   DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
1355                                kFunctionEntry)
1356   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1357                                     MachineType::AnyTagged(),  // result 2
1358                                     MachineType::Int32(),  // kNumberOfArguments
1359                                     MachineType::Pointer(),  // kFirstArgument
1360                                     MachineType::Pointer())  // kFunctionEntry
1361   DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
1362 };
1363 
1364 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
1365  public:
1366   DEFINE_PARAMETERS(kValue, kGenerator)
1367   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
1368                          MachineType::AnyTagged())  // kGenerator
1369   DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
1370 };
1371 
1372 class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
1373  public:
1374   DEFINE_PARAMETERS(kRestartFp)
1375   DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1376   DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
1377 };
1378 
1379 class RunMicrotasksEntryDescriptor final : public CallInterfaceDescriptor {
1380  public:
1381   DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
1382   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),  // kRootRegisterValue
1383                          MachineType::Pointer())  // kMicrotaskQueue
1384   DECLARE_DESCRIPTOR(RunMicrotasksEntryDescriptor, CallInterfaceDescriptor)
1385 };
1386 
1387 class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
1388  public:
1389   DEFINE_PARAMETERS(kMicrotaskQueue)
1390   DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1391   DECLARE_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)
1392 
1393   static Register MicrotaskQueueRegister();
1394 };
1395 
1396 class WasmFloat32ToNumberDescriptor final : public CallInterfaceDescriptor {
1397  public:
1398   DEFINE_PARAMETERS_NO_CONTEXT(kValue)
1399   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result
1400                                     MachineType::Float32())    // value
1401   DECLARE_DESCRIPTOR(WasmFloat32ToNumberDescriptor, CallInterfaceDescriptor)
1402 };
1403 
1404 class WasmFloat64ToNumberDescriptor final : public CallInterfaceDescriptor {
1405  public:
1406   DEFINE_PARAMETERS_NO_CONTEXT(kValue)
1407   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result
1408                                     MachineType::Float64())    // value
1409   DECLARE_DESCRIPTOR(WasmFloat64ToNumberDescriptor, CallInterfaceDescriptor)
1410 };
1411 
1412 class V8_EXPORT_PRIVATE I64ToBigIntDescriptor final
1413     : public CallInterfaceDescriptor {
1414  public:
1415   DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
1416   DEFINE_PARAMETER_TYPES(MachineType::Int64())  // kArgument
1417   DECLARE_DESCRIPTOR(I64ToBigIntDescriptor, CallInterfaceDescriptor)
1418 };
1419 
1420 // 32 bits version of the I64ToBigIntDescriptor call interface descriptor
1421 class V8_EXPORT_PRIVATE I32PairToBigIntDescriptor final
1422     : public CallInterfaceDescriptor {
1423  public:
1424   DEFINE_PARAMETERS_NO_CONTEXT(kLow, kHigh)
1425   DEFINE_PARAMETER_TYPES(MachineType::Uint32(),  // kLow
1426                          MachineType::Uint32())  // kHigh
1427   DECLARE_DESCRIPTOR(I32PairToBigIntDescriptor, CallInterfaceDescriptor)
1428 };
1429 
1430 class V8_EXPORT_PRIVATE BigIntToI64Descriptor final
1431     : public CallInterfaceDescriptor {
1432  public:
1433   DEFINE_PARAMETERS(kArgument)
1434   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(),      // result 1
1435                                     MachineType::AnyTagged())  // kArgument
1436   DECLARE_DESCRIPTOR(BigIntToI64Descriptor, CallInterfaceDescriptor)
1437 };
1438 
1439 class V8_EXPORT_PRIVATE BigIntToI32PairDescriptor final
1440     : public CallInterfaceDescriptor {
1441  public:
1442   DEFINE_RESULT_AND_PARAMETERS(2, kArgument)
1443   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),     // result 1
1444                                     MachineType::Uint32(),     // result 2
1445                                     MachineType::AnyTagged())  // kArgument
1446   DECLARE_DESCRIPTOR(BigIntToI32PairDescriptor, CallInterfaceDescriptor)
1447 };
1448 
1449 class WasmI32AtomicWait32Descriptor final : public CallInterfaceDescriptor {
1450  public:
1451   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeoutLow,
1452                                kTimeoutHigh)
1453   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
1454                                     MachineType::Uint32(),  // kAddress
1455                                     MachineType::Int32(),   // kExpectedValue
1456                                     MachineType::Uint32(),  // kTimeoutLow
1457                                     MachineType::Uint32())  // kTimeoutHigh
1458   DECLARE_DESCRIPTOR(WasmI32AtomicWait32Descriptor, CallInterfaceDescriptor)
1459 };
1460 
1461 class WasmI64AtomicWait32Descriptor final : public CallInterfaceDescriptor {
1462  public:
1463   DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValueLow, kExpectedValueHigh,
1464                                kTimeoutLow, kTimeoutHigh)
1465 
1466   DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(
1467       CallInterfaceDescriptorData::kNoStackScan,  // allow untagged stack params
1468       MachineType::Uint32(),                      // result 1
1469       MachineType::Uint32(),                      // kAddress
1470       MachineType::Uint32(),                      // kExpectedValueLow
1471       MachineType::Uint32(),                      // kExpectedValueHigh
1472       MachineType::Uint32(),                      // kTimeoutLow
1473       MachineType::Uint32())                      // kTimeoutHigh
1474 
1475 #if V8_TARGET_ARCH_IA32
1476   static constexpr bool kPassLastArgOnStack = true;
1477 #else
1478   static constexpr bool kPassLastArgOnStack = false;
1479 #endif
1480 
1481   // Pass the last parameter through the stack.
1482   static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;
1483 
1484   DECLARE_DESCRIPTOR(WasmI64AtomicWait32Descriptor, CallInterfaceDescriptor)
1485 };
1486 
1487 class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
1488  public:
1489   DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
1490   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
1491                                     MachineType::AnyTagged(),      // kSource
1492                                     MachineType::TaggedSigned(),   // kFlags
1493                                     MachineType::TaggedSigned(),   // kSlot
1494                                     MachineType::AnyTagged())      // kVector
1495   DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
1496 };
1497 
1498 class BinaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1499  public:
1500   DEFINE_PARAMETERS(kLeft, kRight, kSlot, kMaybeFeedbackVector)
1501   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
1502                          MachineType::AnyTagged(),  // kRight
1503                          MachineType::UintPtr(),    // kSlot
1504                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1505   DECLARE_DESCRIPTOR(BinaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
1506 };
1507 
1508 // TODO(jgruber): Pass the slot as UintPtr.
1509 class CallTrampoline_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1510  public:
1511   DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount, kSlot,
1512                             kMaybeFeedbackVector)
1513   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
1514                          MachineType::Int32(),      // kActualArgumentsCount
1515                          MachineType::Int32(),      // kSlot
1516                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1517   DECLARE_DESCRIPTOR(CallTrampoline_WithFeedbackDescriptor,
1518                      CallInterfaceDescriptor)
1519 };
1520 
1521 class Compare_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1522  public:
1523   DEFINE_PARAMETERS(kLeft, kRight, kSlot, kMaybeFeedbackVector)
1524   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
1525                          MachineType::AnyTagged(),  // kRight
1526                          MachineType::UintPtr(),    // kSlot
1527                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1528   DECLARE_DESCRIPTOR(Compare_WithFeedbackDescriptor, CallInterfaceDescriptor)
1529 };
1530 
1531 // TODO(jgruber): Pass the slot as UintPtr.
1532 class Construct_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1533  public:
1534   // kSlot is passed in a register, kMaybeFeedbackVector on the stack.
1535   DEFINE_JS_PARAMETERS(kSlot, kMaybeFeedbackVector)
1536   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(),      // kSlot
1537                             MachineType::AnyTagged())  // kMaybeFeedbackVector
1538   DECLARE_JS_COMPATIBLE_DESCRIPTOR(Construct_WithFeedbackDescriptor,
1539                                    CallInterfaceDescriptor, 1)
1540 };
1541 
1542 class UnaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
1543  public:
1544   DEFINE_PARAMETERS(kValue, kSlot, kMaybeFeedbackVector)
1545   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
1546                          MachineType::UintPtr(),    // kSlot
1547                          MachineType::AnyTagged())  // kMaybeFeedbackVector
1548   DECLARE_DESCRIPTOR(UnaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
1549 };
1550 
1551 #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...)                          \
1552   class Name##Descriptor : public CallInterfaceDescriptor {               \
1553    public:                                                                \
1554     DEFINE_PARAMETERS(__VA_ARGS__)                                        \
1555     DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
1556   };
1557 BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
1558 #undef DEFINE_TFS_BUILTIN_DESCRIPTOR
1559 
1560 // This file contains interface descriptor class definitions for builtins
1561 // defined in Torque. It is included here because the class definitions need to
1562 // precede the definition of name##Descriptor::key() below.
1563 #include "torque-generated/interface-descriptors.inc"
1564 
1565 #undef DECLARE_DEFAULT_DESCRIPTOR
1566 #undef DECLARE_DESCRIPTOR_WITH_BASE
1567 #undef DECLARE_DESCRIPTOR
1568 #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
1569 #undef DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS
1570 #undef DEFINE_RESULT_AND_PARAMETERS
1571 #undef DEFINE_PARAMETERS
1572 #undef DEFINE_PARAMETERS_VARARGS
1573 #undef DEFINE_PARAMETERS_NO_CONTEXT
1574 #undef DEFINE_RESULT_AND_PARAMETER_TYPES
1575 #undef DEFINE_PARAMETER_TYPES
1576 #undef DEFINE_JS_PARAMETERS
1577 #undef DEFINE_JS_PARAMETER_TYPES
1578 
1579 // We define the association between CallDescriptors::Key and the specialized
1580 // descriptor here to reduce boilerplate and mistakes.
1581 #define DEF_KEY(name, ...) \
1582   CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
1583 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
1584 #undef DEF_KEY
1585 }  // namespace internal
1586 }  // namespace v8
1587 
1588 #endif  // V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
1589