Chromium Code Reviews| Index: src/interface-descriptors.h |
| diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h |
| index 5b552e892b530cafafd2e2e8d8f717ab7439f76d..7c5bb3ecdf9f86a4d770abccda1b73d995a554c2 100644 |
| --- a/src/interface-descriptors.h |
| +++ b/src/interface-descriptors.h |
| @@ -13,12 +13,45 @@ namespace internal { |
| class PlatformInterfaceDescriptor; |
| -class CallInterfaceDescriptor { |
| +#define INTERFACE_DESCRIPTOR_LIST(V) \ |
| + V(Load) \ |
| + V(Store) \ |
| + V(ElementTransitionAndStore) \ |
| + V(Instanceof) \ |
| + V(VectorLoadIC) \ |
| + V(FastNewClosure) \ |
| + V(FastNewContext) \ |
| + V(ToNumber) \ |
| + V(NumberToString) \ |
| + V(FastCloneShallowArray) \ |
| + V(FastCloneShallowObject) \ |
| + V(CreateAllocationSite) \ |
| + V(CallFunction) \ |
| + V(CallConstruct) \ |
| + V(RegExpConstructResult) \ |
| + V(TransitionElementsKind) \ |
| + V(ArrayConstructorConstantArgCount) \ |
| + V(ArrayConstructor) \ |
| + V(InternalArrayConstructorConstantArgCount) \ |
| + V(InternalArrayConstructor) \ |
| + V(CompareNil) \ |
| + V(ToBoolean) \ |
| + V(BinaryOp) \ |
| + V(BinaryOpWithAllocationSite) \ |
| + V(StringAdd) \ |
| + V(Keyed) \ |
| + V(Named) \ |
| + V(CallHandler) \ |
| + V(ArgumentAdaptor) \ |
| + V(ApiFunction) |
| + |
| + |
| +class CallInterfaceDescriptorData { |
| public: |
| - CallInterfaceDescriptor() : register_param_count_(-1) {} |
| + CallInterfaceDescriptorData() : register_param_count_(-1) {} |
| // A copy of the passed in registers and param_representations is made |
| - // and owned by the CallInterfaceDescriptor. |
| + // and owned by the CallInterfaceDescriptorData. |
| // TODO(mvstanton): Instead of taking parallel arrays register and |
| // param_representations, how about a struct that puts the representation |
| @@ -30,21 +63,80 @@ class CallInterfaceDescriptor { |
| bool IsInitialized() const { return register_param_count_ >= 0; } |
| - int GetEnvironmentLength() const { return register_param_count_; } |
| + int register_param_count() const { return register_param_count_; } |
| + Register register_param(int index) const { return register_params_[index]; } |
| + Register* register_params() const { return register_params_.get(); } |
| + Representation register_param_representation(int index) const { |
| + return register_param_representations_[index]; |
| + } |
| + Representation* register_param_representations() const { |
| + return register_param_representations_.get(); |
| + } |
| + PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
| + return platform_specific_descriptor_; |
| + } |
| + |
| + private: |
| + int register_param_count_; |
| + |
| + // The Register params are allocated dynamically by the |
| + // InterfaceDescriptor, and freed on destruction. This is because static |
| + // arrays of Registers cause creation of runtime static initializers |
| + // which we don't want. |
| + SmartArrayPointer<Register> register_params_; |
| + // Specifies Representations for the stub's parameter. Points to an array of |
| + // Representations of the same length of the numbers of parameters to the |
| + // stub, or if NULL (the default value), Representation of each parameter |
| + // assumed to be Tagged(). |
| + SmartArrayPointer<Representation> register_param_representations_; |
| - int GetRegisterParameterCount() const { return register_param_count_; } |
| + PlatformInterfaceDescriptor* platform_specific_descriptor_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptorData); |
| +}; |
| + |
| + |
| +class CallDescriptors { |
| + public: |
| + enum Key { |
| +#define DEF_ENUM(name) name, |
| + INTERFACE_DESCRIPTOR_LIST(DEF_ENUM) |
| +#undef DEF_ENUM |
| + NUMBER_OF_DESCRIPTORS |
| + }; |
| + |
| + static void InitializeForIsolate(Isolate* isolate); |
| +}; |
| + |
| + |
| +class CallInterfaceDescriptor { |
| + public: |
| + CallInterfaceDescriptor() : data_(NULL) {} |
| + |
| + CallInterfaceDescriptor(Isolate* isolate, CallDescriptors::Key key) |
| + : data_(isolate->call_descriptor_data(key)) {} |
|
Yang
2014/09/03 09:24:34
Can we simply
- fetch data from the isolate
- chec
|
| + |
| + bool IsInitialized() const { |
| + return data() != NULL && data()->IsInitialized(); |
|
Yang
2014/09/03 09:24:34
We then would also not need this any more. The con
|
| + } |
| + |
| + int GetEnvironmentLength() const { return data()->register_param_count(); } |
| + |
| + int GetRegisterParameterCount() const { |
| + return data()->register_param_count(); |
| + } |
| Register GetParameterRegister(int index) const { |
| - return register_params_[index]; |
| + return data()->register_param(index); |
| } |
| Representation GetParameterRepresentation(int index) const { |
| - DCHECK(index < register_param_count_); |
| - if (register_param_representations_.get() == NULL) { |
| + DCHECK(index < data()->register_param_count()); |
| + if (data()->register_param_representations() == NULL) { |
| return Representation::Tagged(); |
| } |
| - return register_param_representations_[index]; |
| + return data()->register_param_representation(index); |
| } |
| // "Environment" versions of parameter functions. The first register |
| @@ -63,76 +155,264 @@ class CallInterfaceDescriptor { |
| // Some platforms have extra information to associate with the descriptor. |
| PlatformInterfaceDescriptor* platform_specific_descriptor() const { |
| - return platform_specific_descriptor_; |
| + return data()->platform_specific_descriptor(); |
| } |
| static const Register ContextRegister(); |
| + protected: |
| + const CallInterfaceDescriptorData* data() const { return data_; } |
| + |
| + static void InitializeData( |
| + Isolate* isolate, CallDescriptors::Key key, int register_parameter_count, |
| + Register* registers, Representation* param_representations, |
| + PlatformInterfaceDescriptor* platform_descriptor = NULL) { |
| + isolate->call_descriptor_data(key) |
| + ->Initialize(register_parameter_count, registers, param_representations, |
| + platform_descriptor); |
| + } |
| + |
| private: |
| - int register_param_count_; |
| + const CallInterfaceDescriptorData* data_; |
| +}; |
| - // The Register params are allocated dynamically by the |
| - // InterfaceDescriptor, and freed on destruction. This is because static |
| - // arrays of Registers cause creation of runtime static initializers |
| - // which we don't want. |
| - SmartArrayPointer<Register> register_params_; |
| - // Specifies Representations for the stub's parameter. Points to an array of |
| - // Representations of the same length of the numbers of parameters to the |
| - // stub, or if NULL (the default value), Representation of each parameter |
| - // assumed to be Tagged(). |
| - SmartArrayPointer<Representation> register_param_representations_; |
| - PlatformInterfaceDescriptor* platform_specific_descriptor_; |
| +#define DECLARE_DESCRIPTOR(name) \ |
| + explicit name(Isolate* isolate) : CallInterfaceDescriptor(isolate, key()) {} \ |
| + static inline CallDescriptors::Key key(); \ |
| + static void Initialize(Isolate* isolate); |
| + |
| - DISALLOW_COPY_AND_ASSIGN(CallInterfaceDescriptor); |
| -}; |
| - |
| - |
| -enum CallDescriptorKey { |
| - LoadICCall, |
| - StoreICCall, |
| - ElementTransitionAndStoreCall, |
| - InstanceofCall, |
| - VectorLoadICCall, |
| - FastNewClosureCall, |
| - FastNewContextCall, |
| - ToNumberCall, |
| - NumberToStringCall, |
| - FastCloneShallowArrayCall, |
| - FastCloneShallowObjectCall, |
| - CreateAllocationSiteCall, |
| - CallFunctionCall, |
| - CallConstructCall, |
| - RegExpConstructResultCall, |
| - TransitionElementsKindCall, |
| - ArrayConstructorConstantArgCountCall, |
| - ArrayConstructorCall, |
| - InternalArrayConstructorConstantArgCountCall, |
| - InternalArrayConstructorCall, |
| - CompareNilCall, |
| - ToBooleanCall, |
| - BinaryOpCall, |
| - BinaryOpWithAllocationSiteCall, |
| - StringAddCall, |
| - KeyedCall, |
| - NamedCall, |
| - CallHandler, |
| - ArgumentAdaptorCall, |
| - ApiFunctionCall, |
| - NUMBER_OF_CALL_DESCRIPTORS |
| +class LoadDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(LoadDescriptor) |
| + |
| + enum ParameterIndices { kReceiverIndex, kNameIndex }; |
| + static const Register ReceiverRegister(); |
| + static const Register NameRegister(); |
| }; |
| -class CallDescriptors { |
| +class StoreDescriptor : public CallInterfaceDescriptor { |
| public: |
| - static void InitializeForIsolate(Isolate* isolate); |
| + DECLARE_DESCRIPTOR(StoreDescriptor) |
| - private: |
| - static void InitializeForIsolateAllPlatforms(Isolate* isolate); |
| + enum ParameterIndices { |
| + kReceiverIndex, |
| + kNameIndex, |
| + kValueIndex, |
| + kParameterCount |
| + }; |
| + static const Register ReceiverRegister(); |
| + static const Register NameRegister(); |
| + static const Register ValueRegister(); |
| }; |
| + |
| + |
| +class ElementTransitionAndStoreDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor) |
| + |
| + static const Register ReceiverRegister(); |
| + static const Register NameRegister(); |
| + static const Register ValueRegister(); |
| + static const Register MapRegister(); |
| +}; |
| + |
| + |
| +class InstanceofDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(InstanceofDescriptor) |
| + |
| + enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount }; |
| + static const Register left(); |
| + static const Register right(); |
| +}; |
| + |
| + |
| +class VectorLoadICDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(VectorLoadICDescriptor) |
| + |
| + enum ParameterIndices { |
| + kReceiverIndex, |
| + kNameIndex, |
| + kSlotIndex, |
| + kVectorIndex, |
| + kParameterCount |
| + }; |
| + |
| + static const Register ReceiverRegister(); |
| + static const Register NameRegister(); |
| + static const Register SlotRegister(); |
| + static const Register VectorRegister(); |
| +}; |
| + |
| + |
| +class FastNewClosureDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(FastNewClosureDescriptor) |
| +}; |
| + |
| + |
| +class FastNewContextDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(FastNewContextDescriptor) |
| +}; |
| + |
| + |
| +class ToNumberDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ToNumberDescriptor) |
| +}; |
| + |
| + |
| +class NumberToStringDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(NumberToStringDescriptor) |
| +}; |
| + |
| + |
| +class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor) |
| +}; |
| + |
| + |
| +class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor) |
| +}; |
| + |
| + |
| +class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor) |
| +}; |
| + |
| + |
| +class CallFunctionDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(CallFunctionDescriptor) |
| +}; |
| + |
| + |
| +class CallConstructDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(CallConstructDescriptor) |
| +}; |
| + |
| + |
| +class RegExpConstructResultDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor) |
| +}; |
| + |
| + |
| +class TransitionElementsKindDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor) |
| +}; |
| + |
| + |
| +class ArrayConstructorConstantArgCountDescriptor |
| + : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor) |
| +}; |
| + |
| + |
| +class ArrayConstructorDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ArrayConstructorDescriptor) |
| +}; |
| + |
| + |
| +class InternalArrayConstructorConstantArgCountDescriptor |
| + : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor) |
| +}; |
| + |
| + |
| +class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor) |
| +}; |
| + |
| + |
| +class CompareNilDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(CompareNilDescriptor) |
| +}; |
| + |
| + |
| +class ToBooleanDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ToBooleanDescriptor) |
| +}; |
| + |
| + |
| +class BinaryOpDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(BinaryOpDescriptor) |
| +}; |
| + |
| + |
| +class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor) |
| +}; |
| + |
| + |
| +class StringAddDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(StringAddDescriptor) |
| +}; |
| + |
| + |
| +class KeyedDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(KeyedDescriptor) |
| +}; |
| + |
| + |
| +class NamedDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(NamedDescriptor) |
| +}; |
| + |
| + |
| +class CallHandlerDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(CallHandlerDescriptor) |
| +}; |
| + |
| + |
| +class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor) |
| +}; |
| + |
| + |
| +class ApiFunctionDescriptor : public CallInterfaceDescriptor { |
| + public: |
| + DECLARE_DESCRIPTOR(ApiFunctionDescriptor) |
| +}; |
| + |
| +#undef DECLARE_DESCRIPTOR |
| + |
| + |
| +// We define the association between CallDescriptors::Key and the specialized |
| +// descriptor here to reduce boilerplate and mistakes. |
| +#define DEF_KEY(name) \ |
| + CallDescriptors::Key name##Descriptor::key() { return CallDescriptors::name; } |
| +INTERFACE_DESCRIPTOR_LIST(DEF_KEY) |
| +#undef DEF_KEY |
| } |
| } // namespace v8::internal |
| + |
| #if V8_TARGET_ARCH_ARM64 |
| #include "src/arm64/interface-descriptors-arm64.h" |
| #elif V8_TARGET_ARCH_ARM |