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_CALL_INTERFACE_DESCRIPTOR_H_ 6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_ 7 8 #include <memory> 9 10 #include "src/assembler.h" 11 #include "src/globals.h" 12 #include "src/macro-assembler.h" 13 14 namespace v8 { 15 namespace internal { 16 17 class PlatformInterfaceDescriptor; 18 19 #define INTERFACE_DESCRIPTOR_LIST(V) \ 20 V(Void) \ 21 V(ContextOnly) \ 22 V(Load) \ 23 V(LoadWithVector) \ 24 V(LoadICProtoArray) \ 25 V(LoadGlobal) \ 26 V(LoadGlobalWithVector) \ 27 V(Store) \ 28 V(StoreWithVector) \ 29 V(StoreNamedTransition) \ 30 V(StoreTransition) \ 31 V(VarArgFunction) \ 32 V(FastNewClosure) \ 33 V(FastNewFunctionContext) \ 34 V(FastNewObject) \ 35 V(FastNewRestParameter) \ 36 V(FastNewSloppyArguments) \ 37 V(FastNewStrictArguments) \ 38 V(TypeConversion) \ 39 V(Typeof) \ 40 V(FastCloneRegExp) \ 41 V(FastCloneShallowArray) \ 42 V(FastCloneShallowObject) \ 43 V(CreateAllocationSite) \ 44 V(CreateWeakCell) \ 45 V(CallFunction) \ 46 V(CallFunctionWithFeedback) \ 47 V(CallFunctionWithFeedbackAndVector) \ 48 V(CallConstruct) \ 49 V(CallTrampoline) \ 50 V(ConstructStub) \ 51 V(ConstructTrampoline) \ 52 V(RegExpExec) \ 53 V(CopyFastSmiOrObjectElements) \ 54 V(TransitionElementsKind) \ 55 V(AllocateHeapNumber) \ 56 V(AllocateFloat32x4) \ 57 V(AllocateInt32x4) \ 58 V(AllocateUint32x4) \ 59 V(AllocateBool32x4) \ 60 V(AllocateInt16x8) \ 61 V(AllocateUint16x8) \ 62 V(AllocateBool16x8) \ 63 V(AllocateInt8x16) \ 64 V(AllocateUint8x16) \ 65 V(AllocateBool8x16) \ 66 V(Builtin) \ 67 V(ArrayNoArgumentConstructor) \ 68 V(ArraySingleArgumentConstructor) \ 69 V(ArrayNArgumentsConstructor) \ 70 V(Compare) \ 71 V(BinaryOp) \ 72 V(BinaryOpWithAllocationSite) \ 73 V(BinaryOpWithVector) \ 74 V(CountOp) \ 75 V(StringAdd) \ 76 V(StringCompare) \ 77 V(SubString) \ 78 V(Keyed) \ 79 V(Named) \ 80 V(HasProperty) \ 81 V(ForInFilter) \ 82 V(GetProperty) \ 83 V(CallHandler) \ 84 V(ArgumentAdaptor) \ 85 V(ApiCallback) \ 86 V(ApiGetter) \ 87 V(MathPowTagged) \ 88 V(MathPowInteger) \ 89 V(GrowArrayElements) \ 90 V(InterpreterDispatch) \ 91 V(InterpreterPushArgsAndCall) \ 92 V(InterpreterPushArgsAndConstruct) \ 93 V(InterpreterPushArgsAndConstructArray) \ 94 V(InterpreterCEntry) \ 95 V(ResumeGenerator) 96 97 class V8_EXPORT_PRIVATE CallInterfaceDescriptorData { 98 public: 99 CallInterfaceDescriptorData() : register_param_count_(-1), param_count_(-1) {} 100 101 // A copy of the passed in registers and param_representations is made 102 // and owned by the CallInterfaceDescriptorData. 103 104 void InitializePlatformSpecific( 105 int register_parameter_count, const Register* registers, 106 PlatformInterfaceDescriptor* platform_descriptor = NULL); 107 108 // if machine_types is null, then an array of size 109 // (register_parameter_count + extra_parameter_count) will be created 110 // with MachineType::AnyTagged() for each member. 111 // 112 // if machine_types is not null, then it should be of the size 113 // register_parameter_count. Those members of the parameter array 114 // will be initialized from {machine_types}, and the rest initialized 115 // to MachineType::AnyTagged(). 116 void InitializePlatformIndependent(int parameter_count, 117 int extra_parameter_count, 118 const MachineType* machine_types); 119 120 bool IsInitialized() const { 121 return register_param_count_ >= 0 && param_count_ >= 0; 122 } 123 124 int param_count() const { return param_count_; } 125 int register_param_count() const { return register_param_count_; } 126 Register register_param(int index) const { return register_params_[index]; } 127 Register* register_params() const { return register_params_.get(); } 128 MachineType param_type(int index) const { return machine_types_[index]; } 129 PlatformInterfaceDescriptor* platform_specific_descriptor() const { 130 return platform_specific_descriptor_; 131 } 132 133 private: 134 int register_param_count_; 135 int param_count_; 136 137 // The Register params are allocated dynamically by the 138 // InterfaceDescriptor, and freed on destruction. This is because static 139 // arrays of Registers cause creation of runtime static initializers 140 // which we don't want. 141 std::unique_ptr<Register[]> register_params_; 142 std::unique_ptr<MachineType[]> machine_types_; 143 144 PlatformInterfaceDescriptor* platform_specific_descriptor_; 145 146 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); 147 }; 148 149 150 class CallDescriptors { 151 public: 152 enum Key { 153 #define DEF_ENUM(name) name, 154 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM) 155 #undef DEF_ENUM 156 NUMBER_OF_DESCRIPTORS 157 }; 158 }; 159 160 161 class CallInterfaceDescriptor { 162 public: 163 CallInterfaceDescriptor() : data_(NULL) {} 164 virtual ~CallInterfaceDescriptor() {} 165 166 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key) 167 : data_(isolate->call_descriptor_data(key)) {} 168 169 int GetParameterCount() const { return data()->param_count(); } 170 171 int GetRegisterParameterCount() const { 172 return data()->register_param_count(); 173 } 174 175 int GetStackParameterCount() const { 176 return data()->param_count() - data()->register_param_count(); 177 } 178 179 Register GetRegisterParameter(int index) const { 180 return data()->register_param(index); 181 } 182 183 MachineType GetParameterType(int index) const { 184 DCHECK(index < data()->param_count()); 185 return data()->param_type(index); 186 } 187 188 // Some platforms have extra information to associate with the descriptor. 189 PlatformInterfaceDescriptor* platform_specific_descriptor() const { 190 return data()->platform_specific_descriptor(); 191 } 192 193 static const Register ContextRegister(); 194 195 const char* DebugName(Isolate* isolate) const; 196 197 protected: 198 const CallInterfaceDescriptorData* data() const { return data_; } 199 200 virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) { 201 UNREACHABLE(); 202 } 203 204 virtual void InitializePlatformIndependent( 205 CallInterfaceDescriptorData* data) { 206 data->InitializePlatformIndependent(data->register_param_count(), 0, NULL); 207 } 208 209 void Initialize(Isolate* isolate, CallDescriptors::Key key) { 210 if (!data()->IsInitialized()) { 211 // We should only initialize descriptors on the isolate's main thread. 212 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); 213 CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key); 214 DCHECK(d == data()); // d should be a modifiable pointer to data(). 215 InitializePlatformSpecific(d); 216 InitializePlatformIndependent(d); 217 } 218 } 219 220 // Initializes |data| using the platform dependent default set of registers. 221 // It is intended to be used for TurboFan stubs when particular set of 222 // registers does not matter. 223 static void DefaultInitializePlatformSpecific( 224 CallInterfaceDescriptorData* data, int register_parameter_count); 225 226 private: 227 const CallInterfaceDescriptorData* data_; 228 }; 229 230 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 231 public: \ 232 explicit name(Isolate* isolate) : base(isolate, key()) { \ 233 Initialize(isolate, key()); \ 234 } \ 235 static inline CallDescriptors::Key key(); 236 237 #define DECLARE_DEFAULT_DESCRIPTOR(name, base, parameter_count) \ 238 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 239 protected: \ 240 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \ 241 override { \ 242 DefaultInitializePlatformSpecific(data, parameter_count); \ 243 } \ 244 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ 245 \ 246 public: 247 248 #define DECLARE_DESCRIPTOR(name, base) \ 249 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 250 protected: \ 251 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \ 252 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ 253 \ 254 public: 255 256 #define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \ 257 DECLARE_DESCRIPTOR(name, base) \ 258 protected: \ 259 void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \ 260 override; \ 261 \ 262 public: 263 264 #define DECLARE_DESCRIPTOR_WITH_STACK_ARGS(name, base) \ 265 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 266 protected: \ 267 void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \ 268 override { \ 269 data->InitializePlatformIndependent(0, kParameterCount, NULL); \ 270 } \ 271 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \ 272 override { \ 273 data->InitializePlatformSpecific(0, nullptr); \ 274 } \ 275 \ 276 public: 277 278 #define DEFINE_PARAMETERS(...) \ 279 enum ParameterIndices { \ 280 __VA_ARGS__, \ 281 \ 282 kParameterCount, \ 283 kContext = kParameterCount /* implicit parameter */ \ 284 }; 285 286 class VoidDescriptor : public CallInterfaceDescriptor { 287 public: 288 DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor) 289 }; 290 291 class ContextOnlyDescriptor : public CallInterfaceDescriptor { 292 public: 293 DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor) 294 }; 295 296 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs. 297 class LoadDescriptor : public CallInterfaceDescriptor { 298 public: 299 DEFINE_PARAMETERS(kReceiver, kName, kSlot) 300 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadDescriptor, 301 CallInterfaceDescriptor) 302 303 static const Register ReceiverRegister(); 304 static const Register NameRegister(); 305 static const Register SlotRegister(); 306 }; 307 308 class LoadGlobalDescriptor : public CallInterfaceDescriptor { 309 public: 310 DEFINE_PARAMETERS(kSlot) 311 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalDescriptor, 312 CallInterfaceDescriptor) 313 314 static const Register SlotRegister() { 315 return LoadDescriptor::SlotRegister(); 316 } 317 }; 318 319 class StoreDescriptor : public CallInterfaceDescriptor { 320 public: 321 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot) 322 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreDescriptor, 323 CallInterfaceDescriptor) 324 325 static const Register ReceiverRegister(); 326 static const Register NameRegister(); 327 static const Register ValueRegister(); 328 static const Register SlotRegister(); 329 330 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 331 static const bool kPassLastArgsOnStack = true; 332 #else 333 static const bool kPassLastArgsOnStack = false; 334 #endif 335 336 // Pass value and slot through the stack. 337 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0; 338 }; 339 340 class StoreTransitionDescriptor : public StoreDescriptor { 341 public: 342 DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector) 343 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreTransitionDescriptor, 344 StoreDescriptor) 345 346 static const Register MapRegister(); 347 static const Register SlotRegister(); 348 static const Register VectorRegister(); 349 350 // Pass value, slot and vector through the stack. 351 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; 352 }; 353 354 class StoreNamedTransitionDescriptor : public StoreTransitionDescriptor { 355 public: 356 DEFINE_PARAMETERS(kReceiver, kFieldOffset, kMap, kValue, kSlot, kVector, 357 kName) 358 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreNamedTransitionDescriptor, 359 StoreTransitionDescriptor) 360 361 // Always pass name on the stack. 362 static const bool kPassLastArgsOnStack = true; 363 static const int kStackArgumentsCount = 364 StoreTransitionDescriptor::kStackArgumentsCount + 1; 365 366 static const Register NameRegister() { return no_reg; } 367 static const Register FieldOffsetRegister() { 368 return StoreTransitionDescriptor::NameRegister(); 369 } 370 }; 371 372 class StoreWithVectorDescriptor : public StoreDescriptor { 373 public: 374 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector) 375 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreWithVectorDescriptor, 376 StoreDescriptor) 377 378 static const Register VectorRegister(); 379 380 // Pass value, slot and vector through the stack. 381 static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0; 382 }; 383 384 class LoadWithVectorDescriptor : public LoadDescriptor { 385 public: 386 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector) 387 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadWithVectorDescriptor, 388 LoadDescriptor) 389 390 static const Register VectorRegister(); 391 }; 392 393 class LoadICProtoArrayDescriptor : public LoadWithVectorDescriptor { 394 public: 395 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector, kHandler) 396 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadICProtoArrayDescriptor, 397 LoadWithVectorDescriptor) 398 399 static const Register HandlerRegister(); 400 }; 401 402 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor { 403 public: 404 DEFINE_PARAMETERS(kSlot, kVector) 405 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalWithVectorDescriptor, 406 LoadGlobalDescriptor) 407 408 static const Register VectorRegister() { 409 return LoadWithVectorDescriptor::VectorRegister(); 410 } 411 }; 412 413 class FastNewClosureDescriptor : public CallInterfaceDescriptor { 414 public: 415 DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor) 416 }; 417 418 class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor { 419 public: 420 DEFINE_PARAMETERS(kFunction, kSlots) 421 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastNewFunctionContextDescriptor, 422 CallInterfaceDescriptor) 423 424 static const Register FunctionRegister(); 425 static const Register SlotsRegister(); 426 }; 427 428 class FastNewObjectDescriptor : public CallInterfaceDescriptor { 429 public: 430 DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor) 431 }; 432 433 class FastNewRestParameterDescriptor : public CallInterfaceDescriptor { 434 public: 435 DECLARE_DESCRIPTOR(FastNewRestParameterDescriptor, CallInterfaceDescriptor) 436 }; 437 438 class FastNewSloppyArgumentsDescriptor : public CallInterfaceDescriptor { 439 public: 440 DECLARE_DESCRIPTOR(FastNewSloppyArgumentsDescriptor, 441 CallInterfaceDescriptor) 442 }; 443 444 class FastNewStrictArgumentsDescriptor : public CallInterfaceDescriptor { 445 public: 446 DECLARE_DESCRIPTOR(FastNewStrictArgumentsDescriptor, 447 CallInterfaceDescriptor) 448 }; 449 450 class TypeConversionDescriptor final : public CallInterfaceDescriptor { 451 public: 452 DEFINE_PARAMETERS(kArgument) 453 DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor) 454 455 static const Register ArgumentRegister(); 456 }; 457 458 class HasPropertyDescriptor final : public CallInterfaceDescriptor { 459 public: 460 DEFINE_PARAMETERS(kKey, kObject) 461 DECLARE_DEFAULT_DESCRIPTOR(HasPropertyDescriptor, CallInterfaceDescriptor, 462 kParameterCount) 463 }; 464 465 class ForInFilterDescriptor final : public CallInterfaceDescriptor { 466 public: 467 DEFINE_PARAMETERS(kKey, kObject) 468 DECLARE_DEFAULT_DESCRIPTOR(ForInFilterDescriptor, CallInterfaceDescriptor, 469 kParameterCount) 470 }; 471 472 class GetPropertyDescriptor final : public CallInterfaceDescriptor { 473 public: 474 DEFINE_PARAMETERS(kObject, kKey) 475 DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor, 476 kParameterCount) 477 }; 478 479 class TypeofDescriptor : public CallInterfaceDescriptor { 480 public: 481 DEFINE_PARAMETERS(kObject) 482 DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor) 483 }; 484 485 486 class FastCloneRegExpDescriptor : public CallInterfaceDescriptor { 487 public: 488 DEFINE_PARAMETERS(kClosure, kLiteralIndex, kPattern, kFlags) 489 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneRegExpDescriptor, 490 CallInterfaceDescriptor) 491 }; 492 493 494 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor { 495 public: 496 DEFINE_PARAMETERS(kClosure, kLiteralIndex, kConstantElements) 497 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneShallowArrayDescriptor, 498 CallInterfaceDescriptor) 499 }; 500 501 502 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor { 503 public: 504 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor) 505 }; 506 507 508 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor { 509 public: 510 DEFINE_PARAMETERS(kVector, kSlot) 511 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateAllocationSiteDescriptor, 512 CallInterfaceDescriptor) 513 }; 514 515 516 class CreateWeakCellDescriptor : public CallInterfaceDescriptor { 517 public: 518 DEFINE_PARAMETERS(kVector, kSlot, kValue) 519 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateWeakCellDescriptor, 520 CallInterfaceDescriptor) 521 }; 522 523 524 class CallTrampolineDescriptor : public CallInterfaceDescriptor { 525 public: 526 DEFINE_PARAMETERS(kFunction, kActualArgumentsCount) 527 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallTrampolineDescriptor, 528 CallInterfaceDescriptor) 529 }; 530 531 532 class ConstructStubDescriptor : public CallInterfaceDescriptor { 533 public: 534 DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount, 535 kAllocationSite) 536 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructStubDescriptor, 537 CallInterfaceDescriptor) 538 }; 539 540 541 class ConstructTrampolineDescriptor : public CallInterfaceDescriptor { 542 public: 543 DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount) 544 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructTrampolineDescriptor, 545 CallInterfaceDescriptor) 546 }; 547 548 549 class CallFunctionDescriptor : public CallInterfaceDescriptor { 550 public: 551 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor) 552 }; 553 554 555 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor { 556 public: 557 DEFINE_PARAMETERS(kFunction, kSlot) 558 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 559 CallFunctionWithFeedbackDescriptor, CallInterfaceDescriptor) 560 }; 561 562 563 class CallFunctionWithFeedbackAndVectorDescriptor 564 : public CallInterfaceDescriptor { 565 public: 566 DEFINE_PARAMETERS(kFunction, kActualArgumentsCount, kSlot, kVector) 567 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 568 CallFunctionWithFeedbackAndVectorDescriptor, CallInterfaceDescriptor) 569 }; 570 571 572 class CallConstructDescriptor : public CallInterfaceDescriptor { 573 public: 574 DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor) 575 }; 576 577 class RegExpExecDescriptor : public CallInterfaceDescriptor { 578 public: 579 DEFINE_PARAMETERS(kRegExpObject, kString, kPreviousIndex, kLastMatchInfo) 580 DECLARE_DESCRIPTOR_WITH_STACK_ARGS(RegExpExecDescriptor, 581 CallInterfaceDescriptor) 582 }; 583 584 class CopyFastSmiOrObjectElementsDescriptor : public CallInterfaceDescriptor { 585 public: 586 DEFINE_PARAMETERS(kObject) 587 DECLARE_DEFAULT_DESCRIPTOR(CopyFastSmiOrObjectElementsDescriptor, 588 CallInterfaceDescriptor, kParameterCount) 589 }; 590 591 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor { 592 public: 593 DEFINE_PARAMETERS(kObject, kMap) 594 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor) 595 }; 596 597 598 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor { 599 public: 600 DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor) 601 }; 602 603 #define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \ 604 class Allocate##Type##Descriptor : public CallInterfaceDescriptor { \ 605 public: \ 606 DECLARE_DESCRIPTOR(Allocate##Type##Descriptor, CallInterfaceDescriptor) \ 607 }; 608 SIMD128_TYPES(SIMD128_ALLOC_DESC) 609 #undef SIMD128_ALLOC_DESC 610 611 class BuiltinDescriptor : public CallInterfaceDescriptor { 612 public: 613 DEFINE_PARAMETERS(kNewTarget, kArgumentsCount) 614 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(BuiltinDescriptor, 615 CallInterfaceDescriptor) 616 static const Register ArgumentsCountRegister(); 617 static const Register NewTargetRegister(); 618 }; 619 620 class ArrayNoArgumentConstructorDescriptor : public CallInterfaceDescriptor { 621 public: 622 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount, 623 kFunctionParameter) 624 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 625 ArrayNoArgumentConstructorDescriptor, CallInterfaceDescriptor) 626 }; 627 628 class ArraySingleArgumentConstructorDescriptor 629 : public CallInterfaceDescriptor { 630 public: 631 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount, 632 kFunctionParameter, kArraySizeSmiParameter) 633 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 634 ArraySingleArgumentConstructorDescriptor, CallInterfaceDescriptor) 635 }; 636 637 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor { 638 public: 639 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount) 640 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 641 ArrayNArgumentsConstructorDescriptor, CallInterfaceDescriptor) 642 }; 643 644 645 class CompareDescriptor : public CallInterfaceDescriptor { 646 public: 647 DEFINE_PARAMETERS(kLeft, kRight) 648 DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor) 649 }; 650 651 652 class BinaryOpDescriptor : public CallInterfaceDescriptor { 653 public: 654 DEFINE_PARAMETERS(kLeft, kRight) 655 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor) 656 }; 657 658 659 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor { 660 public: 661 DEFINE_PARAMETERS(kAllocationSite, kLeft, kRight) 662 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor, 663 CallInterfaceDescriptor) 664 }; 665 666 class BinaryOpWithVectorDescriptor : public CallInterfaceDescriptor { 667 public: 668 DEFINE_PARAMETERS(kLeft, kRight, kSlot, kVector) 669 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(BinaryOpWithVectorDescriptor, 670 CallInterfaceDescriptor) 671 }; 672 673 class CountOpDescriptor final : public CallInterfaceDescriptor { 674 public: 675 DECLARE_DESCRIPTOR(CountOpDescriptor, CallInterfaceDescriptor) 676 }; 677 678 class StringAddDescriptor : public CallInterfaceDescriptor { 679 public: 680 DEFINE_PARAMETERS(kLeft, kRight) 681 DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor) 682 }; 683 684 685 class StringCompareDescriptor : public CallInterfaceDescriptor { 686 public: 687 DEFINE_PARAMETERS(kLeft, kRight) 688 DECLARE_DESCRIPTOR(StringCompareDescriptor, CallInterfaceDescriptor) 689 690 static const Register LeftRegister(); 691 static const Register RightRegister(); 692 }; 693 694 class SubStringDescriptor : public CallInterfaceDescriptor { 695 public: 696 DEFINE_PARAMETERS(kString, kFrom, kTo) 697 DECLARE_DESCRIPTOR_WITH_STACK_ARGS(SubStringDescriptor, 698 CallInterfaceDescriptor) 699 }; 700 701 // TODO(ishell): not used, remove. 702 class KeyedDescriptor : public CallInterfaceDescriptor { 703 public: 704 DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor) 705 }; 706 707 // TODO(ishell): not used, remove 708 class NamedDescriptor : public CallInterfaceDescriptor { 709 public: 710 DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor) 711 }; 712 713 // TODO(ishell): not used, remove. 714 class CallHandlerDescriptor : public CallInterfaceDescriptor { 715 public: 716 DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor) 717 }; 718 719 720 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { 721 public: 722 DEFINE_PARAMETERS(kFunction, kNewTarget, kActualArgumentsCount, 723 kExpectedArgumentsCount) 724 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArgumentAdaptorDescriptor, 725 CallInterfaceDescriptor) 726 }; 727 728 class ApiCallbackDescriptor : public CallInterfaceDescriptor { 729 public: 730 DEFINE_PARAMETERS(kFunction, kCallData, kHolder, kApiFunctionAddress) 731 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ApiCallbackDescriptor, 732 CallInterfaceDescriptor) 733 }; 734 735 class ApiGetterDescriptor : public CallInterfaceDescriptor { 736 public: 737 DEFINE_PARAMETERS(kReceiver, kHolder, kCallback) 738 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor) 739 740 static const Register ReceiverRegister(); 741 static const Register HolderRegister(); 742 static const Register CallbackRegister(); 743 }; 744 745 class MathPowTaggedDescriptor : public CallInterfaceDescriptor { 746 public: 747 DEFINE_PARAMETERS(kExponent) 748 DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor) 749 750 static const Register exponent(); 751 }; 752 753 class MathPowIntegerDescriptor : public CallInterfaceDescriptor { 754 public: 755 DEFINE_PARAMETERS(kExponent) 756 DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor) 757 758 static const Register exponent(); 759 }; 760 761 class VarArgFunctionDescriptor : public CallInterfaceDescriptor { 762 public: 763 DEFINE_PARAMETERS(kActualArgumentsCount) 764 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(VarArgFunctionDescriptor, 765 CallInterfaceDescriptor) 766 }; 767 768 // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor. 769 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor { 770 public: 771 DEFINE_PARAMETERS(kObject, kKey) 772 DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor) 773 774 static const Register ObjectRegister(); 775 static const Register KeyRegister(); 776 }; 777 778 class InterpreterDispatchDescriptor : public CallInterfaceDescriptor { 779 public: 780 DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray, 781 kDispatchTable) 782 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor, 783 CallInterfaceDescriptor) 784 }; 785 786 class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor { 787 public: 788 DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction) 789 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 790 InterpreterPushArgsAndCallDescriptor, CallInterfaceDescriptor) 791 }; 792 793 794 class InterpreterPushArgsAndConstructDescriptor 795 : public CallInterfaceDescriptor { 796 public: 797 DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor, 798 kFeedbackElement, kFirstArgument) 799 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 800 InterpreterPushArgsAndConstructDescriptor, CallInterfaceDescriptor) 801 }; 802 803 class InterpreterPushArgsAndConstructArrayDescriptor 804 : public CallInterfaceDescriptor { 805 public: 806 DEFINE_PARAMETERS(kNumberOfArguments, kFunction, kFeedbackElement, 807 kFirstArgument) 808 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 809 InterpreterPushArgsAndConstructArrayDescriptor, CallInterfaceDescriptor) 810 }; 811 812 class InterpreterCEntryDescriptor : public CallInterfaceDescriptor { 813 public: 814 DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunctionEntry) 815 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterCEntryDescriptor, 816 CallInterfaceDescriptor) 817 }; 818 819 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor { 820 public: 821 DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor) 822 }; 823 824 #undef DECLARE_DESCRIPTOR_WITH_BASE 825 #undef DECLARE_DESCRIPTOR 826 #undef DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE 827 #undef DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG 828 #undef DEFINE_PARAMETERS 829 830 // We define the association between CallDescriptors::Key and the specialized 831 // descriptor here to reduce boilerplate and mistakes. 832 #define DEF_KEY(name) \ 833 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; } 834 INTERFACE_DESCRIPTOR_LIST(DEF_KEY) 835 #undef DEF_KEY 836 } // namespace internal 837 } // namespace v8 838 839 840 #if V8_TARGET_ARCH_ARM64 841 #include "src/arm64/interface-descriptors-arm64.h" 842 #elif V8_TARGET_ARCH_ARM 843 #include "src/arm/interface-descriptors-arm.h" 844 #endif 845 846 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ 847