v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
interface-descriptors.h
Go to the documentation of this file.
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/base/logging.h"
13#include "src/codegen/tnode.h"
14#include "src/common/globals.h"
16
17namespace v8 {
18namespace internal {
19
20#define TORQUE_BUILTIN_LIST_TFC(V) \
21 BUILTIN_LIST_FROM_TORQUE(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \
22 IGNORE_BUILTIN, IGNORE_BUILTIN)
23
24#define INTERFACE_DESCRIPTOR_LIST(V) \
25 V(Abort) \
26 V(Allocate) \
27 V(CallApiCallbackGeneric) \
28 V(CallApiCallbackOptimized) \
29 V(ApiGetter) \
30 V(ArrayConstructor) \
31 V(ArrayNArgumentsConstructor) \
32 V(ArrayNoArgumentConstructor) \
33 V(ArraySingleArgumentConstructor) \
34 V(AsyncFunctionStackParameter) \
35 V(BaselineLeaveFrame) \
36 V(BaselineOutOfLinePrologue) \
37 V(BigIntToI32Pair) \
38 V(BigIntToI64) \
39 V(BinaryOp) \
40 V(BinaryOp_Baseline) \
41 V(BinaryOp_WithFeedback) \
42 V(BinarySmiOp_Baseline) \
43 V(CallForwardVarargs) \
44 V(CallFunctionTemplate) \
45 V(CallFunctionTemplateGeneric) \
46 V(CallTrampoline) \
47 V(CallTrampoline_Baseline) \
48 V(CallTrampoline_Baseline_Compact) \
49 V(CallTrampoline_WithFeedback) \
50 V(CallVarargs) \
51 V(CallWithArrayLike) \
52 V(CallWithArrayLike_WithFeedback) \
53 V(CallWithSpread) \
54 V(CallWithSpread_Baseline) \
55 V(CallWithSpread_WithFeedback) \
56 V(CCall) \
57 V(CEntryDummy) \
58 V(CEntry1ArgvOnStack) \
59 V(CloneObjectBaseline) \
60 V(CloneObjectWithVector) \
61 V(Compare) \
62 V(CompareNoContext) \
63 V(StringEqual) \
64 V(Compare_Baseline) \
65 V(Compare_WithFeedback) \
66 V(Construct_Baseline) \
67 V(ConstructForwardVarargs) \
68 V(ConstructForwardAllArgs) \
69 V(ConstructForwardAllArgs_Baseline) \
70 V(ConstructForwardAllArgs_WithFeedback) \
71 V(ConstructStub) \
72 V(ConstructVarargs) \
73 V(ConstructWithArrayLike) \
74 V(Construct_WithFeedback) \
75 V(ConstructWithSpread) \
76 V(ConstructWithSpread_Baseline) \
77 V(ConstructWithSpread_WithFeedback) \
78 V(ContextOnly) \
79 V(CopyDataPropertiesWithExcludedProperties) \
80 V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
81 V(CppBuiltinAdaptor) \
82 V(CreateFromSlowBoilerplateHelper) \
83 V(DefineKeyedOwn) \
84 V(DefineKeyedOwnBaseline) \
85 V(DefineKeyedOwnWithVector) \
86 V(FastNewObject) \
87 V(FindNonDefaultConstructorOrConstruct) \
88 V(ForInPrepare) \
89 V(GetIteratorStackParameter) \
90 V(GetProperty) \
91 V(GrowArrayElements) \
92 V(I32PairToBigInt) \
93 V(I64ToBigInt) \
94 V(InterpreterCEntry1) \
95 V(InterpreterCEntry2) \
96 V(InterpreterDispatch) \
97 V(InterpreterPushArgsThenCall) \
98 V(InterpreterPushArgsThenConstruct) \
99 V(JSTrampoline) \
100 V(KeyedHasICBaseline) \
101 V(KeyedHasICWithVector) \
102 V(KeyedLoad) \
103 V(KeyedLoadBaseline) \
104 V(EnumeratedKeyedLoadBaseline) \
105 V(KeyedLoadWithVector) \
106 V(EnumeratedKeyedLoad) \
107 V(Load) \
108 V(LoadBaseline) \
109 V(LoadGlobal) \
110 V(LoadGlobalBaseline) \
111 V(LoadGlobalNoFeedback) \
112 V(LoadGlobalWithVector) \
113 V(LoadNoFeedback) \
114 V(LoadWithReceiverAndVector) \
115 V(LoadWithReceiverBaseline) \
116 V(LoadWithVector) \
117 V(LookupWithVector) \
118 V(LookupTrampoline) \
119 V(LookupBaseline) \
120 V(MaglevOptimizeCodeOrTailCallOptimizedCodeSlot) \
121 V(NewHeapNumber) \
122 V(NoContext) \
123 V(OnStackReplacement) \
124 V(RegExpTrampoline) \
125 V(RestartFrameTrampoline) \
126 V(ResumeGenerator) \
127 V(ResumeGeneratorBaseline) \
128 V(RunMicrotasks) \
129 V(RunMicrotasksEntry) \
130 V(SingleParameterOnStack) \
131 V(Store) \
132 V(StoreNoFeedback) \
133 V(StoreBaseline) \
134 V(StoreGlobal) \
135 V(StoreGlobalBaseline) \
136 V(StoreGlobalWithVector) \
137 V(StoreTransition) \
138 V(StoreWithVector) \
139 V(StringAtAsString) \
140 V(StringSubstring) \
141 V(SuspendGeneratorBaseline) \
142 V(TypeConversion) \
143 V(TypeConversion_Baseline) \
144 V(TypeConversionNoContext) \
145 V(Typeof) \
146 V(UnaryOp_Baseline) \
147 V(UnaryOp_WithFeedback) \
148 V(Void) \
149 V(WasmDummy) \
150 V(WasmFloat32ToNumber) \
151 V(WasmFloat64ToTagged) \
152 V(WasmJSToWasmWrapper) \
153 V(WasmToJSWrapper) \
154 V(WasmSuspend) \
155 V(WasmHandleStackOverflow) \
156 V(WriteBarrier) \
157 V(IndirectPointerWriteBarrier) \
158 IF_TSAN(V, TSANLoad) \
159 IF_TSAN(V, TSANStore) \
160 BUILTIN_LIST_TFS(V) \
161 TORQUE_BUILTIN_LIST_TFC(V)
162
164 kDefault, // Arguments in the stack are pushed in the default/stub order (the
165 // first argument is pushed first).
166 kJS, // Arguments in the stack are pushed in the same order as the one used
167 // by JS-to-JS function calls. This should be used if calling a
168 // JSFunction or if the builtin is expected to be called directly from a
169 // JSFunction. This order is reversed compared to kDefault.
170};
171
173 public:
174 enum Flag {
176 kNoContext = 1u << 0,
177 // This indicates that the code uses a special frame that does not scan the
178 // stack arguments, e.g. EntryFrame. And this allows the code to use
179 // untagged stack arguments.
180 kNoStackScan = 1u << 1,
181 // In addition to the specified parameters, additional arguments can be
182 // passed on the stack.
183 // This does not indicate if arguments adaption is used or not.
184 kAllowVarArgs = 1u << 2,
185 // Callee save allocatable_registers.
186 kCalleeSaveRegisters = 1u << 3,
187 };
189
190 static constexpr int kUninitializedCount = -1;
191
193
196 delete;
197
198 // The passed registers are owned by the caller, and their lifetime is
199 // expected to exceed that of this data. In practice, they are expected to
200 // be in a static local.
201 void InitializeRegisters(Flags flags, CodeEntrypointTag tag, int return_count,
202 int parameter_count, StackArgumentOrder stack_order,
203 int register_parameter_count,
204 const Register* registers,
205 const DoubleRegister* double_registers,
206 const Register* return_registers,
207 const DoubleRegister* return_double_registers);
208
209 // if machine_types is null, then an array of size
210 // (return_count + parameter_count) will be created with
211 // MachineType::AnyTagged() for each member.
212 //
213 // if machine_types is not null, then it should be of the size
214 // (return_count + parameter_count). Those members of the parameter array will
215 // be initialized from {machine_types}, and the rest initialized to
216 // MachineType::AnyTagged().
217 void InitializeTypes(const MachineType* machine_types,
218 int machine_types_length);
219
220 void Reset();
221
222 bool IsInitialized() const {
223 return IsInitializedRegisters() && IsInitializedTypes();
224 }
225
226 Flags flags() const { return flags_; }
227 CodeEntrypointTag tag() const { return tag_; }
228 int return_count() const { return return_count_; }
229 int param_count() const { return param_count_; }
230 int register_param_count() const { return register_param_count_; }
231 Register register_param(int index) const { return register_params_[index]; }
233 return double_register_params_[index];
234 }
235 Register register_return(int index) const { return register_returns_[index]; }
237 return double_register_returns_[index];
238 }
239 MachineType return_type(int index) const {
240 DCHECK_LT(index, return_count_);
241 return machine_types_[index];
242 }
243 MachineType param_type(int index) const {
244 DCHECK_LT(index, param_count_);
245 return machine_types_[return_count_ + index];
246 }
247 StackArgumentOrder stack_order() const { return stack_order_; }
248
250 DCHECK(allocatable_registers_.is_empty());
251 for (size_t i = 0; i < num; ++i) {
252 allocatable_registers_.set(registers[i]);
253 }
254 DCHECK(!allocatable_registers_.is_empty());
255 }
256
257 RegList allocatable_registers() const { return allocatable_registers_; }
258
259 private:
261 const bool initialized =
262 return_count_ != kUninitializedCount &&
263 param_count_ != kUninitializedCount &&
264 (register_param_count_ == 0 || register_params_ != nullptr);
265 // Register initialization happens before type initialization.
266 return initialized;
267 }
268 bool IsInitializedTypes() const {
269 const bool initialized = machine_types_ != nullptr;
270 // Register initialization happens before type initialization.
271 return initialized;
272 }
273
274#ifdef DEBUG
275 bool AllStackParametersAreTagged() const;
276#endif // DEBUG
277
278 int register_param_count_ = kUninitializedCount;
279 int return_count_ = kUninitializedCount;
280 int param_count_ = kUninitializedCount;
283 StackArgumentOrder stack_order_ = StackArgumentOrder::kDefault;
284
285 // Specifying the set of registers that could be used by the register
286 // allocator. Currently, it's only used by RecordWrite code stub.
288
289 // |registers_params_| defines registers that are used for parameter passing.
290 // |machine_types_| defines machine types for resulting values and incomping
291 // parameters.
292 // The register params array is owned by the caller, and it's expected that it
293 // is a static local stored in the caller function. The machine types are
294 // allocated dynamically by the InterfaceDescriptor and freed on destruction.
295 const Register* register_params_ = nullptr;
296 const DoubleRegister* double_register_params_ = nullptr;
297 const Register* register_returns_ = nullptr;
298 const DoubleRegister* double_register_returns_ = nullptr;
299 MachineType* machine_types_ = nullptr;
300};
301
303 public:
304 enum Key {
305#define DEF_ENUM(name, ...) name,
307#undef DEF_ENUM
308 NUMBER_OF_DESCRIPTORS
309 };
310
311 static void InitializeOncePerProcess();
312 static void TearDown();
313
316 return &call_descriptor_data_[key];
317 }
318
320 ptrdiff_t index = data - call_descriptor_data_;
321 DCHECK_LE(0, index);
322 DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
323 return static_cast<CallDescriptors::Key>(index);
324 }
325
326 private:
328 call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
329};
330
331#if defined(V8_TARGET_ARCH_IA32)
332// To support all possible cases, we must limit the number of register args for
333// TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
334// as the context register and ebx is the root register. One register must
335// remain available to store the jump/call target. Thus 3 registers remain for
336// arguments. The reason this applies to TFS builtins specifically is because
337// this becomes relevant for builtins used as targets of Torque function
338// pointers (which must have a register available to store the target).
339// TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
340// that comes with its own set of complications. It's possible, but requires
341// refactoring the calling convention of other existing stubs.
342constexpr int kMaxBuiltinRegisterParams = 4;
343constexpr int kMaxTFSBuiltinRegisterParams = 3;
344#else
347#endif
349constexpr int kJSBuiltinRegisterParams = 4;
350
351// Polymorphic base class for call interface descriptors, which defines getters
352// for the various descriptor properties via a runtime-loaded
353// CallInterfaceDescriptorData field.
355 public:
357
360
362 : data_(CallDescriptors::call_descriptor_data(key)) {}
363
364 Flags flags() const { return data()->flags(); }
365
366 CodeEntrypointTag tag() const { return data()->tag(); }
367
368 bool HasContextParameter() const {
369 return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
370 }
371
372 bool AllowVarArgs() const {
373 return flags() & CallInterfaceDescriptorData::kAllowVarArgs;
374 }
375
376 bool CalleeSaveRegisters() const {
377 return flags() & CallInterfaceDescriptorData::kCalleeSaveRegisters;
378 }
379
380 int GetReturnCount() const { return data()->return_count(); }
381
382 MachineType GetReturnType(int index) const {
383 DCHECK_LT(index, data()->return_count());
384 return data()->return_type(index);
385 }
386
387 int GetParameterCount() const { return data()->param_count(); }
388
390 return data()->register_param_count();
391 }
392
394 return data()->param_count() - data()->register_param_count();
395 }
396
398 DCHECK_LT(index, data()->register_param_count());
399 return data()->register_param(index);
400 }
401
403 DCHECK_LT(index, data()->register_param_count());
404 return data()->double_register_param(index);
405 }
406
407 Register GetRegisterReturn(int index) const {
408 DCHECK_LT(index, data()->return_count());
409 return data()->register_return(index);
410 }
411
413 DCHECK_LT(index, data()->return_count());
414 return data()->double_register_return(index);
415 }
416
417 MachineType GetParameterType(int index) const {
418 DCHECK_LT(index, data()->param_count());
419 return data()->param_type(index);
420 }
421
423 return data()->allocatable_registers();
424 }
425
427 return data()->stack_order();
428 }
429
430 static constexpr inline Register ContextRegister() {
431 return kContextRegister;
432 }
433
434 const char* DebugName() const;
435
436 bool operator==(const CallInterfaceDescriptor& other) const {
437 return data() == other.data();
438 }
439
440 protected:
441 const CallInterfaceDescriptorData* data() const { return data_; }
442
443 // Helper for defining the default register set.
444 //
445 // Use auto for the return type to allow different architectures to have
446 // differently sized default register arrays.
447 static constexpr inline auto DefaultRegisterArray();
448 static constexpr inline auto DefaultDoubleRegisterArray();
449 static constexpr inline auto DefaultReturnRegisterArray();
450 static constexpr inline auto DefaultReturnDoubleRegisterArray();
451 static constexpr inline std::array<Register, kJSBuiltinRegisterParams>
452 DefaultJSRegisterArray();
453
454 // Checks if float parameters are not assigned invalid registers.
456 for (int i = 0; i < data->register_param_count(); i++) {
457 if (IsFloatingPoint(data->param_type(i).representation())) {
458 if (!IsValidFloatParameterRegister(data->register_param(i))) {
459 return false;
460 }
461 }
462 }
463 return true;
464 }
465
466 bool IsValidFloatParameterRegister(Register reg);
467
468 private:
470};
471
472// CRTP base class for call interface descriptors, which defines static getters
473// for the various descriptor properties based on static values defined in the
474// subclass.
475template <typename DerivedDescriptor>
477 public:
478 // ===========================================================================
479 // The following are the descriptor's CRTP configuration points, overwritable
480 // by DerivedDescriptor.
481 static constexpr int kReturnCount =
483 static constexpr int kParameterCount =
485 static constexpr bool kNoContext = false;
486 static constexpr bool kAllowVarArgs = false;
487 static constexpr bool kNoStackScan = false;
489
490 // The set of registers available to the parameters, as a
491 // std::array<Register,N>. Can be larger or smaller than kParameterCount; if
492 // larger then any remaining registers are ignored; if smaller, any parameters
493 // after registers().size() will be stack registers.
494 //
495 // Defaults to CallInterfaceDescriptor::DefaultRegisterArray().
496 static constexpr inline auto registers();
497 static constexpr inline auto double_registers();
498 static constexpr inline auto return_registers();
499 static constexpr inline auto return_double_registers();
500
501 // An additional limit on the number of register parameters allowed. This is
502 // here so that it can be overwritten to kMaxTFSBuiltinRegisterParams for TFS
503 // builtins, see comment on kMaxTFSBuiltinRegisterParams above.
505
506 // If set to true, the descriptor will restrict the set of allocatable
507 // registers to the set returned by registers(). Then, it is expected that
508 // the first kParameterCount registers() are the parameters of the builtin.
509 static constexpr bool kRestrictAllocatableRegisters = false;
510
511 // If set to true, builtins will callee save the set returned by registers().
512 static constexpr bool kCalleeSaveRegisters = false;
513
514 // If set to true, the descriptor will define a kMachineTypes array with the
515 // types of each result value and parameter.
516 static constexpr bool kCustomMachineTypes = false;
517
518 // End of customization points.
519 // ===========================================================================
520
521 static constexpr inline Flags flags() {
522 return Flags((DerivedDescriptor::kNoContext
524 : 0) |
525 (DerivedDescriptor::kAllowVarArgs
527 : 0) |
528 (DerivedDescriptor::kNoStackScan
530 : 0) |
531 (DerivedDescriptor::kCalleeSaveRegisters
533 : 0));
534 }
535 static constexpr inline bool AllowVarArgs() {
536 return DerivedDescriptor::kAllowVarArgs;
537 }
538 static constexpr inline bool HasContextParameter() {
539 return !DerivedDescriptor::kNoContext;
540 }
541
542 static constexpr inline int GetReturnCount();
543 static constexpr inline int GetParameterCount();
544 static constexpr inline int GetRegisterParameterCount();
545 static constexpr inline int GetStackParameterCount();
546 static constexpr inline Register* GetRegisterData();
547 static constexpr inline Register GetRegisterParameter(int i);
548 static constexpr inline int GetStackParameterIndex(int i);
549 static constexpr inline MachineType GetParameterType(int i);
550
551 // Interface descriptors don't really support double registers.
552 // This reinterprets the i-th register as a double with the same code.
553 static constexpr inline DoubleRegister GetDoubleRegisterParameter(int i);
554
557
558#if DEBUG
559 // Overwritten in DerivedDescriptor.
560 static void Verify(CallInterfaceDescriptorData* data);
561 // Verify that the CallInterfaceDescriptorData contains the default
562 // argument registers for {argc} arguments.
563 static inline void VerifyArgumentRegisterCount(
564 CallInterfaceDescriptorData* data, int nof_expected_args);
565#endif
566
567 private:
568 // {CallDescriptors} is allowed to call the private {Initialize} method.
569 friend class CallDescriptors;
570
571 inline void Initialize(CallInterfaceDescriptorData* data);
572
573 // Set up the types of the descriptor. This is a static function, so that it
574 // is overwritable by subclasses. By default, all parameters have
575 // MachineType::AnyTagged() type.
578 data->InitializeTypes(nullptr, 0);
579 }
580};
581
582template <typename Descriptor>
584 : public StaticCallInterfaceDescriptor<Descriptor> {
585 public:
587 static constexpr inline auto registers();
588
591};
592
593template <Builtin kBuiltin>
595
596// Stub class replacing std::array<Register, 0>, as a workaround for MSVC's
597// https://github.com/microsoft/STL/issues/942
599 const Register* data() const { return nullptr; }
600 size_t size() const { return 0; }
601 Register operator[](size_t i) const { UNREACHABLE(); }
602};
603
604// Helper method for defining an array of unique registers for the various
605// Descriptor::registers() methods.
606template <typename... Registers>
607constexpr std::array<Register, 1 + sizeof...(Registers)> RegisterArray(
608 Register first_reg, Registers... regs) {
609 DCHECK(!AreAliased(first_reg, regs...));
610 return {first_reg, regs...};
611}
612constexpr EmptyRegisterArray RegisterArray() { return {}; }
613
614// Stub class replacing std::array<Register, 0>, as a workaround for MSVC's
615// https://github.com/microsoft/STL/issues/942
617 const DoubleRegister* data() const { return nullptr; }
618 size_t size() const { return 0; }
620};
621
622// Helper method for defining an array of unique registers for the various
623// Descriptor::double_registers() methods.
624template <typename... Registers>
625constexpr std::array<DoubleRegister, 1 + sizeof...(Registers)>
627 DCHECK(!AreAliased(first_reg, regs...));
628 return {first_reg, regs...};
629}
630
632
633#define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
634 public: \
635 /* StaticCallInterfaceDescriptor can call Initialize methods */ \
636 friend class StaticCallInterfaceDescriptor<name>; \
637 explicit name() : base(key()) {} \
638 static inline CallDescriptors::Key key();
639
640#define DECLARE_DEFAULT_DESCRIPTOR(name) \
641 DECLARE_DESCRIPTOR_WITH_BASE(name, StaticCallInterfaceDescriptor) \
642 static constexpr int kMaxRegisterParams = kMaxTFSBuiltinRegisterParams; \
643 \
644 protected: \
645 explicit name(CallDescriptors::Key key) \
646 : StaticCallInterfaceDescriptor(key) {} \
647 \
648 public:
649
650#define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name) \
651 DECLARE_DESCRIPTOR_WITH_BASE(name, StaticJSCallInterfaceDescriptor) \
652 protected: \
653 explicit name(CallDescriptors::Key key) \
654 : StaticJSCallInterfaceDescriptor(key) {} \
655 \
656 public:
657
658#define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
659 static constexpr int kReturnCount = return_count; \
660 enum ParameterIndices { \
661 __dummy = -1, /* to be able to pass zero arguments */ \
662 ##__VA_ARGS__, \
663 \
664 kParameterCount, \
665 kContext = kParameterCount /* implicit parameter */ \
666 };
667
668// This is valid only for builtins that use EntryFrame, which does not scan
669// stack arguments on GC.
670#define DEFINE_PARAMETERS_ENTRY(...) \
671 static constexpr bool kNoContext = true; \
672 static constexpr bool kNoStackScan = true; \
673 static constexpr StackArgumentOrder kStackArgumentOrder = \
674 StackArgumentOrder::kDefault; \
675 static constexpr int kReturnCount = 1; \
676 enum ParameterIndices { \
677 __dummy = -1, /* to be able to pass zero arguments */ \
678 ##__VA_ARGS__, \
679 \
680 kParameterCount \
681 };
682
683#define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
684
685#define DEFINE_PARAMETERS_NO_CONTEXT(...) \
686 DEFINE_PARAMETERS(__VA_ARGS__) \
687 static constexpr bool kNoContext = true;
688
689#define DEFINE_PARAMETERS_VARARGS(...) \
690 DEFINE_PARAMETERS(__VA_ARGS__) \
691 static constexpr bool kAllowVarArgs = true; \
692 static constexpr StackArgumentOrder kStackArgumentOrder = \
693 StackArgumentOrder::kJS;
694
695#define DEFINE_PARAMETERS_NO_CONTEXT_VARARGS(...) \
696 DEFINE_PARAMETERS_NO_CONTEXT(__VA_ARGS__) \
697 static constexpr bool kAllowVarArgs = true; \
698 static constexpr StackArgumentOrder kStackArgumentOrder = \
699 StackArgumentOrder::kJS;
700
701#define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \
702 DEFINE_RESULT_AND_PARAMETERS(return_count, ##__VA_ARGS__) \
703 static constexpr bool kNoContext = true;
704
705#define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
706 static constexpr bool kCustomMachineTypes = true; \
707 static constexpr MachineType kMachineTypes[] = {__VA_ARGS__}; \
708 static void InitializeTypes(CallInterfaceDescriptorData* data) { \
709 static_assert( \
710 kReturnCount + kParameterCount == arraysize(kMachineTypes), \
711 "Parameter names definition is not consistent with parameter types"); \
712 data->InitializeTypes(kMachineTypes, arraysize(kMachineTypes)); \
713 }
714
715#define DEFINE_PARAMETER_TYPES(...) \
716 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
717 ##__VA_ARGS__)
718
719// When the extra arguments described here are located in the stack, they are
720// just above the return address in the frame (first arguments).
721#define DEFINE_JS_PARAMETERS(...) \
722 static constexpr bool kAllowVarArgs = true; \
723 static constexpr int kReturnCount = 1; \
724 static constexpr StackArgumentOrder kStackArgumentOrder = \
725 StackArgumentOrder::kJS; \
726 enum ParameterIndices { \
727 kTarget, \
728 kNewTarget, \
729 kActualArgumentsCount, \
730 ##__VA_ARGS__, \
731 kParameterCount, \
732 kContext = kParameterCount /* implicit parameter */ \
733 };
734
735#define DEFINE_JS_PARAMETERS_NO_CONTEXT(...) \
736 static constexpr bool kAllowVarArgs = true; \
737 static constexpr bool kNoContext = true; \
738 static constexpr int kReturnCount = 1; \
739 static constexpr StackArgumentOrder kStackArgumentOrder = \
740 StackArgumentOrder::kJS; \
741 enum ParameterIndices { \
742 kTarget, \
743 kNewTarget, \
744 kActualArgumentsCount, \
745 ##__VA_ARGS__, \
746 kParameterCount, \
747 };
748
749#define DEFINE_JS_PARAMETER_TYPES(...) \
750 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */ \
751 MachineType::AnyTagged(), /* kNewTarget */ \
752 MachineType::Int32(), /* kActualArgumentsCount */ \
753 ##__VA_ARGS__)
754
755// Code/Builtins using this descriptor are referenced from inside the sandbox
756// through a code pointer and must therefore be exposed via the code pointer
757// table (CPT). They should use a code entrypoint tag which will be used to tag
758// the entry in the CPT and will be checked to match the tag expected at the
759// callsite. Only "compatible" builtins should use the same code entrypoint tag
760// as it must be assumed that an attacker can swap code pointers (the indices
761// into the CPT) and therefore can invoke all builtins that use the same tag
762// from a given callsite.
763#define SANDBOX_EXPOSED_DESCRIPTOR(tag) \
764 static constexpr CodeEntrypointTag kEntrypointTag = tag;
765
766// Code/Builtins using this descriptor are not referenced from inside the
767// sandbox but only called directly from other code. They are therefore not
768// exposed to the sandbox via the CPT and so use the kInvalidEntrypointTag.
769#define INTERNAL_DESCRIPTOR() \
770 static constexpr CodeEntrypointTag kEntrypointTag = kInvalidEntrypointTag;
771
772#define DECLARE_DESCRIPTOR(name) \
773 DECLARE_DESCRIPTOR_WITH_BASE(name, StaticCallInterfaceDescriptor) \
774 protected: \
775 explicit name(CallDescriptors::Key key) \
776 : StaticCallInterfaceDescriptor(key) {} \
777 \
778 public:
779
781 : public StaticCallInterfaceDescriptor<VoidDescriptor> {
782 public:
783 // The void descriptor could (and indeed probably should) also be NO_CONTEXT,
784 // but this breaks some code assembler unittests.
789
790 static constexpr auto registers();
791};
792
793// Marks deoptimization entry builtins. Precise calling conventions currently
794// differ based on the platform.
795// TODO(jgruber): Once this is unified, we could create a better description
796// here.
798
799// TODO(jgruber): Consider filling in the details here; however, this doesn't
800// make too much sense as long as the descriptor isn't used or verified.
802
803// TODO(jgruber): Consider filling in the details here; however, this doesn't
804// make too much sense as long as the descriptor isn't used or verified.
806
807// Dummy descriptor that marks builtins with C calling convention.
808// TODO(jgruber): Define real descriptors for C calling conventions.
816
817// TODO(jgruber): Consider filling in the details here; however, this doesn't
818// make too much sense as long as the descriptor isn't used or verified.
827
828// TODO(wasm): Consider filling in details / defining real descriptors for all
829// builtins still using this placeholder descriptor.
838
840 : public StaticCallInterfaceDescriptor<WasmHandleStackOverflowDescriptor> {
841 public:
843 DEFINE_PARAMETERS_NO_CONTEXT(kFrameBase, kGap)
845 MachineType::Pointer(), // kFrameBase
846 MachineType::Uint32()) // kGap
848
849 static constexpr inline Register FrameBaseRegister();
850 static constexpr inline Register GapRegister();
851};
852
855 public:
857 DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
858 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
859 MachineType::IntPtr()) // kRequestedSize
861
862 static constexpr auto registers();
863};
864
874
875// This descriptor defines the JavaScript calling convention and is used by all
876// code that can be installed on a JSFunction. Target, new.target, argc,
877// context and potentially the dispatch entry are passed in registers while
878// receiver and the rest of the JS arguments are passed on the stack.
879#ifdef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
881 : public StaticJSCallInterfaceDescriptor<JSTrampolineDescriptor> {
882 public:
883 SANDBOX_EXPOSED_DESCRIPTOR(kJSEntrypointTag)
884 DEFINE_JS_PARAMETERS(kDispatchHandle)
885 DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
886
888
889 static constexpr auto registers();
890};
891#else
903#endif
904
905// Descriptor used for code using the RegExp calling convention, in particular
906// the RegExp interpreter trampolines.
915
917 : public StaticCallInterfaceDescriptor<ContextOnlyDescriptor> {
918 public:
923
924 static constexpr auto registers();
925};
926
928 : public StaticCallInterfaceDescriptor<NoContextDescriptor> {
929 public:
934
935 static constexpr auto registers();
936};
937
938// LoadDescriptor is used by all stubs that implement Load ICs.
939class LoadDescriptor : public StaticCallInterfaceDescriptor<LoadDescriptor> {
940 public:
942 DEFINE_PARAMETERS(kReceiver, kName, kSlot)
943 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
944 MachineType::AnyTagged(), // kName
945 MachineType::TaggedSigned()) // kSlot
947
948 static constexpr inline Register ReceiverRegister();
949 static constexpr inline Register NameRegister();
950 static constexpr inline Register SlotRegister();
951
952 static constexpr auto registers();
953};
954
955// LoadBaselineDescriptor is a load descriptor that does not take a context as
956// input.
959 public:
962 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
963 MachineType::AnyTagged(), // kName
964 MachineType::TaggedSigned()) // kSlot
966
967 static constexpr auto registers();
968};
969
972 public:
974 DEFINE_PARAMETERS(kName, kICKind)
975 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
976 MachineType::TaggedSigned()) // kICKind
978
979 static constexpr inline Register ICKindRegister();
980
981 static constexpr auto registers();
982};
983
986 public:
988 DEFINE_PARAMETERS(kReceiver, kName, kICKind)
989 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
990 MachineType::AnyTagged(), // kName
991 MachineType::TaggedSigned()) // kICKind
993
994 static constexpr inline Register ICKindRegister();
995
996 static constexpr auto registers();
997};
998
1001 public:
1003 DEFINE_PARAMETERS(kName, kSlot)
1005 MachineType::TaggedSigned()) // kSlot
1007
1008 static constexpr auto registers();
1009};
1010
1013 public:
1015 DEFINE_PARAMETERS_NO_CONTEXT(kName, kSlot)
1017 MachineType::TaggedSigned()) // kSlot
1019
1020 static constexpr auto registers();
1021};
1022
1025 public:
1027 DEFINE_PARAMETERS(kName, kDepth, kSlot, kVector)
1028 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
1029 MachineType::AnyTagged(), // kDepth
1030 MachineType::AnyTagged(), // kSlot
1031 MachineType::AnyTagged()) // kVector
1033};
1034
1036 : public StaticCallInterfaceDescriptor<LookupTrampolineDescriptor> {
1037 public:
1039 DEFINE_PARAMETERS(kName, kDepth, kSlot)
1040 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
1041 MachineType::AnyTagged(), // kDepth
1042 MachineType::AnyTagged()) // kSlot
1044};
1045
1047 : public StaticCallInterfaceDescriptor<LookupBaselineDescriptor> {
1048 public:
1050 DEFINE_PARAMETERS_NO_CONTEXT(kName, kDepth, kSlot)
1051 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
1052 MachineType::AnyTagged(), // kDepth
1053 MachineType::AnyTagged()) // kSlot
1055};
1056
1059 MaglevOptimizeCodeOrTailCallOptimizedCodeSlotDescriptor> {
1060 public:
1062 DEFINE_PARAMETERS_NO_CONTEXT(kFlags, kFeedbackVector, kTemporary)
1064 MachineType::TaggedPointer(), // kFeedbackVector
1065 MachineType::AnyTagged()) // kTemporary
1067
1068 static constexpr inline Register FlagsRegister();
1069 static constexpr inline Register FeedbackVectorRegister();
1070
1071 static constexpr inline Register TemporaryRegister();
1072
1073 static constexpr inline auto registers();
1074};
1075
1077 public:
1079 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
1080 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1081 MachineType::AnyTagged(), // kName
1082 MachineType::AnyTagged(), // kValue
1083 MachineType::TaggedSigned()) // kSlot
1085
1086 static constexpr inline Register ReceiverRegister();
1087 static constexpr inline Register NameRegister();
1088 static constexpr inline Register ValueRegister();
1089 static constexpr inline Register SlotRegister();
1090
1091 static constexpr auto registers();
1092};
1093
1096 public:
1099 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1100 MachineType::AnyTagged(), // kName
1101 MachineType::AnyTagged()) // kValue
1103
1104 static constexpr auto registers();
1105};
1106
1109 public:
1112 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1113 MachineType::AnyTagged(), // kName
1114 MachineType::AnyTagged(), // kValue
1115 MachineType::TaggedSigned()) // kSlot
1117
1118 static constexpr auto registers();
1119};
1120
1123 public:
1125 DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
1126 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1127 MachineType::AnyTagged(), // kName
1128 MachineType::AnyTagged(), // kMap
1129 MachineType::AnyTagged(), // kValue
1130 MachineType::TaggedSigned(), // kSlot
1131 MachineType::AnyTagged()) // kVector
1133
1134 static constexpr inline Register MapRegister();
1135
1136 static constexpr auto registers();
1137};
1138
1141 public:
1143 DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
1144 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1145 MachineType::AnyTagged(), // kName
1146 MachineType::AnyTagged(), // kValue
1147 MachineType::TaggedSigned(), // kSlot
1148 MachineType::AnyTagged()) // kVector
1150
1151 static constexpr inline Register VectorRegister();
1152
1153 static constexpr auto registers();
1154};
1155
1158 public:
1160 DEFINE_PARAMETERS(kName, kValue, kSlot)
1162 MachineType::AnyTagged(), // kValue
1163 MachineType::TaggedSigned()) // kSlot
1165
1166 static constexpr auto registers();
1167};
1168
1171 public:
1175 MachineType::AnyTagged(), // kValue
1176 MachineType::TaggedSigned()) // kSlot
1178
1179 static constexpr auto registers();
1180};
1181
1184 public:
1186 DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
1188 MachineType::AnyTagged(), // kValue
1189 MachineType::TaggedSigned(), // kSlot
1190 MachineType::AnyTagged()) // kVector
1192
1193 static constexpr auto registers();
1194};
1195
1198 public:
1200 DEFINE_PARAMETERS(kReceiver, kName, kValue, kFlags, kSlot)
1201 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1202 MachineType::AnyTagged(), // kName
1203 MachineType::AnyTagged(), // kValue
1204 MachineType::TaggedSigned(), // kFlags
1205 MachineType::TaggedSigned()) // kSlot
1207
1208 static constexpr inline Register FlagsRegister();
1209
1210 static constexpr auto registers();
1211};
1212
1215 public:
1217 DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kName, kValue, kFlags, kSlot)
1218 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1219 MachineType::AnyTagged(), // kName
1220 MachineType::AnyTagged(), // kValue
1221 MachineType::TaggedSigned(), // kFlags
1222 MachineType::TaggedSigned()) // kSlot
1224
1225 static constexpr auto registers();
1226};
1227
1230 public:
1232 DEFINE_PARAMETERS(kReceiver, kName, kValue, kFlags,
1233 kSlot, // register argument
1234 kVector // stack argument
1235 )
1236 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1237 MachineType::AnyTagged(), // kName
1238 MachineType::AnyTagged(), // kValue
1239 MachineType::TaggedSigned(), // kFlags
1240 MachineType::TaggedSigned(), // kSlot
1241 MachineType::AnyTagged()) // kVector
1243
1244 static constexpr auto registers();
1245};
1246
1248 : public StaticCallInterfaceDescriptor<LoadWithVectorDescriptor> {
1249 public:
1251 // TODO(v8:9497): Revert the Machine type for kSlot to the
1252 // TaggedSigned once Torque can emit better call descriptors
1253 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
1254 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1255 MachineType::AnyTagged(), // kName
1256 MachineType::AnyTagged(), // kSlot
1257 MachineType::AnyTagged()) // kVector
1259
1260 static constexpr inline Register VectorRegister();
1261
1262 static constexpr auto registers();
1263};
1264
1267 public:
1270 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1271 MachineType::AnyTagged(), // kName
1272 MachineType::TaggedSigned()) // kSlot
1274
1275 static constexpr inline Register ReceiverRegister();
1276 static constexpr inline Register NameRegister();
1277 static constexpr inline Register SlotRegister();
1278
1279 static constexpr auto registers();
1280};
1281
1284 public:
1286 DEFINE_PARAMETERS(kReceiver, kName, kSlot)
1287 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1288 MachineType::AnyTagged(), // kName
1289 MachineType::TaggedSigned()) // kSlot
1291
1292 static constexpr auto registers();
1293};
1294
1297 public:
1299 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
1300 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1301 MachineType::AnyTagged(), // kName
1302 MachineType::TaggedSigned(), // kSlot
1303 MachineType::AnyTagged()) // kVector
1305
1306 static constexpr inline Register VectorRegister();
1307
1308 static constexpr auto registers();
1309};
1310
1314 public:
1316 DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kName, kEnumIndex, kCacheType, kSlot)
1317 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1318 MachineType::AnyTagged(), // kName
1319 MachineType::TaggedSigned(), // kEnumIndex
1320 MachineType::AnyTagged(), // kCacheType
1321 MachineType::TaggedSigned()) // kSlot
1323
1324 static constexpr inline Register EnumIndexRegister();
1325 static constexpr inline Register CacheTypeRegister();
1326 static constexpr inline Register SlotRegister();
1327
1328 static constexpr auto registers();
1329};
1330
1333 public:
1335 DEFINE_PARAMETERS(kReceiver, kName, kEnumIndex, kCacheType, kSlot, kVector)
1336 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1337 MachineType::AnyTagged(), // kName
1338 MachineType::TaggedSigned(), // kEnumIndex
1339 MachineType::AnyTagged(), // kCacheType
1340 MachineType::TaggedSigned(), // kSlot
1341 MachineType::AnyTagged()) // kVector
1343
1344 static constexpr auto registers();
1345};
1346
1349 public:
1352 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1353 MachineType::AnyTagged(), // kName
1354 MachineType::TaggedSigned()) // kSlot
1356
1357 static constexpr inline Register ReceiverRegister();
1358 static constexpr inline Register NameRegister();
1359 static constexpr inline Register SlotRegister();
1360
1361 static constexpr auto registers();
1362};
1363
1366 public:
1368 DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
1369 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1370 MachineType::AnyTagged(), // kName
1371 MachineType::TaggedSigned(), // kSlot
1372 MachineType::AnyTagged()) // kVector
1374
1375 static constexpr inline Register VectorRegister();
1376
1377 static constexpr auto registers();
1378};
1379
1380// Like LoadWithVectorDescriptor, except we pass the receiver (the object which
1381// should be used as the receiver for accessor function calls) and the lookup
1382// start object separately.
1386 public:
1388 // TODO(v8:9497): Revert the Machine type for kSlot to the
1389 // TaggedSigned once Torque can emit better call descriptors
1390 DEFINE_PARAMETERS(kReceiver, kLookupStartObject, kName, kSlot, kVector)
1391 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1392 MachineType::AnyTagged(), // kLookupStartObject
1393 MachineType::AnyTagged(), // kName
1394 MachineType::AnyTagged(), // kSlot
1395 MachineType::AnyTagged()) // kVector
1397
1398 static constexpr inline Register LookupStartObjectRegister();
1399
1400 static constexpr auto registers();
1401};
1402
1405 public:
1407 // TODO(v8:9497): Revert the Machine type for kSlot to the
1408 // TaggedSigned once Torque can emit better call descriptors
1409 DEFINE_PARAMETERS_NO_CONTEXT(kReceiver, kLookupStartObject, kName, kSlot)
1410 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1411 MachineType::AnyTagged(), // kLookupStartObject
1412 MachineType::AnyTagged(), // kName
1413 MachineType::AnyTagged()) // kSlot
1415
1416 static constexpr auto registers();
1417};
1418
1421 public:
1423 DEFINE_PARAMETERS(kName, kSlot, kVector)
1425 MachineType::TaggedSigned(), // kSlot
1426 MachineType::AnyTagged()) // kVector
1428
1429 static constexpr inline Register VectorRegister();
1430
1431 static constexpr auto registers();
1432};
1433
1436 public:
1438 DEFINE_PARAMETERS(kTarget, kNewTarget)
1439 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1440 MachineType::AnyTagged()) // kNewTarget
1442
1443 static constexpr inline Register TargetRegister();
1444 static constexpr inline Register NewTargetRegister();
1445
1446 static constexpr auto registers();
1447};
1448
1451 public:
1454 DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
1455 MachineType::Pointer()) // kSlotAddress
1456
1458 static constexpr auto registers();
1459 static constexpr bool kRestrictAllocatableRegisters = true;
1460 static constexpr bool kCalleeSaveRegisters = true;
1461 static constexpr inline Register ObjectRegister();
1462 static constexpr inline Register SlotAddressRegister();
1463 // A temporary register used in helpers.
1464 static constexpr inline Register ValueRegister();
1465 static constexpr inline RegList ComputeSavedRegisters(
1466 Register object, Register slot_address = no_reg);
1467#if DEBUG
1468 static void Verify(CallInterfaceDescriptorData* data);
1469#endif
1470};
1471
1472// Write barriers for indirect pointer field writes require one additional
1473// parameter (the IndirectPointerTag associated with the stored field).
1474// Otherwise, they are identical to the other write barriers.
1477 IndirectPointerWriteBarrierDescriptor> {
1478 public:
1480 DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress, kIndirectPointerTag)
1481 DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
1482 MachineType::Pointer(), // kSlotAddress
1483 MachineType::Uint64()) // kIndirectPointerTag
1484
1486 static constexpr auto registers();
1487 static constexpr bool kRestrictAllocatableRegisters = true;
1488 static constexpr bool kCalleeSaveRegisters = true;
1489 static constexpr inline Register ObjectRegister();
1490 static constexpr inline Register SlotAddressRegister();
1491 static constexpr inline Register IndirectPointerTagRegister();
1492 static constexpr inline RegList ComputeSavedRegisters(
1493 Register object, Register slot_address = no_reg);
1494#if DEBUG
1495 static void Verify(CallInterfaceDescriptorData* data);
1496#endif
1497};
1498
1499#ifdef V8_IS_TSAN
1500class TSANStoreDescriptor final
1501 : public StaticCallInterfaceDescriptor<TSANStoreDescriptor> {
1502 public:
1504 DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kValue)
1505 DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kAddress
1506 MachineType::AnyTagged()) // kValue
1507
1508 DECLARE_DESCRIPTOR(TSANStoreDescriptor)
1509
1510 static constexpr auto registers();
1511 static constexpr bool kRestrictAllocatableRegisters = true;
1512};
1513
1514class TSANLoadDescriptor final
1515 : public StaticCallInterfaceDescriptor<TSANLoadDescriptor> {
1516 public:
1519 DEFINE_PARAMETER_TYPES(MachineType::Pointer()) // kAddress
1520
1521 DECLARE_DESCRIPTOR(TSANLoadDescriptor)
1522
1523 static constexpr auto registers();
1524 static constexpr bool kRestrictAllocatableRegisters = true;
1525};
1526
1527#endif // V8_IS_TSAN
1528
1530 : public StaticCallInterfaceDescriptor<TypeConversionDescriptor> {
1531 public:
1533 DEFINE_PARAMETERS(kArgument)
1534 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1536
1537 static constexpr inline Register ArgumentRegister();
1538
1539 static constexpr auto registers();
1540};
1541
1543 : public StaticCallInterfaceDescriptor<TypeConversionNoContextDescriptor> {
1544 public:
1547 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1549
1550 static constexpr auto registers();
1551};
1552
1554 : public StaticCallInterfaceDescriptor<TypeConversion_BaselineDescriptor> {
1555 public:
1557 DEFINE_PARAMETERS_NO_CONTEXT(kArgument, kSlot)
1558 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::UintPtr())
1560};
1561
1563 : public StaticCallInterfaceDescriptor<SingleParameterOnStackDescriptor> {
1564 public:
1566 DEFINE_PARAMETERS(kArgument)
1567 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1569
1570 static constexpr auto registers();
1571};
1572
1575 AsyncFunctionStackParameterDescriptor> {
1576 public:
1578 DEFINE_PARAMETERS(kPromise, kResult)
1579 DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
1581
1582 static constexpr auto registers();
1583};
1584
1588 public:
1590 DEFINE_PARAMETERS(kReceiver, kCallSlot, kFeedback, kResult)
1592 MachineType::AnyTagged(), MachineType::AnyTagged())
1594
1595 static constexpr auto registers();
1596};
1597
1605
1607 : public StaticCallInterfaceDescriptor<TypeofDescriptor> {
1608 public:
1611 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1613
1614 static constexpr inline auto registers();
1615};
1616
1618 : public StaticCallInterfaceDescriptor<CallTrampolineDescriptor> {
1619 public:
1621 DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount)
1622 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
1623 MachineType::Int32()) // kActualArgumentsCount
1625
1626 static constexpr inline auto registers();
1627};
1628
1632 public:
1634 DEFINE_PARAMETERS_VARARGS(kSource, kExcludedPropertyCount)
1635 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kSource
1636 MachineType::AnyTagged()) // kExcludedPropertyCount
1638
1639 static constexpr inline auto registers();
1640};
1641
1645 public:
1647 DEFINE_PARAMETERS(kSource, kExcludedPropertyCount, kExcludedPropertyBase)
1648 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kSource
1649 MachineType::IntPtr(),
1650 MachineType::IntPtr()) // kExcludedPropertyCount
1652
1653 static constexpr inline auto registers();
1654};
1655
1658 public:
1660 DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kArgumentsLength,
1661 kArgumentsList)
1662 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1663 MachineType::Int32(), // kActualArgumentsCount
1664 MachineType::Int32(), // kArgumentsLength
1665 MachineType::AnyTagged()) // kArgumentsList
1667
1668 static constexpr inline auto registers();
1669};
1670
1672 : public StaticCallInterfaceDescriptor<CallForwardVarargsDescriptor> {
1673 public:
1675 DEFINE_PARAMETERS_VARARGS(kTarget, kActualArgumentsCount, kStartIndex)
1676 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1677 MachineType::Int32(), // kActualArgumentsCount
1678 MachineType::Int32()) // kStartIndex
1680
1681 static constexpr inline auto registers();
1682};
1683
1686 public:
1688 DEFINE_PARAMETERS_VARARGS(kFunctionTemplateInfo, kArgumentsCount)
1689 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunctionTemplateInfo
1690 MachineType::Int32()) // kArgumentsCount
1692
1693 static constexpr inline auto registers();
1694};
1695
1699 public:
1701 DEFINE_PARAMETERS_VARARGS(kFunctionTemplateInfo, kArgumentsCount,
1702 kTopmostScriptHavingContext)
1704 MachineType::AnyTagged(), // kFunctionTemplateInfo
1705 MachineType::Int32(), // kArgumentsCount
1706 MachineType::AnyTagged()) // kTopmostScriptHavingContext
1708
1709 static constexpr inline auto registers();
1710};
1711
1713 : public StaticCallInterfaceDescriptor<CallWithSpreadDescriptor> {
1714 public:
1716 DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread)
1717 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1718 MachineType::Int32(), // kArgumentsCount
1719 MachineType::AnyTagged()) // kSpread
1721
1722 static constexpr inline auto registers();
1723};
1724
1727 public:
1729 DEFINE_PARAMETERS_NO_CONTEXT_VARARGS(kTarget, kArgumentsCount, kSpread, kSlot)
1730 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1731 MachineType::Int32(), // kArgumentsCount
1732 MachineType::AnyTagged(), // kSpread
1733 MachineType::UintPtr()) // kSlot
1735};
1736
1739 CallWithSpread_WithFeedbackDescriptor> {
1740 public:
1742 DEFINE_PARAMETERS_VARARGS(kTarget, kArgumentsCount, kSpread, kSlot,
1743 kFeedbackVector, kReceiver)
1744 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1745 MachineType::Int32(), // kArgumentsCount
1746 MachineType::AnyTagged(), // kSpread
1747 MachineType::UintPtr(), // kSlot
1748 MachineType::AnyTagged(), // kFeedbackVector
1749 MachineType::AnyTagged()) // kReceiver
1751};
1752
1754 : public StaticCallInterfaceDescriptor<CallWithArrayLikeDescriptor> {
1755 public:
1757 DEFINE_PARAMETERS(kTarget, kArgumentsList)
1758 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1759 MachineType::AnyTagged()) // kArgumentsList
1761
1762 static constexpr inline auto registers();
1763};
1764
1768 public:
1770 DEFINE_PARAMETERS(kTarget, kArgumentsList, kSlot, kFeedbackVector, kReceiver)
1771 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1772 MachineType::AnyTagged(), // kArgumentsList
1773 MachineType::UintPtr(), // kSlot
1774 MachineType::AnyTagged(), // kFeedbackVector
1775 MachineType::AnyTagged()) // kReceiver
1777};
1778
1779// TODO(ishell): consider merging this with ArrayConstructorDescriptor
1781 : public StaticCallInterfaceDescriptor<ConstructStubDescriptor> {
1782 public:
1786
1787 // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
1789
1790 static constexpr inline auto registers();
1791};
1792
1794 : public StaticCallInterfaceDescriptor<ConstructVarargsDescriptor> {
1795 public:
1797 DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
1799 MachineType::AnyTagged()) // kArgumentsList
1800
1802
1803 static constexpr inline auto registers();
1804};
1805
1808 public:
1810 DEFINE_JS_PARAMETERS(kStartIndex)
1811 DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
1813
1814 static constexpr inline auto registers();
1815};
1816
1818 : public StaticCallInterfaceDescriptor<ConstructWithSpreadDescriptor> {
1819 public:
1822 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1824
1825 static constexpr inline auto registers();
1826};
1827
1830 ConstructWithSpread_BaselineDescriptor> {
1831 public:
1834 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged(), // kSpread
1835 MachineType::AnyTagged()) // kSlot
1837};
1838
1841 ConstructWithSpread_WithFeedbackDescriptor> {
1842 public:
1844 DEFINE_JS_PARAMETERS(kSpread, kSlot, kVector)
1845 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged(), // kSpread
1846 MachineType::AnyTagged(), // kSlot
1847 MachineType::AnyTagged()) // kVector
1849};
1850
1852 : public StaticCallInterfaceDescriptor<ConstructWithArrayLikeDescriptor> {
1853 public:
1855 DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
1856 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1857 MachineType::AnyTagged(), // kNewTarget
1858 MachineType::AnyTagged()) // kArgumentsList
1860
1861 static constexpr inline auto registers();
1862};
1863
1866 public:
1868 DEFINE_PARAMETERS(kConstructor, kNewTarget)
1869 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kConstructor
1870 MachineType::AnyTagged()) // kNewTarget
1872
1873 static constexpr inline auto registers();
1874};
1875
1879 public:
1881 DEFINE_PARAMETERS(kTarget, kNewTarget, kSlot)
1882 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1883 MachineType::AnyTagged(), // kNewTarget
1884 MachineType::AnyTagged()) // kSlot
1886};
1887
1890 ConstructForwardAllArgs_WithFeedbackDescriptor> {
1891 public:
1893 DEFINE_PARAMETERS(kTarget, kNewTarget, kSlot, kVector)
1894 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
1895 MachineType::AnyTagged(), // kNewTarget
1896 MachineType::AnyTagged(), // kSlot
1897 MachineType::AnyTagged()) // kVector
1899};
1900
1901class AbortDescriptor : public StaticCallInterfaceDescriptor<AbortDescriptor> {
1902 public:
1904 DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
1905 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
1907
1908 static constexpr inline auto registers();
1909};
1910
1912 : public StaticJSCallInterfaceDescriptor<ArrayConstructorDescriptor> {
1913 public:
1915 DEFINE_JS_PARAMETERS(kAllocationSite)
1916 DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
1917
1919};
1920
1923 ArrayNArgumentsConstructorDescriptor> {
1924 public:
1926 // This descriptor declares only register arguments while respective number
1927 // of JS arguments stay on the expression stack.
1928 // The ArrayNArgumentsConstructor builtin does not access stack arguments
1929 // directly it just forwards them to the runtime function.
1930 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
1931 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction,
1932 MachineType::AnyTagged(), // kAllocationSite
1933 MachineType::Int32()) // kActualArgumentsCount
1935
1936 static constexpr auto registers();
1937};
1938
1942 public:
1944 // This descriptor declares same register arguments as the parent
1945 // ArrayNArgumentsConstructorDescriptor and it declares indices for
1946 // JS arguments passed on the expression stack.
1947 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1948 kFunctionParameter)
1949 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
1950 MachineType::AnyTagged(), // kAllocationSite
1951 MachineType::Int32(), // kActualArgumentsCount
1952 MachineType::AnyTagged()) // kFunctionParameter
1954
1955 static constexpr auto registers();
1956};
1957
1960 ArraySingleArgumentConstructorDescriptor> {
1961 public:
1963 // This descriptor declares same register arguments as the parent
1964 // ArrayNArgumentsConstructorDescriptor and it declares indices for
1965 // JS arguments passed on the expression stack.
1966 DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
1967 kArraySizeSmiParameter, kReceiverParameter)
1968 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
1969 MachineType::AnyTagged(), // kAllocationSite
1970 MachineType::Int32(), // kActualArgumentsCount
1971 // JS arguments on the stack
1972 MachineType::AnyTagged(), // kArraySizeSmiParameter
1973 MachineType::AnyTagged()) // kReceiverParameter
1975
1976 static constexpr auto registers();
1977};
1978
1980 : public StaticCallInterfaceDescriptor<CompareDescriptor> {
1981 public:
1983 DEFINE_PARAMETERS(kLeft, kRight)
1985
1986 static constexpr inline auto registers();
1987};
1988
1990 : public StaticCallInterfaceDescriptor<CompareNoContextDescriptor> {
1991 public:
1993 DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight)
1995
1996 static constexpr inline auto registers();
1997};
1998
2000 : public StaticCallInterfaceDescriptor<StringEqualDescriptor> {
2001 public:
2003 DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kLength)
2004 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kLeft
2005 MachineType::AnyTagged(), // kRight
2006 MachineType::IntPtr()) // kLength
2008};
2009
2011 : public StaticCallInterfaceDescriptor<BinaryOpDescriptor> {
2012 public:
2014 DEFINE_PARAMETERS(kLeft, kRight)
2016
2017 static constexpr inline auto registers();
2018};
2019
2021 : public StaticCallInterfaceDescriptor<BinaryOp_BaselineDescriptor> {
2022 public:
2024 DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kSlot)
2026 MachineType::AnyTagged(), // kRight
2027 MachineType::UintPtr()) // kSlot
2029
2030 static constexpr inline auto registers();
2031};
2032
2035 public:
2037 DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kSlot)
2039 MachineType::TaggedSigned(), // kRight
2040 MachineType::UintPtr()) // kSlot
2042
2043 static constexpr inline auto registers();
2044};
2045
2048 public:
2051 // TODO(turbofan): Return untagged value here.
2053 MachineType::TaggedPointer(), // result string
2054 MachineType::AnyTagged(), // kReceiver
2055 MachineType::IntPtr()) // kPosition
2057};
2058
2060 : public StaticCallInterfaceDescriptor<StringSubstringDescriptor> {
2061 public:
2064 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kString
2065 MachineType::IntPtr(), // kFrom
2066 MachineType::IntPtr()) // kTo
2067
2068 // TODO(turbofan): Allow builtins to return untagged values.
2070};
2071
2073 : public StaticJSCallInterfaceDescriptor<CppBuiltinAdaptorDescriptor> {
2074 public:
2076 DEFINE_JS_PARAMETERS(kCFunction)
2077 DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
2079};
2080
2083 CreateFromSlowBoilerplateHelperDescriptor> {
2084 public:
2086 DEFINE_RESULT_AND_PARAMETERS(2, kAllocationSite, kBoilerplate)
2088 MachineType::AnyTagged(), // result 1 (object)
2089 MachineType::AnyTagged(), // result 2 (allocation site)
2090 MachineType::AnyTagged(), // kAllocationSite
2091 MachineType::AnyTagged()) // kBoilerplate
2093};
2094
2096 : public StaticCallInterfaceDescriptor<CEntry1ArgvOnStackDescriptor> {
2097 public:
2099 DEFINE_PARAMETERS(kArity, // register argument
2100 kCFunction, // register argument
2101 kPadding, // stack argument 1 (just padding)
2102 kArgcSmi, // stack argument 2
2103 kTargetCopy, // stack argument 3
2104 kNewTargetCopy) // stack argument 4
2105 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kArity
2106 MachineType::Pointer(), // kCFunction
2107 MachineType::AnyTagged(), // kPadding
2108 MachineType::AnyTagged(), // kArgcSmi
2109 MachineType::AnyTagged(), // kTargetCopy
2110 MachineType::AnyTagged()) // kNewTargetCopy
2112
2113 static constexpr auto registers();
2114};
2115
2117 : public StaticCallInterfaceDescriptor<CallApiCallbackOptimizedDescriptor> {
2118 public:
2120 DEFINE_PARAMETERS_VARARGS(kApiFunctionAddress, kActualArgumentsCount,
2121 kFunctionTemplateInfo)
2122 // receiver is implicit stack argument 1
2123 // argv are implicit stack arguments [2, 2 + kArgc[
2124 DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kApiFunctionAddress
2125 MachineType::Int32(), // kActualArgumentsCount
2126 MachineType::AnyTagged()) // kFunctionTemplateInfo
2128
2129 static constexpr inline Register ApiFunctionAddressRegister();
2130 static constexpr inline Register ActualArgumentsCountRegister();
2131 static constexpr inline Register FunctionTemplateInfoRegister();
2132
2133 static constexpr inline auto registers();
2134};
2135
2137 : public StaticCallInterfaceDescriptor<CallApiCallbackGenericDescriptor> {
2138 public:
2140 DEFINE_PARAMETERS_VARARGS(kActualArgumentsCount, kTopmostScriptHavingContext,
2141 kFunctionTemplateInfo)
2142 // receiver is implicit stack argument 1
2143 // argv are implicit stack arguments [2, 2 + kArgc[
2145 MachineType::Int32(), // kActualArgumentsCount
2146 MachineType::AnyTagged(), // kTopmostScriptHavingContext
2147 MachineType::AnyTagged()) // kFunctionTemplateInfo
2149
2150 static constexpr inline Register ActualArgumentsCountRegister();
2151 static constexpr inline Register TopmostScriptHavingContextRegister();
2152 static constexpr inline Register FunctionTemplateInfoRegister();
2153
2154 static constexpr inline auto registers();
2155};
2156
2158 : public StaticCallInterfaceDescriptor<ApiGetterDescriptor> {
2159 public:
2162 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
2163 MachineType::AnyTagged(), // kHolder
2164 MachineType::AnyTagged()) // kCallback
2166
2167 static constexpr inline Register ReceiverRegister();
2168 static constexpr inline Register HolderRegister();
2169 static constexpr inline Register CallbackRegister();
2170
2171 static constexpr auto registers();
2172};
2173
2174// TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
2177 public:
2180 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kObject
2181 MachineType::AnyTagged()) // kKey
2183
2184 static constexpr inline Register ObjectRegister();
2185 static constexpr inline Register KeyRegister();
2186
2187 static constexpr auto registers();
2188};
2189
2193 public:
2195 DEFINE_PARAMETERS_NO_CONTEXT(kCalleeContext, kClosure,
2196 kJavaScriptCallArgCount, kStackFrameSize,
2197 kJavaScriptCallNewTarget,
2198 kInterpreterBytecodeArray)
2199 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kCalleeContext
2200 MachineType::AnyTagged(), // kClosure
2201 MachineType::Int32(), // kJavaScriptCallArgCount
2202 MachineType::Int32(), // kStackFrameSize
2203 MachineType::AnyTagged(), // kJavaScriptCallNewTarget
2204 MachineType::AnyTagged()) // kInterpreterBytecodeArray
2206
2207 static constexpr inline auto registers();
2208
2209 // We pass the context manually, so we have one extra register.
2210 static constexpr int kMaxRegisterParams =
2211 StaticCallInterfaceDescriptor::kMaxRegisterParams + 1;
2212};
2213
2215 : public StaticCallInterfaceDescriptor<BaselineLeaveFrameDescriptor> {
2216 public:
2218 DEFINE_PARAMETERS_NO_CONTEXT(kParamsSize, kWeight)
2220 MachineType::Int32()) // kWeight
2222
2223 static constexpr inline Register ParamsSizeRegister();
2224 static constexpr inline Register WeightRegister();
2225
2226 static constexpr inline auto registers();
2227};
2228
2231 public:
2233 DEFINE_PARAMETERS(kMaybeTargetCode, kExpectedParameterCount)
2235 MachineType::AnyTagged(), // kMaybeTargetCode
2236 MachineType::TaggedSigned()) // kExpectedParameterCount
2238
2239 static constexpr inline Register MaybeTargetCodeRegister();
2240 static constexpr inline Register ExpectedParameterCountRegister();
2241
2242 static constexpr inline auto registers();
2243};
2244
2247 public:
2249 DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
2250 kDispatchTable)
2251 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kAccumulator
2252 MachineType::IntPtr(), // kBytecodeOffset
2253 MachineType::AnyTagged(), // kBytecodeArray
2254 MachineType::IntPtr()) // kDispatchTable
2256
2257 static constexpr inline auto registers();
2258};
2259
2262 InterpreterPushArgsThenCallDescriptor> {
2263 public:
2265 DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
2266 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
2267 MachineType::Pointer(), // kFirstArgument
2268 MachineType::AnyTagged()) // kFunction
2270
2271 static constexpr inline auto registers();
2272};
2273
2277 public:
2279 DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
2280 kNewTarget, kFeedbackElement)
2281 DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
2282 MachineType::Pointer(), // kFirstArgument
2283 MachineType::AnyTagged(), // kConstructor
2284 MachineType::AnyTagged(), // kNewTarget
2285 MachineType::AnyTagged()) // kFeedbackElement
2287
2288 static constexpr inline auto registers();
2289};
2290
2292 : public StaticCallInterfaceDescriptor<InterpreterCEntry1Descriptor> {
2293 public:
2295 DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
2296 kFunctionEntry)
2297 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
2298 MachineType::Int32(), // kNumberOfArguments
2299 MachineType::Pointer(), // kFirstArgument
2300 MachineType::Pointer()) // kFunctionEntry
2302
2303 static constexpr auto registers();
2304};
2305
2307 : public StaticCallInterfaceDescriptor<InterpreterCEntry2Descriptor> {
2308 public:
2310 DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
2311 kFunctionEntry)
2312 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
2313 MachineType::AnyTagged(), // result 2
2314 MachineType::Int32(), // kNumberOfArguments
2315 MachineType::Pointer(), // kFirstArgument
2316 MachineType::Pointer()) // kFunctionEntry
2318
2319 static constexpr auto registers();
2320};
2321
2324 FindNonDefaultConstructorOrConstructDescriptor> {
2325 public:
2327 DEFINE_RESULT_AND_PARAMETERS(2, kThisFunction, kNewTarget)
2329 MachineType::AnyTagged(), // result 1 (true / false)
2330 MachineType::AnyTagged(), // result 2 (constructor_or_instance)
2331 MachineType::AnyTagged(), // kThisFunction
2332 MachineType::AnyTagged()) // kNewTarget
2334};
2335
2337 : public StaticCallInterfaceDescriptor<ForInPrepareDescriptor> {
2338 public:
2340 DEFINE_RESULT_AND_PARAMETERS(2, kEnumerator, kVectorIndex, kFeedbackVector)
2342 MachineType::AnyTagged(), // result 1 (cache array)
2343 MachineType::AnyTagged(), // result 2 (cache length)
2344 MachineType::AnyTagged(), // kEnumerator
2345 MachineType::TaggedSigned(), // kVectorIndex
2346 MachineType::AnyTagged()) // kFeedbackVector
2348};
2349
2351 : public StaticCallInterfaceDescriptor<ResumeGeneratorDescriptor> {
2352 public:
2354 DEFINE_PARAMETERS(kValue, kGenerator)
2355 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
2356 MachineType::AnyTagged()) // kGenerator
2358
2359 static constexpr inline auto registers();
2360};
2361
2364 public:
2366 DEFINE_PARAMETERS_NO_CONTEXT(kGeneratorObject, kRegisterCount)
2368 MachineType::TaggedSigned(), // return type
2369 MachineType::AnyTagged(), // kGeneratorObject
2370 MachineType::IntPtr(), // kRegisterCount
2371 )
2373};
2374
2376 : public StaticCallInterfaceDescriptor<SuspendGeneratorBaselineDescriptor> {
2377 public:
2379 DEFINE_PARAMETERS_NO_CONTEXT(kGeneratorObject, kSuspendId, kBytecodeOffset,
2380 kRegisterCount)
2381 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kGeneratorObject
2382 MachineType::IntPtr(), // kSuspendId
2383 MachineType::IntPtr(), // kBytecodeOffset
2384 MachineType::IntPtr(), // kRegisterCount
2385 )
2387};
2388
2390 : public StaticCallInterfaceDescriptor<RestartFrameTrampolineDescriptor> {
2391 public:
2395};
2396
2398 : public StaticCallInterfaceDescriptor<RunMicrotasksEntryDescriptor> {
2399 public:
2401 DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
2402 DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kRootRegisterValue
2403 MachineType::Pointer()) // kMicrotaskQueue
2405
2406 static constexpr inline auto registers();
2407};
2408
2411 public:
2413 DEFINE_PARAMETERS(kMicrotaskQueue)
2414 DEFINE_PARAMETER_TYPES(MachineType::Pointer())
2416
2417 static constexpr inline Register MicrotaskQueueRegister();
2418};
2419
2421 : public StaticCallInterfaceDescriptor<WasmFloat32ToNumberDescriptor> {
2422 public:
2425 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result
2426 MachineType::Float32()) // value
2428};
2429
2431 : public StaticCallInterfaceDescriptor<WasmFloat64ToTaggedDescriptor> {
2432 public:
2435 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result
2436 MachineType::Float64()) // value
2438};
2439
2441 : public StaticCallInterfaceDescriptor<WasmJSToWasmWrapperDescriptor> {
2442 public:
2444 DEFINE_PARAMETERS_NO_CONTEXT(kWrapperBuffer, kInstance, kResultJSArray)
2446 MachineType::IntPtr(), // ParamBuffer
2447 MachineType::AnyTagged(), // Instance
2448 MachineType::AnyTagged()) // Result jsarray
2450
2451 static constexpr int kMaxRegisterParams = 1;
2452 // Only the first parameter, `WrapperBuffer` gets passed over a register, the
2453 // instance and the js-array get passed over the stack. The reason is that
2454 // these parameters get forwarded to another function, and GC's may happen
2455 // until this other function gets called. By passing these parameters over the
2456 // stack the references get scanned as part of the caller frame, and the GC
2457 // does not have to scan anything on the `WasmJSToWasmWrapper` frame.
2458 static constexpr inline auto registers();
2459 static constexpr inline Register WrapperBufferRegister();
2460};
2461
2464 public:
2466 DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(4, kWasmImportData)
2468 MachineType::IntPtr(), // GP return 2
2469 MachineType::Float64(), // FP return 1
2470 MachineType::Float64(), // FP return 2
2471 MachineType::AnyTagged()) // WasmImportData
2473
2474 static constexpr int kMaxRegisterParams = 1;
2475 static constexpr inline auto registers();
2476 static constexpr inline auto return_registers();
2477 static constexpr inline auto return_double_registers();
2478};
2479
2482 public:
2485 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result
2486 MachineType::AnyTagged()) // value
2488};
2489
2491 : public StaticCallInterfaceDescriptor<I64ToBigIntDescriptor> {
2492 public:
2495 DEFINE_PARAMETER_TYPES(MachineType::Int64()) // kArgument
2497};
2498
2499// 32 bits version of the I64ToBigIntDescriptor call interface descriptor
2501 : public StaticCallInterfaceDescriptor<I32PairToBigIntDescriptor> {
2502 public:
2504 DEFINE_PARAMETERS_NO_CONTEXT(kLow, kHigh)
2505 DEFINE_PARAMETER_TYPES(MachineType::Uint32(), // kLow
2506 MachineType::Uint32()) // kHigh
2508};
2509
2511 : public StaticCallInterfaceDescriptor<BigIntToI64Descriptor> {
2512 public:
2514 DEFINE_PARAMETERS(kArgument)
2515 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(), // result 1
2516 MachineType::AnyTagged()) // kArgument
2518};
2519
2521 : public StaticCallInterfaceDescriptor<BigIntToI32PairDescriptor> {
2522 public:
2524 DEFINE_RESULT_AND_PARAMETERS(2, kArgument)
2525 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
2526 MachineType::Uint32(), // result 2
2527 MachineType::AnyTagged()) // kArgument
2529};
2530
2532 : public StaticCallInterfaceDescriptor<CloneObjectWithVectorDescriptor> {
2533 public:
2535 DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
2536 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
2537 MachineType::AnyTagged(), // kSource
2538 MachineType::TaggedSigned(), // kFlags
2539 MachineType::TaggedSigned(), // kSlot
2540 MachineType::AnyTagged()) // kVector
2542};
2543
2545 : public StaticCallInterfaceDescriptor<CloneObjectBaselineDescriptor> {
2546 public:
2549 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kSource
2550 MachineType::TaggedSigned(), // kFlags
2551 MachineType::TaggedSigned()) // kSlot
2553};
2554
2556 : public StaticCallInterfaceDescriptor<BinaryOp_WithFeedbackDescriptor> {
2557 public:
2559 DEFINE_PARAMETERS(kLeft, kRight, kSlot, kFeedbackVector)
2560 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kLeft
2561 MachineType::AnyTagged(), // kRight
2562 MachineType::UintPtr(), // kSlot
2563 MachineType::AnyTagged()) // kFeedbackVector
2565};
2566
2569 CallTrampoline_Baseline_CompactDescriptor> {
2570 public:
2572 using ArgumentCountField = base::BitField<uint32_t, 0, 8>;
2573 using SlotField = base::BitField<uintptr_t, 8, 24>;
2574
2575 static bool EncodeBitField(uint32_t argc, uintptr_t slot, uint32_t* out) {
2576 if (ArgumentCountField::is_valid(argc) && SlotField::is_valid(slot)) {
2577 *out = ArgumentCountField::encode(argc) | SlotField::encode(slot);
2578 return true;
2579 }
2580 return false;
2581 }
2582
2583 DEFINE_PARAMETERS_NO_CONTEXT_VARARGS(kFunction, kBitField)
2585 MachineType::AnyTagged(), // kFunction
2586 MachineType::Uint32()) // kBitField = ArgumentCountField | SlotField
2588};
2589
2592 public:
2594 DEFINE_PARAMETERS_NO_CONTEXT_VARARGS(kFunction, kActualArgumentsCount, kSlot)
2595 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
2596 MachineType::Int32(), // kActualArgumentsCount
2597 MachineType::UintPtr()) // kSlot
2599};
2600
2603 CallTrampoline_WithFeedbackDescriptor> {
2604 public:
2606 DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount, kSlot,
2607 kFeedbackVector, kReceiver)
2608 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
2609 MachineType::Int32(), // kActualArgumentsCount
2610 MachineType::UintPtr(), // kSlot
2611 MachineType::AnyTagged(), // kFeedbackVector
2612 MachineType::AnyTagged()) // kReceiver
2614};
2615
2617 : public StaticCallInterfaceDescriptor<Compare_WithFeedbackDescriptor> {
2618 public:
2620 DEFINE_PARAMETERS(kLeft, kRight, kSlot, kFeedbackVector)
2621 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kLeft
2622 MachineType::AnyTagged(), // kRight
2623 MachineType::UintPtr(), // kSlot
2624 MachineType::AnyTagged()) // kFeedbackVector
2626};
2627
2629 : public StaticCallInterfaceDescriptor<Compare_BaselineDescriptor> {
2630 public:
2632 DEFINE_PARAMETERS_NO_CONTEXT(kLeft, kRight, kSlot)
2634 MachineType::AnyTagged(), // kRight
2635 MachineType::UintPtr()) // kSlot
2637
2638 static constexpr inline auto registers();
2639};
2640
2649
2651 : public StaticJSCallInterfaceDescriptor<Construct_WithFeedbackDescriptor> {
2652 public:
2654 // kSlot is passed in a register, kFeedbackVector on the stack.
2655 DEFINE_JS_PARAMETERS(kSlot, kFeedbackVector)
2656 DEFINE_JS_PARAMETER_TYPES(MachineType::UintPtr(), // kSlot
2657 MachineType::AnyTagged()) // kFeedbackVector
2659};
2660
2662 : public StaticCallInterfaceDescriptor<UnaryOp_WithFeedbackDescriptor> {
2663 public:
2665 DEFINE_PARAMETERS(kValue, kSlot, kFeedbackVector)
2666 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
2667 MachineType::UintPtr(), // kSlot
2668 MachineType::AnyTagged()) // kFeedbackVector
2670};
2671
2673 : public StaticCallInterfaceDescriptor<UnaryOp_BaselineDescriptor> {
2674 public:
2677 DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
2678 MachineType::UintPtr()) // kSlot
2680};
2681
2684 CheckTurboshaftFloat32TypeDescriptor> {
2685 public:
2687 DEFINE_RESULT_AND_PARAMETERS(1, kValue, kExpectedType, kNodeId)
2688 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),
2690 MachineType::TaggedPointer(),
2691 MachineType::TaggedSigned())
2693};
2694
2697 CheckTurboshaftFloat64TypeDescriptor> {
2698 public:
2700 DEFINE_RESULT_AND_PARAMETERS(1, kValue, kExpectedType, kNodeId)
2701 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),
2703 MachineType::TaggedPointer(),
2704 MachineType::TaggedSigned())
2706};
2707
2709 : public StaticCallInterfaceDescriptor<DebugPrintWordPtrDescriptor> {
2710 public:
2713 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),
2714 MachineType::UintPtr())
2716};
2717
2719 : public StaticCallInterfaceDescriptor<DebugPrintFloat64Descriptor> {
2720 public:
2723 DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(),
2724 MachineType::Float64())
2726};
2727
2728#define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, DoesNeedContext, ...) \
2729 class Name##Descriptor \
2730 : public StaticCallInterfaceDescriptor<Name##Descriptor> { \
2731 public: \
2732 INTERNAL_DESCRIPTOR() \
2733 DEFINE_PARAMETERS(__VA_ARGS__) \
2734 static constexpr bool kNoContext = DoesNeedContext == NeedsContext::kNo; \
2735 DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor) \
2736 };
2738#undef DEFINE_TFS_BUILTIN_DESCRIPTOR
2739
2740// This file contains interface descriptor class definitions for builtins
2741// defined in Torque. It is included here because the class definitions need to
2742// precede the definition of name##Descriptor::key() below.
2743#include "torque-generated/interface-descriptors.inc"
2744
2745#undef DECLARE_DEFAULT_DESCRIPTOR
2746#undef DECLARE_DESCRIPTOR_WITH_BASE
2747#undef DECLARE_DESCRIPTOR
2748#undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
2749#undef DEFINE_RESULT_AND_PARAMETERS
2750#undef DEFINE_PARAMETERS_ENTRY
2751#undef DEFINE_PARAMETERS
2752#undef DEFINE_PARAMETERS_VARARGS
2753#undef DEFINE_PARAMETERS_NO_CONTEXT
2754#undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT
2755#undef DEFINE_RESULT_AND_PARAMETER_TYPES
2756#undef DEFINE_PARAMETER_TYPES
2757#undef DEFINE_JS_PARAMETERS
2758#undef DEFINE_JS_PARAMETER_TYPES
2759
2760// We define the association between CallDescriptors::Key and the specialized
2761// descriptor here to reduce boilerplate and mistakes.
2762#define DEF_KEY(name, ...) \
2763 CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
2765#undef DEF_KEY
2766} // namespace internal
2767} // namespace v8
2768
2769#endif // V8_CODEGEN_INTERFACE_DESCRIPTORS_H_
#define BUILTIN_LIST_TFS(V)
uint8_t data_[MAX_STACK_LENGTH]
int16_t parameter_count
Definition builtins.cc:67
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
#define DEF_ENUM(Name,...)
Definition builtins.h:50
static CallInterfaceDescriptorData * call_descriptor_data(CallDescriptors::Key key)
static Key GetKey(const CallInterfaceDescriptorData *data)
void RestrictAllocatableRegisters(const Register *registers, size_t num)
CallInterfaceDescriptorData & operator=(const CallInterfaceDescriptorData &)=delete
CallInterfaceDescriptorData(const CallInterfaceDescriptorData &)=delete
DoubleRegister double_register_return(int index) const
DoubleRegister double_register_param(int index) const
DoubleRegister GetDoubleRegisterParameter(int index) const
bool CheckFloatingPointParameters(CallInterfaceDescriptorData *data)
MachineType GetReturnType(int index) const
CallInterfaceDescriptorData::Flags Flags
const CallInterfaceDescriptorData * data_
bool operator==(const CallInterfaceDescriptor &other) const
DoubleRegister GetDoubleRegisterReturn(int index) const
StackArgumentOrder GetStackArgumentOrder() const
CallInterfaceDescriptor(CallDescriptors::Key key)
const CallInterfaceDescriptorData * data() const
MachineType GetParameterType(int index) const
static constexpr Register ContextRegister()
static constexpr MachineType Float64()
static constexpr MachineType TaggedPointer()
static constexpr MachineType GetParameterType(int i)
static void InitializeTypes(CallInterfaceDescriptorData *data)
static constexpr DoubleRegister GetDoubleRegisterParameter(int i)
static constexpr Register GetRegisterParameter(int i)
void Initialize(CallInterfaceDescriptorData *data)
static constexpr Register * GetRegisterData()
JSRegExp::Flags flags_
other heap size flags(e.g. initial_heap_size) take precedence") DEFINE_SIZE_T( max_shared_heap_size
OptionalOpIndex index
#define DEFINE_PARAMETERS_ENTRY(...)
#define INTERNAL_DESCRIPTOR()
#define DEFINE_PARAMETERS_VARARGS(...)
#define DECLARE_DEFAULT_DESCRIPTOR(name)
#define INTERFACE_DESCRIPTOR_LIST(V)
#define DEFINE_JS_PARAMETERS(...)
#define DEFINE_JS_PARAMETERS_NO_CONTEXT(...)
#define DEFINE_JS_PARAMETER_TYPES(...)
#define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, DoesNeedContext,...)
#define DEFINE_PARAMETER_TYPES(...)
#define DEFINE_PARAMETERS_NO_CONTEXT_VARARGS(...)
#define DEFINE_PARAMETERS(...)
#define DEFINE_PARAMETERS_NO_CONTEXT(...)
#define DEFINE_RESULT_AND_PARAMETER_TYPES(...)
#define DEFINE_RESULT_AND_PARAMETERS(return_count,...)
#define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count,...)
#define DECLARE_DESCRIPTOR(name)
#define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name)
#define DEF_KEY(name,...)
#define SANDBOX_EXPOSED_DESCRIPTOR(tag)
LiftoffRegister reg
RegListBase< RegisterT > registers
constexpr EmptyDoubleRegisterArray DoubleRegisterArray()
DwVfpRegister DoubleRegister
@ kStoreTransitionICHandlerEntrypointTag
@ kLoadWithVectorICHandlerEntrypointTag
@ kStoreWithVectorICHandlerEntrypointTag
constexpr EmptyRegisterArray RegisterArray()
constexpr int kJSBuiltinRegisterParams
constexpr bool IsFloatingPoint(MachineRepresentation rep)
constexpr int kMaxTFSBuiltinRegisterParams
constexpr Register kContextRegister
V8_EXPORT_PRIVATE bool AreAliased(const CPURegister &reg1, const CPURegister &reg2, const CPURegister &reg3=NoReg, const CPURegister &reg4=NoReg, const CPURegister &reg5=NoReg, const CPURegister &reg6=NoReg, const CPURegister &reg7=NoReg, const CPURegister &reg8=NoReg)
constexpr int kMaxBuiltinRegisterParams
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define V8_EXPORT_PRIVATE
Definition macros.h:460
DoubleRegister operator[](size_t i) const
std::unique_ptr< ValueMirror > key