Home | History | Annotate | Download | only in src
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_CALL_INTERFACE_DESCRIPTOR_H_
      6 #define V8_CALL_INTERFACE_DESCRIPTOR_H_
      7 
      8 #include "src/assembler.h"
      9 #include "src/macro-assembler.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 class PlatformInterfaceDescriptor;
     15 
     16 #define INTERFACE_DESCRIPTOR_LIST(V)          \
     17   V(Load)                                     \
     18   V(Store)                                    \
     19   V(ElementTransitionAndStore)                \
     20   V(Instanceof)                               \
     21   V(VectorLoadICTrampoline)                   \
     22   V(VectorLoadIC)                             \
     23   V(FastNewClosure)                           \
     24   V(FastNewContext)                           \
     25   V(ToNumber)                                 \
     26   V(NumberToString)                           \
     27   V(FastCloneShallowArray)                    \
     28   V(FastCloneShallowObject)                   \
     29   V(CreateAllocationSite)                     \
     30   V(CallFunction)                             \
     31   V(CallFunctionWithFeedback)                 \
     32   V(CallConstruct)                            \
     33   V(RegExpConstructResult)                    \
     34   V(TransitionElementsKind)                   \
     35   V(ArrayConstructorConstantArgCount)         \
     36   V(ArrayConstructor)                         \
     37   V(InternalArrayConstructorConstantArgCount) \
     38   V(InternalArrayConstructor)                 \
     39   V(CompareNil)                               \
     40   V(ToBoolean)                                \
     41   V(BinaryOp)                                 \
     42   V(BinaryOpWithAllocationSite)               \
     43   V(StringAdd)                                \
     44   V(Keyed)                                    \
     45   V(Named)                                    \
     46   V(CallHandler)                              \
     47   V(ArgumentAdaptor)                          \
     48   V(ApiGetter)                                \
     49   V(ApiFunction)                              \
     50   V(ArgumentsAccessRead)                      \
     51   V(StoreArrayLiteralElement)                 \
     52   V(MathPowTagged)                            \
     53   V(MathPowInteger)                           \
     54   V(ContextOnly)
     55 
     56 
     57 class CallInterfaceDescriptorData {
     58  public:
     59   CallInterfaceDescriptorData() : register_param_count_(-1) {}
     60 
     61   // A copy of the passed in registers and param_representations is made
     62   // and owned by the CallInterfaceDescriptorData.
     63 
     64   // TODO(mvstanton): Instead of taking parallel arrays register and
     65   // param_representations, how about a struct that puts the representation
     66   // and register side by side (eg, RegRep(r1, Representation::Tagged()).
     67   // The same should go for the CodeStubDescriptor class.
     68   void Initialize(int register_parameter_count, Register* registers,
     69                   Representation* param_representations,
     70                   PlatformInterfaceDescriptor* platform_descriptor = NULL);
     71 
     72   bool IsInitialized() const { return register_param_count_ >= 0; }
     73 
     74   int register_param_count() const { return register_param_count_; }
     75   Register register_param(int index) const { return register_params_[index]; }
     76   Register* register_params() const { return register_params_.get(); }
     77   Representation register_param_representation(int index) const {
     78     return register_param_representations_[index];
     79   }
     80   Representation* register_param_representations() const {
     81     return register_param_representations_.get();
     82   }
     83   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
     84     return platform_specific_descriptor_;
     85   }
     86 
     87  private:
     88   int register_param_count_;
     89 
     90   // The Register params are allocated dynamically by the
     91   // InterfaceDescriptor, and freed on destruction. This is because static
     92   // arrays of Registers cause creation of runtime static initializers
     93   // which we don't want.
     94   SmartArrayPointer<Register> register_params_;
     95   // Specifies Representations for the stub's parameter. Points to an array of
     96   // Representations of the same length of the numbers of parameters to the
     97   // stub, or if NULL (the default value), Representation of each parameter
     98   // assumed to be Tagged().
     99   SmartArrayPointer<Representation> register_param_representations_;
    100 
    101   PlatformInterfaceDescriptor* platform_specific_descriptor_;
    102 
    103   DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData);
    104 };
    105 
    106 
    107 class CallDescriptors {
    108  public:
    109   enum Key {
    110 #define DEF_ENUM(name) name,
    111     INTERFACE_DESCRIPTOR_LIST(DEF_ENUM)
    112 #undef DEF_ENUM
    113     NUMBER_OF_DESCRIPTORS
    114   };
    115 };
    116 
    117 
    118 class CallInterfaceDescriptor {
    119  public:
    120   CallInterfaceDescriptor() : data_(NULL) {}
    121 
    122   CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key)
    123       : data_(isolate->call_descriptor_data(key)) {}
    124 
    125   int GetEnvironmentLength() const { return data()->register_param_count(); }
    126 
    127   int GetRegisterParameterCount() const {
    128     return data()->register_param_count();
    129   }
    130 
    131   Register GetParameterRegister(int index) const {
    132     return data()->register_param(index);
    133   }
    134 
    135   Representation GetParameterRepresentation(int index) const {
    136     DCHECK(index < data()->register_param_count());
    137     if (data()->register_param_representations() == NULL) {
    138       return Representation::Tagged();
    139     }
    140 
    141     return data()->register_param_representation(index);
    142   }
    143 
    144   // "Environment" versions of parameter functions. The first register
    145   // parameter (context) is not included.
    146   int GetEnvironmentParameterCount() const {
    147     return GetEnvironmentLength() - 1;
    148   }
    149 
    150   Register GetEnvironmentParameterRegister(int index) const {
    151     return GetParameterRegister(index + 1);
    152   }
    153 
    154   Representation GetEnvironmentParameterRepresentation(int index) const {
    155     return GetParameterRepresentation(index + 1);
    156   }
    157 
    158   // Some platforms have extra information to associate with the descriptor.
    159   PlatformInterfaceDescriptor* platform_specific_descriptor() const {
    160     return data()->platform_specific_descriptor();
    161   }
    162 
    163   static const Register ContextRegister();
    164 
    165   const char* DebugName(Isolate* isolate);
    166 
    167  protected:
    168   const CallInterfaceDescriptorData* data() const { return data_; }
    169 
    170  private:
    171   const CallInterfaceDescriptorData* data_;
    172 };
    173 
    174 
    175 #define DECLARE_DESCRIPTOR(name, base)                                     \
    176   explicit name(Isolate* isolate) : base(isolate, key()) {                 \
    177     if (!data()->IsInitialized())                                          \
    178       Initialize(isolate->call_descriptor_data(key()));                    \
    179   }                                                                        \
    180                                                                            \
    181  protected:                                                                \
    182   void Initialize(CallInterfaceDescriptorData* data);                      \
    183   name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \
    184                                                                            \
    185  public:                                                                   \
    186   static inline CallDescriptors::Key key();
    187 
    188 
    189 // LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs.
    190 class LoadDescriptor : public CallInterfaceDescriptor {
    191  public:
    192   DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor)
    193 
    194   enum ParameterIndices { kReceiverIndex, kNameIndex };
    195   static const Register ReceiverRegister();
    196   static const Register NameRegister();
    197 };
    198 
    199 
    200 class StoreDescriptor : public CallInterfaceDescriptor {
    201  public:
    202   DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
    203 
    204   enum ParameterIndices {
    205     kReceiverIndex,
    206     kNameIndex,
    207     kValueIndex,
    208     kParameterCount
    209   };
    210   static const Register ReceiverRegister();
    211   static const Register NameRegister();
    212   static const Register ValueRegister();
    213 };
    214 
    215 
    216 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
    217  public:
    218   DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
    219 
    220   static const Register MapRegister();
    221 };
    222 
    223 
    224 class InstanceofDescriptor : public CallInterfaceDescriptor {
    225  public:
    226   DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor)
    227 
    228   enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
    229   static const Register left();
    230   static const Register right();
    231 };
    232 
    233 
    234 class VectorLoadICTrampolineDescriptor : public LoadDescriptor {
    235  public:
    236   DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor)
    237 
    238   enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex };
    239 
    240   static const Register SlotRegister();
    241 };
    242 
    243 
    244 class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor {
    245  public:
    246   DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor)
    247 
    248   enum ParameterIndices {
    249     kReceiverIndex,
    250     kNameIndex,
    251     kSlotIndex,
    252     kVectorIndex
    253   };
    254 
    255   static const Register VectorRegister();
    256 };
    257 
    258 
    259 class FastNewClosureDescriptor : public CallInterfaceDescriptor {
    260  public:
    261   DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor)
    262 };
    263 
    264 
    265 class FastNewContextDescriptor : public CallInterfaceDescriptor {
    266  public:
    267   DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor)
    268 };
    269 
    270 
    271 class ToNumberDescriptor : public CallInterfaceDescriptor {
    272  public:
    273   DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor)
    274 };
    275 
    276 
    277 class NumberToStringDescriptor : public CallInterfaceDescriptor {
    278  public:
    279   DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor)
    280 };
    281 
    282 
    283 class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor {
    284  public:
    285   DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor)
    286 };
    287 
    288 
    289 class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor {
    290  public:
    291   DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor)
    292 };
    293 
    294 
    295 class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor {
    296  public:
    297   DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor)
    298 };
    299 
    300 
    301 class CallFunctionDescriptor : public CallInterfaceDescriptor {
    302  public:
    303   DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor)
    304 };
    305 
    306 
    307 class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor {
    308  public:
    309   DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor,
    310                      CallInterfaceDescriptor)
    311 };
    312 
    313 
    314 class CallConstructDescriptor : public CallInterfaceDescriptor {
    315  public:
    316   DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
    317 };
    318 
    319 
    320 class RegExpConstructResultDescriptor : public CallInterfaceDescriptor {
    321  public:
    322   DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor)
    323 };
    324 
    325 
    326 class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
    327  public:
    328   DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor)
    329 };
    330 
    331 
    332 class ArrayConstructorConstantArgCountDescriptor
    333     : public CallInterfaceDescriptor {
    334  public:
    335   DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor,
    336                      CallInterfaceDescriptor)
    337 };
    338 
    339 
    340 class ArrayConstructorDescriptor : public CallInterfaceDescriptor {
    341  public:
    342   DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor)
    343 };
    344 
    345 
    346 class InternalArrayConstructorConstantArgCountDescriptor
    347     : public CallInterfaceDescriptor {
    348  public:
    349   DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor,
    350                      CallInterfaceDescriptor)
    351 };
    352 
    353 
    354 class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor {
    355  public:
    356   DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor,
    357                      CallInterfaceDescriptor)
    358 };
    359 
    360 
    361 class CompareNilDescriptor : public CallInterfaceDescriptor {
    362  public:
    363   DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor)
    364 };
    365 
    366 
    367 class ToBooleanDescriptor : public CallInterfaceDescriptor {
    368  public:
    369   DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor)
    370 };
    371 
    372 
    373 class BinaryOpDescriptor : public CallInterfaceDescriptor {
    374  public:
    375   DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor)
    376 };
    377 
    378 
    379 class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor {
    380  public:
    381   DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor,
    382                      CallInterfaceDescriptor)
    383 };
    384 
    385 
    386 class StringAddDescriptor : public CallInterfaceDescriptor {
    387  public:
    388   DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor)
    389 };
    390 
    391 
    392 class KeyedDescriptor : public CallInterfaceDescriptor {
    393  public:
    394   DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor)
    395 };
    396 
    397 
    398 class NamedDescriptor : public CallInterfaceDescriptor {
    399  public:
    400   DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor)
    401 };
    402 
    403 
    404 class CallHandlerDescriptor : public CallInterfaceDescriptor {
    405  public:
    406   DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor)
    407 };
    408 
    409 
    410 class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor {
    411  public:
    412   DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor)
    413 };
    414 
    415 
    416 class ApiFunctionDescriptor : public CallInterfaceDescriptor {
    417  public:
    418   DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor)
    419 };
    420 
    421 
    422 class ApiGetterDescriptor : public CallInterfaceDescriptor {
    423  public:
    424   DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor)
    425 
    426   static const Register function_address();
    427 };
    428 
    429 
    430 class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor {
    431  public:
    432   DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor)
    433 
    434   static const Register index();
    435   static const Register parameter_count();
    436 };
    437 
    438 
    439 class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor {
    440  public:
    441   DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor,
    442                      CallInterfaceDescriptor)
    443 };
    444 
    445 
    446 class MathPowTaggedDescriptor : public CallInterfaceDescriptor {
    447  public:
    448   DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor)
    449 
    450   static const Register exponent();
    451 };
    452 
    453 
    454 class MathPowIntegerDescriptor : public CallInterfaceDescriptor {
    455  public:
    456   DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor)
    457 
    458   static const Register exponent();
    459 };
    460 
    461 
    462 class ContextOnlyDescriptor : public CallInterfaceDescriptor {
    463  public:
    464   DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor)
    465 };
    466 
    467 #undef DECLARE_DESCRIPTOR
    468 
    469 
    470 // We define the association between CallDescriptors::Key and the specialized
    471 // descriptor here to reduce boilerplate and mistakes.
    472 #define DEF_KEY(name) \
    473   CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; }
    474 INTERFACE_DESCRIPTOR_LIST(DEF_KEY)
    475 #undef DEF_KEY
    476 }
    477 }  // namespace v8::internal
    478 
    479 
    480 #if V8_TARGET_ARCH_ARM64
    481 #include "src/arm64/interface-descriptors-arm64.h"
    482 #elif V8_TARGET_ARCH_ARM
    483 #include "src/arm/interface-descriptors-arm.h"
    484 #endif
    485 
    486 #endif  // V8_CALL_INTERFACE_DESCRIPTOR_H_
    487