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