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 "src/assembler.h" 9 #include "src/macro-assembler.h" 10 11 namespace v8 { 12 namespace internal { 13 14 class PlatformInterfaceDescriptor; 15 16 #define INTERFACE_DESCRIPTOR_LIST(V) \ 17 V(Void) \ 18 V(ContextOnly) \ 19 V(OnStackWith1Args) \ 20 V(OnStackWith2Args) \ 21 V(OnStackWith3Args) \ 22 V(OnStackWith4Args) \ 23 V(OnStackWith5Args) \ 24 V(OnStackWith6Args) \ 25 V(OnStackWith7Args) \ 26 V(Load) \ 27 V(LoadGlobal) \ 28 V(LoadGlobalWithVector) \ 29 V(Store) \ 30 V(StoreTransition) \ 31 V(VectorStoreTransition) \ 32 V(VectorStoreICTrampoline) \ 33 V(VectorStoreIC) \ 34 V(LoadWithVector) \ 35 V(VarArgFunction) \ 36 V(FastNewClosure) \ 37 V(FastNewContext) \ 38 V(FastNewObject) \ 39 V(FastNewRestParameter) \ 40 V(FastNewSloppyArguments) \ 41 V(FastNewStrictArguments) \ 42 V(TypeConversion) \ 43 V(Typeof) \ 44 V(FastCloneRegExp) \ 45 V(FastCloneShallowArray) \ 46 V(FastCloneShallowObject) \ 47 V(CreateAllocationSite) \ 48 V(CreateWeakCell) \ 49 V(CallFunction) \ 50 V(CallFunctionWithFeedback) \ 51 V(CallFunctionWithFeedbackAndVector) \ 52 V(CallConstruct) \ 53 V(CallTrampoline) \ 54 V(ConstructStub) \ 55 V(ConstructTrampoline) \ 56 V(RegExpConstructResult) \ 57 V(TransitionElementsKind) \ 58 V(AllocateHeapNumber) \ 59 V(AllocateFloat32x4) \ 60 V(AllocateInt32x4) \ 61 V(AllocateUint32x4) \ 62 V(AllocateBool32x4) \ 63 V(AllocateInt16x8) \ 64 V(AllocateUint16x8) \ 65 V(AllocateBool16x8) \ 66 V(AllocateInt8x16) \ 67 V(AllocateUint8x16) \ 68 V(AllocateBool8x16) \ 69 V(ArrayNoArgumentConstructor) \ 70 V(ArraySingleArgumentConstructor) \ 71 V(ArrayNArgumentsConstructor) \ 72 V(Compare) \ 73 V(BinaryOp) \ 74 V(BinaryOpWithAllocationSite) \ 75 V(CountOp) \ 76 V(StringAdd) \ 77 V(StringCompare) \ 78 V(Keyed) \ 79 V(Named) \ 80 V(HasProperty) \ 81 V(CallHandler) \ 82 V(ArgumentAdaptor) \ 83 V(ApiCallbackWith0Args) \ 84 V(ApiCallbackWith1Args) \ 85 V(ApiCallbackWith2Args) \ 86 V(ApiCallbackWith3Args) \ 87 V(ApiCallbackWith4Args) \ 88 V(ApiCallbackWith5Args) \ 89 V(ApiCallbackWith6Args) \ 90 V(ApiCallbackWith7Args) \ 91 V(ApiGetter) \ 92 V(StoreGlobalViaContext) \ 93 V(MathPowTagged) \ 94 V(MathPowInteger) \ 95 V(GrowArrayElements) \ 96 V(InterpreterDispatch) \ 97 V(InterpreterPushArgsAndCall) \ 98 V(InterpreterPushArgsAndConstruct) \ 99 V(InterpreterCEntry) \ 100 V(ResumeGenerator) 101 102 class CallInterfaceDescriptorData { 103 public: 104 CallInterfaceDescriptorData() 105 : register_param_count_(-1), function_type_(nullptr) {} 106 107 // A copy of the passed in registers and param_representations is made 108 // and owned by the CallInterfaceDescriptorData. 109 110 void InitializePlatformIndependent(FunctionType* function_type) { 111 function_type_ = function_type; 112 } 113 114 // TODO(mvstanton): Instead of taking parallel arrays register and 115 // param_representations, how about a struct that puts the representation 116 // and register side by side (eg, RegRep(r1, Representation::Tagged()). 117 // The same should go for the CodeStubDescriptor class. 118 void InitializePlatformSpecific( 119 int register_parameter_count, const Register* registers, 120 PlatformInterfaceDescriptor* platform_descriptor = NULL); 121 122 bool IsInitialized() const { return register_param_count_ >= 0; } 123 124 int param_count() const { return function_type_->Arity(); } 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 Type* param_type(int index) const { return function_type_->Parameter(index); } 129 PlatformInterfaceDescriptor* platform_specific_descriptor() const { 130 return platform_specific_descriptor_; 131 } 132 133 FunctionType* function_type() const { return function_type_; } 134 135 private: 136 int register_param_count_; 137 138 // The Register params are allocated dynamically by the 139 // InterfaceDescriptor, and freed on destruction. This is because static 140 // arrays of Registers cause creation of runtime static initializers 141 // which we don't want. 142 base::SmartArrayPointer<Register> register_params_; 143 144 // Specifies types for parameters and return 145 FunctionType* function_type_; 146 147 PlatformInterfaceDescriptor* platform_specific_descriptor_; 148 149 DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); 150 }; 151 152 153 class CallDescriptors { 154 public: 155 enum Key { 156 #define DEF_ENUM(name) name, 157 INTERFACE_DESCRIPTOR_LIST(DEF_ENUM) 158 #undef DEF_ENUM 159 NUMBER_OF_DESCRIPTORS 160 }; 161 }; 162 163 164 class CallInterfaceDescriptor { 165 public: 166 CallInterfaceDescriptor() : data_(NULL) {} 167 virtual ~CallInterfaceDescriptor() {} 168 169 CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key) 170 : data_(isolate->call_descriptor_data(key)) {} 171 172 int GetParameterCount() const { return data()->param_count(); } 173 174 int GetRegisterParameterCount() const { 175 return data()->register_param_count(); 176 } 177 178 int GetStackParameterCount() const { 179 return data()->function_type()->Arity() - data()->register_param_count(); 180 } 181 182 Register GetRegisterParameter(int index) const { 183 return data()->register_param(index); 184 } 185 186 Type* GetParameterType(int index) const { 187 DCHECK(index < data()->param_count()); 188 return data()->param_type(index); 189 } 190 191 // Some platforms have extra information to associate with the descriptor. 192 PlatformInterfaceDescriptor* platform_specific_descriptor() const { 193 return data()->platform_specific_descriptor(); 194 } 195 196 FunctionType* GetFunctionType() const { return data()->function_type(); } 197 198 static const Register ContextRegister(); 199 200 const char* DebugName(Isolate* isolate) const; 201 202 static FunctionType* BuildDefaultFunctionType(Isolate* isolate, 203 int paramater_count); 204 205 protected: 206 const CallInterfaceDescriptorData* data() const { return data_; } 207 208 virtual FunctionType* BuildCallInterfaceDescriptorFunctionType( 209 Isolate* isolate, int register_param_count) { 210 return BuildDefaultFunctionType(isolate, register_param_count); 211 } 212 213 virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) { 214 UNREACHABLE(); 215 } 216 217 void Initialize(Isolate* isolate, CallDescriptors::Key key) { 218 if (!data()->IsInitialized()) { 219 CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key); 220 DCHECK(d == data()); // d should be a modifiable pointer to data(). 221 InitializePlatformSpecific(d); 222 FunctionType* function_type = BuildCallInterfaceDescriptorFunctionType( 223 isolate, d->register_param_count()); 224 d->InitializePlatformIndependent(function_type); 225 } 226 } 227 228 // Initializes |data| using the platform dependent default set of registers. 229 // It is intended to be used for TurboFan stubs when particular set of 230 // registers does not matter. 231 static void DefaultInitializePlatformSpecific( 232 CallInterfaceDescriptorData* data, int register_parameter_count); 233 234 private: 235 const CallInterfaceDescriptorData* data_; 236 }; 237 238 #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 239 public: \ 240 explicit name(Isolate* isolate) : base(isolate, key()) { \ 241 Initialize(isolate, key()); \ 242 } \ 243 static inline CallDescriptors::Key key(); 244 245 #define DECLARE_DEFAULT_DESCRIPTOR(name, base, parameter_count) \ 246 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 247 protected: \ 248 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \ 249 override { \ 250 DefaultInitializePlatformSpecific(data, parameter_count); \ 251 } \ 252 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ 253 \ 254 public: 255 256 #define DECLARE_DESCRIPTOR(name, base) \ 257 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 258 protected: \ 259 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \ 260 name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ 261 \ 262 public: 263 264 #define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \ 265 DECLARE_DESCRIPTOR(name, base) \ 266 protected: \ 267 FunctionType* BuildCallInterfaceDescriptorFunctionType( \ 268 Isolate* isolate, int register_param_count) override; \ 269 \ 270 public: 271 272 #define DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(name, base, arg) \ 273 DECLARE_DESCRIPTOR_WITH_BASE(name, base) \ 274 protected: \ 275 FunctionType* BuildCallInterfaceDescriptorFunctionType( \ 276 Isolate* isolate, int register_param_count) override { \ 277 return BuildCallInterfaceDescriptorFunctionTypeWithArg( \ 278 isolate, register_param_count, arg); \ 279 } \ 280 \ 281 public: 282 283 class VoidDescriptor : public CallInterfaceDescriptor { 284 public: 285 DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor) 286 }; 287 288 class ContextOnlyDescriptor : public CallInterfaceDescriptor { 289 public: 290 DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor) 291 }; 292 293 // The OnStackWith*ArgsDescriptors have a lot of boilerplate. The superclass 294 // OnStackArgsDescriptorBase is not meant to be instantiated directly and has no 295 // public constructors to ensure this is so.contains all the logic, and the 296 // 297 // Use OnStackArgsDescriptorBase::ForArgs(isolate, parameter_count) to 298 // instantiate a descriptor with the number of args. 299 class OnStackArgsDescriptorBase : public CallInterfaceDescriptor { 300 public: 301 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int parameter_count); 302 303 protected: 304 OnStackArgsDescriptorBase(Isolate* isolate, CallDescriptors::Key key) 305 : CallInterfaceDescriptor(isolate, key) {} 306 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; 307 FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg( 308 Isolate* isolate, int register_parameter_count, int parameter_count); 309 }; 310 311 class OnStackWith1ArgsDescriptor : public OnStackArgsDescriptorBase { 312 public: 313 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith1ArgsDescriptor, 314 OnStackArgsDescriptorBase, 315 1) 316 }; 317 318 class OnStackWith2ArgsDescriptor : public OnStackArgsDescriptorBase { 319 public: 320 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith2ArgsDescriptor, 321 OnStackArgsDescriptorBase, 322 2) 323 }; 324 325 class OnStackWith3ArgsDescriptor : public OnStackArgsDescriptorBase { 326 public: 327 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith3ArgsDescriptor, 328 OnStackArgsDescriptorBase, 329 3) 330 }; 331 332 class OnStackWith4ArgsDescriptor : public OnStackArgsDescriptorBase { 333 public: 334 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith4ArgsDescriptor, 335 OnStackArgsDescriptorBase, 336 4) 337 }; 338 339 class OnStackWith5ArgsDescriptor : public OnStackArgsDescriptorBase { 340 public: 341 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith5ArgsDescriptor, 342 OnStackArgsDescriptorBase, 343 5) 344 }; 345 346 class OnStackWith6ArgsDescriptor : public OnStackArgsDescriptorBase { 347 public: 348 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith6ArgsDescriptor, 349 OnStackArgsDescriptorBase, 350 6) 351 }; 352 353 class OnStackWith7ArgsDescriptor : public OnStackArgsDescriptorBase { 354 public: 355 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG(OnStackWith7ArgsDescriptor, 356 OnStackArgsDescriptorBase, 357 7) 358 }; 359 360 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs. 361 class LoadDescriptor : public CallInterfaceDescriptor { 362 public: 363 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadDescriptor, 364 CallInterfaceDescriptor) 365 366 enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex }; 367 static const Register ReceiverRegister(); 368 static const Register NameRegister(); 369 static const Register SlotRegister(); 370 }; 371 372 class LoadGlobalDescriptor : public CallInterfaceDescriptor { 373 public: 374 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalDescriptor, 375 CallInterfaceDescriptor) 376 377 enum ParameterIndices { kSlotIndex }; 378 379 static const Register SlotRegister() { 380 return LoadDescriptor::SlotRegister(); 381 } 382 }; 383 384 class StoreDescriptor : public CallInterfaceDescriptor { 385 public: 386 DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor) 387 388 enum ParameterIndices { 389 kReceiverIndex, 390 kNameIndex, 391 kValueIndex, 392 kParameterCount 393 }; 394 static const Register ReceiverRegister(); 395 static const Register NameRegister(); 396 static const Register ValueRegister(); 397 }; 398 399 400 class StoreTransitionDescriptor : public StoreDescriptor { 401 public: 402 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreTransitionDescriptor, 403 StoreDescriptor) 404 405 // Extends StoreDescriptor with Map parameter. 406 enum ParameterIndices { 407 kReceiverIndex, 408 kNameIndex, 409 kValueIndex, 410 kMapIndex, 411 kParameterCount 412 }; 413 414 static const Register MapRegister(); 415 }; 416 417 418 class VectorStoreTransitionDescriptor : public StoreDescriptor { 419 public: 420 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(VectorStoreTransitionDescriptor, 421 StoreDescriptor) 422 423 // Extends StoreDescriptor with Map parameter. 424 enum ParameterIndices { 425 kReceiverIndex = 0, 426 kNameIndex = 1, 427 kValueIndex = 2, 428 429 kMapIndex = 3, 430 431 kSlotIndex = 4, // not present on ia32. 432 kVirtualSlotVectorIndex = 4, 433 434 kVectorIndex = 5 435 }; 436 437 static const Register MapRegister(); 438 static const Register SlotRegister(); 439 static const Register VectorRegister(); 440 }; 441 442 443 class VectorStoreICTrampolineDescriptor : public StoreDescriptor { 444 public: 445 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 446 VectorStoreICTrampolineDescriptor, StoreDescriptor) 447 448 enum ParameterIndices { kReceiverIndex, kNameIndex, kValueIndex, kSlotIndex }; 449 450 static const Register SlotRegister(); 451 }; 452 453 454 class VectorStoreICDescriptor : public VectorStoreICTrampolineDescriptor { 455 public: 456 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 457 VectorStoreICDescriptor, VectorStoreICTrampolineDescriptor) 458 459 enum ParameterIndices { 460 kReceiverIndex, 461 kNameIndex, 462 kValueIndex, 463 kSlotIndex, 464 kVectorIndex 465 }; 466 467 static const Register VectorRegister(); 468 }; 469 470 471 class LoadWithVectorDescriptor : public LoadDescriptor { 472 public: 473 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadWithVectorDescriptor, 474 LoadDescriptor) 475 476 enum ParameterIndices { 477 kReceiverIndex, 478 kNameIndex, 479 kSlotIndex, 480 kVectorIndex 481 }; 482 483 static const Register VectorRegister(); 484 }; 485 486 class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor { 487 public: 488 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(LoadGlobalWithVectorDescriptor, 489 LoadGlobalDescriptor) 490 491 enum ParameterIndices { kSlotIndex, kVectorIndex }; 492 493 static const Register VectorRegister() { 494 return LoadWithVectorDescriptor::VectorRegister(); 495 } 496 }; 497 498 class FastNewClosureDescriptor : public CallInterfaceDescriptor { 499 public: 500 DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor) 501 }; 502 503 504 class FastNewContextDescriptor : public CallInterfaceDescriptor { 505 public: 506 DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor) 507 }; 508 509 class FastNewObjectDescriptor : public CallInterfaceDescriptor { 510 public: 511 DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor) 512 }; 513 514 class FastNewRestParameterDescriptor : public CallInterfaceDescriptor { 515 public: 516 DECLARE_DESCRIPTOR(FastNewRestParameterDescriptor, CallInterfaceDescriptor) 517 }; 518 519 class FastNewSloppyArgumentsDescriptor : public CallInterfaceDescriptor { 520 public: 521 DECLARE_DESCRIPTOR(FastNewSloppyArgumentsDescriptor, 522 CallInterfaceDescriptor) 523 }; 524 525 class FastNewStrictArgumentsDescriptor : public CallInterfaceDescriptor { 526 public: 527 DECLARE_DESCRIPTOR(FastNewStrictArgumentsDescriptor, 528 CallInterfaceDescriptor) 529 }; 530 531 class TypeConversionDescriptor final : public CallInterfaceDescriptor { 532 public: 533 enum ParameterIndices { kArgumentIndex }; 534 535 DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor) 536 537 static const Register ArgumentRegister(); 538 }; 539 540 class HasPropertyDescriptor final : public CallInterfaceDescriptor { 541 public: 542 enum ParameterIndices { kKeyIndex, kObjectIndex }; 543 544 DECLARE_DEFAULT_DESCRIPTOR(HasPropertyDescriptor, CallInterfaceDescriptor, 2) 545 }; 546 547 class TypeofDescriptor : public CallInterfaceDescriptor { 548 public: 549 DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor) 550 }; 551 552 553 class FastCloneRegExpDescriptor : public CallInterfaceDescriptor { 554 public: 555 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneRegExpDescriptor, 556 CallInterfaceDescriptor) 557 }; 558 559 560 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor { 561 public: 562 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(FastCloneShallowArrayDescriptor, 563 CallInterfaceDescriptor) 564 }; 565 566 567 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor { 568 public: 569 DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor) 570 }; 571 572 573 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor { 574 public: 575 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateAllocationSiteDescriptor, 576 CallInterfaceDescriptor) 577 }; 578 579 580 class CreateWeakCellDescriptor : public CallInterfaceDescriptor { 581 public: 582 enum ParameterIndices { 583 kVectorIndex, 584 kSlotIndex, 585 kValueIndex, 586 kParameterCount 587 }; 588 589 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CreateWeakCellDescriptor, 590 CallInterfaceDescriptor) 591 }; 592 593 594 class CallTrampolineDescriptor : public CallInterfaceDescriptor { 595 public: 596 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(CallTrampolineDescriptor, 597 CallInterfaceDescriptor) 598 }; 599 600 601 class ConstructStubDescriptor : public CallInterfaceDescriptor { 602 public: 603 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructStubDescriptor, 604 CallInterfaceDescriptor) 605 }; 606 607 608 class ConstructTrampolineDescriptor : public CallInterfaceDescriptor { 609 public: 610 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ConstructTrampolineDescriptor, 611 CallInterfaceDescriptor) 612 }; 613 614 615 class CallFunctionDescriptor : public CallInterfaceDescriptor { 616 public: 617 DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor) 618 }; 619 620 621 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor { 622 public: 623 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 624 CallFunctionWithFeedbackDescriptor, CallInterfaceDescriptor) 625 }; 626 627 628 class CallFunctionWithFeedbackAndVectorDescriptor 629 : public CallInterfaceDescriptor { 630 public: 631 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 632 CallFunctionWithFeedbackAndVectorDescriptor, CallInterfaceDescriptor) 633 }; 634 635 636 class CallConstructDescriptor : public CallInterfaceDescriptor { 637 public: 638 DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor) 639 }; 640 641 642 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor { 643 public: 644 DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor) 645 }; 646 647 648 class StoreGlobalViaContextDescriptor : public CallInterfaceDescriptor { 649 public: 650 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(StoreGlobalViaContextDescriptor, 651 CallInterfaceDescriptor) 652 653 static const Register SlotRegister(); 654 static const Register ValueRegister(); 655 }; 656 657 658 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor { 659 public: 660 DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor) 661 }; 662 663 664 class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor { 665 public: 666 DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor) 667 }; 668 669 #define SIMD128_ALLOC_DESC(TYPE, Type, type, lane_count, lane_type) \ 670 class Allocate##Type##Descriptor : public CallInterfaceDescriptor { \ 671 public: \ 672 DECLARE_DESCRIPTOR(Allocate##Type##Descriptor, CallInterfaceDescriptor) \ 673 }; 674 SIMD128_TYPES(SIMD128_ALLOC_DESC) 675 #undef SIMD128_ALLOC_DESC 676 677 class ArrayNoArgumentConstructorDescriptor : public CallInterfaceDescriptor { 678 public: 679 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 680 ArrayNoArgumentConstructorDescriptor, CallInterfaceDescriptor) 681 enum ParameterIndices { 682 kFunctionIndex, 683 kAllocationSiteIndex, 684 kArgumentCountIndex, 685 kFunctionParameterIndex, 686 kContextIndex 687 }; 688 }; 689 690 class ArraySingleArgumentConstructorDescriptor 691 : public CallInterfaceDescriptor { 692 public: 693 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 694 ArraySingleArgumentConstructorDescriptor, CallInterfaceDescriptor) 695 enum ParameterIndices { 696 kFunctionIndex, 697 kAllocationSiteIndex, 698 kArgumentCountIndex, 699 kFunctionParameterIndex, 700 kArraySizeSmiParameterIndex, 701 kContextIndex 702 }; 703 }; 704 705 class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor { 706 public: 707 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE( 708 ArrayNArgumentsConstructorDescriptor, CallInterfaceDescriptor) 709 enum ParameterIndices { 710 kFunctionIndex, 711 kAllocationSiteIndex, 712 kArgumentCountIndex, 713 kContextIndex 714 }; 715 }; 716 717 718 class CompareDescriptor : public CallInterfaceDescriptor { 719 public: 720 DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor) 721 }; 722 723 724 class BinaryOpDescriptor : public CallInterfaceDescriptor { 725 public: 726 DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor) 727 }; 728 729 730 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor { 731 public: 732 DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor, 733 CallInterfaceDescriptor) 734 }; 735 736 class CountOpDescriptor final : public CallInterfaceDescriptor { 737 public: 738 DECLARE_DESCRIPTOR(CountOpDescriptor, CallInterfaceDescriptor) 739 }; 740 741 class StringAddDescriptor : public CallInterfaceDescriptor { 742 public: 743 DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor) 744 }; 745 746 747 class StringCompareDescriptor : public CallInterfaceDescriptor { 748 public: 749 DECLARE_DESCRIPTOR(StringCompareDescriptor, CallInterfaceDescriptor) 750 751 enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount }; 752 static const Register LeftRegister(); 753 static const Register RightRegister(); 754 }; 755 756 757 class KeyedDescriptor : public CallInterfaceDescriptor { 758 public: 759 DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor) 760 }; 761 762 763 class NamedDescriptor : public CallInterfaceDescriptor { 764 public: 765 DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor) 766 }; 767 768 769 class CallHandlerDescriptor : public CallInterfaceDescriptor { 770 public: 771 DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor) 772 }; 773 774 775 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { 776 public: 777 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(ArgumentAdaptorDescriptor, 778 CallInterfaceDescriptor) 779 }; 780 781 // The ApiCallback*Descriptors have a lot of boilerplate. The superclass 782 // ApiCallbackDescriptorBase contains all the logic, and the 783 // ApiCallbackWith*ArgsDescriptor merely instantiate these with a 784 // parameter for the number of args. 785 // 786 // The base class is not meant to be instantiated directly and has no 787 // public constructors to ensure this is so. 788 // 789 // The simplest usage for all the ApiCallback*Descriptors is probably 790 // ApiCallbackDescriptorBase::ForArgs(isolate, argc) 791 // 792 class ApiCallbackDescriptorBase : public CallInterfaceDescriptor { 793 public: 794 static CallInterfaceDescriptor ForArgs(Isolate* isolate, int argc); 795 796 protected: 797 ApiCallbackDescriptorBase(Isolate* isolate, CallDescriptors::Key key) 798 : CallInterfaceDescriptor(isolate, key) {} 799 void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; 800 FunctionType* BuildCallInterfaceDescriptorFunctionTypeWithArg( 801 Isolate* isolate, int parameter_count, int argc); 802 }; 803 804 class ApiCallbackWith0ArgsDescriptor : public ApiCallbackDescriptorBase { 805 public: 806 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 807 ApiCallbackWith0ArgsDescriptor, ApiCallbackDescriptorBase, 0) 808 }; 809 810 class ApiCallbackWith1ArgsDescriptor : public ApiCallbackDescriptorBase { 811 public: 812 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 813 ApiCallbackWith1ArgsDescriptor, ApiCallbackDescriptorBase, 1) 814 }; 815 816 class ApiCallbackWith2ArgsDescriptor : public ApiCallbackDescriptorBase { 817 public: 818 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 819 ApiCallbackWith2ArgsDescriptor, ApiCallbackDescriptorBase, 2) 820 }; 821 822 class ApiCallbackWith3ArgsDescriptor : public ApiCallbackDescriptorBase { 823 public: 824 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 825 ApiCallbackWith3ArgsDescriptor, ApiCallbackDescriptorBase, 3) 826 }; 827 828 class ApiCallbackWith4ArgsDescriptor : public ApiCallbackDescriptorBase { 829 public: 830 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 831 ApiCallbackWith4ArgsDescriptor, ApiCallbackDescriptorBase, 4) 832 }; 833 834 class ApiCallbackWith5ArgsDescriptor : public ApiCallbackDescriptorBase { 835 public: 836 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 837 ApiCallbackWith5ArgsDescriptor, ApiCallbackDescriptorBase, 5) 838 }; 839 840 class ApiCallbackWith6ArgsDescriptor : public ApiCallbackDescriptorBase { 841 public: 842 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 843 ApiCallbackWith6ArgsDescriptor, ApiCallbackDescriptorBase, 6) 844 }; 845 846 class ApiCallbackWith7ArgsDescriptor : public ApiCallbackDescriptorBase { 847 public: 848 DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG( 849 ApiCallbackWith7ArgsDescriptor, ApiCallbackDescriptorBase, 7) 850 }; 851 852 853 class ApiGetterDescriptor : public CallInterfaceDescriptor { 854 public: 855 DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor) 856 857 static const Register ReceiverRegister(); 858 static const Register HolderRegister(); 859 static const Register CallbackRegister(); 860 }; 861 862 class MathPowTaggedDescriptor : public CallInterfaceDescriptor { 863 public: 864 DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor) 865 866 static const Register exponent(); 867 }; 868 869 class MathPowIntegerDescriptor : public CallInterfaceDescriptor { 870 public: 871 DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor) 872 873 static const Register exponent(); 874 }; 875 876 class VarArgFunctionDescriptor : public CallInterfaceDescriptor { 877 public: 878 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(VarArgFunctionDescriptor, 879 CallInterfaceDescriptor) 880 }; 881 882 class GrowArrayElementsDescriptor : public CallInterfaceDescriptor { 883 public: 884 DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor) 885 886 enum RegisterInfo { kObjectIndex, kKeyIndex }; 887 static const Register ObjectRegister(); 888 static const Register KeyRegister(); 889 }; 890 891 class InterpreterDispatchDescriptor : public CallInterfaceDescriptor { 892 public: 893 DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(InterpreterDispatchDescriptor, 894 CallInterfaceDescriptor) 895 896 static const int kAccumulatorParameter = 0; 897 static const int kBytecodeOffsetParameter = 1; 898 static const int kBytecodeArrayParameter = 2; 899 static const int kDispatchTableParameter = 3; 900 }; 901 902 class InterpreterPushArgsAndCallDescriptor : public CallInterfaceDescriptor { 903 public: 904 DECLARE_DESCRIPTOR(InterpreterPushArgsAndCallDescriptor, 905 CallInterfaceDescriptor) 906 }; 907 908 909 class InterpreterPushArgsAndConstructDescriptor 910 : public CallInterfaceDescriptor { 911 public: 912 DECLARE_DESCRIPTOR(InterpreterPushArgsAndConstructDescriptor, 913 CallInterfaceDescriptor) 914 }; 915 916 917 class InterpreterCEntryDescriptor : public CallInterfaceDescriptor { 918 public: 919 DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor) 920 }; 921 922 class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor { 923 public: 924 DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor) 925 }; 926 927 #undef DECLARE_DESCRIPTOR_WITH_BASE 928 #undef DECLARE_DESCRIPTOR 929 #undef DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE 930 #undef DECLARE_DESCRIPTOR_WITH_BASE_AND_FUNCTION_TYPE_ARG 931 932 // We define the association between CallDescriptors::Key and the specialized 933 // descriptor here to reduce boilerplate and mistakes. 934 #define DEF_KEY(name) \ 935 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; } 936 INTERFACE_DESCRIPTOR_LIST(DEF_KEY) 937 #undef DEF_KEY 938 } // namespace internal 939 } // namespace v8 940 941 942 #if V8_TARGET_ARCH_ARM64 943 #include "src/arm64/interface-descriptors-arm64.h" 944 #elif V8_TARGET_ARCH_ARM 945 #include "src/arm/interface-descriptors-arm.h" 946 #endif 947 948 #endif // V8_CALL_INTERFACE_DESCRIPTOR_H_ 949