Home | History | Annotate | Download | only in src
      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/assembler.h"
     11 #include "src/globals.h"
     12 #include "src/isolate.h"
     13 #include "src/macro-assembler.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 #define INTERFACE_DESCRIPTOR_LIST(V)  \
     19   V(CppBuiltinAdaptor)                \
     20   V(CEntry1ArgvOnStack)               \
     21   V(Allocate)                         \
     22   V(Void)                             \
     23   V(ContextOnly)                      \
     24   V(NoContext)                        \
     25   V(Load)                             \
     26   V(LoadWithVector)                   \
     27   V(LoadGlobal)                       \
     28   V(LoadGlobalWithVector)             \
     29   V(Store)                            \
     30   V(StoreWithVector)                  \
     31   V(StoreTransition)                  \
     32   V(StoreGlobal)                      \
     33   V(StoreGlobalWithVector)            \
     34   V(FastNewFunctionContext)           \
     35   V(FastNewObject)                    \
     36   V(RecordWrite)                      \
     37   V(TypeConversion)                   \
     38   V(TypeConversionStackParameter)     \
     39   V(Typeof)                           \
     40   V(CallFunction)                     \
     41   V(CallVarargs)                      \
     42   V(CallForwardVarargs)               \
     43   V(CallWithSpread)                   \
     44   V(CallWithArrayLike)                \
     45   V(CallTrampoline)                   \
     46   V(ConstructStub)                    \
     47   V(ConstructVarargs)                 \
     48   V(ConstructForwardVarargs)          \
     49   V(ConstructWithSpread)              \
     50   V(ConstructWithArrayLike)           \
     51   V(JSTrampoline)                     \
     52   V(Abort)                            \
     53   V(AllocateHeapNumber)               \
     54   V(ArrayConstructor)                 \
     55   V(ArrayNoArgumentConstructor)       \
     56   V(ArraySingleArgumentConstructor)   \
     57   V(ArrayNArgumentsConstructor)       \
     58   V(Compare)                          \
     59   V(BinaryOp)                         \
     60   V(StringAt)                         \
     61   V(StringSubstring)                  \
     62   V(GetProperty)                      \
     63   V(ArgumentAdaptor)                  \
     64   V(ApiCallback)                      \
     65   V(ApiGetter)                        \
     66   V(GrowArrayElements)                \
     67   V(NewArgumentsElements)             \
     68   V(InterpreterDispatch)              \
     69   V(InterpreterPushArgsThenCall)      \
     70   V(InterpreterPushArgsThenConstruct) \
     71   V(InterpreterCEntry1)               \
     72   V(InterpreterCEntry2)               \
     73   V(ResumeGenerator)                  \
     74   V(FrameDropperTrampoline)           \
     75   V(RunMicrotasks)                    \
     76   V(WasmGrowMemory)                   \
     77   V(CloneObjectWithVector)            \
     78   BUILTIN_LIST_TFS(V)
     79 
     80 class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
     81  public:
     82   enum Flag {
     83     kNoFlags = 0u,
     84     kNoContext = 1u << 0,
     85   };
     86   typedef base::Flags<Flag> Flags;
     87 
     88   CallInterfaceDescriptorData() = default;
     89 
     90   // A copy of the passed in registers and param_representations is made
     91   // and owned by the CallInterfaceDescriptorData.
     92 
     93   void InitializePlatformSpecific(int register_parameter_count,
     94                                   const Register* registers);
     95 
     96   // if machine_types is null, then an array of size
     97   // (return_count + parameter_count) will be created with
     98   // MachineType::AnyTagged() for each member.
     99   //
    100   // if machine_types is not null, then it should be of the size
    101   // (return_count + parameter_count). Those members of the parameter array will
    102   // be initialized from {machine_types}, and the rest initialized to
    103   // MachineType::AnyTagged().
    104   void InitializePlatformIndependent(Flags flags, int return_count,
    105                                      int parameter_count,
    106                                      const MachineType* machine_types,
    107                                      int machine_types_length);
    108 
    109   void Reset();
    110 
    111   bool IsInitialized() const {
    112     return IsInitializedPlatformSpecific() &&
    113            IsInitializedPlatformIndependent();
    114   }
    115 
    116   Flags flags() const { return flags_; }
    117   int return_count() const { return return_count_; }
    118   int param_count() const { return param_count_; }
    119   int register_param_count() const { return register_param_count_; }
    120   Register register_param(int index) const { return register_params_[index]; }
    121   Register* register_params() const { return register_params_; }
    122   MachineType return_type(int index) const {
    123     DCHECK_LT(index, return_count_);
    124     return machine_types_[index];
    125   }
    126   MachineType param_type(int index) const {
    127     DCHECK_LT(index, param_count_);
    128     return machine_types_[return_count_ + index];
    129   }
    130 
    131   void RestrictAllocatableRegisters(const Register* registers, int num) {
    132     DCHECK_EQ(allocatable_registers_, 0);
    133     for (int i = 0; i < num; ++i) {
    134       allocatable_registers_ |= registers[i].bit();
    135     }
    136     DCHECK_GT(NumRegs(allocatable_registers_), 0);
    137   }
    138 
    139   RegList allocatable_registers() const { return allocatable_registers_; }
    140 
    141  private:
    142   bool IsInitializedPlatformSpecific() const {
    143     const bool initialized =
    144         register_param_count_ >= 0 && register_params_ != nullptr;
    145     // Platform-specific initialization happens before platform-independent.
    146     return initialized;
    147   }
    148   bool IsInitializedPlatformIndependent() const {
    149     const bool initialized =
    150         return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
    151     // Platform-specific initialization happens before platform-independent.
    152     return initialized;
    153   }
    154 
    155 #ifdef DEBUG
    156   bool AllStackParametersAreTagged() const;
    157 #endif  // DEBUG
    158 
    159   int register_param_count_ = -1;
    160   int return_count_ = -1;
    161   int param_count_ = -1;
    162   Flags flags_ = kNoFlags;
    163 
    164   // Specifying the set of registers that could be used by the register
    165   // allocator. Currently, it's only used by RecordWrite code stub.
    166   RegList allocatable_registers_ = 0;
    167 
    168   // |registers_params_| defines registers that are used for parameter passing.
    169   // |machine_types_| defines machine types for resulting values and incomping
    170   // parameters.
    171   // Both arrays are allocated dynamically by the InterfaceDescriptor and
    172   // freed on destruction. This is because static arrays cause creation of
    173   // runtime static initializers which we don't want.
    174   Register* register_params_ = nullptr;
    175   MachineType* machine_types_ = nullptr;
    176 
    177   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
    178 };
    179 
    180 class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
    181  public:
    182   enum Key {
    183 #define DEF_ENUM(name, ...) name,
    184     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
    185 #undef DEF_ENUM
    186         NUMBER_OF_DESCRIPTORS
    187   };
    188 
    189   static void InitializeOncePerProcess();
    190   static void TearDown();
    191 
    192   static CallInterfaceDescriptorData* call_descriptor_data(
    193       CallDescriptors::Key key) {
    194     return &call_descriptor_data_[key];
    195   }
    196 
    197   static Key GetKey(const CallInterfaceDescriptorData* data) {
    198     ptrdiff_t index = data - call_descriptor_data_;
    199     DCHECK_LE(0, index);
    200     DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
    201     return static_cast<CallDescriptors::Key>(index);
    202   }
    203 
    204  private:
    205   static CallInterfaceDescriptorData
    206       call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
    207 };
    208 
    209 class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
    210  public:
    211   typedef CallInterfaceDescriptorData::Flags Flags;
    212 
    213   CallInterfaceDescriptor() : data_(nullptr) {}
    214   virtual ~CallInterfaceDescriptor() {}
    215 
    216   CallInterfaceDescriptor(CallDescriptors::Key key)
    217       : data_(CallDescriptors::call_descriptor_data(key)) {}
    218 
    219   Flags flags() const { return data()->flags(); }
    220 
    221   bool HasContextParameter() const {
    222     return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
    223   }
    224 
    225   int GetReturnCount() const { return data()->return_count(); }
    226 
    227   MachineType GetReturnType(int index) const {
    228     DCHECK_LT(index, data()->return_count());
    229     return data()->return_type(index);
    230   }
    231 
    232   int GetParameterCount() const { return data()->param_count(); }
    233 
    234   int GetRegisterParameterCount() const {
    235     return data()->register_param_count();
    236   }
    237 
    238   int GetStackParameterCount() const {
    239     return data()->param_count() - data()->register_param_count();
    240   }
    241 
    242   Register GetRegisterParameter(int index) const {
    243     return data()->register_param(index);
    244   }
    245 
    246   MachineType GetParameterType(int index) const {
    247     DCHECK_LT(index, data()->param_count());
    248     return data()->param_type(index);
    249   }
    250 
    251   RegList allocatable_registers() const {
    252     return data()->allocatable_registers();
    253   }
    254 
    255   static const Register ContextRegister();
    256 
    257   const char* DebugName() const;
    258 
    259  protected:
    260   const CallInterfaceDescriptorData* data() const { return data_; }
    261 
    262   virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
    263     UNREACHABLE();
    264   }
    265 
    266   virtual void InitializePlatformIndependent(
    267       CallInterfaceDescriptorData* data) {
    268     // Default descriptor configuration: one result, all parameters are passed
    269     // in registers and all parameters have MachineType::AnyTagged() type.
    270     data->InitializePlatformIndependent(CallInterfaceDescriptorData::kNoFlags,
    271                                         1, data->register_param_count(),
    272                                         nullptr, 0);
    273   }
    274 
    275   // Initializes |data| using the platform dependent default set of registers.
    276   // It is intended to be used for TurboFan stubs when particular set of
    277   // registers does not matter.
    278   static void DefaultInitializePlatformSpecific(
    279       CallInterfaceDescriptorData* data, int register_parameter_count);
    280 
    281   // Initializes |data| using the platform dependent default set of registers
    282   // for JavaScript-compatible calling convention.
    283   // It is intended to be used for TurboFan stubs being called with JavaScript
    284   // linkage + additional parameters on registers and stack.
    285   static void JSDefaultInitializePlatformSpecific(
    286       CallInterfaceDescriptorData* data, int non_js_register_parameter_count);
    287 
    288  private:
    289   // {CallDescriptors} is allowed to call the private {Initialize} method.
    290   friend class CallDescriptors;
    291 
    292   const CallInterfaceDescriptorData* data_;
    293 
    294   void Initialize(CallInterfaceDescriptorData* data) {
    295     // The passed pointer should be a modifiable pointer to our own data.
    296     DCHECK_EQ(data, data_);
    297     DCHECK(!data->IsInitialized());
    298     InitializePlatformSpecific(data);
    299     InitializePlatformIndependent(data);
    300     DCHECK(data->IsInitialized());
    301   }
    302 };
    303 
    304 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
    305  public:                                         \
    306   explicit name() : base(key()) {}               \
    307   static inline CallDescriptors::Key key();
    308 
    309 #if defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
    310 // TODO(jgruber,v8:6666): Keep kRootRegister free unconditionally.
    311 constexpr int kMaxBuiltinRegisterParams = 4;
    312 #else
    313 constexpr int kMaxBuiltinRegisterParams = 5;
    314 #endif
    315 
    316 #define DECLARE_DEFAULT_DESCRIPTOR(name, base)                                 \
    317   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
    318  protected:                                                                    \
    319   static const int kRegisterParams =                                           \
    320       kParameterCount > kMaxBuiltinRegisterParams ? kMaxBuiltinRegisterParams  \
    321                                                   : kParameterCount;           \
    322   static const int kStackParams = kParameterCount - kRegisterParams;           \
    323   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)           \
    324       override {                                                               \
    325     DefaultInitializePlatformSpecific(data, kRegisterParams);                  \
    326   }                                                                            \
    327   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)        \
    328       override {                                                               \
    329     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
    330                                         kParameterCount, nullptr, 0);          \
    331   }                                                                            \
    332   name(CallDescriptors::Key key) : base(key) {}                                \
    333                                                                                \
    334  public:
    335 
    336 #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base,                        \
    337                                          non_js_reg_parameters_count)       \
    338   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                  \
    339  protected:                                                                 \
    340   void InitializePlatformSpecific(CallInterfaceDescriptorData* data)        \
    341       override {                                                            \
    342     JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
    343   }                                                                         \
    344   name(CallDescriptors::Key key) : base(key) {}                             \
    345                                                                             \
    346  public:
    347 
    348 #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...)   \
    349   static constexpr int kDescriptorFlags =                 \
    350       CallInterfaceDescriptorData::kNoFlags;              \
    351   static constexpr int kReturnCount = return_count;       \
    352   enum ParameterIndices {                                 \
    353     __dummy = -1, /* to be able to pass zero arguments */ \
    354     ##__VA_ARGS__,                                        \
    355                                                           \
    356     kParameterCount,                                      \
    357     kContext = kParameterCount /* implicit parameter */   \
    358   };
    359 
    360 #define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \
    361   static constexpr int kDescriptorFlags =                          \
    362       CallInterfaceDescriptorData::kNoContext;                     \
    363   static constexpr int kReturnCount = return_count;                \
    364   enum ParameterIndices {                                          \
    365     __dummy = -1, /* to be able to pass zero arguments */          \
    366     ##__VA_ARGS__,                                                 \
    367                                                                    \
    368     kParameterCount                                                \
    369   };
    370 
    371 #define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
    372 
    373 #define DEFINE_PARAMETERS_NO_CONTEXT(...) \
    374   DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(1, ##__VA_ARGS__)
    375 
    376 #define DEFINE_RESULT_AND_PARAMETER_TYPES(...)                                 \
    377   void InitializePlatformIndependent(CallInterfaceDescriptorData* data)        \
    378       override {                                                               \
    379     MachineType machine_types[] = {__VA_ARGS__};                               \
    380     static_assert(                                                             \
    381         kReturnCount + kParameterCount == arraysize(machine_types),            \
    382         "Parameter names definition is not consistent with parameter types");  \
    383     data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
    384                                         kParameterCount, machine_types,        \
    385                                         arraysize(machine_types));             \
    386   }
    387 
    388 #define DEFINE_PARAMETER_TYPES(...)                                        \
    389   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
    390                                     ##__VA_ARGS__)
    391 
    392 #define DEFINE_JS_PARAMETERS(...)                       \
    393   static constexpr int kDescriptorFlags =               \
    394       CallInterfaceDescriptorData::kNoFlags;            \
    395   static constexpr int kReturnCount = 1;                \
    396   enum ParameterIndices {                               \
    397     kTarget,                                            \
    398     kNewTarget,                                         \
    399     kActualArgumentsCount,                              \
    400     ##__VA_ARGS__,                                      \
    401                                                         \
    402     kParameterCount,                                    \
    403     kContext = kParameterCount /* implicit parameter */ \
    404   };
    405 
    406 #define DEFINE_JS_PARAMETER_TYPES(...)                                         \
    407   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */               \
    408                          MachineType::AnyTagged(), /* kNewTarget */            \
    409                          MachineType::Int32(),     /* kActualArgumentsCount */ \
    410                          ##__VA_ARGS__)
    411 
    412 #define DECLARE_DESCRIPTOR(name, base)                                         \
    413   DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
    414  protected:                                                                    \
    415   void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
    416   name(CallDescriptors::Key key) : base(key) {}                                \
    417                                                                                \
    418  public:
    419 
    420 class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
    421  public:
    422   DEFINE_PARAMETERS()
    423   DEFINE_PARAMETER_TYPES()
    424   DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
    425 };
    426 
    427 class AllocateDescriptor : public CallInterfaceDescriptor {
    428  public:
    429   DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
    430   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
    431                                     MachineType::Int32())  // kRequestedSize
    432   DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
    433 };
    434 
    435 // This descriptor defines the JavaScript calling convention that can be used
    436 // by stubs: target, new.target, argc (not including the receiver) and context
    437 // are passed in registers while receiver and the rest of the JS arguments are
    438 // passed on the stack.
    439 class JSTrampolineDescriptor : public CallInterfaceDescriptor {
    440  public:
    441   DEFINE_JS_PARAMETERS()
    442   DEFINE_JS_PARAMETER_TYPES()
    443 
    444   DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
    445                                    CallInterfaceDescriptor, 0)
    446 };
    447 
    448 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
    449  public:
    450   DEFINE_PARAMETERS()
    451   DEFINE_PARAMETER_TYPES()
    452   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
    453 };
    454 
    455 class NoContextDescriptor : public CallInterfaceDescriptor {
    456  public:
    457   DEFINE_PARAMETERS_NO_CONTEXT()
    458   DEFINE_PARAMETER_TYPES()
    459   DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
    460 };
    461 
    462 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
    463 class LoadDescriptor : public CallInterfaceDescriptor {
    464  public:
    465   DEFINE_PARAMETERS(kReceiver, kName, kSlot)
    466   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
    467                          MachineType::AnyTagged(),     // kName
    468                          MachineType::TaggedSigned())  // kSlot
    469   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
    470 
    471   static const Register ReceiverRegister();
    472   static const Register NameRegister();
    473   static const Register SlotRegister();
    474 };
    475 
    476 class LoadGlobalDescriptor : public CallInterfaceDescriptor {
    477  public:
    478   DEFINE_PARAMETERS(kName, kSlot)
    479   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
    480                          MachineType::TaggedSigned())  // kSlot
    481   DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
    482 
    483   static const Register NameRegister() {
    484     return LoadDescriptor::NameRegister();
    485   }
    486 
    487   static const Register SlotRegister() {
    488     return LoadDescriptor::SlotRegister();
    489   }
    490 };
    491 
    492 class StoreDescriptor : public CallInterfaceDescriptor {
    493  public:
    494   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
    495   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
    496                          MachineType::AnyTagged(),     // kName
    497                          MachineType::AnyTagged(),     // kValue
    498                          MachineType::TaggedSigned())  // kSlot
    499   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
    500 
    501   static const Register ReceiverRegister();
    502   static const Register NameRegister();
    503   static const Register ValueRegister();
    504   static const Register SlotRegister();
    505 
    506 #if V8_TARGET_ARCH_IA32
    507   static const bool kPassLastArgsOnStack = true;
    508 #else
    509   static const bool kPassLastArgsOnStack = false;
    510 #endif
    511 
    512   // Pass value and slot through the stack.
    513   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
    514 };
    515 
    516 class StoreTransitionDescriptor : public StoreDescriptor {
    517  public:
    518   DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
    519   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
    520                          MachineType::AnyTagged(),     // kName
    521                          MachineType::AnyTagged(),     // kMap
    522                          MachineType::AnyTagged(),     // kValue
    523                          MachineType::TaggedSigned(),  // kSlot
    524                          MachineType::AnyTagged())     // kVector
    525   DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
    526 
    527   static const Register MapRegister();
    528   static const Register SlotRegister();
    529   static const Register VectorRegister();
    530 
    531   // Pass value, slot and vector through the stack.
    532   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
    533 };
    534 
    535 class StoreWithVectorDescriptor : public StoreDescriptor {
    536  public:
    537   DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
    538   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
    539                          MachineType::AnyTagged(),     // kName
    540                          MachineType::AnyTagged(),     // kValue
    541                          MachineType::TaggedSigned(),  // kSlot
    542                          MachineType::AnyTagged())     // kVector
    543   DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
    544 
    545   static const Register VectorRegister();
    546 
    547   // Pass value, slot and vector through the stack.
    548   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
    549 };
    550 
    551 class StoreGlobalDescriptor : public CallInterfaceDescriptor {
    552  public:
    553   DEFINE_PARAMETERS(kName, kValue, kSlot)
    554   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
    555                          MachineType::AnyTagged(),     // kValue
    556                          MachineType::TaggedSigned())  // kSlot
    557   DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
    558 
    559   static const bool kPassLastArgsOnStack =
    560       StoreDescriptor::kPassLastArgsOnStack;
    561   // Pass value and slot through the stack.
    562   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
    563 
    564   static const Register NameRegister() {
    565     return StoreDescriptor::NameRegister();
    566   }
    567 
    568   static const Register ValueRegister() {
    569     return StoreDescriptor::ValueRegister();
    570   }
    571 
    572   static const Register SlotRegister() {
    573     return StoreDescriptor::SlotRegister();
    574   }
    575 };
    576 
    577 class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
    578  public:
    579   DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
    580   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
    581                          MachineType::AnyTagged(),     // kValue
    582                          MachineType::TaggedSigned(),  // kSlot
    583                          MachineType::AnyTagged())     // kVector
    584   DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
    585 
    586   static const Register VectorRegister() {
    587     return StoreWithVectorDescriptor::VectorRegister();
    588   }
    589 
    590   // Pass value, slot and vector through the stack.
    591   static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
    592 };
    593 
    594 class LoadWithVectorDescriptor : public LoadDescriptor {
    595  public:
    596   DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
    597   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
    598                          MachineType::AnyTagged(),     // kName
    599                          MachineType::TaggedSigned(),  // kSlot
    600                          MachineType::AnyTagged())     // kVector
    601   DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
    602 
    603   static const Register VectorRegister();
    604 };
    605 
    606 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
    607  public:
    608   DEFINE_PARAMETERS(kName, kSlot, kVector)
    609   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
    610                          MachineType::TaggedSigned(),  // kSlot
    611                          MachineType::AnyTagged())     // kVector
    612   DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
    613 
    614   static const Register VectorRegister() {
    615     return LoadWithVectorDescriptor::VectorRegister();
    616   }
    617 };
    618 
    619 class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor {
    620  public:
    621   DEFINE_PARAMETERS(kScopeInfo, kSlots)
    622   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kScopeInfo
    623                          MachineType::Int32())      // kSlots
    624   DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor)
    625 
    626   static const Register ScopeInfoRegister();
    627   static const Register SlotsRegister();
    628 };
    629 
    630 class FastNewObjectDescriptor : public CallInterfaceDescriptor {
    631  public:
    632   DEFINE_PARAMETERS(kTarget, kNewTarget)
    633   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    634                          MachineType::AnyTagged())  // kNewTarget
    635   DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
    636   static const Register TargetRegister();
    637   static const Register NewTargetRegister();
    638 };
    639 
    640 class RecordWriteDescriptor final : public CallInterfaceDescriptor {
    641  public:
    642   DEFINE_PARAMETERS(kObject, kSlot, kIsolate, kRememberedSet, kFPMode)
    643   DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
    644                          MachineType::Pointer(),        // kSlot
    645                          MachineType::Pointer(),        // kIsolate
    646                          MachineType::TaggedSigned(),   // kRememberedSet
    647                          MachineType::TaggedSigned())   // kFPMode
    648 
    649   DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
    650 };
    651 
    652 class TypeConversionDescriptor final : public CallInterfaceDescriptor {
    653  public:
    654   DEFINE_PARAMETERS(kArgument)
    655   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
    656   DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
    657 
    658   static const Register ArgumentRegister();
    659 };
    660 
    661 class TypeConversionStackParameterDescriptor final
    662     : public CallInterfaceDescriptor {
    663  public:
    664   DEFINE_PARAMETERS(kArgument)
    665   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
    666   DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor,
    667                      CallInterfaceDescriptor)
    668 };
    669 
    670 class GetPropertyDescriptor final : public CallInterfaceDescriptor {
    671  public:
    672   DEFINE_PARAMETERS(kObject, kKey)
    673   DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
    674 };
    675 
    676 class TypeofDescriptor : public CallInterfaceDescriptor {
    677  public:
    678   DEFINE_PARAMETERS(kObject)
    679   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
    680   DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
    681 };
    682 
    683 class CallTrampolineDescriptor : public CallInterfaceDescriptor {
    684  public:
    685   DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
    686   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
    687                          MachineType::Int32())      // kActualArgumentsCount
    688   DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
    689 };
    690 
    691 class CallVarargsDescriptor : public CallInterfaceDescriptor {
    692  public:
    693   DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsList,
    694                     kArgumentsLength)
    695   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    696                          MachineType::Int32(),      // kActualArgumentsCount
    697                          MachineType::AnyTagged(),  // kArgumentsList
    698                          MachineType::Int32())      // kArgumentsLength
    699   DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
    700 };
    701 
    702 class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
    703  public:
    704   DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kStartIndex)
    705   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    706                          MachineType::Int32(),      // kActualArgumentsCount
    707                          MachineType::Int32())      // kStartIndex
    708   DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
    709 };
    710 
    711 class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
    712  public:
    713   DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread)
    714   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    715                          MachineType::Int32(),      // kArgumentsCount
    716                          MachineType::AnyTagged())  // kSpread
    717   DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
    718 };
    719 
    720 class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
    721  public:
    722   DEFINE_PARAMETERS(kTarget, kArgumentsList)
    723   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    724                          MachineType::AnyTagged())  // kArgumentsList
    725   DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
    726 };
    727 
    728 class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
    729  public:
    730   DEFINE_JS_PARAMETERS(kArgumentsList, kArgumentsLength)
    731   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged(),  // kArgumentsList
    732                             MachineType::Int32())      // kArgumentsLength
    733   DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
    734 };
    735 
    736 class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
    737  public:
    738   DEFINE_JS_PARAMETERS(kStartIndex)
    739   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
    740   DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
    741 };
    742 
    743 class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
    744  public:
    745   DEFINE_JS_PARAMETERS(kSpread)
    746   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
    747   DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
    748 };
    749 
    750 class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
    751  public:
    752   DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
    753   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
    754                          MachineType::AnyTagged(),  // kNewTarget
    755                          MachineType::AnyTagged())  // kArgumentsList
    756   DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
    757 };
    758 
    759 // TODO(ishell): consider merging this with ArrayConstructorDescriptor
    760 class ConstructStubDescriptor : public CallInterfaceDescriptor {
    761  public:
    762   DEFINE_JS_PARAMETERS(kAllocationSite)
    763   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged());
    764 
    765   // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
    766   DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
    767 };
    768 
    769 class CallFunctionDescriptor : public CallInterfaceDescriptor {
    770  public:
    771   DEFINE_PARAMETERS(kTarget)
    772   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
    773   DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
    774 };
    775 
    776 class AbortDescriptor : public CallInterfaceDescriptor {
    777  public:
    778   DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
    779   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
    780   DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
    781 };
    782 
    783 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
    784  public:
    785   DEFINE_PARAMETERS_NO_CONTEXT()
    786   DEFINE_PARAMETER_TYPES()
    787   DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
    788 };
    789 
    790 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
    791  public:
    792   DEFINE_JS_PARAMETERS(kAllocationSite)
    793   DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged());
    794 
    795   DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
    796                                    CallInterfaceDescriptor, 1)
    797 };
    798 
    799 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
    800  public:
    801   // This descriptor declares only register arguments while respective number
    802   // of JS arguments stay on the expression stack.
    803   // The ArrayNArgumentsConstructor builtin does not access stack arguments
    804   // directly it just forwards them to the runtime function.
    805   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
    806   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction,
    807                          MachineType::AnyTagged(),  // kAllocationSite
    808                          MachineType::Int32())      // kActualArgumentsCount
    809   DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
    810                      CallInterfaceDescriptor)
    811 };
    812 
    813 class ArrayNoArgumentConstructorDescriptor
    814     : public ArrayNArgumentsConstructorDescriptor {
    815  public:
    816   // This descriptor declares same register arguments as the parent
    817   // ArrayNArgumentsConstructorDescriptor and it declares indices for
    818   // JS arguments passed on the expression stack.
    819   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
    820                     kFunctionParameter)
    821   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
    822                          MachineType::AnyTagged(),  // kAllocationSite
    823                          MachineType::Int32(),      // kActualArgumentsCount
    824                          MachineType::AnyTagged())  // kFunctionParameter
    825   DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
    826                      ArrayNArgumentsConstructorDescriptor)
    827 };
    828 
    829 class ArraySingleArgumentConstructorDescriptor
    830     : public ArrayNArgumentsConstructorDescriptor {
    831  public:
    832   // This descriptor declares same register arguments as the parent
    833   // ArrayNArgumentsConstructorDescriptor and it declares indices for
    834   // JS arguments passed on the expression stack.
    835   DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
    836                     kFunctionParameter, kArraySizeSmiParameter)
    837   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
    838                          MachineType::AnyTagged(),  // kAllocationSite
    839                          MachineType::Int32(),      // kActualArgumentsCount
    840                          MachineType::AnyTagged(),  // kFunctionParameter
    841                          MachineType::AnyTagged())  // kArraySizeSmiParameter
    842   DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
    843                      ArrayNArgumentsConstructorDescriptor)
    844 };
    845 
    846 class CompareDescriptor : public CallInterfaceDescriptor {
    847  public:
    848   DEFINE_PARAMETERS(kLeft, kRight)
    849   DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
    850 };
    851 
    852 
    853 class BinaryOpDescriptor : public CallInterfaceDescriptor {
    854  public:
    855   DEFINE_PARAMETERS(kLeft, kRight)
    856   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
    857 };
    858 
    859 // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
    860 // as they all have the same interface.
    861 class StringAtDescriptor final : public CallInterfaceDescriptor {
    862  public:
    863   DEFINE_PARAMETERS(kReceiver, kPosition)
    864   // TODO(turbofan): Return untagged value here.
    865   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(),  // result 1
    866                                     MachineType::AnyTagged(),     // kReceiver
    867                                     MachineType::IntPtr())        // kPosition
    868   DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
    869 };
    870 
    871 class StringSubstringDescriptor final : public CallInterfaceDescriptor {
    872  public:
    873   DEFINE_PARAMETERS(kString, kFrom, kTo)
    874   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kString
    875                          MachineType::IntPtr(),     // kFrom
    876                          MachineType::IntPtr())     // kTo
    877 
    878   // TODO(turbofan): Allow builtins to return untagged values.
    879   DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
    880 };
    881 
    882 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
    883  public:
    884   DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
    885   DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
    886   DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
    887 };
    888 
    889 class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
    890  public:
    891   DEFINE_JS_PARAMETERS(kCFunction)
    892   DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
    893   DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
    894                                    CallInterfaceDescriptor, 1)
    895 };
    896 
    897 class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
    898  public:
    899   DEFINE_PARAMETERS(kArity,          // register argument
    900                     kCFunction,      // register argument
    901                     kPadding,        // stack argument 1 (just padding)
    902                     kArgcSmi,        // stack argument 2
    903                     kTargetCopy,     // stack argument 3
    904                     kNewTargetCopy)  // stack argument 4
    905   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kArity
    906                          MachineType::Pointer(),    // kCFunction
    907                          MachineType::AnyTagged(),  // kPadding
    908                          MachineType::AnyTagged(),  // kArgcSmi
    909                          MachineType::AnyTagged(),  // kTargetCopy
    910                          MachineType::AnyTagged())  // kNewTargetCopy
    911   DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
    912 };
    913 
    914 class ApiCallbackDescriptor : public CallInterfaceDescriptor {
    915  public:
    916   DEFINE_PARAMETERS_NO_CONTEXT(kTargetContext, kCallData, kHolder,
    917                                kApiFunctionAddress)
    918   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTargetContext
    919                          MachineType::AnyTagged(),  // kCallData
    920                          MachineType::AnyTagged(),  // kHolder
    921                          MachineType::Pointer())    // kApiFunctionAddress
    922   DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
    923 };
    924 
    925 class ApiGetterDescriptor : public CallInterfaceDescriptor {
    926  public:
    927   DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
    928   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
    929                          MachineType::AnyTagged(),  // kHolder
    930                          MachineType::AnyTagged())  // kCallback
    931   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
    932 
    933   static const Register ReceiverRegister();
    934   static const Register HolderRegister();
    935   static const Register CallbackRegister();
    936 };
    937 
    938 // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
    939 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
    940  public:
    941   DEFINE_PARAMETERS(kObject, kKey)
    942   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kObject
    943                          MachineType::AnyTagged())  // kKey
    944   DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
    945 
    946   static const Register ObjectRegister();
    947   static const Register KeyRegister();
    948 };
    949 
    950 class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
    951  public:
    952   DEFINE_PARAMETERS(kFrame, kLength, kMappedCount)
    953   DEFINE_PARAMETER_TYPES(MachineType::Pointer(),       // kFrame
    954                          MachineType::TaggedSigned(),  // kLength
    955                          MachineType::TaggedSigned())  // kMappedCount
    956   DECLARE_DESCRIPTOR(NewArgumentsElementsDescriptor, CallInterfaceDescriptor)
    957 };
    958 
    959 class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
    960     : public CallInterfaceDescriptor {
    961  public:
    962   DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
    963                     kDispatchTable)
    964   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kAccumulator
    965                          MachineType::IntPtr(),     // kBytecodeOffset
    966                          MachineType::AnyTagged(),  // kBytecodeArray
    967                          MachineType::IntPtr())     // kDispatchTable
    968   DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
    969 };
    970 
    971 class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
    972  public:
    973   DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
    974   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
    975                          MachineType::Pointer(),    // kFirstArgument
    976                          MachineType::AnyTagged())  // kFunction
    977   DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
    978                      CallInterfaceDescriptor)
    979 };
    980 
    981 class InterpreterPushArgsThenConstructDescriptor
    982     : public CallInterfaceDescriptor {
    983  public:
    984   DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor,
    985                     kFeedbackElement, kFirstArgument)
    986   DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
    987                          MachineType::AnyTagged(),  // kNewTarget
    988                          MachineType::AnyTagged(),  // kConstructor
    989                          MachineType::AnyTagged(),  // kFeedbackElement
    990                          MachineType::Pointer())    // kFirstArgument
    991   DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
    992                      CallInterfaceDescriptor)
    993 };
    994 
    995 class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
    996  public:
    997   DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
    998                                kFunctionEntry)
    999   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
   1000                                     MachineType::Int32(),  // kNumberOfArguments
   1001                                     MachineType::Pointer(),  // kFirstArgument
   1002                                     MachineType::Pointer())  // kFunctionEntry
   1003   DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
   1004 };
   1005 
   1006 class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
   1007  public:
   1008   DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
   1009                                kFunctionEntry)
   1010   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
   1011                                     MachineType::AnyTagged(),  // result 2
   1012                                     MachineType::Int32(),  // kNumberOfArguments
   1013                                     MachineType::Pointer(),  // kFirstArgument
   1014                                     MachineType::Pointer())  // kFunctionEntry
   1015   DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
   1016 };
   1017 
   1018 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
   1019  public:
   1020   DEFINE_PARAMETERS(kValue, kGenerator)
   1021   DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
   1022                          MachineType::AnyTagged())  // kGenerator
   1023   DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
   1024 };
   1025 
   1026 class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
   1027  public:
   1028   DEFINE_PARAMETERS(kRestartFp)
   1029   DEFINE_PARAMETER_TYPES(MachineType::Pointer())
   1030   DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
   1031 };
   1032 
   1033 class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
   1034  public:
   1035   DEFINE_PARAMETERS()
   1036   DECLARE_DEFAULT_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)
   1037 };
   1038 
   1039 class WasmGrowMemoryDescriptor final : public CallInterfaceDescriptor {
   1040  public:
   1041   DEFINE_PARAMETERS_NO_CONTEXT(kNumPages)
   1042   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(),  // result 1
   1043                                     MachineType::Int32())  // kNumPages
   1044   DECLARE_DESCRIPTOR(WasmGrowMemoryDescriptor, CallInterfaceDescriptor)
   1045 };
   1046 
   1047 class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
   1048  public:
   1049   DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
   1050   DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
   1051                                     MachineType::AnyTagged(),      // kSource
   1052                                     MachineType::TaggedSigned(),   // kFlags
   1053                                     MachineType::TaggedSigned(),   // kSlot
   1054                                     MachineType::AnyTagged())      // kVector
   1055   DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
   1056 };
   1057 
   1058 #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...)                          \
   1059   class Name##Descriptor : public CallInterfaceDescriptor {               \
   1060    public:                                                                \
   1061     DEFINE_PARAMETERS(__VA_ARGS__)                                        \
   1062     DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
   1063   };
   1064 BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
   1065 #undef DEFINE_TFS_BUILTIN_DESCRIPTOR
   1066 
   1067 #undef DECLARE_DEFAULT_DESCRIPTOR
   1068 #undef DECLARE_DESCRIPTOR_WITH_BASE
   1069 #undef DECLARE_DESCRIPTOR
   1070 #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
   1071 #undef DEFINE_RESULT_AND_PARAMETERS
   1072 #undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT
   1073 #undef DEFINE_PARAMETERS
   1074 #undef DEFINE_PARAMETERS_NO_CONTEXT
   1075 #undef DEFINE_RESULT_AND_PARAMETER_TYPES
   1076 #undef DEFINE_PARAMETER_TYPES
   1077 #undef DEFINE_JS_PARAMETERS
   1078 #undef DEFINE_JS_PARAMETER_TYPES
   1079 
   1080 // We define the association between CallDescriptors::Key and the specialized
   1081 // descriptor here to reduce boilerplate and mistakes.
   1082 #define DEF_KEY(name, ...) \
   1083   CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
   1084 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
   1085 #undef DEF_KEY
   1086 }  // namespace internal
   1087 }  // namespace v8
   1088 
   1089 #endif  // V8_INTERFACE_DESCRIPTORS_H_
   1090