interface-descriptors.h 77 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
#define V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
7

8 9
#include <memory>

10 11
#include "src/codegen/machine-type.h"
#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 17 18

namespace v8 {
namespace internal {

19 20 21 22
#define TORQUE_BUILTIN_LIST_TFC(V)                                            \
  BUILTIN_LIST_FROM_TORQUE(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
                           IGNORE_BUILTIN, IGNORE_BUILTIN)

23 24 25 26 27 28 29 30 31 32 33 34 35
#define INTERFACE_DESCRIPTOR_LIST(V)     \
  V(Abort)                               \
  V(Allocate)                            \
  V(ApiCallback)                         \
  V(ApiGetter)                           \
  V(ArrayConstructor)                    \
  V(ArrayNArgumentsConstructor)          \
  V(ArrayNoArgumentConstructor)          \
  V(ArraySingleArgumentConstructor)      \
  V(AsyncFunctionStackParameter)         \
  V(BigIntToI32Pair)                     \
  V(BigIntToI64)                         \
  V(BinaryOp)                            \
36
  V(BinaryOp_Baseline)                   \
37 38 39 40
  V(BinaryOp_WithFeedback)               \
  V(CallForwardVarargs)                  \
  V(CallFunctionTemplate)                \
  V(CallTrampoline)                      \
41
  V(CallTrampoline_Baseline)             \
42 43 44 45 46
  V(CallTrampoline_WithFeedback)         \
  V(CallVarargs)                         \
  V(CallWithArrayLike)                   \
  V(CallWithArrayLike_WithFeedback)      \
  V(CallWithSpread)                      \
47
  V(CallWithSpread_Baseline)             \
48 49
  V(CallWithSpread_WithFeedback)         \
  V(CEntry1ArgvOnStack)                  \
50
  V(CloneObjectBaseline)                 \
51 52
  V(CloneObjectWithVector)               \
  V(Compare)                             \
53
  V(Compare_Baseline)                    \
54 55 56 57 58 59 60
  V(Compare_WithFeedback)                \
  V(ConstructForwardVarargs)             \
  V(ConstructStub)                       \
  V(ConstructVarargs)                    \
  V(ConstructWithArrayLike)              \
  V(ConstructWithArrayLike_WithFeedback) \
  V(Construct_WithFeedback)              \
61
  V(Construct_Baseline)                  \
62
  V(ConstructWithSpread)                 \
63
  V(ConstructWithSpread_Baseline)        \
64 65 66
  V(ConstructWithSpread_WithFeedback)    \
  V(ContextOnly)                         \
  V(CppBuiltinAdaptor)                   \
67
  V(DynamicCheckMaps)                    \
68 69
  V(EphemeronKeyBarrier)                 \
  V(FastNewObject)                       \
70
  V(ForInPrepare)                        \
71 72 73 74 75 76 77 78 79
  V(FrameDropperTrampoline)              \
  V(GetIteratorStackParameter)           \
  V(GetProperty)                         \
  V(GrowArrayElements)                   \
  V(I32PairToBigInt)                     \
  V(I64ToBigInt)                         \
  V(InterpreterCEntry1)                  \
  V(InterpreterCEntry2)                  \
  V(InterpreterDispatch)                 \
80
  V(TailCallOptimizedCodeSlot)           \
81 82 83
  V(InterpreterPushArgsThenCall)         \
  V(InterpreterPushArgsThenConstruct)    \
  V(JSTrampoline)                        \
84 85
  V(BaselineOutOfLinePrologue)           \
  V(BaselineLeaveFrame)                  \
86
  V(Load)                                \
87
  V(LoadBaseline)                        \
88
  V(LoadGlobal)                          \
89
  V(LoadGlobalBaseline)                  \
90 91 92 93
  V(LoadGlobalNoFeedback)                \
  V(LoadGlobalWithVector)                \
  V(LoadNoFeedback)                      \
  V(LoadWithVector)                      \
94
  V(LoadWithReceiverAndVector)           \
95 96
  V(LoadWithReceiverBaseline)            \
  V(LookupBaseline)                      \
97 98 99 100 101
  V(NoContext)                           \
  V(RecordWrite)                         \
  V(ResumeGenerator)                     \
  V(RunMicrotasks)                       \
  V(RunMicrotasksEntry)                  \
102
  V(SingleParameterOnStack)              \
103
  V(Store)                               \
104
  V(StoreBaseline)                       \
105
  V(StoreGlobal)                         \
106
  V(StoreGlobalBaseline)                 \
107 108 109 110 111 112 113
  V(StoreGlobalWithVector)               \
  V(StoreTransition)                     \
  V(StoreWithVector)                     \
  V(StringAt)                            \
  V(StringAtAsString)                    \
  V(StringSubstring)                     \
  V(TypeConversion)                      \
114
  V(TypeConversionNoContext)             \
115
  V(TypeConversion_Baseline)             \
116
  V(Typeof)                              \
117
  V(UnaryOp_Baseline)                    \
118 119 120 121 122 123 124
  V(UnaryOp_WithFeedback)                \
  V(Void)                                \
  V(WasmFloat32ToNumber)                 \
  V(WasmFloat64ToNumber)                 \
  V(WasmI32AtomicWait32)                 \
  V(WasmI64AtomicWait32)                 \
  BUILTIN_LIST_TFS(V)                    \
125
  TORQUE_BUILTIN_LIST_TFC(V)
126

127 128 129 130 131 132
enum class StackArgumentOrder {
  kDefault,  // Arguments in the stack are pushed in the default/stub order (the
             // first argument is pushed first).
  kJS,  // Arguments in the stack are pushed in the same order as the one used
        // by JS-to-JS function calls. This should be used if calling a
        // JSFunction or if the builtin is expected to be called directly from a
133
        // JSFunction. This order is reversed compared to kDefault.
134 135
};

136
class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
137
 public:
138 139 140
  enum Flag {
    kNoFlags = 0u,
    kNoContext = 1u << 0,
141 142 143 144
    // This indicates that the code uses a special frame that does not scan the
    // stack arguments, e.g. EntryFrame. And this allows the code to use
    // untagged stack arguments.
    kNoStackScan = 1u << 1,
145 146 147 148
    // In addition to the specified parameters, additional arguments can be
    // passed on the stack.
    // This does not indicate if arguments adaption is used or not.
    kAllowVarArgs = 1u << 2,
149
  };
150
  using Flags = base::Flags<Flag>;
151

152
  CallInterfaceDescriptorData() = default;
153

154 155 156 157
  CallInterfaceDescriptorData(const CallInterfaceDescriptorData&) = delete;
  CallInterfaceDescriptorData& operator=(const CallInterfaceDescriptorData&) =
      delete;

158
  // A copy of the passed in registers and param_representations is made
159
  // and owned by the CallInterfaceDescriptorData.
160

161 162
  void InitializePlatformSpecific(int register_parameter_count,
                                  const Register* registers);
163

164
  // if machine_types is null, then an array of size
165
  // (return_count + parameter_count) will be created with
166
  // MachineType::AnyTagged() for each member.
167 168
  //
  // if machine_types is not null, then it should be of the size
169 170 171
  // (return_count + parameter_count). Those members of the parameter array will
  // be initialized from {machine_types}, and the rest initialized to
  // MachineType::AnyTagged().
172 173
  void InitializePlatformIndependent(Flags flags, int return_count,
                                     int parameter_count,
174
                                     const MachineType* machine_types,
175 176
                                     int machine_types_length,
                                     StackArgumentOrder stack_order);
177

178 179
  void Reset();

180
  bool IsInitialized() const {
181 182
    return IsInitializedPlatformSpecific() &&
           IsInitializedPlatformIndependent();
183
  }
184

185
  Flags flags() const { return flags_; }
186
  int return_count() const { return return_count_; }
187
  int param_count() const { return param_count_; }
188 189
  int register_param_count() const { return register_param_count_; }
  Register register_param(int index) const { return register_params_[index]; }
190
  Register* register_params() const { return register_params_; }
191 192 193 194 195 196 197 198
  MachineType return_type(int index) const {
    DCHECK_LT(index, return_count_);
    return machine_types_[index];
  }
  MachineType param_type(int index) const {
    DCHECK_LT(index, param_count_);
    return machine_types_[return_count_ + index];
  }
199
  StackArgumentOrder stack_order() const { return stack_order_; }
200

201
  void RestrictAllocatableRegisters(const Register* registers, int num) {
202
    DCHECK_EQ(allocatable_registers_, 0);
203 204 205
    for (int i = 0; i < num; ++i) {
      allocatable_registers_ |= registers[i].bit();
    }
206
    DCHECK_GT(NumRegs(allocatable_registers_), 0);
207 208 209 210
  }

  RegList allocatable_registers() const { return allocatable_registers_; }

211
 private:
212 213
  bool IsInitializedPlatformSpecific() const {
    const bool initialized =
214 215
        (register_param_count_ == 0 && register_params_ == nullptr) ||
        (register_param_count_ > 0 && register_params_ != nullptr);
216 217 218 219 220 221 222 223 224 225 226 227 228 229
    // Platform-specific initialization happens before platform-independent.
    return initialized;
  }
  bool IsInitializedPlatformIndependent() const {
    const bool initialized =
        return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
    // Platform-specific initialization happens before platform-independent.
    return initialized;
  }

#ifdef DEBUG
  bool AllStackParametersAreTagged() const;
#endif  // DEBUG

230
  int register_param_count_ = -1;
231
  int return_count_ = -1;
232
  int param_count_ = -1;
233
  Flags flags_ = kNoFlags;
234
  StackArgumentOrder stack_order_ = StackArgumentOrder::kDefault;
235

236 237
  // Specifying the set of registers that could be used by the register
  // allocator. Currently, it's only used by RecordWrite code stub.
238
  RegList allocatable_registers_ = 0;
239

240 241 242 243 244 245
  // |registers_params_| defines registers that are used for parameter passing.
  // |machine_types_| defines machine types for resulting values and incomping
  // parameters.
  // Both arrays are allocated dynamically by the InterfaceDescriptor and
  // freed on destruction. This is because static arrays cause creation of
  // runtime static initializers which we don't want.
246 247
  Register* register_params_ = nullptr;
  MachineType* machine_types_ = nullptr;
248 249
};

250
class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
251 252
 public:
  enum Key {
253
#define DEF_ENUM(name, ...) name,
254 255
    INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
#undef DEF_ENUM
256
        NUMBER_OF_DESCRIPTORS
257
  };
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276

  static void InitializeOncePerProcess();
  static void TearDown();

  static CallInterfaceDescriptorData* call_descriptor_data(
      CallDescriptors::Key key) {
    return &call_descriptor_data_[key];
  }

  static Key GetKey(const CallInterfaceDescriptorData* data) {
    ptrdiff_t index = data - call_descriptor_data_;
    DCHECK_LE(0, index);
    DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
    return static_cast<CallDescriptors::Key>(index);
  }

 private:
  static CallInterfaceDescriptorData
      call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
277 278
};

279
class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
280
 public:
281
  using Flags = CallInterfaceDescriptorData::Flags;
282

283
  CallInterfaceDescriptor() : data_(nullptr) {}
284
  virtual ~CallInterfaceDescriptor() = default;
285

286
  explicit CallInterfaceDescriptor(CallDescriptors::Key key)
287
      : data_(CallDescriptors::call_descriptor_data(key)) {}
288

289 290 291 292 293 294
  Flags flags() const { return data()->flags(); }

  bool HasContextParameter() const {
    return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
  }

295 296 297 298
  bool AllowVarArgs() const {
    return flags() & CallInterfaceDescriptorData::kAllowVarArgs;
  }

299 300 301 302 303 304 305
  int GetReturnCount() const { return data()->return_count(); }

  MachineType GetReturnType(int index) const {
    DCHECK_LT(index, data()->return_count());
    return data()->return_type(index);
  }

306 307
  int GetParameterCount() const { return data()->param_count(); }

308 309 310
  int GetRegisterParameterCount() const {
    return data()->register_param_count();
  }
311

312
  int GetStackParameterCount() const {
313
    return data()->param_count() - data()->register_param_count();
314 315 316
  }

  Register GetRegisterParameter(int index) const {
317
    DCHECK_LT(index, data()->register_param_count());
318
    return data()->register_param(index);
319 320
  }

321
  MachineType GetParameterType(int index) const {
322
    DCHECK_LT(index, data()->param_count());
323
    return data()->param_type(index);
324 325
  }

326 327 328 329
  RegList allocatable_registers() const {
    return data()->allocatable_registers();
  }

330 331 332 333
  StackArgumentOrder GetStackArgumentOrder() const {
    return data()->stack_order();
  }

334 335
  static const Register ContextRegister();

336
  const char* DebugName() const;
337

338 339 340 341
  bool operator==(const CallInterfaceDescriptor& other) const {
    return data() == other.data();
  }

342 343 344
 protected:
  const CallInterfaceDescriptorData* data() const { return data_; }

345 346 347 348
  virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
    UNREACHABLE();
  }

349 350 351 352 353 354 355 356
  // Initializes |data| to an unspecified state, for platforms that haven't
  // implemented a given builtin.
  static void InitializePlatformUnimplemented(CallInterfaceDescriptorData* data,
                                              int register_parameter_count) {
    DefaultInitializePlatformSpecific(data,
                                      std::min(register_parameter_count, 4));
  }

357 358
  virtual void InitializePlatformIndependent(
      CallInterfaceDescriptorData* data) {
359 360
    // Default descriptor configuration: one result, all parameters are passed
    // in registers and all parameters have MachineType::AnyTagged() type.
361 362 363
    data->InitializePlatformIndependent(
        CallInterfaceDescriptorData::kNoFlags, 1, data->register_param_count(),
        nullptr, 0, StackArgumentOrder::kDefault);
364 365
  }

366 367 368 369 370 371
  // Initializes |data| using the platform dependent default set of registers.
  // It is intended to be used for TurboFan stubs when particular set of
  // registers does not matter.
  static void DefaultInitializePlatformSpecific(
      CallInterfaceDescriptorData* data, int register_parameter_count);

372 373 374 375 376 377 378
  // Initializes |data| using the platform dependent default set of registers
  // for JavaScript-compatible calling convention.
  // It is intended to be used for TurboFan stubs being called with JavaScript
  // linkage + additional parameters on registers and stack.
  static void JSDefaultInitializePlatformSpecific(
      CallInterfaceDescriptorData* data, int non_js_register_parameter_count);

379
  // Checks if float parameters are not assigned invalid registers.
380 381 382 383 384 385 386 387
  bool CheckFloatingPointParameters(CallInterfaceDescriptorData* data) {
    for (int i = 0; i < data->register_param_count(); i++) {
      if (IsFloatingPoint(data->param_type(i).representation())) {
        if (!IsValidFloatParameterRegister(data->register_param(i))) {
          return false;
        }
      }
    }
388 389 390
    return true;
  }

391 392
  bool IsValidFloatParameterRegister(Register reg);

393
 private:
394 395 396
  // {CallDescriptors} is allowed to call the private {Initialize} method.
  friend class CallDescriptors;

397
  const CallInterfaceDescriptorData* data_;
398 399 400 401 402 403 404 405

  void Initialize(CallInterfaceDescriptorData* data) {
    // The passed pointer should be a modifiable pointer to our own data.
    DCHECK_EQ(data, data_);
    DCHECK(!data->IsInitialized());
    InitializePlatformSpecific(data);
    InitializePlatformIndependent(data);
    DCHECK(data->IsInitialized());
406
    DCHECK(CheckFloatingPointParameters(data));
407
  }
408
};
409

410 411 412
#define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
 public:                                         \
  explicit name() : base(key()) {}               \
vogelheim's avatar
vogelheim committed
413
  static inline CallDescriptors::Key key();
414

415
#if defined(V8_TARGET_ARCH_IA32)
416 417 418 419 420 421 422 423 424 425
// To support all possible cases, we must limit the number of register args for
// TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
// as the context register and ebx is the root register. One register must
// remain available to store the jump/call target. Thus 3 registers remain for
// arguments. The reason this applies to TFS builtins specifically is because
// this becomes relevant for builtins used as targets of Torque function
// pointers (which must have a register available to store the target).
// TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
// that comes with its own set of complications. It's possible, but requires
// refactoring the calling convention of other existing stubs.
426
constexpr int kMaxBuiltinRegisterParams = 4;
427
constexpr int kMaxTFSBuiltinRegisterParams = 3;
428
#else
429
constexpr int kMaxBuiltinRegisterParams = 5;
430
constexpr int kMaxTFSBuiltinRegisterParams = kMaxBuiltinRegisterParams;
431
#endif
432
STATIC_ASSERT(kMaxTFSBuiltinRegisterParams <= kMaxBuiltinRegisterParams);
433

434 435 436 437
#define DECLARE_DEFAULT_DESCRIPTOR(name, base)                                 \
  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
 protected:                                                                    \
  static const int kRegisterParams =                                           \
438 439 440
      kParameterCount > kMaxTFSBuiltinRegisterParams                           \
          ? kMaxTFSBuiltinRegisterParams                                       \
          : kParameterCount;                                                   \
441 442 443 444 445 446 447 448
  static const int kStackParams = kParameterCount - kRegisterParams;           \
  void InitializePlatformSpecific(CallInterfaceDescriptorData* data)           \
      override {                                                               \
    DefaultInitializePlatformSpecific(data, kRegisterParams);                  \
  }                                                                            \
  void InitializePlatformIndependent(CallInterfaceDescriptorData* data)        \
      override {                                                               \
    data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
449 450
                                        kParameterCount, nullptr, 0,           \
                                        kStackArgumentOrder);                  \
451 452 453
  }                                                                            \
  name(CallDescriptors::Key key) : base(key) {}                                \
                                                                               \
454 455
 public:

456 457 458 459 460 461 462 463
#define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base,                        \
                                         non_js_reg_parameters_count)       \
  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                  \
 protected:                                                                 \
  void InitializePlatformSpecific(CallInterfaceDescriptorData* data)        \
      override {                                                            \
    JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
  }                                                                         \
464
  name(CallDescriptors::Key key) : base(key) {}                             \
465 466 467
                                                                            \
 public:

468 469
#define DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(flags, stack_order,       \
                                               return_count, ...)        \
470 471
  static constexpr int kDescriptorFlags = flags;                         \
  static constexpr int kReturnCount = return_count;                      \
472
  static constexpr StackArgumentOrder kStackArgumentOrder = stack_order; \
473 474 475 476 477 478
  enum ParameterIndices {                                                \
    __dummy = -1, /* to be able to pass zero arguments */                \
    ##__VA_ARGS__,                                                       \
                                                                         \
    kParameterCount,                                                     \
    kContext = kParameterCount /* implicit parameter */                  \
479 480
  };

481 482 483 484
#define DEFINE_RESULT_AND_PARAMETERS(return_count, ...)                    \
  DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                  \
      CallInterfaceDescriptorData::kNoFlags, StackArgumentOrder::kDefault, \
      return_count, ##__VA_ARGS__)
485

486 487
// This is valid only for builtins that use EntryFrame, which does not scan
// stack arguments on GC.
488 489 490 491 492 493 494 495 496 497 498 499
#define DEFINE_PARAMETERS_ENTRY(...)                        \
  static constexpr int kDescriptorFlags =                   \
      CallInterfaceDescriptorData::kNoContext |             \
      CallInterfaceDescriptorData::kNoStackScan;            \
  static constexpr StackArgumentOrder kStackArgumentOrder = \
      StackArgumentOrder::kDefault;                         \
  static constexpr int kReturnCount = 1;                    \
  enum ParameterIndices {                                   \
    __dummy = -1, /* to be able to pass zero arguments */   \
    ##__VA_ARGS__,                                          \
                                                            \
    kParameterCount                                         \
500 501
  };

502 503 504 505
#define DEFINE_PARAMETERS(...)                                                \
  DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                     \
      CallInterfaceDescriptorData::kNoFlags, StackArgumentOrder::kDefault, 1, \
      ##__VA_ARGS__)
506

507 508 509 510
#define DEFINE_PARAMETERS_NO_CONTEXT(...)                                    \
  DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                    \
      CallInterfaceDescriptorData::kNoContext, StackArgumentOrder::kDefault, \
      1, ##__VA_ARGS__)
511

512 513 514 515
#define DEFINE_PARAMETERS_VARARGS(...)                                        \
  DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS(                                     \
      CallInterfaceDescriptorData::kAllowVarArgs, StackArgumentOrder::kJS, 1, \
      ##__VA_ARGS__)
516

517 518 519 520 521 522 523 524 525
#define DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(flag, ...)                \
  void InitializePlatformIndependent(CallInterfaceDescriptorData* data)       \
      override {                                                              \
    MachineType machine_types[] = {__VA_ARGS__};                              \
    static_assert(                                                            \
        kReturnCount + kParameterCount == arraysize(machine_types),           \
        "Parameter names definition is not consistent with parameter types"); \
    data->InitializePlatformIndependent(                                      \
        Flags(flag | kDescriptorFlags), kReturnCount, kParameterCount,        \
526
        machine_types, arraysize(machine_types), kStackArgumentOrder);        \
527 528
  }

529 530 531 532
#define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
  DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG( \
      CallInterfaceDescriptorData::kNoFlags, __VA_ARGS__)

533 534 535
#define DEFINE_PARAMETER_TYPES(...)                                        \
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
                                    ##__VA_ARGS__)
536

537
// When the extra arguments described here are located in the stack, they are
538
// just above the return address in the frame (first arguments).
539 540 541 542 543 544 545 546 547 548 549 550 551
#define DEFINE_JS_PARAMETERS(...)                           \
  static constexpr int kDescriptorFlags =                   \
      CallInterfaceDescriptorData::kAllowVarArgs;           \
  static constexpr int kReturnCount = 1;                    \
  static constexpr StackArgumentOrder kStackArgumentOrder = \
      StackArgumentOrder::kJS;                              \
  enum ParameterIndices {                                   \
    kTarget,                                                \
    kNewTarget,                                             \
    kActualArgumentsCount,                                  \
    ##__VA_ARGS__,                                          \
    kParameterCount,                                        \
    kContext = kParameterCount /* implicit parameter */     \
552 553
  };

554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
#define DEFINE_JS_PARAMETERS_NO_CONTEXT(...)                \
  static constexpr int kDescriptorFlags =                   \
      CallInterfaceDescriptorData::kAllowVarArgs |          \
      CallInterfaceDescriptorData::kNoContext;              \
  static constexpr int kReturnCount = 1;                    \
  static constexpr StackArgumentOrder kStackArgumentOrder = \
      StackArgumentOrder::kJS;                              \
  enum ParameterIndices {                                   \
    kTarget,                                                \
    kNewTarget,                                             \
    kActualArgumentsCount,                                  \
    ##__VA_ARGS__,                                          \
    kParameterCount,                                        \
  };

569 570 571 572 573 574 575 576 577 578 579 580 581 582
#define DEFINE_JS_PARAMETER_TYPES(...)                                         \
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */               \
                         MachineType::AnyTagged(), /* kNewTarget */            \
                         MachineType::Int32(),     /* kActualArgumentsCount */ \
                         ##__VA_ARGS__)

#define DECLARE_DESCRIPTOR(name, base)                                         \
  DECLARE_DESCRIPTOR_WITH_BASE(name, base)                                     \
 protected:                                                                    \
  void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
  name(CallDescriptors::Key key) : base(key) {}                                \
                                                                               \
 public:

583
class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
584
 public:
585 586
  DEFINE_PARAMETERS()
  DEFINE_PARAMETER_TYPES()
587 588 589
  DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
};

590
// This class is subclassed by Torque-generated call interface descriptors.
591
template <int return_count, int parameter_count, bool has_context_parameter>
592 593
class TorqueInterfaceDescriptor : public CallInterfaceDescriptor {
 public:
594 595 596
  static constexpr int kDescriptorFlags =
      has_context_parameter ? CallInterfaceDescriptorData::kNoFlags
                            : CallInterfaceDescriptorData::kNoContext;
597 598 599 600 601 602 603
  static constexpr int kParameterCount = parameter_count;
  enum ParameterIndices { kContext = kParameterCount };
  template <int i>
  static ParameterIndices ParameterIndex() {
    STATIC_ASSERT(0 <= i && i < kParameterCount);
    return static_cast<ParameterIndices>(i);
  }
604
  static constexpr int kReturnCount = return_count;
605 606 607 608 609 610 611 612 613

  using CallInterfaceDescriptor::CallInterfaceDescriptor;

 protected:
  static const int kRegisterParams =
      kParameterCount > kMaxTFSBuiltinRegisterParams
          ? kMaxTFSBuiltinRegisterParams
          : kParameterCount;
  static const int kStackParams = kParameterCount - kRegisterParams;
614
  virtual std::vector<MachineType> ReturnType() = 0;
615 616 617 618 619 620
  virtual std::array<MachineType, kParameterCount> ParameterTypes() = 0;
  void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override {
    DefaultInitializePlatformSpecific(data, kRegisterParams);
  }
  void InitializePlatformIndependent(
      CallInterfaceDescriptorData* data) override {
621 622
    std::vector<MachineType> machine_types = ReturnType();
    DCHECK_EQ(kReturnCount, machine_types.size());
623 624 625 626 627 628
    auto parameter_types = ParameterTypes();
    machine_types.insert(machine_types.end(), parameter_types.begin(),
                         parameter_types.end());
    DCHECK_EQ(kReturnCount + kParameterCount, machine_types.size());
    data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount,
                                        kParameterCount, machine_types.data(),
629 630
                                        static_cast<int>(machine_types.size()),
                                        StackArgumentOrder::kDefault);
631 632 633
  }
};

634 635
// Dummy descriptor used to mark builtins that don't yet have their proper
// descriptor associated.
636
using DummyDescriptor = VoidDescriptor;
637

638
// Dummy descriptor that marks builtins with C calling convention.
639
using CCallDescriptor = VoidDescriptor;
640

641 642 643 644 645 646
// Marks deoptimization entry builtins. Precise calling conventions currently
// differ based on the platform.
// TODO(jgruber): Once this is unified, we could create a better description
// here.
using DeoptimizationEntryDescriptor = VoidDescriptor;

647 648
class AllocateDescriptor : public CallInterfaceDescriptor {
 public:
649 650
  DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
651
                                    MachineType::IntPtr())  // kRequestedSize
652
  DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
653 654
};

655 656 657 658 659 660 661
// This descriptor defines the JavaScript calling convention that can be used
// by stubs: target, new.target, argc (not including the receiver) and context
// are passed in registers while receiver and the rest of the JS arguments are
// passed on the stack.
class JSTrampolineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_JS_PARAMETERS()
662
  DEFINE_JS_PARAMETER_TYPES()
663 664 665 666 667

  DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
                                   CallInterfaceDescriptor, 0)
};

668 669
class ContextOnlyDescriptor : public CallInterfaceDescriptor {
 public:
670 671
  DEFINE_PARAMETERS()
  DEFINE_PARAMETER_TYPES()
672 673 674
  DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
};

675 676 677 678 679 680 681
class NoContextDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT()
  DEFINE_PARAMETER_TYPES()
  DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
};

682
// LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
683 684
class LoadDescriptor : public CallInterfaceDescriptor {
 public:
685
  DEFINE_PARAMETERS(kReceiver, kName, kSlot)
686 687 688 689
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
690 691 692

  static const Register ReceiverRegister();
  static const Register NameRegister();
693
  static const Register SlotRegister();
694 695
};

696 697 698 699 700 701 702 703 704 705 706
// LoadBaselineDescriptor is a load descriptor that does not take a context as
// input.
class LoadBaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kName, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(LoadBaselineDescriptor, CallInterfaceDescriptor)
};

707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
class LoadGlobalNoFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kName, kICKind)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kICKind
  DECLARE_DESCRIPTOR(LoadGlobalNoFeedbackDescriptor, CallInterfaceDescriptor)

  static const Register NameRegister() {
    return LoadDescriptor::NameRegister();
  }

  static const Register ICKindRegister() {
    return LoadDescriptor::SlotRegister();
  }
};

class LoadNoFeedbackDescriptor : public LoadGlobalNoFeedbackDescriptor {
 public:
  DEFINE_PARAMETERS(kReceiver, kName, kICKind)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kICKind
  DECLARE_DESCRIPTOR(LoadNoFeedbackDescriptor, LoadGlobalNoFeedbackDescriptor)

  static const Register ReceiverRegister() {
    return LoadDescriptor::ReceiverRegister();
  }

  static const Register NameRegister() {
    return LoadGlobalNoFeedbackDescriptor::NameRegister();
  }

  static const Register ICKindRegister() {
    return LoadGlobalNoFeedbackDescriptor::ICKindRegister();
  }
};

744 745
class LoadGlobalDescriptor : public CallInterfaceDescriptor {
 public:
746
  DEFINE_PARAMETERS(kName, kSlot)
747 748 749
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
750

751 752 753 754
  static const Register NameRegister() {
    return LoadDescriptor::NameRegister();
  }

755 756 757
  static const Register SlotRegister() {
    return LoadDescriptor::SlotRegister();
  }
758
};
759

760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776
class LoadGlobalBaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kName, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(LoadGlobalBaselineDescriptor, CallInterfaceDescriptor)
};

class LookupBaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kName, kDepth, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kName
                         MachineType::AnyTagged(),  // kDepth
                         MachineType::AnyTagged())  // kSlot
  DECLARE_DESCRIPTOR(LookupBaselineDescriptor, CallInterfaceDescriptor)
};

777
class StoreDescriptor : public CallInterfaceDescriptor {
778
 public:
779
  DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
780 781 782 783 784
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
785

786 787 788
  static const Register ReceiverRegister();
  static const Register NameRegister();
  static const Register ValueRegister();
789
  static const Register SlotRegister();
790

Jakob Kummerow's avatar
Jakob Kummerow committed
791
#if V8_TARGET_ARCH_IA32
792 793 794 795 796 797 798
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass value and slot through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
799
};
800

801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
class StoreBaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kName, kValue, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(StoreBaselineDescriptor, CallInterfaceDescriptor)

#if V8_TARGET_ARCH_IA32
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass value and slot through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
};

820
class StoreTransitionDescriptor : public StoreDescriptor {
821
 public:
822
  DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
823 824 825 826 827 828 829
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kMap
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned(),  // kSlot
                         MachineType::AnyTagged())     // kVector
  DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
830

831
  static const Register MapRegister();
832 833
  static const Register SlotRegister();
  static const Register VectorRegister();
834

835 836
  // Pass value, slot and vector through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
837 838
};

839
class StoreWithVectorDescriptor : public StoreDescriptor {
840
 public:
841
  DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
842 843 844 845 846 847
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kReceiver
                         MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned(),  // kSlot
                         MachineType::AnyTagged())     // kVector
  DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
848 849

  static const Register VectorRegister();
850 851 852

  // Pass value, slot and vector through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
853 854
};

855 856 857
class StoreGlobalDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kName, kValue, kSlot)
858 859 860 861
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880

  static const bool kPassLastArgsOnStack =
      StoreDescriptor::kPassLastArgsOnStack;
  // Pass value and slot through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;

  static const Register NameRegister() {
    return StoreDescriptor::NameRegister();
  }

  static const Register ValueRegister() {
    return StoreDescriptor::ValueRegister();
  }

  static const Register SlotRegister() {
    return StoreDescriptor::SlotRegister();
  }
};

881 882 883 884 885 886 887 888 889 890 891 892 893 894
class StoreGlobalBaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kName, kValue, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(StoreGlobalBaselineDescriptor, CallInterfaceDescriptor)

  static const bool kPassLastArgsOnStack =
      StoreDescriptor::kPassLastArgsOnStack;
  // Pass value and slot through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
};

895 896 897
class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
 public:
  DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
898 899 900 901 902
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::AnyTagged(),     // kValue
                         MachineType::TaggedSigned(),  // kSlot
                         MachineType::AnyTagged())     // kVector
  DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
903 904 905 906 907 908 909 910 911

  static const Register VectorRegister() {
    return StoreWithVectorDescriptor::VectorRegister();
  }

  // Pass value, slot and vector through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
};

912
class LoadWithVectorDescriptor : public LoadDescriptor {
913
 public:
914 915
  // TODO(v8:9497): Revert the Machine type for kSlot to the
  // TaggedSigned once Torque can emit better call descriptors
916
  DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
917 918 919 920
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
                         MachineType::AnyTagged(),  // kName
                         MachineType::AnyTagged(),  // kSlot
                         MachineType::AnyTagged())  // kVector
921
  DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
922 923

  static const Register VectorRegister();
924 925 926 927 928 929 930 931 932

#if V8_TARGET_ARCH_IA32
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass vector through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
933 934
};

935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962
// Like LoadWithVectorDescriptor, except we pass the receiver (the object which
// should be used as the receiver for accessor function calls) and the lookup
// start object separately.
class LoadWithReceiverAndVectorDescriptor : public LoadWithVectorDescriptor {
 public:
  // TODO(v8:9497): Revert the Machine type for kSlot to the
  // TaggedSigned once Torque can emit better call descriptors
  DEFINE_PARAMETERS(kReceiver, kLookupStartObject, kName, kSlot, kVector)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
                         MachineType::AnyTagged(),  // kLookupStartObject
                         MachineType::AnyTagged(),  // kName
                         MachineType::AnyTagged(),  // kSlot
                         MachineType::AnyTagged())  // kVector
  DECLARE_DESCRIPTOR(LoadWithReceiverAndVectorDescriptor,
                     LoadWithVectorDescriptor)

  static const Register LookupStartObjectRegister();

#if V8_TARGET_ARCH_IA32
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass vector through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
};

963 964 965 966 967 968 969 970 971 972 973 974
class LoadWithReceiverBaselineDescriptor : public LoadBaselineDescriptor {
 public:
  // TODO(v8:9497): Revert the Machine type for kSlot to the
  // TaggedSigned once Torque can emit better call descriptors
  DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kLookupStartObject, kName, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
                         MachineType::AnyTagged(),  // kLookupStartObject
                         MachineType::AnyTagged(),  // kName
                         MachineType::AnyTagged())  // kSlot
  DECLARE_DESCRIPTOR(LoadWithReceiverBaselineDescriptor, LoadBaselineDescriptor)
};

975 976
class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
 public:
977
  DEFINE_PARAMETERS(kName, kSlot, kVector)
978 979 980 981
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kName
                         MachineType::TaggedSigned(),  // kSlot
                         MachineType::AnyTagged())     // kVector
  DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
982

983 984 985 986 987
#if V8_TARGET_ARCH_IA32
  // On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
  // need to choose a new register here.
  static const Register VectorRegister() { return edx; }
#else
988 989 990
  static const Register VectorRegister() {
    return LoadWithVectorDescriptor::VectorRegister();
  }
991
#endif
992
};
993

994
class DynamicCheckMapsDescriptor final : public CallInterfaceDescriptor {
995
 public:
996
  DEFINE_PARAMETERS(kMap, kSlot, kHandler)
997
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(),          // return val
998
                                    MachineType::TaggedPointer(),  // kMap
999
                                    MachineType::IntPtr(),         // kSlot
1000 1001
                                    MachineType::TaggedSigned())   // kHandler

1002
  DECLARE_DESCRIPTOR(DynamicCheckMapsDescriptor, CallInterfaceDescriptor)
1003 1004
};

1005 1006
class FastNewObjectDescriptor : public CallInterfaceDescriptor {
 public:
1007
  DEFINE_PARAMETERS(kTarget, kNewTarget)
1008 1009
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::AnyTagged())  // kNewTarget
1010
  DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
1011 1012
  static const Register TargetRegister();
  static const Register NewTargetRegister();
1013 1014
};

1015 1016
class RecordWriteDescriptor final : public CallInterfaceDescriptor {
 public:
1017
  DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
1018 1019 1020 1021 1022 1023
  DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
                         MachineType::Pointer(),        // kSlot
                         MachineType::TaggedSigned(),   // kRememberedSet
                         MachineType::TaggedSigned())   // kFPMode

  DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
1024 1025
};

1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
class EphemeronKeyBarrierDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress, kFPMode)
  DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(),  // kObject
                         MachineType::Pointer(),        // kSlotAddress
                         MachineType::TaggedSigned())   // kFPMode

  DECLARE_DESCRIPTOR(EphemeronKeyBarrierDescriptor, CallInterfaceDescriptor)
};

1036
class TypeConversionDescriptor final : public CallInterfaceDescriptor {
1037
 public:
1038
  DEFINE_PARAMETERS(kArgument)
1039
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1040
  DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
1041

1042
  static const Register ArgumentRegister();
1043 1044
};

1045 1046 1047 1048 1049 1050 1051
class TypeConversionNoContextDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
  DECLARE_DESCRIPTOR(TypeConversionNoContextDescriptor, CallInterfaceDescriptor)
};

1052 1053 1054 1055 1056 1057 1058
class TypeConversion_BaselineDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kArgument, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::UintPtr())
  DECLARE_DESCRIPTOR(TypeConversion_BaselineDescriptor, CallInterfaceDescriptor)
};

1059
class SingleParameterOnStackDescriptor final : public CallInterfaceDescriptor {
1060 1061
 public:
  DEFINE_PARAMETERS(kArgument)
1062
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1063
  DECLARE_DESCRIPTOR(SingleParameterOnStackDescriptor, CallInterfaceDescriptor)
1064 1065
};

1066 1067 1068 1069 1070 1071 1072 1073 1074
class AsyncFunctionStackParameterDescriptor final
    : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kPromise, kResult)
  DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
  DECLARE_DESCRIPTOR(AsyncFunctionStackParameterDescriptor,
                     CallInterfaceDescriptor)
};

1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
class GetIteratorStackParameterDescriptor final
    : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kReceiver, kCallSlot, kFeedback, kResult)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::AnyTagged(),
                         MachineType::AnyTagged(), MachineType::AnyTagged())
  DECLARE_DESCRIPTOR(GetIteratorStackParameterDescriptor,
                     CallInterfaceDescriptor)
};

1085 1086
class GetPropertyDescriptor final : public CallInterfaceDescriptor {
 public:
1087
  DEFINE_PARAMETERS(kObject, kKey)
1088
  DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
1089 1090
};

1091 1092
class TypeofDescriptor : public CallInterfaceDescriptor {
 public:
1093
  DEFINE_PARAMETERS(kObject)
1094
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1095 1096 1097
  DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
};

1098 1099
class CallTrampolineDescriptor : public CallInterfaceDescriptor {
 public:
1100
  DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount)
1101 1102 1103
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
                         MachineType::Int32())      // kActualArgumentsCount
  DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
1104 1105
};

1106 1107
class CallVarargsDescriptor : public CallInterfaceDescriptor {
 public:
1108 1109
  DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kArgumentsLength,
                            kArgumentsList)
1110 1111
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::Int32(),      // kActualArgumentsCount
1112 1113
                         MachineType::Int32(),      // kArgumentsLength
                         MachineType::AnyTagged())  // kArgumentsList
1114
  DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
1115 1116
};

1117 1118
class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
 public:
1119
  DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kStartIndex)
1120 1121 1122 1123
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::Int32(),      // kActualArgumentsCount
                         MachineType::Int32())      // kStartIndex
  DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
1124
};
1125

1126 1127
class CallFunctionTemplateDescriptor : public CallInterfaceDescriptor {
 public:
1128
  DEFINE_PARAMETERS_VARARGS(kFunctionTemplateInfo, kArgumentsCount)
1129 1130 1131 1132 1133
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunctionTemplateInfo
                         MachineType::IntPtr())     // kArgumentsCount
  DECLARE_DESCRIPTOR(CallFunctionTemplateDescriptor, CallInterfaceDescriptor)
};

1134 1135
class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
 public:
1136
  DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread)
1137 1138 1139 1140
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::Int32(),      // kArgumentsCount
                         MachineType::AnyTagged())  // kSpread
  DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
1141 1142
};

1143 1144 1145 1146 1147 1148
class CallWithSpread_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::Int32(),      // kArgumentsCount
                         MachineType::AnyTagged(),  // kSpread
1149
                         MachineType::UintPtr())    // kSlot
1150 1151 1152
  DECLARE_DESCRIPTOR(CallWithSpread_BaselineDescriptor, CallInterfaceDescriptor)
};

1153 1154
class CallWithSpread_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
1155
  DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread, kSlot,
1156
                            kFeedbackVector)
1157 1158 1159
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::Int32(),      // kArgumentsCount
                         MachineType::AnyTagged(),  // kSpread
1160
                         MachineType::UintPtr(),    // kSlot
1161
                         MachineType::AnyTagged())  // kFeedbackVector
1162 1163 1164 1165
  DECLARE_DESCRIPTOR(CallWithSpread_WithFeedbackDescriptor,
                     CallInterfaceDescriptor)
};

1166 1167 1168
class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kTarget, kArgumentsList)
1169 1170 1171
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::AnyTagged())  // kArgumentsList
  DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
1172 1173
};

1174 1175 1176
class CallWithArrayLike_WithFeedbackDescriptor
    : public CallInterfaceDescriptor {
 public:
1177
  DEFINE_PARAMETERS(kTarget, kArgumentsList, kSlot, kFeedbackVector)
1178 1179
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::AnyTagged(),  // kArgumentsList
1180
                         MachineType::UintPtr(),    // kSlot
1181
                         MachineType::AnyTagged())  // kFeedbackVector
1182 1183 1184 1185
  DECLARE_DESCRIPTOR(CallWithArrayLike_WithFeedbackDescriptor,
                     CallInterfaceDescriptor)
};

1186 1187
class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
 public:
1188 1189 1190 1191
  DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
  DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(),      // kArgumentsLength
                            MachineType::AnyTagged())  // kArgumentsList

1192
  DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
1193 1194
};

1195 1196
class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
 public:
1197 1198 1199
  DEFINE_JS_PARAMETERS(kStartIndex)
  DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
  DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
1200 1201
};

1202 1203
class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
 public:
1204 1205 1206
  DEFINE_JS_PARAMETERS(kSpread)
  DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
  DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
1207 1208
};

1209 1210 1211 1212 1213
class ConstructWithSpread_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  // Note: kSlot comes before kSpread since as an untagged value it must be
  // passed in a register.
  DEFINE_JS_PARAMETERS(kSlot, kSpread)
1214
  DEFINE_JS_PARAMETER_TYPES(MachineType::UintPtr(),    // kSlot
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
                            MachineType::AnyTagged())  // kSpread
  DECLARE_DESCRIPTOR(ConstructWithSpread_BaselineDescriptor,
                     CallInterfaceDescriptor)

#if V8_TARGET_ARCH_IA32
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass spread through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
};

1229 1230 1231 1232 1233
class ConstructWithSpread_WithFeedbackDescriptor
    : public CallInterfaceDescriptor {
 public:
  // Note: kSlot comes before kSpread since as an untagged value it must be
  // passed in a register.
1234
  DEFINE_JS_PARAMETERS(kSlot, kSpread, kFeedbackVector)
1235
  DEFINE_JS_PARAMETER_TYPES(MachineType::UintPtr(),    // kSlot
1236
                            MachineType::AnyTagged(),  // kSpread
1237
                            MachineType::AnyTagged())  // kFeedbackVector
1238 1239 1240 1241
  DECLARE_DESCRIPTOR(ConstructWithSpread_WithFeedbackDescriptor,
                     CallInterfaceDescriptor)
};

1242 1243 1244
class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
1245 1246 1247 1248
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::AnyTagged(),  // kNewTarget
                         MachineType::AnyTagged())  // kArgumentsList
  DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
1249 1250
};

1251 1252 1253
class ConstructWithArrayLike_WithFeedbackDescriptor
    : public CallInterfaceDescriptor {
 public:
1254
  DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList, kSlot, kFeedbackVector)
1255 1256 1257
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kTarget
                         MachineType::AnyTagged(),  // kNewTarget
                         MachineType::AnyTagged(),  // kArgumentsList
1258
                         MachineType::UintPtr(),    // kSlot
1259
                         MachineType::AnyTagged())  // kFeedbackVector
1260 1261 1262 1263
  DECLARE_DESCRIPTOR(ConstructWithArrayLike_WithFeedbackDescriptor,
                     CallInterfaceDescriptor)
};

1264
// TODO(ishell): consider merging this with ArrayConstructorDescriptor
1265 1266
class ConstructStubDescriptor : public CallInterfaceDescriptor {
 public:
1267
  // TODO(jgruber): Remove the unused allocation site parameter.
1268
  DEFINE_JS_PARAMETERS(kAllocationSite)
1269
  DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1270 1271 1272

  // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
  DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
1273 1274
};

1275
class AbortDescriptor : public CallInterfaceDescriptor {
1276
 public:
1277
  DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
1278
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1279
  DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
1280
};
1281

1282 1283
class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
 public:
1284
  DEFINE_JS_PARAMETERS(kAllocationSite)
1285
  DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1286 1287 1288

  DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
                                   CallInterfaceDescriptor, 1)
1289 1290
};

1291
class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
1292
 public:
1293 1294 1295 1296 1297
  // This descriptor declares only register arguments while respective number
  // of JS arguments stay on the expression stack.
  // The ArrayNArgumentsConstructor builtin does not access stack arguments
  // directly it just forwards them to the runtime function.
  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
1298 1299 1300 1301 1302
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction,
                         MachineType::AnyTagged(),  // kAllocationSite
                         MachineType::Int32())      // kActualArgumentsCount
  DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
                     CallInterfaceDescriptor)
1303
};
1304

1305 1306
class ArrayNoArgumentConstructorDescriptor
    : public ArrayNArgumentsConstructorDescriptor {
1307
 public:
1308 1309 1310
  // This descriptor declares same register arguments as the parent
  // ArrayNArgumentsConstructorDescriptor and it declares indices for
  // JS arguments passed on the expression stack.
1311
  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1312
                    kFunctionParameter)
1313 1314 1315 1316 1317 1318
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
                         MachineType::AnyTagged(),  // kAllocationSite
                         MachineType::Int32(),      // kActualArgumentsCount
                         MachineType::AnyTagged())  // kFunctionParameter
  DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
                     ArrayNArgumentsConstructorDescriptor)
1319 1320
};

1321 1322
class ArraySingleArgumentConstructorDescriptor
    : public ArrayNArgumentsConstructorDescriptor {
1323
 public:
1324 1325 1326 1327
  // This descriptor declares same register arguments as the parent
  // ArrayNArgumentsConstructorDescriptor and it declares indices for
  // JS arguments passed on the expression stack.
  DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1328
                    kArraySizeSmiParameter, kReceiverParameter)
1329 1330 1331
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
                         MachineType::AnyTagged(),  // kAllocationSite
                         MachineType::Int32(),      // kActualArgumentsCount
1332 1333 1334 1335 1336 1337
                         // JS arguments on the stack
                         MachineType::AnyTagged(),  // kArraySizeSmiParameter
                         MachineType::AnyTagged())  // kReceiverParameter
  DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
                     ArrayNArgumentsConstructorDescriptor)
};
1338

1339 1340
class CompareDescriptor : public CallInterfaceDescriptor {
 public:
1341
  DEFINE_PARAMETERS(kLeft, kRight)
1342 1343 1344
  DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
};

1345 1346
class BinaryOpDescriptor : public CallInterfaceDescriptor {
 public:
1347
  DEFINE_PARAMETERS(kLeft, kRight)
1348
  DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
1349 1350
};

1351 1352 1353 1354 1355 1356 1357 1358 1359
class BinaryOp_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
                         MachineType::AnyTagged(),  // kRight
                         MachineType::UintPtr())    // kSlot
  DECLARE_DESCRIPTOR(BinaryOp_BaselineDescriptor, CallInterfaceDescriptor)
};

1360 1361 1362
// This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
// as they all have the same interface.
class StringAtDescriptor final : public CallInterfaceDescriptor {
1363 1364
 public:
  DEFINE_PARAMETERS(kReceiver, kPosition)
1365
  // TODO(turbofan): Return untagged value here.
1366
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(),  // result 1
1367 1368
                                    MachineType::AnyTagged(),     // kReceiver
                                    MachineType::IntPtr())        // kPosition
1369
  DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
1370
};
1371

1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
class StringAtAsStringDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kReceiver, kPosition)
  // TODO(turbofan): Return untagged value here.
  DEFINE_RESULT_AND_PARAMETER_TYPES(
      MachineType::TaggedPointer(),  // result string
      MachineType::AnyTagged(),      // kReceiver
      MachineType::IntPtr())         // kPosition
  DECLARE_DESCRIPTOR(StringAtAsStringDescriptor, CallInterfaceDescriptor)
};

1383 1384 1385
class StringSubstringDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kString, kFrom, kTo)
1386 1387 1388 1389 1390 1391
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kString
                         MachineType::IntPtr(),     // kFrom
                         MachineType::IntPtr())     // kTo

  // TODO(turbofan): Allow builtins to return untagged values.
  DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
1392 1393
};

1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_JS_PARAMETERS(kCFunction)
  DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
  DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
                                   CallInterfaceDescriptor, 1)
};

class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kArity,          // register argument
                    kCFunction,      // register argument
                    kPadding,        // stack argument 1 (just padding)
                    kArgcSmi,        // stack argument 2
                    kTargetCopy,     // stack argument 3
                    kNewTargetCopy)  // stack argument 4
  DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kArity
                         MachineType::Pointer(),    // kCFunction
                         MachineType::AnyTagged(),  // kPadding
                         MachineType::AnyTagged(),  // kArgcSmi
                         MachineType::AnyTagged(),  // kTargetCopy
                         MachineType::AnyTagged())  // kNewTargetCopy
  DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
};

1419
class ApiCallbackDescriptor : public CallInterfaceDescriptor {
vogelheim's avatar
vogelheim committed
1420
 public:
1421 1422
  DEFINE_PARAMETERS_VARARGS(kApiFunctionAddress, kActualArgumentsCount,
                            kCallData, kHolder)
1423 1424 1425 1426
  //                           receiver is implicit stack argument 1
  //                           argv are implicit stack arguments [2, 2 + kArgc[
  DEFINE_PARAMETER_TYPES(MachineType::Pointer(),    // kApiFunctionAddress
                         MachineType::IntPtr(),     // kActualArgumentsCount
1427
                         MachineType::AnyTagged(),  // kCallData
1428
                         MachineType::AnyTagged())  // kHolder
1429
  DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
1430 1431
};

1432 1433
class ApiGetterDescriptor : public CallInterfaceDescriptor {
 public:
1434
  DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
1435 1436 1437
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kReceiver
                         MachineType::AnyTagged(),  // kHolder
                         MachineType::AnyTagged())  // kCallback
1438
  DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
1439

1440 1441 1442
  static const Register ReceiverRegister();
  static const Register HolderRegister();
  static const Register CallbackRegister();
1443 1444
};

1445
// TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
1446 1447
class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
 public:
1448
  DEFINE_PARAMETERS(kObject, kKey)
1449 1450
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kObject
                         MachineType::AnyTagged())  // kKey
1451 1452 1453 1454 1455 1456
  DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)

  static const Register ObjectRegister();
  static const Register KeyRegister();
};

1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
class V8_EXPORT_PRIVATE TailCallOptimizedCodeSlotDescriptor
    : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kOptimizedCodeEntry)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())  // kAccumulator
  DECLARE_DESCRIPTOR(TailCallOptimizedCodeSlotDescriptor,
                     CallInterfaceDescriptor)
};

class BaselineOutOfLinePrologueDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kCalleeContext, kClosure,
                               kJavaScriptCallArgCount,
1470 1471
                               kInterpreterBytecodeArray,
                               kJavaScriptCallNewTarget)
1472 1473 1474
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kCalleeContext
                         MachineType::AnyTagged(),  // kClosure
                         MachineType::Int32(),      // kJavaScriptCallArgCount
1475 1476
                         MachineType::AnyTagged(),  // kInterpreterBytecodeArray
                         MachineType::AnyTagged())  // kJavaScriptCallNewTarget
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
  DECLARE_DESCRIPTOR(BaselineOutOfLinePrologueDescriptor,
                     CallInterfaceDescriptor)
};

class BaselineLeaveFrameDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kParamsSize, kWeight)
  DEFINE_PARAMETER_TYPES(MachineType::Int32(),  // kParamsSize
                         MachineType::Int32())  // kWeight
  DECLARE_DESCRIPTOR(BaselineLeaveFrameDescriptor, CallInterfaceDescriptor)

  static const Register ParamsSizeRegister();
  static const Register WeightRegister();
};

1492 1493
class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
    : public CallInterfaceDescriptor {
1494
 public:
1495 1496
  DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
                    kDispatchTable)
1497 1498 1499 1500 1501
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kAccumulator
                         MachineType::IntPtr(),     // kBytecodeOffset
                         MachineType::AnyTagged(),  // kBytecodeArray
                         MachineType::IntPtr())     // kDispatchTable
  DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
1502
};
1503

1504
class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
1505
 public:
1506
  DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
1507 1508 1509 1510 1511
  DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
                         MachineType::Pointer(),    // kFirstArgument
                         MachineType::AnyTagged())  // kFunction
  DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
                     CallInterfaceDescriptor)
1512 1513
};

1514
class InterpreterPushArgsThenConstructDescriptor
1515 1516
    : public CallInterfaceDescriptor {
 public:
1517 1518
  DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
                    kNewTarget, kFeedbackElement)
1519
  DEFINE_PARAMETER_TYPES(MachineType::Int32(),      // kNumberOfArguments
1520
                         MachineType::Pointer(),    // kFirstArgument
1521
                         MachineType::AnyTagged(),  // kConstructor
1522 1523
                         MachineType::AnyTagged(),  // kNewTarget
                         MachineType::AnyTagged())  // kFeedbackElement
1524 1525
  DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
                     CallInterfaceDescriptor)
1526 1527 1528 1529 1530 1531 1532 1533 1534

#if V8_TARGET_ARCH_IA32
  static const bool kPassLastArgsOnStack = true;
#else
  static const bool kPassLastArgsOnStack = false;
#endif

  // Pass constructor, new target and feedback element through the stack.
  static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
1535 1536
};

1537 1538 1539 1540
class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
                               kFunctionEntry)
1541
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
1542 1543 1544 1545 1546 1547 1548
                                    MachineType::Int32(),  // kNumberOfArguments
                                    MachineType::Pointer(),  // kFirstArgument
                                    MachineType::Pointer())  // kFunctionEntry
  DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
};

class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
1549
 public:
1550 1551
  DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
                               kFunctionEntry)
1552 1553
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result 1
                                    MachineType::AnyTagged(),  // result 2
1554 1555 1556 1557
                                    MachineType::Int32(),  // kNumberOfArguments
                                    MachineType::Pointer(),  // kFirstArgument
                                    MachineType::Pointer())  // kFunctionEntry
  DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
1558 1559
};

1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
class ForInPrepareDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_RESULT_AND_PARAMETERS(2, kEnumerator, kVectorIndex, kFeedbackVector)
  DEFINE_RESULT_AND_PARAMETER_TYPES(
      MachineType::AnyTagged(),     // result 1 (cache array)
      MachineType::AnyTagged(),     // result 2 (cache length)
      MachineType::AnyTagged(),     // kEnumerator
      MachineType::TaggedSigned(),  // kVectorIndex
      MachineType::AnyTagged())     // kFeedbackVector
  DECLARE_DESCRIPTOR(ForInPrepareDescriptor, CallInterfaceDescriptor)
};

1572 1573
class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
 public:
1574 1575 1576
  DEFINE_PARAMETERS(kValue, kGenerator)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
                         MachineType::AnyTagged())  // kGenerator
1577
  DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
1578 1579 1580
};

class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
1581 1582 1583 1584
 public:
  DEFINE_PARAMETERS(kRestartFp)
  DEFINE_PARAMETER_TYPES(MachineType::Pointer())
  DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
1585 1586
};

1587 1588 1589 1590 1591 1592 1593 1594
class RunMicrotasksEntryDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
  DEFINE_PARAMETER_TYPES(MachineType::Pointer(),  // kRootRegisterValue
                         MachineType::Pointer())  // kMicrotaskQueue
  DECLARE_DESCRIPTOR(RunMicrotasksEntryDescriptor, CallInterfaceDescriptor)
};

1595 1596
class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
 public:
1597 1598 1599 1600 1601
  DEFINE_PARAMETERS(kMicrotaskQueue)
  DEFINE_PARAMETER_TYPES(MachineType::Pointer())
  DECLARE_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)

  static Register MicrotaskQueueRegister();
1602 1603
};

1604 1605 1606 1607 1608 1609 1610 1611
class WasmFloat32ToNumberDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kValue)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result
                                    MachineType::Float32())    // value
  DECLARE_DESCRIPTOR(WasmFloat32ToNumberDescriptor, CallInterfaceDescriptor)
};

1612 1613 1614 1615 1616 1617 1618 1619
class WasmFloat64ToNumberDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kValue)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(),  // result
                                    MachineType::Float64())    // value
  DECLARE_DESCRIPTOR(WasmFloat64ToNumberDescriptor, CallInterfaceDescriptor)
};

1620 1621
class V8_EXPORT_PRIVATE I64ToBigIntDescriptor final
    : public CallInterfaceDescriptor {
1622 1623 1624
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
  DEFINE_PARAMETER_TYPES(MachineType::Int64())  // kArgument
1625
  DECLARE_DESCRIPTOR(I64ToBigIntDescriptor, CallInterfaceDescriptor)
1626 1627
};

1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639
// 32 bits version of the I64ToBigIntDescriptor call interface descriptor
class V8_EXPORT_PRIVATE I32PairToBigIntDescriptor final
    : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kLow, kHigh)
  DEFINE_PARAMETER_TYPES(MachineType::Uint32(),  // kLow
                         MachineType::Uint32())  // kHigh
  DECLARE_DESCRIPTOR(I32PairToBigIntDescriptor, CallInterfaceDescriptor)
};

class V8_EXPORT_PRIVATE BigIntToI64Descriptor final
    : public CallInterfaceDescriptor {
1640 1641 1642 1643 1644 1645 1646
 public:
  DEFINE_PARAMETERS(kArgument)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(),      // result 1
                                    MachineType::AnyTagged())  // kArgument
  DECLARE_DESCRIPTOR(BigIntToI64Descriptor, CallInterfaceDescriptor)
};

1647 1648 1649 1650 1651 1652 1653 1654 1655 1656
class V8_EXPORT_PRIVATE BigIntToI32PairDescriptor final
    : public CallInterfaceDescriptor {
 public:
  DEFINE_RESULT_AND_PARAMETERS(2, kArgument)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),     // result 1
                                    MachineType::Uint32(),     // result 2
                                    MachineType::AnyTagged())  // kArgument
  DECLARE_DESCRIPTOR(BigIntToI32PairDescriptor, CallInterfaceDescriptor)
};

1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
class WasmI32AtomicWait32Descriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeoutLow,
                               kTimeoutHigh)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(),  // result 1
                                    MachineType::Uint32(),  // kAddress
                                    MachineType::Int32(),   // kExpectedValue
                                    MachineType::Uint32(),  // kTimeoutLow
                                    MachineType::Uint32())  // kTimeoutHigh
  DECLARE_DESCRIPTOR(WasmI32AtomicWait32Descriptor, CallInterfaceDescriptor)
};

class WasmI64AtomicWait32Descriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValueLow, kExpectedValueHigh,
                               kTimeoutLow, kTimeoutHigh)

  DEFINE_RESULT_AND_PARAMETER_TYPES_WITH_FLAG(
      CallInterfaceDescriptorData::kNoStackScan,  // allow untagged stack params
      MachineType::Uint32(),                      // result 1
      MachineType::Uint32(),                      // kAddress
      MachineType::Uint32(),                      // kExpectedValueLow
      MachineType::Uint32(),                      // kExpectedValueHigh
      MachineType::Uint32(),                      // kTimeoutLow
      MachineType::Uint32())                      // kTimeoutHigh

#if V8_TARGET_ARCH_IA32
  static constexpr bool kPassLastArgOnStack = true;
#else
  static constexpr bool kPassLastArgOnStack = false;
#endif

  // Pass the last parameter through the stack.
  static constexpr int kStackArgumentsCount = kPassLastArgOnStack ? 1 : 0;

  DECLARE_DESCRIPTOR(WasmI64AtomicWait32Descriptor, CallInterfaceDescriptor)
};

1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
  DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),  // result 1
                                    MachineType::AnyTagged(),      // kSource
                                    MachineType::TaggedSigned(),   // kFlags
                                    MachineType::TaggedSigned(),   // kSlot
                                    MachineType::AnyTagged())      // kVector
  DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
};

1706 1707 1708 1709 1710 1711 1712 1713 1714
class CloneObjectBaselineDescriptor final : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kSource, kFlags, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),     // kSource
                         MachineType::TaggedSigned(),  // kFlags
                         MachineType::TaggedSigned())  // kSlot
  DECLARE_DESCRIPTOR(CloneObjectBaselineDescriptor, CallInterfaceDescriptor)
};

1715 1716
class BinaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
1717
  DEFINE_PARAMETERS(kLeft, kRight, kSlot, kFeedbackVector)
1718 1719
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
                         MachineType::AnyTagged(),  // kRight
1720
                         MachineType::UintPtr(),    // kSlot
1721
                         MachineType::AnyTagged())  // kFeedbackVector
1722 1723 1724
  DECLARE_DESCRIPTOR(BinaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
};

1725 1726 1727 1728 1729
class CallTrampoline_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
                         MachineType::Int32(),      // kActualArgumentsCount
1730
                         MachineType::UintPtr())    // kSlot
1731 1732 1733
  DECLARE_DESCRIPTOR(CallTrampoline_BaselineDescriptor, CallInterfaceDescriptor)
};

1734 1735 1736
class CallTrampoline_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount, kSlot,
1737
                            kFeedbackVector)
1738 1739
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kFunction
                         MachineType::Int32(),      // kActualArgumentsCount
1740
                         MachineType::UintPtr(),    // kSlot
1741
                         MachineType::AnyTagged())  // kFeedbackVector
1742 1743 1744 1745 1746 1747
  DECLARE_DESCRIPTOR(CallTrampoline_WithFeedbackDescriptor,
                     CallInterfaceDescriptor)
};

class Compare_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
1748
  DEFINE_PARAMETERS(kLeft, kRight, kSlot, kFeedbackVector)
1749 1750
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
                         MachineType::AnyTagged(),  // kRight
1751
                         MachineType::UintPtr(),    // kSlot
1752
                         MachineType::AnyTagged())  // kFeedbackVector
1753 1754 1755
  DECLARE_DESCRIPTOR(Compare_WithFeedbackDescriptor, CallInterfaceDescriptor)
};

1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
class Compare_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kLeft
                         MachineType::AnyTagged(),  // kRight
                         MachineType::UintPtr())    // kSlot
  DECLARE_DESCRIPTOR(Compare_BaselineDescriptor, CallInterfaceDescriptor)
};

class Construct_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_JS_PARAMETERS_NO_CONTEXT(kSlot)
1768
  DEFINE_JS_PARAMETER_TYPES(MachineType::UintPtr())  // kSlot
1769 1770 1771 1772
  DECLARE_JS_COMPATIBLE_DESCRIPTOR(Construct_BaselineDescriptor,
                                   CallInterfaceDescriptor, 1)
};

1773 1774
class Construct_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
1775 1776
  // kSlot is passed in a register, kFeedbackVector on the stack.
  DEFINE_JS_PARAMETERS(kSlot, kFeedbackVector)
1777
  DEFINE_JS_PARAMETER_TYPES(MachineType::UintPtr(),    // kSlot
1778
                            MachineType::AnyTagged())  // kFeedbackVector
1779 1780 1781 1782 1783 1784
  DECLARE_JS_COMPATIBLE_DESCRIPTOR(Construct_WithFeedbackDescriptor,
                                   CallInterfaceDescriptor, 1)
};

class UnaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
 public:
1785
  DEFINE_PARAMETERS(kValue, kSlot, kFeedbackVector)
1786
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
1787
                         MachineType::UintPtr(),    // kSlot
1788
                         MachineType::AnyTagged())  // kFeedbackVector
1789 1790 1791
  DECLARE_DESCRIPTOR(UnaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
};

1792 1793 1794 1795 1796 1797 1798 1799
class UnaryOp_BaselineDescriptor : public CallInterfaceDescriptor {
 public:
  DEFINE_PARAMETERS(kValue, kSlot)
  DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(),  // kValue
                         MachineType::UintPtr())    // kSlot
  DECLARE_DESCRIPTOR(UnaryOp_BaselineDescriptor, CallInterfaceDescriptor)
};

1800 1801 1802 1803
#define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...)                          \
  class Name##Descriptor : public CallInterfaceDescriptor {               \
   public:                                                                \
    DEFINE_PARAMETERS(__VA_ARGS__)                                        \
1804
    DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
1805 1806 1807 1808
  };
BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
#undef DEFINE_TFS_BUILTIN_DESCRIPTOR

1809 1810 1811
// This file contains interface descriptor class definitions for builtins
// defined in Torque. It is included here because the class definitions need to
// precede the definition of name##Descriptor::key() below.
1812
#include "torque-generated/interface-descriptors.inc"
1813

1814
#undef DECLARE_DEFAULT_DESCRIPTOR
vogelheim's avatar
vogelheim committed
1815
#undef DECLARE_DESCRIPTOR_WITH_BASE
1816
#undef DECLARE_DESCRIPTOR
1817
#undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
1818
#undef DEFINE_FLAGS_AND_RESULT_AND_PARAMETERS
1819
#undef DEFINE_RESULT_AND_PARAMETERS
1820
#undef DEFINE_PARAMETERS
1821
#undef DEFINE_PARAMETERS_VARARGS
1822
#undef DEFINE_PARAMETERS_NO_CONTEXT
1823
#undef DEFINE_RESULT_AND_PARAMETER_TYPES
1824 1825
#undef DEFINE_PARAMETER_TYPES
#undef DEFINE_JS_PARAMETERS
1826
#undef DEFINE_JS_PARAMETER_TYPES
1827 1828 1829

// We define the association between CallDescriptors::Key and the specialized
// descriptor here to reduce boilerplate and mistakes.
1830
#define DEF_KEY(name, ...) \
1831 1832 1833
  CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
#undef DEF_KEY
1834 1835
}  // namespace internal
}  // namespace v8
1836

1837
#endif  // V8_CODEGEN_INTERFACE_DESCRIPTORS_H_