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