Line data Source code
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_INTERFACE_DESCRIPTORS_H_
6 : #define V8_INTERFACE_DESCRIPTORS_H_
7 :
8 : #include <memory>
9 :
10 : #include "src/globals.h"
11 : #include "src/isolate.h"
12 : #include "src/machine-type.h"
13 : #include "src/register-arch.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : #define INTERFACE_DESCRIPTOR_LIST(V) \
19 : V(Abort) \
20 : V(Allocate) \
21 : V(AllocateHeapNumber) \
22 : V(ApiCallback) \
23 : V(ApiGetter) \
24 : V(ArgumentsAdaptor) \
25 : V(ArrayConstructor) \
26 : V(ArrayNArgumentsConstructor) \
27 : V(ArrayNoArgumentConstructor) \
28 : V(ArraySingleArgumentConstructor) \
29 : V(AsyncFunctionStackParameter) \
30 : V(BigIntToI64) \
31 : V(BigIntToWasmI64) \
32 : V(BinaryOp) \
33 : V(CallForwardVarargs) \
34 : V(CallFunctionTemplate) \
35 : V(CallTrampoline) \
36 : V(CallVarargs) \
37 : V(CallWithArrayLike) \
38 : V(CallWithSpread) \
39 : V(CEntry1ArgvOnStack) \
40 : V(CloneObjectWithVector) \
41 : V(Compare) \
42 : V(ConstructForwardVarargs) \
43 : V(ConstructStub) \
44 : V(ConstructVarargs) \
45 : V(ConstructWithArrayLike) \
46 : V(ConstructWithSpread) \
47 : V(ContextOnly) \
48 : V(CppBuiltinAdaptor) \
49 : V(FastNewFunctionContext) \
50 : V(FastNewObject) \
51 : V(FrameDropperTrampoline) \
52 : V(GetProperty) \
53 : V(GrowArrayElements) \
54 : V(InterpreterCEntry1) \
55 : V(InterpreterCEntry2) \
56 : V(InterpreterDispatch) \
57 : V(InterpreterPushArgsThenCall) \
58 : V(InterpreterPushArgsThenConstruct) \
59 : V(JSTrampoline) \
60 : V(Load) \
61 : V(LoadGlobal) \
62 : V(LoadGlobalWithVector) \
63 : V(LoadWithVector) \
64 : V(NewArgumentsElements) \
65 : V(NoContext) \
66 : V(RecordWrite) \
67 : V(ResumeGenerator) \
68 : V(RunMicrotasksEntry) \
69 : V(RunMicrotasks) \
70 : V(Store) \
71 : V(StoreGlobal) \
72 : V(StoreGlobalWithVector) \
73 : V(StoreTransition) \
74 : V(StoreWithVector) \
75 : V(StringAt) \
76 : V(StringSubstring) \
77 : V(TypeConversion) \
78 : V(TypeConversionStackParameter) \
79 : V(Typeof) \
80 : V(Void) \
81 : V(WasmAtomicWake) \
82 : V(WasmI32AtomicWait) \
83 : V(WasmI64AtomicWait) \
84 : V(WasmMemoryGrow) \
85 : V(WasmThrow) \
86 : BUILTIN_LIST_TFS(V)
87 :
88 : class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
89 : public:
90 : enum Flag {
91 : kNoFlags = 0u,
92 : kNoContext = 1u << 0,
93 :
94 : // This indicates that the code uses a special frame that does not scan the
95 : // stack arguments, e.g. EntryFrame. And this allows the code to use
96 : // untagged stack arguments.
97 : kNoStackScan = 1u << 1,
98 : };
99 : typedef base::Flags<Flag> Flags;
100 :
101 28604640 : CallInterfaceDescriptorData() = default;
102 :
103 : // A copy of the passed in registers and param_representations is made
104 : // and owned by the CallInterfaceDescriptorData.
105 :
106 : void InitializePlatformSpecific(int register_parameter_count,
107 : const Register* registers);
108 :
109 : // if machine_types is null, then an array of size
110 : // (return_count + parameter_count) will be created with
111 : // MachineType::AnyTagged() for each member.
112 : //
113 : // if machine_types is not null, then it should be of the size
114 : // (return_count + parameter_count). Those members of the parameter array will
115 : // be initialized from {machine_types}, and the rest initialized to
116 : // MachineType::AnyTagged().
117 : void InitializePlatformIndependent(Flags flags, int return_count,
118 : int parameter_count,
119 : const MachineType* machine_types,
120 : int machine_types_length);
121 :
122 : void Reset();
123 :
124 : bool IsInitialized() const {
125 : return IsInitializedPlatformSpecific() &&
126 : IsInitializedPlatformIndependent();
127 : }
128 :
129 : Flags flags() const { return flags_; }
130 : int return_count() const { return return_count_; }
131 2688 : int param_count() const { return param_count_; }
132 0 : int register_param_count() const { return register_param_count_; }
133 8107629 : Register register_param(int index) const { return register_params_[index]; }
134 : Register* register_params() const { return register_params_; }
135 : MachineType return_type(int index) const {
136 : DCHECK_LT(index, return_count_);
137 3414128 : return machine_types_[index];
138 : }
139 : MachineType param_type(int index) const {
140 : DCHECK_LT(index, param_count_);
141 7625418 : return machine_types_[return_count_ + index];
142 : }
143 :
144 : void RestrictAllocatableRegisters(const Register* registers, int num) {
145 : DCHECK_EQ(allocatable_registers_, 0);
146 297915 : for (int i = 0; i < num; ++i) {
147 595830 : allocatable_registers_ |= registers[i].bit();
148 : }
149 : DCHECK_GT(NumRegs(allocatable_registers_), 0);
150 : }
151 :
152 : RegList allocatable_registers() const { return allocatable_registers_; }
153 :
154 : private:
155 : bool IsInitializedPlatformSpecific() const {
156 : const bool initialized =
157 : (register_param_count_ == 0 && register_params_ == nullptr) ||
158 : (register_param_count_ > 0 && register_params_ != nullptr);
159 : // Platform-specific initialization happens before platform-independent.
160 : return initialized;
161 : }
162 : bool IsInitializedPlatformIndependent() const {
163 : const bool initialized =
164 : return_count_ >= 0 && param_count_ >= 0 && machine_types_ != nullptr;
165 : // Platform-specific initialization happens before platform-independent.
166 : return initialized;
167 : }
168 :
169 : #ifdef DEBUG
170 : bool AllStackParametersAreTagged() const;
171 : #endif // DEBUG
172 :
173 : int register_param_count_ = -1;
174 : int return_count_ = -1;
175 : int param_count_ = -1;
176 : Flags flags_ = kNoFlags;
177 :
178 : // Specifying the set of registers that could be used by the register
179 : // allocator. Currently, it's only used by RecordWrite code stub.
180 : RegList allocatable_registers_ = 0;
181 :
182 : // |registers_params_| defines registers that are used for parameter passing.
183 : // |machine_types_| defines machine types for resulting values and incomping
184 : // parameters.
185 : // Both arrays are allocated dynamically by the InterfaceDescriptor and
186 : // freed on destruction. This is because static arrays cause creation of
187 : // runtime static initializers which we don't want.
188 : Register* register_params_ = nullptr;
189 : MachineType* machine_types_ = nullptr;
190 :
191 : DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
192 : };
193 :
194 : class V8_EXPORT_PRIVATE CallDescriptors : public AllStatic {
195 : public:
196 : enum Key {
197 : #define DEF_ENUM(name, ...) name,
198 : INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
199 : #undef DEF_ENUM
200 : NUMBER_OF_DESCRIPTORS
201 : };
202 :
203 : static void InitializeOncePerProcess();
204 : static void TearDown();
205 :
206 93856 : static CallInterfaceDescriptorData* call_descriptor_data(
207 : CallDescriptors::Key key) {
208 2923868 : return &call_descriptor_data_[key];
209 : }
210 :
211 : static Key GetKey(const CallInterfaceDescriptorData* data) {
212 3413952 : ptrdiff_t index = data - call_descriptor_data_;
213 : DCHECK_LE(0, index);
214 : DCHECK_LT(index, CallDescriptors::NUMBER_OF_DESCRIPTORS);
215 3413952 : return static_cast<CallDescriptors::Key>(index);
216 : }
217 :
218 : private:
219 : static CallInterfaceDescriptorData
220 : call_descriptor_data_[NUMBER_OF_DESCRIPTORS];
221 : };
222 :
223 11454355 : class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
224 : public:
225 : typedef CallInterfaceDescriptorData::Flags Flags;
226 :
227 : CallInterfaceDescriptor() : data_(nullptr) {}
228 15612475 : virtual ~CallInterfaceDescriptor() = default;
229 :
230 93856 : explicit CallInterfaceDescriptor(CallDescriptors::Key key)
231 17449407 : : data_(CallDescriptors::call_descriptor_data(key)) {}
232 :
233 237532 : Flags flags() const { return data()->flags(); }
234 :
235 : bool HasContextParameter() const {
236 : return (flags() & CallInterfaceDescriptorData::kNoContext) == 0;
237 : }
238 :
239 3369607 : int GetReturnCount() const { return data()->return_count(); }
240 :
241 3414128 : MachineType GetReturnType(int index) const {
242 : DCHECK_LT(index, data()->return_count());
243 3414128 : return data()->return_type(index);
244 : }
245 :
246 50570 : int GetParameterCount() const { return data()->param_count(); }
247 :
248 3416143 : int GetRegisterParameterCount() const {
249 3748301 : return data()->register_param_count();
250 : }
251 :
252 98943 : int GetStackParameterCount() const {
253 2665751 : return data()->param_count() - data()->register_param_count();
254 : }
255 :
256 7623627 : Register GetRegisterParameter(int index) const {
257 8107573 : return data()->register_param(index);
258 : }
259 :
260 : MachineType GetParameterType(int index) const {
261 : DCHECK_LT(index, data()->param_count());
262 7625418 : return data()->param_type(index);
263 : }
264 :
265 3369595 : RegList allocatable_registers() const {
266 3695340 : return data()->allocatable_registers();
267 : }
268 :
269 : static const Register ContextRegister();
270 :
271 : const char* DebugName() const;
272 :
273 : protected:
274 2688 : const CallInterfaceDescriptorData* data() const { return data_; }
275 :
276 0 : virtual void InitializePlatformSpecific(CallInterfaceDescriptorData* data) {
277 0 : UNREACHABLE();
278 : }
279 :
280 119166 : virtual void InitializePlatformIndependent(
281 119166 : CallInterfaceDescriptorData* data) {
282 : // Default descriptor configuration: one result, all parameters are passed
283 : // in registers and all parameters have MachineType::AnyTagged() type.
284 : data->InitializePlatformIndependent(CallInterfaceDescriptorData::kNoFlags,
285 : 1, data->register_param_count(),
286 119166 : nullptr, 0);
287 119166 : }
288 :
289 : // Initializes |data| using the platform dependent default set of registers.
290 : // It is intended to be used for TurboFan stubs when particular set of
291 : // registers does not matter.
292 : static void DefaultInitializePlatformSpecific(
293 : CallInterfaceDescriptorData* data, int register_parameter_count);
294 :
295 : // Initializes |data| using the platform dependent default set of registers
296 : // for JavaScript-compatible calling convention.
297 : // It is intended to be used for TurboFan stubs being called with JavaScript
298 : // linkage + additional parameters on registers and stack.
299 : static void JSDefaultInitializePlatformSpecific(
300 : CallInterfaceDescriptorData* data, int non_js_register_parameter_count);
301 :
302 : // Checks if float parameters are not assigned invalid registers.
303 : bool CheckFloatingPointParameters(CallInterfaceDescriptorData* data) {
304 : for (int i = 0; i < data->register_param_count(); i++) {
305 : if (IsFloatingPoint(data->param_type(i).representation())) {
306 : if (!IsValidFloatParameterRegister(data->register_param(i))) {
307 : return false;
308 : }
309 : }
310 : }
311 : return true;
312 : }
313 :
314 : bool IsValidFloatParameterRegister(Register reg);
315 :
316 : private:
317 : // {CallDescriptors} is allowed to call the private {Initialize} method.
318 : friend class CallDescriptors;
319 :
320 : const CallInterfaceDescriptorData* data_;
321 :
322 2204571 : void Initialize(CallInterfaceDescriptorData* data) {
323 : // The passed pointer should be a modifiable pointer to our own data.
324 : DCHECK_EQ(data, data_);
325 : DCHECK(!data->IsInitialized());
326 14299920 : InitializePlatformSpecific(data);
327 14299920 : InitializePlatformIndependent(data);
328 : DCHECK(data->IsInitialized());
329 : DCHECK(CheckFloatingPointParameters(data));
330 2204571 : }
331 : };
332 :
333 : #define DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
334 : public: \
335 : explicit name() : base(key()) {} \
336 : static inline CallDescriptors::Key key();
337 :
338 : #if defined(V8_TARGET_ARCH_IA32)
339 : // To support all possible cases, we must limit the number of register args for
340 : // TFS builtins on ia32 to 3. Out of the 6 allocatable registers, esi is taken
341 : // as the context register and ebx is the root register. One register must
342 : // remain available to store the jump/call target. Thus 3 registers remain for
343 : // arguments. The reason this applies to TFS builtins specifically is because
344 : // this becomes relevant for builtins used as targets of Torque function
345 : // pointers (which must have a register available to store the target).
346 : // TODO(jgruber): Ideally we should just decrement kMaxBuiltinRegisterParams but
347 : // that comes with its own set of complications. It's possible, but requires
348 : // refactoring the calling convention of other existing stubs.
349 : constexpr int kMaxBuiltinRegisterParams = 4;
350 : constexpr int kMaxTFSBuiltinRegisterParams = 3;
351 : #else
352 : constexpr int kMaxBuiltinRegisterParams = 5;
353 : constexpr int kMaxTFSBuiltinRegisterParams = kMaxBuiltinRegisterParams;
354 : #endif
355 : STATIC_ASSERT(kMaxTFSBuiltinRegisterParams <= kMaxBuiltinRegisterParams);
356 :
357 : #define DECLARE_DEFAULT_DESCRIPTOR(name, base) \
358 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
359 : protected: \
360 : static const int kRegisterParams = \
361 : kParameterCount > kMaxTFSBuiltinRegisterParams \
362 : ? kMaxTFSBuiltinRegisterParams \
363 : : kParameterCount; \
364 : static const int kStackParams = kParameterCount - kRegisterParams; \
365 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
366 : override { \
367 : DefaultInitializePlatformSpecific(data, kRegisterParams); \
368 : } \
369 : void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
370 : override { \
371 : data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
372 : kParameterCount, nullptr, 0); \
373 : } \
374 : name(CallDescriptors::Key key) : base(key) {} \
375 : \
376 : public:
377 :
378 : #define DECLARE_JS_COMPATIBLE_DESCRIPTOR(name, base, \
379 : non_js_reg_parameters_count) \
380 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
381 : protected: \
382 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) \
383 : override { \
384 : JSDefaultInitializePlatformSpecific(data, non_js_reg_parameters_count); \
385 : } \
386 : name(CallDescriptors::Key key) : base(key) {} \
387 : \
388 : public:
389 :
390 : #define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
391 : static constexpr int kDescriptorFlags = \
392 : CallInterfaceDescriptorData::kNoFlags; \
393 : static constexpr int kReturnCount = return_count; \
394 : enum ParameterIndices { \
395 : __dummy = -1, /* to be able to pass zero arguments */ \
396 : ##__VA_ARGS__, \
397 : \
398 : kParameterCount, \
399 : kContext = kParameterCount /* implicit parameter */ \
400 : };
401 :
402 : #define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \
403 : static constexpr int kDescriptorFlags = \
404 : CallInterfaceDescriptorData::kNoContext; \
405 : static constexpr int kReturnCount = return_count; \
406 : enum ParameterIndices { \
407 : __dummy = -1, /* to be able to pass zero arguments */ \
408 : ##__VA_ARGS__, \
409 : \
410 : kParameterCount \
411 : };
412 :
413 : // This is valid only for builtins that use EntryFrame, which does not scan
414 : // stack arguments on GC.
415 : #define DEFINE_PARAMETERS_ENTRY(...) \
416 : static constexpr int kDescriptorFlags = \
417 : CallInterfaceDescriptorData::kNoContext | \
418 : CallInterfaceDescriptorData::kNoStackScan; \
419 : static constexpr int kReturnCount = 1; \
420 : enum ParameterIndices { \
421 : __dummy = -1, /* to be able to pass zero arguments */ \
422 : ##__VA_ARGS__, \
423 : \
424 : kParameterCount \
425 : };
426 :
427 : #define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
428 :
429 : #define DEFINE_PARAMETERS_NO_CONTEXT(...) \
430 : DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(1, ##__VA_ARGS__)
431 :
432 : #define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
433 : void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
434 : override { \
435 : MachineType machine_types[] = {__VA_ARGS__}; \
436 : static_assert( \
437 : kReturnCount + kParameterCount == arraysize(machine_types), \
438 : "Parameter names definition is not consistent with parameter types"); \
439 : data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, \
440 : kParameterCount, machine_types, \
441 : arraysize(machine_types)); \
442 : }
443 :
444 : #define DEFINE_PARAMETER_TYPES(...) \
445 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
446 : ##__VA_ARGS__)
447 :
448 : #define DEFINE_JS_PARAMETERS(...) \
449 : static constexpr int kDescriptorFlags = \
450 : CallInterfaceDescriptorData::kNoFlags; \
451 : static constexpr int kReturnCount = 1; \
452 : enum ParameterIndices { \
453 : kTarget, \
454 : kNewTarget, \
455 : kActualArgumentsCount, \
456 : ##__VA_ARGS__, \
457 : \
458 : kParameterCount, \
459 : kContext = kParameterCount /* implicit parameter */ \
460 : };
461 :
462 : #define DEFINE_JS_PARAMETER_TYPES(...) \
463 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), /* kTarget */ \
464 : MachineType::AnyTagged(), /* kNewTarget */ \
465 : MachineType::Int32(), /* kActualArgumentsCount */ \
466 : ##__VA_ARGS__)
467 :
468 : #define DECLARE_DESCRIPTOR(name, base) \
469 : DECLARE_DESCRIPTOR_WITH_BASE(name, base) \
470 : protected: \
471 : void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override; \
472 : name(CallDescriptors::Key key) : base(key) {} \
473 : \
474 : public:
475 :
476 59583 : class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
477 : public:
478 : DEFINE_PARAMETERS()
479 119166 : DEFINE_PARAMETER_TYPES()
480 59696 : DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
481 : };
482 :
483 : // Dummy descriptor used to mark builtins that don't yet have their proper
484 : // descriptor associated.
485 : typedef VoidDescriptor DummyDescriptor;
486 :
487 : // Dummy descriptor that marks builtins with C calling convention.
488 : typedef VoidDescriptor CCallDescriptor;
489 :
490 171286 : class AllocateDescriptor : public CallInterfaceDescriptor {
491 : public:
492 : DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
493 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
494 : MachineType::IntPtr()) // kRequestedSize
495 171284 : DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
496 : };
497 :
498 : // This descriptor defines the JavaScript calling convention that can be used
499 : // by stubs: target, new.target, argc (not including the receiver) and context
500 : // are passed in registers while receiver and the rest of the JS arguments are
501 : // passed on the stack.
502 59583 : class JSTrampolineDescriptor : public CallInterfaceDescriptor {
503 : public:
504 : DEFINE_JS_PARAMETERS()
505 119166 : DEFINE_JS_PARAMETER_TYPES()
506 :
507 119670 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(JSTrampolineDescriptor,
508 : CallInterfaceDescriptor, 0)
509 : };
510 :
511 59583 : class ContextOnlyDescriptor : public CallInterfaceDescriptor {
512 : public:
513 : DEFINE_PARAMETERS()
514 119166 : DEFINE_PARAMETER_TYPES()
515 59583 : DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
516 : };
517 :
518 71475 : class NoContextDescriptor : public CallInterfaceDescriptor {
519 : public:
520 : DEFINE_PARAMETERS_NO_CONTEXT()
521 119166 : DEFINE_PARAMETER_TYPES()
522 71475 : DECLARE_DESCRIPTOR(NoContextDescriptor, CallInterfaceDescriptor)
523 : };
524 :
525 : // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
526 120454 : class LoadDescriptor : public CallInterfaceDescriptor {
527 : public:
528 : DEFINE_PARAMETERS(kReceiver, kName, kSlot)
529 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
530 : MachineType::AnyTagged(), // kName
531 : MachineType::TaggedSigned()) // kSlot
532 120454 : DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
533 :
534 : static const Register ReceiverRegister();
535 : static const Register NameRegister();
536 : static const Register SlotRegister();
537 : };
538 :
539 119166 : class LoadGlobalDescriptor : public CallInterfaceDescriptor {
540 : public:
541 : DEFINE_PARAMETERS(kName, kSlot)
542 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
543 : MachineType::TaggedSigned()) // kSlot
544 119166 : DECLARE_DESCRIPTOR(LoadGlobalDescriptor, CallInterfaceDescriptor)
545 :
546 : static const Register NameRegister() {
547 119166 : return LoadDescriptor::NameRegister();
548 : }
549 :
550 : static const Register SlotRegister() {
551 119166 : return LoadDescriptor::SlotRegister();
552 : }
553 : };
554 :
555 179141 : class StoreDescriptor : public CallInterfaceDescriptor {
556 : public:
557 : DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot)
558 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
559 : MachineType::AnyTagged(), // kName
560 : MachineType::AnyTagged(), // kValue
561 : MachineType::TaggedSigned()) // kSlot
562 179141 : DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
563 :
564 : static const Register ReceiverRegister();
565 : static const Register NameRegister();
566 : static const Register ValueRegister();
567 : static const Register SlotRegister();
568 :
569 : #if V8_TARGET_ARCH_IA32
570 : static const bool kPassLastArgsOnStack = true;
571 : #else
572 : static const bool kPassLastArgsOnStack = false;
573 : #endif
574 :
575 : // Pass value and slot through the stack.
576 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
577 : };
578 :
579 59697 : class StoreTransitionDescriptor : public StoreDescriptor {
580 : public:
581 : DEFINE_PARAMETERS(kReceiver, kName, kMap, kValue, kSlot, kVector)
582 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
583 : MachineType::AnyTagged(), // kName
584 : MachineType::AnyTagged(), // kMap
585 : MachineType::AnyTagged(), // kValue
586 : MachineType::TaggedSigned(), // kSlot
587 : MachineType::AnyTagged()) // kVector
588 59695 : DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
589 :
590 : static const Register MapRegister();
591 : static const Register SlotRegister();
592 : static const Register VectorRegister();
593 :
594 : // Pass value, slot and vector through the stack.
595 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
596 : };
597 :
598 59868 : class StoreWithVectorDescriptor : public StoreDescriptor {
599 : public:
600 : DEFINE_PARAMETERS(kReceiver, kName, kValue, kSlot, kVector)
601 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
602 : MachineType::AnyTagged(), // kName
603 : MachineType::AnyTagged(), // kValue
604 : MachineType::TaggedSigned(), // kSlot
605 : MachineType::AnyTagged()) // kVector
606 59863 : DECLARE_DESCRIPTOR(StoreWithVectorDescriptor, StoreDescriptor)
607 :
608 : static const Register VectorRegister();
609 :
610 : // Pass value, slot and vector through the stack.
611 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
612 : };
613 :
614 119166 : class StoreGlobalDescriptor : public CallInterfaceDescriptor {
615 : public:
616 : DEFINE_PARAMETERS(kName, kValue, kSlot)
617 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
618 : MachineType::AnyTagged(), // kValue
619 : MachineType::TaggedSigned()) // kSlot
620 119166 : DECLARE_DESCRIPTOR(StoreGlobalDescriptor, CallInterfaceDescriptor)
621 :
622 : static const bool kPassLastArgsOnStack =
623 : StoreDescriptor::kPassLastArgsOnStack;
624 : // Pass value and slot through the stack.
625 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 2 : 0;
626 :
627 : static const Register NameRegister() {
628 119166 : return StoreDescriptor::NameRegister();
629 : }
630 :
631 : static const Register ValueRegister() {
632 119166 : return StoreDescriptor::ValueRegister();
633 : }
634 :
635 : static const Register SlotRegister() {
636 119166 : return StoreDescriptor::SlotRegister();
637 : }
638 : };
639 :
640 59583 : class StoreGlobalWithVectorDescriptor : public StoreGlobalDescriptor {
641 : public:
642 : DEFINE_PARAMETERS(kName, kValue, kSlot, kVector)
643 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
644 : MachineType::AnyTagged(), // kValue
645 : MachineType::TaggedSigned(), // kSlot
646 : MachineType::AnyTagged()) // kVector
647 59583 : DECLARE_DESCRIPTOR(StoreGlobalWithVectorDescriptor, StoreGlobalDescriptor)
648 :
649 : static const Register VectorRegister() {
650 59583 : return StoreWithVectorDescriptor::VectorRegister();
651 : }
652 :
653 : // Pass value, slot and vector through the stack.
654 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
655 : };
656 :
657 60894 : class LoadWithVectorDescriptor : public LoadDescriptor {
658 : public:
659 : DEFINE_PARAMETERS(kReceiver, kName, kSlot, kVector)
660 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
661 : MachineType::AnyTagged(), // kName
662 : MachineType::TaggedSigned(), // kSlot
663 : MachineType::AnyTagged()) // kVector
664 60871 : DECLARE_DESCRIPTOR(LoadWithVectorDescriptor, LoadDescriptor)
665 :
666 : static const Register VectorRegister();
667 :
668 : #if V8_TARGET_ARCH_IA32
669 : static const bool kPassLastArgsOnStack = true;
670 : #else
671 : static const bool kPassLastArgsOnStack = false;
672 : #endif
673 :
674 : // Pass vector through the stack.
675 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 1 : 0;
676 : };
677 :
678 59583 : class LoadGlobalWithVectorDescriptor : public LoadGlobalDescriptor {
679 : public:
680 : DEFINE_PARAMETERS(kName, kSlot, kVector)
681 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kName
682 : MachineType::TaggedSigned(), // kSlot
683 : MachineType::AnyTagged()) // kVector
684 59583 : DECLARE_DESCRIPTOR(LoadGlobalWithVectorDescriptor, LoadGlobalDescriptor)
685 :
686 : #if V8_TARGET_ARCH_IA32
687 : // On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
688 : // need to choose a new register here.
689 : static const Register VectorRegister() { return edx; }
690 : #else
691 : static const Register VectorRegister() {
692 59583 : return LoadWithVectorDescriptor::VectorRegister();
693 : }
694 : #endif
695 : };
696 :
697 59583 : class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor {
698 : public:
699 : DEFINE_PARAMETERS(kScopeInfo, kSlots)
700 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kScopeInfo
701 : MachineType::Int32()) // kSlots
702 59583 : DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor)
703 :
704 : static const Register ScopeInfoRegister();
705 : static const Register SlotsRegister();
706 : };
707 :
708 59583 : class FastNewObjectDescriptor : public CallInterfaceDescriptor {
709 : public:
710 : DEFINE_PARAMETERS(kTarget, kNewTarget)
711 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
712 : MachineType::AnyTagged()) // kNewTarget
713 59583 : DECLARE_DESCRIPTOR(FastNewObjectDescriptor, CallInterfaceDescriptor)
714 : static const Register TargetRegister();
715 : static const Register NewTargetRegister();
716 : };
717 :
718 59640 : class RecordWriteDescriptor final : public CallInterfaceDescriptor {
719 : public:
720 : DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
721 119166 : DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
722 : MachineType::Pointer(), // kSlot
723 : MachineType::TaggedSigned(), // kRememberedSet
724 : MachineType::TaggedSigned()) // kFPMode
725 :
726 59639 : DECLARE_DESCRIPTOR(RecordWriteDescriptor, CallInterfaceDescriptor)
727 : };
728 :
729 141050 : class TypeConversionDescriptor final : public CallInterfaceDescriptor {
730 : public:
731 : DEFINE_PARAMETERS(kArgument)
732 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
733 141049 : DECLARE_DESCRIPTOR(TypeConversionDescriptor, CallInterfaceDescriptor)
734 :
735 : static const Register ArgumentRegister();
736 : };
737 :
738 59583 : class TypeConversionStackParameterDescriptor final
739 : : public CallInterfaceDescriptor {
740 : public:
741 : DEFINE_PARAMETERS(kArgument)
742 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
743 59583 : DECLARE_DESCRIPTOR(TypeConversionStackParameterDescriptor,
744 : CallInterfaceDescriptor)
745 : };
746 :
747 59583 : class AsyncFunctionStackParameterDescriptor final
748 : : public CallInterfaceDescriptor {
749 : public:
750 : DEFINE_PARAMETERS(kPromise, kResult)
751 119166 : DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), MachineType::AnyTagged())
752 59583 : DECLARE_DESCRIPTOR(AsyncFunctionStackParameterDescriptor,
753 : CallInterfaceDescriptor)
754 : };
755 :
756 59583 : class GetPropertyDescriptor final : public CallInterfaceDescriptor {
757 : public:
758 : DEFINE_PARAMETERS(kObject, kKey)
759 238332 : DECLARE_DEFAULT_DESCRIPTOR(GetPropertyDescriptor, CallInterfaceDescriptor)
760 : };
761 :
762 59583 : class TypeofDescriptor : public CallInterfaceDescriptor {
763 : public:
764 : DEFINE_PARAMETERS(kObject)
765 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
766 59583 : DECLARE_DESCRIPTOR(TypeofDescriptor, CallInterfaceDescriptor)
767 : };
768 :
769 61540 : class CallTrampolineDescriptor : public CallInterfaceDescriptor {
770 : public:
771 : DEFINE_PARAMETERS(kFunction, kActualArgumentsCount)
772 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
773 : MachineType::Int32()) // kActualArgumentsCount
774 61535 : DECLARE_DESCRIPTOR(CallTrampolineDescriptor, CallInterfaceDescriptor)
775 : };
776 :
777 59583 : class CallVarargsDescriptor : public CallInterfaceDescriptor {
778 : public:
779 : DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kArgumentsLength,
780 : kArgumentsList)
781 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
782 : MachineType::Int32(), // kActualArgumentsCount
783 : MachineType::Int32(), // kArgumentsLength
784 : MachineType::AnyTagged()) // kArgumentsList
785 59583 : DECLARE_DESCRIPTOR(CallVarargsDescriptor, CallInterfaceDescriptor)
786 : };
787 :
788 59583 : class CallForwardVarargsDescriptor : public CallInterfaceDescriptor {
789 : public:
790 : DEFINE_PARAMETERS(kTarget, kActualArgumentsCount, kStartIndex)
791 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
792 : MachineType::Int32(), // kActualArgumentsCount
793 : MachineType::Int32()) // kStartIndex
794 59583 : DECLARE_DESCRIPTOR(CallForwardVarargsDescriptor, CallInterfaceDescriptor)
795 : };
796 :
797 59583 : class CallFunctionTemplateDescriptor : public CallInterfaceDescriptor {
798 : public:
799 : DEFINE_PARAMETERS(kFunctionTemplateInfo, kArgumentsCount)
800 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunctionTemplateInfo
801 : MachineType::IntPtr()) // kArgumentsCount
802 59583 : DECLARE_DESCRIPTOR(CallFunctionTemplateDescriptor, CallInterfaceDescriptor)
803 : };
804 :
805 59583 : class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
806 : public:
807 : DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread)
808 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
809 : MachineType::Int32(), // kArgumentsCount
810 : MachineType::AnyTagged()) // kSpread
811 59583 : DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
812 : };
813 :
814 59583 : class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
815 : public:
816 : DEFINE_PARAMETERS(kTarget, kArgumentsList)
817 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
818 : MachineType::AnyTagged()) // kArgumentsList
819 59583 : DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
820 : };
821 :
822 59583 : class ConstructVarargsDescriptor : public CallInterfaceDescriptor {
823 : public:
824 : DEFINE_JS_PARAMETERS(kArgumentsLength, kArgumentsList)
825 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32(), // kArgumentsLength
826 : MachineType::AnyTagged()) // kArgumentsList
827 :
828 59583 : DECLARE_DESCRIPTOR(ConstructVarargsDescriptor, CallInterfaceDescriptor)
829 : };
830 :
831 59583 : class ConstructForwardVarargsDescriptor : public CallInterfaceDescriptor {
832 : public:
833 : DEFINE_JS_PARAMETERS(kStartIndex)
834 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
835 59583 : DECLARE_DESCRIPTOR(ConstructForwardVarargsDescriptor, CallInterfaceDescriptor)
836 : };
837 :
838 59583 : class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
839 : public:
840 : DEFINE_JS_PARAMETERS(kSpread)
841 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
842 59583 : DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
843 : };
844 :
845 59583 : class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
846 : public:
847 : DEFINE_PARAMETERS(kTarget, kNewTarget, kArgumentsList)
848 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kTarget
849 : MachineType::AnyTagged(), // kNewTarget
850 : MachineType::AnyTagged()) // kArgumentsList
851 59583 : DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
852 : };
853 :
854 : // TODO(ishell): consider merging this with ArrayConstructorDescriptor
855 59583 : class ConstructStubDescriptor : public CallInterfaceDescriptor {
856 : public:
857 : // TODO(jgruber): Remove the unused allocation site parameter.
858 : DEFINE_JS_PARAMETERS(kAllocationSite)
859 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
860 :
861 : // TODO(ishell): Use DECLARE_JS_COMPATIBLE_DESCRIPTOR if registers match
862 61931 : DECLARE_DESCRIPTOR(ConstructStubDescriptor, CallInterfaceDescriptor)
863 : };
864 :
865 59583 : class AbortDescriptor : public CallInterfaceDescriptor {
866 : public:
867 : DEFINE_PARAMETERS_NO_CONTEXT(kMessageOrMessageId)
868 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged())
869 59583 : DECLARE_DESCRIPTOR(AbortDescriptor, CallInterfaceDescriptor)
870 : };
871 :
872 71178 : class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
873 : public:
874 : DEFINE_PARAMETERS_NO_CONTEXT()
875 119166 : DEFINE_PARAMETER_TYPES()
876 71168 : DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
877 : };
878 :
879 59703 : class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
880 : public:
881 : DEFINE_JS_PARAMETERS(kAllocationSite)
882 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::AnyTagged())
883 :
884 119286 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(ArrayConstructorDescriptor,
885 : CallInterfaceDescriptor, 1)
886 : };
887 :
888 179547 : class ArrayNArgumentsConstructorDescriptor : public CallInterfaceDescriptor {
889 : public:
890 : // This descriptor declares only register arguments while respective number
891 : // of JS arguments stay on the expression stack.
892 : // The ArrayNArgumentsConstructor builtin does not access stack arguments
893 : // directly it just forwards them to the runtime function.
894 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount)
895 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction,
896 : MachineType::AnyTagged(), // kAllocationSite
897 : MachineType::Int32()) // kActualArgumentsCount
898 179533 : DECLARE_DESCRIPTOR(ArrayNArgumentsConstructorDescriptor,
899 : CallInterfaceDescriptor)
900 : };
901 :
902 59583 : class ArrayNoArgumentConstructorDescriptor
903 : : public ArrayNArgumentsConstructorDescriptor {
904 : public:
905 : // This descriptor declares same register arguments as the parent
906 : // ArrayNArgumentsConstructorDescriptor and it declares indices for
907 : // JS arguments passed on the expression stack.
908 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
909 : kFunctionParameter)
910 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
911 : MachineType::AnyTagged(), // kAllocationSite
912 : MachineType::Int32(), // kActualArgumentsCount
913 : MachineType::AnyTagged()) // kFunctionParameter
914 59583 : DECLARE_DESCRIPTOR(ArrayNoArgumentConstructorDescriptor,
915 : ArrayNArgumentsConstructorDescriptor)
916 : };
917 :
918 59583 : class ArraySingleArgumentConstructorDescriptor
919 : : public ArrayNArgumentsConstructorDescriptor {
920 : public:
921 : // This descriptor declares same register arguments as the parent
922 : // ArrayNArgumentsConstructorDescriptor and it declares indices for
923 : // JS arguments passed on the expression stack.
924 : DEFINE_PARAMETERS(kFunction, kAllocationSite, kActualArgumentsCount,
925 : kFunctionParameter, kArraySizeSmiParameter)
926 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kFunction
927 : MachineType::AnyTagged(), // kAllocationSite
928 : MachineType::Int32(), // kActualArgumentsCount
929 : MachineType::AnyTagged(), // kFunctionParameter
930 : MachineType::AnyTagged()) // kArraySizeSmiParameter
931 59583 : DECLARE_DESCRIPTOR(ArraySingleArgumentConstructorDescriptor,
932 : ArrayNArgumentsConstructorDescriptor)
933 : };
934 :
935 59583 : class CompareDescriptor : public CallInterfaceDescriptor {
936 : public:
937 : DEFINE_PARAMETERS(kLeft, kRight)
938 59583 : DECLARE_DESCRIPTOR(CompareDescriptor, CallInterfaceDescriptor)
939 : };
940 :
941 :
942 59583 : class BinaryOpDescriptor : public CallInterfaceDescriptor {
943 : public:
944 : DEFINE_PARAMETERS(kLeft, kRight)
945 59583 : DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
946 : };
947 :
948 : // This desciptor is shared among String.p.charAt/charCodeAt/codePointAt
949 : // as they all have the same interface.
950 59583 : class StringAtDescriptor final : public CallInterfaceDescriptor {
951 : public:
952 : DEFINE_PARAMETERS(kReceiver, kPosition)
953 : // TODO(turbofan): Return untagged value here.
954 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(), // result 1
955 : MachineType::AnyTagged(), // kReceiver
956 : MachineType::IntPtr()) // kPosition
957 59583 : DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
958 : };
959 :
960 59583 : class StringSubstringDescriptor final : public CallInterfaceDescriptor {
961 : public:
962 : DEFINE_PARAMETERS(kString, kFrom, kTo)
963 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kString
964 : MachineType::IntPtr(), // kFrom
965 : MachineType::IntPtr()) // kTo
966 :
967 : // TODO(turbofan): Allow builtins to return untagged values.
968 59583 : DECLARE_DESCRIPTOR(StringSubstringDescriptor, CallInterfaceDescriptor)
969 : };
970 :
971 60205 : class ArgumentsAdaptorDescriptor : public CallInterfaceDescriptor {
972 : public:
973 : DEFINE_JS_PARAMETERS(kExpectedArgumentsCount)
974 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::Int32())
975 60205 : DECLARE_DESCRIPTOR(ArgumentsAdaptorDescriptor, CallInterfaceDescriptor)
976 : };
977 :
978 59583 : class CppBuiltinAdaptorDescriptor : public CallInterfaceDescriptor {
979 : public:
980 : DEFINE_JS_PARAMETERS(kCFunction)
981 119166 : DEFINE_JS_PARAMETER_TYPES(MachineType::Pointer())
982 119166 : DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor,
983 : CallInterfaceDescriptor, 1)
984 : };
985 :
986 59697 : class CEntry1ArgvOnStackDescriptor : public CallInterfaceDescriptor {
987 : public:
988 : DEFINE_PARAMETERS(kArity, // register argument
989 : kCFunction, // register argument
990 : kPadding, // stack argument 1 (just padding)
991 : kArgcSmi, // stack argument 2
992 : kTargetCopy, // stack argument 3
993 : kNewTargetCopy) // stack argument 4
994 119166 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kArity
995 : MachineType::Pointer(), // kCFunction
996 : MachineType::AnyTagged(), // kPadding
997 : MachineType::AnyTagged(), // kArgcSmi
998 : MachineType::AnyTagged(), // kTargetCopy
999 : MachineType::AnyTagged()) // kNewTargetCopy
1000 59695 : DECLARE_DESCRIPTOR(CEntry1ArgvOnStackDescriptor, CallInterfaceDescriptor)
1001 : };
1002 :
1003 59583 : class ApiCallbackDescriptor : public CallInterfaceDescriptor {
1004 : public:
1005 : DEFINE_PARAMETERS(kApiFunctionAddress, kActualArgumentsCount, kCallData,
1006 : kHolder)
1007 : // receiver is implicit stack argument 1
1008 : // argv are implicit stack arguments [2, 2 + kArgc[
1009 119166 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kApiFunctionAddress
1010 : MachineType::IntPtr(), // kActualArgumentsCount
1011 : MachineType::AnyTagged(), // kCallData
1012 : MachineType::AnyTagged()) // kHolder
1013 59583 : DECLARE_DESCRIPTOR(ApiCallbackDescriptor, CallInterfaceDescriptor)
1014 : };
1015 :
1016 59583 : class ApiGetterDescriptor : public CallInterfaceDescriptor {
1017 : public:
1018 : DEFINE_PARAMETERS(kReceiver, kHolder, kCallback)
1019 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
1020 : MachineType::AnyTagged(), // kHolder
1021 : MachineType::AnyTagged()) // kCallback
1022 59583 : DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
1023 :
1024 : static const Register ReceiverRegister();
1025 : static const Register HolderRegister();
1026 : static const Register CallbackRegister();
1027 : };
1028 :
1029 : // TODO(turbofan): We should probably rename this to GrowFastElementsDescriptor.
1030 59583 : class GrowArrayElementsDescriptor : public CallInterfaceDescriptor {
1031 : public:
1032 : DEFINE_PARAMETERS(kObject, kKey)
1033 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kObject
1034 : MachineType::AnyTagged()) // kKey
1035 59583 : DECLARE_DESCRIPTOR(GrowArrayElementsDescriptor, CallInterfaceDescriptor)
1036 :
1037 : static const Register ObjectRegister();
1038 : static const Register KeyRegister();
1039 : };
1040 :
1041 59583 : class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
1042 : public:
1043 : DEFINE_PARAMETERS(kFrame, kLength, kMappedCount)
1044 119166 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kFrame
1045 : MachineType::TaggedSigned(), // kLength
1046 : MachineType::TaggedSigned()) // kMappedCount
1047 59583 : DECLARE_DESCRIPTOR(NewArgumentsElementsDescriptor, CallInterfaceDescriptor)
1048 : };
1049 :
1050 131745 : class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
1051 : : public CallInterfaceDescriptor {
1052 : public:
1053 : DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
1054 : kDispatchTable)
1055 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kAccumulator
1056 : MachineType::IntPtr(), // kBytecodeOffset
1057 : MachineType::AnyTagged(), // kBytecodeArray
1058 : MachineType::IntPtr()) // kDispatchTable
1059 131925 : DECLARE_DESCRIPTOR(InterpreterDispatchDescriptor, CallInterfaceDescriptor)
1060 : };
1061 :
1062 59583 : class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
1063 : public:
1064 : DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
1065 119166 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
1066 : MachineType::Pointer(), // kFirstArgument
1067 : MachineType::AnyTagged()) // kFunction
1068 59583 : DECLARE_DESCRIPTOR(InterpreterPushArgsThenCallDescriptor,
1069 : CallInterfaceDescriptor)
1070 : };
1071 :
1072 59583 : class InterpreterPushArgsThenConstructDescriptor
1073 : : public CallInterfaceDescriptor {
1074 : public:
1075 : DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kConstructor,
1076 : kNewTarget, kFeedbackElement)
1077 119166 : DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
1078 : MachineType::Pointer(), // kFirstArgument
1079 : MachineType::AnyTagged(), // kConstructor
1080 : MachineType::AnyTagged(), // kNewTarget
1081 : MachineType::AnyTagged()) // kFeedbackElement
1082 59583 : DECLARE_DESCRIPTOR(InterpreterPushArgsThenConstructDescriptor,
1083 : CallInterfaceDescriptor)
1084 :
1085 : #if V8_TARGET_ARCH_IA32
1086 : static const bool kPassLastArgsOnStack = true;
1087 : #else
1088 : static const bool kPassLastArgsOnStack = false;
1089 : #endif
1090 :
1091 : // Pass constructor, new target and feedback element through the stack.
1092 : static const int kStackArgumentsCount = kPassLastArgsOnStack ? 3 : 0;
1093 : };
1094 :
1095 59583 : class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
1096 : public:
1097 : DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
1098 : kFunctionEntry)
1099 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1100 : MachineType::Int32(), // kNumberOfArguments
1101 : MachineType::Pointer(), // kFirstArgument
1102 : MachineType::Pointer()) // kFunctionEntry
1103 59583 : DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
1104 : };
1105 :
1106 59583 : class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
1107 : public:
1108 : DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
1109 : kFunctionEntry)
1110 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1111 : MachineType::AnyTagged(), // result 2
1112 : MachineType::Int32(), // kNumberOfArguments
1113 : MachineType::Pointer(), // kFirstArgument
1114 : MachineType::Pointer()) // kFunctionEntry
1115 59583 : DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
1116 : };
1117 :
1118 59583 : class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
1119 : public:
1120 : DEFINE_PARAMETERS(kValue, kGenerator)
1121 119166 : DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
1122 : MachineType::AnyTagged()) // kGenerator
1123 59583 : DECLARE_DESCRIPTOR(ResumeGeneratorDescriptor, CallInterfaceDescriptor)
1124 : };
1125 :
1126 59583 : class FrameDropperTrampolineDescriptor final : public CallInterfaceDescriptor {
1127 : public:
1128 : DEFINE_PARAMETERS(kRestartFp)
1129 119166 : DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1130 59583 : DECLARE_DESCRIPTOR(FrameDropperTrampolineDescriptor, CallInterfaceDescriptor)
1131 : };
1132 :
1133 59583 : class RunMicrotasksEntryDescriptor final : public CallInterfaceDescriptor {
1134 : public:
1135 : DEFINE_PARAMETERS_ENTRY(kRootRegisterValue, kMicrotaskQueue)
1136 119166 : DEFINE_PARAMETER_TYPES(MachineType::Pointer(), // kRootRegisterValue
1137 : MachineType::Pointer()) // kMicrotaskQueue
1138 59583 : DECLARE_DESCRIPTOR(RunMicrotasksEntryDescriptor, CallInterfaceDescriptor)
1139 : };
1140 :
1141 59583 : class RunMicrotasksDescriptor final : public CallInterfaceDescriptor {
1142 : public:
1143 : DEFINE_PARAMETERS(kMicrotaskQueue)
1144 119166 : DEFINE_PARAMETER_TYPES(MachineType::Pointer())
1145 59583 : DECLARE_DESCRIPTOR(RunMicrotasksDescriptor, CallInterfaceDescriptor)
1146 :
1147 : static Register MicrotaskQueueRegister();
1148 : };
1149 :
1150 59583 : class WasmMemoryGrowDescriptor final : public CallInterfaceDescriptor {
1151 : public:
1152 : DEFINE_PARAMETERS_NO_CONTEXT(kNumPages)
1153 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int32(), // result 1
1154 : MachineType::Int32()) // kNumPages
1155 60703 : DECLARE_DESCRIPTOR(WasmMemoryGrowDescriptor, CallInterfaceDescriptor)
1156 : };
1157 :
1158 59583 : class WasmThrowDescriptor final : public CallInterfaceDescriptor {
1159 : public:
1160 : DEFINE_PARAMETERS_NO_CONTEXT(kException)
1161 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 1
1162 : MachineType::AnyTagged()) // kException
1163 60509 : DECLARE_DESCRIPTOR(WasmThrowDescriptor, CallInterfaceDescriptor)
1164 : };
1165 :
1166 59640 : class BigIntToWasmI64Descriptor final : public CallInterfaceDescriptor {
1167 : public:
1168 : DEFINE_PARAMETERS_NO_CONTEXT(kArgument)
1169 119166 : DEFINE_PARAMETER_TYPES(MachineType::Int64()) // kArgument
1170 59671 : DECLARE_DESCRIPTOR(BigIntToWasmI64Descriptor, CallInterfaceDescriptor)
1171 : };
1172 :
1173 59640 : class BigIntToI64Descriptor final : public CallInterfaceDescriptor {
1174 : public:
1175 : DEFINE_PARAMETERS(kArgument)
1176 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Int64(), // result 1
1177 : MachineType::AnyTagged()) // kArgument
1178 59655 : DECLARE_DESCRIPTOR(BigIntToI64Descriptor, CallInterfaceDescriptor)
1179 : };
1180 :
1181 59743 : class WasmAtomicWakeDescriptor final : public CallInterfaceDescriptor {
1182 : public:
1183 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kCount)
1184 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
1185 : MachineType::Uint32(), // kAddress
1186 : MachineType::Uint32()) // kCount
1187 59743 : DECLARE_DESCRIPTOR(WasmAtomicWakeDescriptor, CallInterfaceDescriptor)
1188 : };
1189 :
1190 59839 : class WasmI32AtomicWaitDescriptor final : public CallInterfaceDescriptor {
1191 : public:
1192 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
1193 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
1194 : MachineType::Uint32(), // kAddress
1195 : MachineType::Int32(), // kExpectedValue
1196 : MachineType::Float64()) // kTimeout
1197 59839 : DECLARE_DESCRIPTOR(WasmI32AtomicWaitDescriptor, CallInterfaceDescriptor)
1198 : };
1199 :
1200 59839 : class WasmI64AtomicWaitDescriptor final : public CallInterfaceDescriptor {
1201 : public:
1202 : DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValueHigh, kExpectedValueLow,
1203 : kTimeout)
1204 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(
1205 : MachineType::Uint32(), // result 1
1206 : MachineType::Uint32(), // kAddress
1207 : MachineType::Uint32(), // kExpectedValueHigh
1208 : MachineType::Uint32(), // kExpectedValueLow
1209 : MachineType::Float64()) // kTimeout
1210 59839 : DECLARE_DESCRIPTOR(WasmI64AtomicWaitDescriptor, CallInterfaceDescriptor)
1211 : };
1212 :
1213 59583 : class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
1214 : public:
1215 : DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
1216 119166 : DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 1
1217 : MachineType::AnyTagged(), // kSource
1218 : MachineType::TaggedSigned(), // kFlags
1219 : MachineType::TaggedSigned(), // kSlot
1220 : MachineType::AnyTagged()) // kVector
1221 59583 : DECLARE_DESCRIPTOR(CloneObjectWithVectorDescriptor, CallInterfaceDescriptor)
1222 : };
1223 :
1224 : #define DEFINE_TFS_BUILTIN_DESCRIPTOR(Name, ...) \
1225 : class Name##Descriptor : public CallInterfaceDescriptor { \
1226 : public: \
1227 : DEFINE_PARAMETERS(__VA_ARGS__) \
1228 : DECLARE_DEFAULT_DESCRIPTOR(Name##Descriptor, CallInterfaceDescriptor) \
1229 : };
1230 51479712 : BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
1231 : #undef DEFINE_TFS_BUILTIN_DESCRIPTOR
1232 :
1233 : #undef DECLARE_DEFAULT_DESCRIPTOR
1234 : #undef DECLARE_DESCRIPTOR_WITH_BASE
1235 : #undef DECLARE_DESCRIPTOR
1236 : #undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
1237 : #undef DEFINE_RESULT_AND_PARAMETERS
1238 : #undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT
1239 : #undef DEFINE_PARAMETERS
1240 : #undef DEFINE_PARAMETERS_NO_CONTEXT
1241 : #undef DEFINE_RESULT_AND_PARAMETER_TYPES
1242 : #undef DEFINE_PARAMETER_TYPES
1243 : #undef DEFINE_JS_PARAMETERS
1244 : #undef DEFINE_JS_PARAMETER_TYPES
1245 :
1246 : // We define the association between CallDescriptors::Key and the specialized
1247 : // descriptor here to reduce boilerplate and mistakes.
1248 : #define DEF_KEY(name, ...) \
1249 : CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
1250 74536 : INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
1251 : #undef DEF_KEY
1252 : } // namespace internal
1253 : } // namespace v8
1254 :
1255 : #endif // V8_INTERFACE_DESCRIPTORS_H_
|