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