diff options
author | Fedor Indutny <fedor@indutny.com> | 2014-10-10 14:49:02 +0400 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2014-10-10 14:49:02 +0400 |
commit | 6bcea4ff932144a5fd02affefd45164fbf471e67 (patch) | |
tree | a8e078c679b12f0daebe10ed254239cb0d79e146 /deps/v8/src/code-stubs.h | |
parent | 4fae2356d105e394115188a814097c4a95ae0c5d (diff) | |
download | node-new-6bcea4ff932144a5fd02affefd45164fbf471e67.tar.gz |
deps: update v8 to 3.29.93.1
Diffstat (limited to 'deps/v8/src/code-stubs.h')
-rw-r--r-- | deps/v8/src/code-stubs.h | 1866 |
1 files changed, 885 insertions, 981 deletions
diff --git a/deps/v8/src/code-stubs.h b/deps/v8/src/code-stubs.h index c1d051b3d7..b127782c6e 100644 --- a/deps/v8/src/code-stubs.h +++ b/deps/v8/src/code-stubs.h @@ -9,6 +9,8 @@ #include "src/assembler.h" #include "src/codegen.h" #include "src/globals.h" +#include "src/ic/ic-state.h" +#include "src/interface-descriptors.h" #include "src/macro-assembler.h" #include "src/ostreams.h" @@ -17,89 +19,91 @@ namespace internal { // List of code stubs used on all platforms. #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ - V(CallFunction) \ - V(CallConstruct) \ - V(BinaryOpIC) \ + /* PlatformCodeStubs */ \ + V(ArgumentsAccess) \ + V(ArrayConstructor) \ V(BinaryOpICWithAllocationSite) \ - V(BinaryOpWithAllocationSite) \ - V(StringAdd) \ - V(SubString) \ - V(StringCompare) \ - V(Compare) \ - V(CompareIC) \ - V(CompareNilIC) \ - V(MathPow) \ + V(CallApiFunction) \ + V(CallApiGetter) \ + V(CallConstruct) \ + V(CallFunction) \ V(CallIC) \ V(CallIC_Array) \ + V(CEntry) \ + V(CompareIC) \ + V(DoubleToI) \ V(FunctionPrototype) \ - V(RecordWrite) \ - V(StoreBufferOverflow) \ - V(RegExpExec) \ V(Instanceof) \ - V(ConvertToDouble) \ - V(WriteInt32ToHeapNumber) \ - V(StackCheck) \ - V(Interrupt) \ - V(FastNewClosure) \ - V(FastNewContext) \ - V(FastCloneShallowArray) \ - V(FastCloneShallowObject) \ - V(CreateAllocationSite) \ - V(ToBoolean) \ - V(ToNumber) \ - V(ArgumentsAccess) \ - V(RegExpConstructResult) \ - V(NumberToString) \ - V(DoubleToI) \ - V(CEntry) \ + V(InternalArrayConstructor) \ V(JSEntry) \ - V(LoadElement) \ - V(KeyedLoadGeneric) \ + V(KeyedLoadICTrampoline) \ + V(LoadICTrampoline) \ + V(LoadIndexedInterceptor) \ + V(MathPow) \ + V(ProfileEntryHook) \ + V(RecordWrite) \ + V(RegExpExec) \ + V(StoreArrayLiteralElement) \ + V(StoreBufferOverflow) \ + V(StoreElement) \ + V(StringCompare) \ + V(StubFailureTrampoline) \ + V(SubString) \ + /* HydrogenCodeStubs */ \ + V(ArrayNArgumentsConstructor) \ V(ArrayNoArgumentConstructor) \ V(ArraySingleArgumentConstructor) \ - V(ArrayNArgumentsConstructor) \ + V(BinaryOpIC) \ + V(BinaryOpWithAllocationSite) \ + V(CompareNilIC) \ + V(CreateAllocationSite) \ + V(ElementsTransitionAndStore) \ + V(FastCloneShallowArray) \ + V(FastCloneShallowObject) \ + V(FastNewClosure) \ + V(FastNewContext) \ + V(InternalArrayNArgumentsConstructor) \ V(InternalArrayNoArgumentConstructor) \ V(InternalArraySingleArgumentConstructor) \ - V(InternalArrayNArgumentsConstructor) \ - V(StoreElement) \ - V(DebuggerStatement) \ + V(KeyedLoadGeneric) \ + V(LoadDictionaryElement) \ + V(LoadFastElement) \ + V(MegamorphicLoad) \ V(NameDictionaryLookup) \ - V(ElementsTransitionAndStore) \ + V(NumberToString) \ + V(RegExpConstructResult) \ + V(StoreFastElement) \ + V(StringAdd) \ + V(ToBoolean) \ + V(ToNumber) \ V(TransitionElementsKind) \ - V(StoreArrayLiteralElement) \ - V(StubFailureTrampoline) \ - V(ArrayConstructor) \ - V(InternalArrayConstructor) \ - V(ProfileEntryHook) \ - V(StoreGlobal) \ - V(CallApiFunction) \ - V(CallApiGetter) \ + V(VectorKeyedLoad) \ + V(VectorLoad) \ /* IC Handler stubs */ \ + V(LoadConstant) \ V(LoadField) \ + V(KeyedLoadSloppyArguments) \ V(StoreField) \ - V(LoadConstant) \ + V(StoreGlobal) \ V(StringLength) // List of code stubs only used on ARM 32 bits platforms. #if V8_TARGET_ARCH_ARM -#define CODE_STUB_LIST_ARM(V) \ - V(GetProperty) \ - V(SetProperty) \ - V(InvokeBuiltin) \ - V(DirectCEntry) +#define CODE_STUB_LIST_ARM(V) \ + V(DirectCEntry) \ + V(WriteInt32ToHeapNumber) + #else #define CODE_STUB_LIST_ARM(V) #endif // List of code stubs only used on ARM 64 bits platforms. #if V8_TARGET_ARCH_ARM64 -#define CODE_STUB_LIST_ARM64(V) \ - V(GetProperty) \ - V(SetProperty) \ - V(InvokeBuiltin) \ - V(DirectCEntry) \ - V(StoreRegistersState) \ - V(RestoreRegistersState) +#define CODE_STUB_LIST_ARM64(V) \ + V(DirectCEntry) \ + V(RestoreRegistersState) \ + V(StoreRegistersState) + #else #define CODE_STUB_LIST_ARM64(V) #endif @@ -107,16 +111,16 @@ namespace internal { // List of code stubs only used on MIPS platforms. #if V8_TARGET_ARCH_MIPS #define CODE_STUB_LIST_MIPS(V) \ - V(RegExpCEntry) \ V(DirectCEntry) \ + V(RestoreRegistersState) \ V(StoreRegistersState) \ - V(RestoreRegistersState) + V(WriteInt32ToHeapNumber) #elif V8_TARGET_ARCH_MIPS64 #define CODE_STUB_LIST_MIPS(V) \ - V(RegExpCEntry) \ V(DirectCEntry) \ + V(RestoreRegistersState) \ V(StoreRegistersState) \ - V(RestoreRegistersState) + V(WriteInt32ToHeapNumber) #else #define CODE_STUB_LIST_MIPS(V) #endif @@ -132,11 +136,12 @@ namespace internal { class CodeStub BASE_EMBEDDED { public: enum Major { - UninitializedMajorKey = 0, + // TODO(mvstanton): eliminate the NoCache key by getting rid + // of the non-monomorphic-cache. + NoCache = 0, // marker for stubs that do custom caching] #define DEF_ENUM(name) name, CODE_STUB_LIST(DEF_ENUM) #undef DEF_ENUM - NoCache, // marker for stubs that do custom caching NUMBER_OF_IDS }; @@ -149,7 +154,7 @@ class CodeStub BASE_EMBEDDED { static Major MajorKeyFromKey(uint32_t key) { return static_cast<Major>(MajorKeyBits::decode(key)); } - static int MinorKeyFromKey(uint32_t key) { + static uint32_t MinorKeyFromKey(uint32_t key) { return MinorKeyBits::decode(key); } @@ -162,7 +167,7 @@ class CodeStub BASE_EMBEDDED { static const char* MajorName(Major major_key, bool allow_unknown_keys); - explicit CodeStub(Isolate* isolate) : isolate_(isolate) { } + explicit CodeStub(Isolate* isolate) : minor_key_(0), isolate_(isolate) {} virtual ~CodeStub() {} static void GenerateStubsAheadOfTime(Isolate* isolate); @@ -179,9 +184,18 @@ class CodeStub BASE_EMBEDDED { // Lookup the code in the (possibly custom) cache. bool FindCodeInCache(Code** code_out); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() = 0; + + virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {} + + static void InitializeDescriptor(Isolate* isolate, uint32_t key, + CodeStubDescriptor* desc); + + static MaybeHandle<Code> GetCode(Isolate* isolate, uint32_t key); + // Returns information for computing the number key. virtual Major MajorKey() const = 0; - virtual int MinorKey() const = 0; + uint32_t MinorKey() const { return minor_key_; } virtual InlineCacheState GetICState() const { return UNINITIALIZED; } virtual ExtraICState GetExtraICState() const { return kNoExtraICState; } @@ -197,6 +211,9 @@ class CodeStub BASE_EMBEDDED { Isolate* isolate() const { return isolate_; } protected: + CodeStub(uint32_t key, Isolate* isolate) + : minor_key_(MinorKeyFromKey(key)), isolate_(isolate) {} + // Generates the assembler code for the stub. virtual Handle<Code> GenerateCode() = 0; @@ -214,6 +231,8 @@ class CodeStub BASE_EMBEDDED { return MinorKeyBits::encode(MinorKey()) | MajorKeyBits::encode(MajorKey()); } + uint32_t minor_key_; + private: // Perform bookkeeping required after code generation when stub code is // initially generated. @@ -242,6 +261,14 @@ class CodeStub BASE_EMBEDDED { // If a stub uses a special cache override this. virtual bool UseSpecialCache() { return false; } + // We use this dispatch to statically instantiate the correct code stub for + // the given stub key and call the passed function with that code stub. + typedef void (*DispatchedCall)(CodeStub* stub, void** value_out); + static void Dispatch(Isolate* isolate, uint32_t key, void** value_out, + DispatchedCall call); + + static void GetCodeDispatchCall(CodeStub* stub, void** value_out); + STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits)); class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {}; class MinorKeyBits: public BitField<uint32_t, @@ -253,111 +280,88 @@ class CodeStub BASE_EMBEDDED { }; -class PlatformCodeStub : public CodeStub { - public: - explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) { } - - // Retrieve the code for the stub. Generate the code if needed. - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual Code::Kind GetCodeKind() const { return Code::STUB; } - - protected: - // Generates the assembler code for the stub. - virtual void Generate(MacroAssembler* masm) = 0; -}; - - -enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; -enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; +#define DEFINE_CODE_STUB_BASE(NAME, SUPER) \ + public: \ + NAME(uint32_t key, Isolate* isolate) : SUPER(key, isolate) {} \ + \ + private: \ + DISALLOW_COPY_AND_ASSIGN(NAME) -class PlatformInterfaceDescriptor; +#define DEFINE_CODE_STUB(NAME, SUPER) \ + protected: \ + virtual inline Major MajorKey() const OVERRIDE { \ + return NAME; \ + }; \ + DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER) -class InterfaceDescriptor { - public: - bool IsInitialized() const { return register_param_count_ >= 0; } +#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER) \ + private: \ + virtual void Generate(MacroAssembler* masm) OVERRIDE; \ + DEFINE_CODE_STUB(NAME, SUPER) - int GetEnvironmentLength() const { return register_param_count_; } - int GetRegisterParameterCount() const { return register_param_count_; } +#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER) \ + public: \ + virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE; \ + virtual Handle<Code> GenerateCode() OVERRIDE; \ + DEFINE_CODE_STUB(NAME, SUPER) - Register GetParameterRegister(int index) const { - return register_params_[index]; - } - - Representation GetParameterRepresentation(int index) const { - DCHECK(index < register_param_count_); - if (register_param_representations_.get() == NULL) { - return Representation::Tagged(); - } +#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \ + public: \ + virtual Handle<Code> GenerateCode() OVERRIDE; \ + DEFINE_CODE_STUB(NAME, SUPER) - return register_param_representations_[index]; +#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME) \ + public: \ + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \ + return NAME##Descriptor(isolate()); \ } - // "Environment" versions of parameter functions. The first register - // parameter (context) is not included. - int GetEnvironmentParameterCount() const { - return GetEnvironmentLength() - 1; +// There are some code stubs we just can't describe right now with a +// CallInterfaceDescriptor. Isolate behavior for those cases with this macro. +// An attempt to retrieve a descriptor will fail. +#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \ + public: \ + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \ + UNREACHABLE(); \ + return CallInterfaceDescriptor(); \ } - Register GetEnvironmentParameterRegister(int index) const { - return GetParameterRegister(index + 1); - } - - Representation GetEnvironmentParameterRepresentation(int index) const { - return GetParameterRepresentation(index + 1); - } - // Some platforms have extra information to associate with the descriptor. - PlatformInterfaceDescriptor* platform_specific_descriptor() const { - return platform_specific_descriptor_; - } +class PlatformCodeStub : public CodeStub { + public: + // Retrieve the code for the stub. Generate the code if needed. + virtual Handle<Code> GenerateCode() OVERRIDE; - static const Register ContextRegister(); + virtual Code::Kind GetCodeKind() const { return Code::STUB; } protected: - InterfaceDescriptor(); - virtual ~InterfaceDescriptor() {} - - void Initialize(int register_parameter_count, Register* registers, - Representation* register_param_representations, - PlatformInterfaceDescriptor* platform_descriptor = NULL); + explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {} - private: - int register_param_count_; + // Generates the assembler code for the stub. + virtual void Generate(MacroAssembler* masm) = 0; - // 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_; + DEFINE_CODE_STUB_BASE(PlatformCodeStub, CodeStub); +}; - PlatformInterfaceDescriptor* platform_specific_descriptor_; - DISALLOW_COPY_AND_ASSIGN(InterfaceDescriptor); -}; +enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; +enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; -class CodeStubInterfaceDescriptor: public InterfaceDescriptor { +class CodeStubDescriptor { public: - CodeStubInterfaceDescriptor(); + explicit CodeStubDescriptor(CodeStub* stub); + + CodeStubDescriptor(Isolate* isolate, uint32_t stub_key); - void Initialize(CodeStub::Major major, int register_parameter_count, - Register* registers, Address deoptimization_handler = NULL, - Representation* register_param_representations = NULL, + void Initialize(Address deoptimization_handler = NULL, int hint_stack_parameter_count = -1, StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE); - void Initialize(CodeStub::Major major, int register_parameter_count, - Register* registers, Register stack_parameter_count, + void Initialize(Register stack_parameter_count, Address deoptimization_handler = NULL, - Representation* register_param_representations = NULL, int hint_stack_parameter_count = -1, StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE, HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS); @@ -370,6 +374,17 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor { DCHECK(!stack_parameter_count_.is_valid()); } + void set_call_descriptor(CallInterfaceDescriptor d) { call_descriptor_ = d; } + CallInterfaceDescriptor call_descriptor() const { return call_descriptor_; } + + int GetEnvironmentParameterCount() const { + return call_descriptor().GetEnvironmentParameterCount(); + } + + Representation GetEnvironmentParameterRepresentation(int index) const { + return call_descriptor().GetEnvironmentParameterRepresentation(index); + } + ExternalReference miss_handler() const { DCHECK(has_miss_handler_); return miss_handler_; @@ -380,11 +395,12 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor { } bool IsEnvironmentParameterCountRegister(int index) const { - return GetEnvironmentParameterRegister(index).is(stack_parameter_count_); + return call_descriptor().GetEnvironmentParameterRegister(index).is( + stack_parameter_count_); } int GetHandlerParameterCount() const { - int params = GetEnvironmentParameterCount(); + int params = call_descriptor().GetEnvironmentParameterCount(); if (handler_arguments_mode_ == PASS_ARGUMENTS) { params += 1; } @@ -395,9 +411,9 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor { Register stack_parameter_count() const { return stack_parameter_count_; } StubFunctionMode function_mode() const { return function_mode_; } Address deoptimization_handler() const { return deoptimization_handler_; } - CodeStub::Major MajorKey() const { return major_; } private: + CallInterfaceDescriptor call_descriptor_; Register stack_parameter_count_; // If hint_stack_parameter_count_ > 0, the code stub can optimize the // return sequence. Default value is -1, which means it is ignored. @@ -409,24 +425,6 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor { ExternalReference miss_handler_; bool has_miss_handler_; - CodeStub::Major major_; -}; - - -class CallInterfaceDescriptor: public InterfaceDescriptor { - public: - CallInterfaceDescriptor() { } - - // A copy of the passed in registers and param_representations is made - // and owned by the CallInterfaceDescriptor. - - // TODO(mvstanton): Instead of taking parallel arrays register and - // param_representations, how about a struct that puts the representation - // and register side by side (eg, RegRep(r1, Representation::Tagged()). - // The same should go for the CodeStubInterfaceDescriptor class. - void Initialize(int register_parameter_count, Register* registers, - Representation* param_representations, - PlatformInterfaceDescriptor* platform_descriptor = NULL); }; @@ -437,50 +435,46 @@ class HydrogenCodeStub : public CodeStub { INITIALIZED }; - explicit HydrogenCodeStub(Isolate* isolate, - InitializationState state = INITIALIZED) - : CodeStub(isolate) { - is_uninitialized_ = (state == UNINITIALIZED); - } - virtual Code::Kind GetCodeKind() const { return Code::STUB; } - CodeStubInterfaceDescriptor* GetInterfaceDescriptor() { - return isolate()->code_stub_interface_descriptor(MajorKey()); - } - - bool IsUninitialized() { return is_uninitialized_; } - template<class SubClass> static Handle<Code> GetUninitialized(Isolate* isolate) { SubClass::GenerateAheadOfTime(isolate); return SubClass().GetCode(isolate); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) = 0; - // Retrieve the code for the stub. Generate the code if needed. virtual Handle<Code> GenerateCode() = 0; - virtual int NotMissMinorKey() const = 0; + bool IsUninitialized() const { return IsMissBits::decode(minor_key_); } - Handle<Code> GenerateLightweightMissCode(); + Handle<Code> GenerateLightweightMissCode(ExternalReference miss); template<class StateType> void TraceTransition(StateType from, StateType to); - private: - class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {}; - class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {}; + protected: + explicit HydrogenCodeStub(Isolate* isolate, + InitializationState state = INITIALIZED) + : CodeStub(isolate) { + minor_key_ = IsMissBits::encode(state == UNINITIALIZED); + } - void GenerateLightweightMiss(MacroAssembler* masm); - virtual int MinorKey() const { - return IsMissBits::encode(is_uninitialized_) | - MinorKeyBits::encode(NotMissMinorKey()); + void set_sub_minor_key(uint32_t key) { + minor_key_ = SubMinorKeyBits::update(minor_key_, key); } - bool is_uninitialized_; + uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); } + + static const int kSubMinorKeyBits = kStubMinorKeyBits - 1; + + private: + class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {}; + class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {}; + + void GenerateLightweightMiss(MacroAssembler* masm, ExternalReference miss); + + DEFINE_CODE_STUB_BASE(HydrogenCodeStub, CodeStub); }; @@ -552,103 +546,72 @@ class ToNumberStub: public HydrogenCodeStub { public: explicit ToNumberStub(Isolate* isolate) : HydrogenCodeStub(isolate) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate) { - ToNumberStub stub(isolate); - stub.InitializeInterfaceDescriptor( - isolate->code_stub_interface_descriptor(CodeStub::ToNumber)); - } - - private: - Major MajorKey() const { return ToNumber; } - int NotMissMinorKey() const { return 0; } + DEFINE_CALL_INTERFACE_DESCRIPTOR(ToNumber); + DEFINE_HYDROGEN_CODE_STUB(ToNumber, HydrogenCodeStub); }; -class NumberToStringStub V8_FINAL : public HydrogenCodeStub { +class NumberToStringStub FINAL : public HydrogenCodeStub { public: explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kNumber = 0; - private: - virtual Major MajorKey() const V8_OVERRIDE { return NumberToString; } - virtual int NotMissMinorKey() const V8_OVERRIDE { return 0; } + DEFINE_CALL_INTERFACE_DESCRIPTOR(NumberToString); + DEFINE_HYDROGEN_CODE_STUB(NumberToString, HydrogenCodeStub); }; class FastNewClosureStub : public HydrogenCodeStub { public: - FastNewClosureStub(Isolate* isolate, - StrictMode strict_mode, - bool is_generator) - : HydrogenCodeStub(isolate), - strict_mode_(strict_mode), - is_generator_(is_generator) { } - - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + FastNewClosureStub(Isolate* isolate, StrictMode strict_mode, + FunctionKind kind) + : HydrogenCodeStub(isolate) { + DCHECK(IsValidFunctionKind(kind)); + set_sub_minor_key(StrictModeBits::encode(strict_mode) | + FunctionKindBits::encode(kind)); + } - static void InstallDescriptors(Isolate* isolate); + StrictMode strict_mode() const { + return StrictModeBits::decode(sub_minor_key()); + } - StrictMode strict_mode() const { return strict_mode_; } - bool is_generator() const { return is_generator_; } + FunctionKind kind() const { + return FunctionKindBits::decode(sub_minor_key()); + } + bool is_arrow() const { return IsArrowFunction(kind()); } + bool is_generator() const { return IsGeneratorFunction(kind()); } + bool is_concise_method() const { return IsConciseMethod(kind()); } private: - class StrictModeBits: public BitField<bool, 0, 1> {}; - class IsGeneratorBits: public BitField<bool, 1, 1> {}; + class StrictModeBits : public BitField<StrictMode, 0, 1> {}; + class FunctionKindBits : public BitField<FunctionKind, 1, 3> {}; - Major MajorKey() const { return FastNewClosure; } - int NotMissMinorKey() const { - return StrictModeBits::encode(strict_mode_ == STRICT) | - IsGeneratorBits::encode(is_generator_); - } - - StrictMode strict_mode_; - bool is_generator_; + DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure); + DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub); }; -class FastNewContextStub V8_FINAL : public HydrogenCodeStub { +class FastNewContextStub FINAL : public HydrogenCodeStub { public: static const int kMaximumSlots = 64; - FastNewContextStub(Isolate* isolate, int slots) - : HydrogenCodeStub(isolate), slots_(slots) { - DCHECK(slots_ > 0 && slots_ <= kMaximumSlots); + FastNewContextStub(Isolate* isolate, int slots) : HydrogenCodeStub(isolate) { + DCHECK(slots > 0 && slots <= kMaximumSlots); + set_sub_minor_key(SlotsBits::encode(slots)); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - - int slots() const { return slots_; } - - virtual Major MajorKey() const V8_OVERRIDE { return FastNewContext; } - virtual int NotMissMinorKey() const V8_OVERRIDE { return slots_; } + int slots() const { return SlotsBits::decode(sub_minor_key()); } // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kFunction = 0; private: - int slots_; + class SlotsBits : public BitField<int, 0, 8> {}; + + DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewContext); + DEFINE_HYDROGEN_CODE_STUB(FastNewContext, HydrogenCodeStub); }; @@ -656,29 +619,19 @@ class FastCloneShallowArrayStub : public HydrogenCodeStub { public: FastCloneShallowArrayStub(Isolate* isolate, AllocationSiteMode allocation_site_mode) - : HydrogenCodeStub(isolate), - allocation_site_mode_(allocation_site_mode) {} + : HydrogenCodeStub(isolate) { + set_sub_minor_key(AllocationSiteModeBits::encode(allocation_site_mode)); + } AllocationSiteMode allocation_site_mode() const { - return allocation_site_mode_; + return AllocationSiteModeBits::decode(sub_minor_key()); } - virtual Handle<Code> GenerateCode(); - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - private: - AllocationSiteMode allocation_site_mode_; - class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {}; - // Ensure data fits within available bits. - Major MajorKey() const { return FastCloneShallowArray; } - int NotMissMinorKey() const { - return AllocationSiteModeBits::encode(allocation_site_mode_); - } + + DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowArray); + DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowArray, HydrogenCodeStub); }; @@ -688,25 +641,19 @@ class FastCloneShallowObjectStub : public HydrogenCodeStub { static const int kMaximumClonedProperties = 6; FastCloneShallowObjectStub(Isolate* isolate, int length) - : HydrogenCodeStub(isolate), length_(length) { - DCHECK_GE(length_, 0); - DCHECK_LE(length_, kMaximumClonedProperties); + : HydrogenCodeStub(isolate) { + DCHECK_GE(length, 0); + DCHECK_LE(length, kMaximumClonedProperties); + set_sub_minor_key(LengthBits::encode(length)); } - int length() const { return length_; } - - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + int length() const { return LengthBits::decode(sub_minor_key()); } private: - int length_; + class LengthBits : public BitField<int, 0, 4> {}; - Major MajorKey() const { return FastCloneShallowObject; } - int NotMissMinorKey() const { return length_; } - - DISALLOW_COPY_AND_ASSIGN(FastCloneShallowObjectStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(FastCloneShallowObject); + DEFINE_HYDROGEN_CODE_STUB(FastCloneShallowObject, HydrogenCodeStub); }; @@ -715,18 +662,10 @@ class CreateAllocationSiteStub : public HydrogenCodeStub { explicit CreateAllocationSiteStub(Isolate* isolate) : HydrogenCodeStub(isolate) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - static void GenerateAheadOfTime(Isolate* isolate); - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - private: - Major MajorKey() const { return CreateAllocationSite; } - int NotMissMinorKey() const { return 0; } - - DISALLOW_COPY_AND_ASSIGN(CreateAllocationSiteStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(CreateAllocationSite); + DEFINE_HYDROGEN_CODE_STUB(CreateAllocationSite, HydrogenCodeStub); }; @@ -739,36 +678,38 @@ class InstanceofStub: public PlatformCodeStub { kReturnTrueFalseObject = 1 << 2 }; - InstanceofStub(Isolate* isolate, Flags flags) - : PlatformCodeStub(isolate), flags_(flags) { } - - static Register left(); - static Register right(); + InstanceofStub(Isolate* isolate, Flags flags) : PlatformCodeStub(isolate) { + minor_key_ = FlagBits::encode(flags); + } - void Generate(MacroAssembler* masm); + static Register left() { return InstanceofDescriptor::left(); } + static Register right() { return InstanceofDescriptor::right(); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor); + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (HasArgsInRegisters()) { + return InstanceofDescriptor(isolate()); + } + return ContextOnlyDescriptor(isolate()); + } private: - Major MajorKey() const { return Instanceof; } - int MinorKey() const { return static_cast<int>(flags_); } + Flags flags() const { return FlagBits::decode(minor_key_); } - bool HasArgsInRegisters() const { - return (flags_ & kArgsInRegisters) != 0; - } + bool HasArgsInRegisters() const { return (flags() & kArgsInRegisters) != 0; } bool HasCallSiteInlineCheck() const { - return (flags_ & kCallSiteInlineCheck) != 0; + return (flags() & kCallSiteInlineCheck) != 0; } bool ReturnTrueFalseObject() const { - return (flags_ & kReturnTrueFalseObject) != 0; + return (flags() & kReturnTrueFalseObject) != 0; } - virtual void PrintName(OStream& os) const V8_OVERRIDE; // NOLINT + virtual void PrintName(OStream& os) const OVERRIDE; // NOLINT + + class FlagBits : public BitField<Flags, 0, 3> {}; - Flags flags_; + DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub); }; @@ -782,20 +723,25 @@ enum AllocationSiteOverrideMode { class ArrayConstructorStub: public PlatformCodeStub { public: enum ArgumentCountKey { ANY, NONE, ONE, MORE_THAN_ONE }; + ArrayConstructorStub(Isolate* isolate, int argument_count); - explicit ArrayConstructorStub(Isolate* isolate); - void Generate(MacroAssembler* masm); + explicit ArrayConstructorStub(Isolate* isolate); private: + ArgumentCountKey argument_count() const { + return ArgumentCountBits::decode(minor_key_); + } + void GenerateDispatchToArrayStub(MacroAssembler* masm, AllocationSiteOverrideMode mode); - virtual void PrintName(OStream& os) const V8_OVERRIDE; // NOLINT - virtual CodeStub::Major MajorKey() const { return ArrayConstructor; } - virtual int MinorKey() const { return argument_count_; } + virtual void PrintName(OStream& os) const OVERRIDE; // NOLINT + + class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {}; - ArgumentCountKey argument_count_; + DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor); + DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub); }; @@ -803,13 +749,11 @@ class InternalArrayConstructorStub: public PlatformCodeStub { public: explicit InternalArrayConstructorStub(Isolate* isolate); - void Generate(MacroAssembler* masm); - private: - virtual CodeStub::Major MajorKey() const { return InternalArrayConstructor; } - virtual int MinorKey() const { return 0; } - void GenerateCase(MacroAssembler* masm, ElementsKind kind); + + DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor); + DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub); }; @@ -818,71 +762,86 @@ class MathPowStub: public PlatformCodeStub { enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK }; MathPowStub(Isolate* isolate, ExponentType exponent_type) - : PlatformCodeStub(isolate), exponent_type_(exponent_type) { } - virtual void Generate(MacroAssembler* masm); + : PlatformCodeStub(isolate) { + minor_key_ = ExponentTypeBits::encode(exponent_type); + } + + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (exponent_type() == TAGGED) { + return MathPowTaggedDescriptor(isolate()); + } else if (exponent_type() == INTEGER) { + return MathPowIntegerDescriptor(isolate()); + } + // A CallInterfaceDescriptor doesn't specify double registers (yet). + return ContextOnlyDescriptor(isolate()); + } private: - virtual CodeStub::Major MajorKey() const { return MathPow; } - virtual int MinorKey() const { return exponent_type_; } + ExponentType exponent_type() const { + return ExponentTypeBits::decode(minor_key_); + } - ExponentType exponent_type_; + class ExponentTypeBits : public BitField<ExponentType, 0, 2> {}; + + DEFINE_PLATFORM_CODE_STUB(MathPow, PlatformCodeStub); }; class CallICStub: public PlatformCodeStub { public: - CallICStub(Isolate* isolate, const CallIC::State& state) - : PlatformCodeStub(isolate), state_(state) {} - - bool CallAsMethod() const { return state_.CallAsMethod(); } - - int arg_count() const { return state_.arg_count(); } + CallICStub(Isolate* isolate, const CallICState& state) + : PlatformCodeStub(isolate) { + minor_key_ = state.GetExtraICState(); + } static int ExtractArgcFromMinorKey(int minor_key) { - CallIC::State state((ExtraICState) minor_key); + CallICState state(static_cast<ExtraICState>(minor_key)); return state.arg_count(); } - virtual void Generate(MacroAssembler* masm); - - virtual Code::Kind GetCodeKind() const V8_OVERRIDE { - return Code::CALL_IC; - } + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::CALL_IC; } - virtual InlineCacheState GetICState() const V8_OVERRIDE { return DEFAULT; } + virtual InlineCacheState GetICState() const OVERRIDE { return DEFAULT; } - virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { - return state_.GetExtraICState(); + virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { + return static_cast<ExtraICState>(minor_key_); } protected: - virtual int MinorKey() const { return GetExtraICState(); } - virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT + bool CallAsMethod() const { + return state().call_type() == CallICState::METHOD; + } + + int arg_count() const { return state().arg_count(); } - virtual CodeStub::Major MajorKey() const { return CallIC; } + CallICState state() const { + return CallICState(static_cast<ExtraICState>(minor_key_)); + } // Code generation helpers. - void GenerateMiss(MacroAssembler* masm, IC::UtilityId id); + void GenerateMiss(MacroAssembler* masm); - const CallIC::State state_; + private: + virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT + + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback); + DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub); }; class CallIC_ArrayStub: public CallICStub { public: - CallIC_ArrayStub(Isolate* isolate, const CallIC::State& state_in) + CallIC_ArrayStub(Isolate* isolate, const CallICState& state_in) : CallICStub(isolate, state_in) {} - virtual void Generate(MacroAssembler* masm); - - virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { + virtual InlineCacheState GetICState() const FINAL OVERRIDE { return MONOMORPHIC; } - protected: - virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT + private: + virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT - virtual CodeStub::Major MajorKey() const { return CallIC_Array; } + DEFINE_PLATFORM_CODE_STUB(CallIC_Array, CallICStub); }; @@ -891,12 +850,28 @@ class FunctionPrototypeStub : public PlatformCodeStub { public: explicit FunctionPrototypeStub(Isolate* isolate) : PlatformCodeStub(isolate) {} - virtual void Generate(MacroAssembler* masm); + virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } - private: - virtual CodeStub::Major MajorKey() const { return FunctionPrototype; } - virtual int MinorKey() const { return 0; } + // TODO(mvstanton): only the receiver register is accessed. When this is + // translated to a hydrogen code stub, a new CallInterfaceDescriptor + // should be created that just uses that register for more efficient code. + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub); +}; + + +// TODO(mvstanton): Translate to hydrogen code stub. +class LoadIndexedInterceptorStub : public PlatformCodeStub { + public: + explicit LoadIndexedInterceptorStub(Isolate* isolate) + : PlatformCodeStub(isolate) {} + + virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } + virtual Code::StubType GetStubType() { return Code::FAST; } + + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_PLATFORM_CODE_STUB(LoadIndexedInterceptor, PlatformCodeStub); }; @@ -906,73 +881,87 @@ class HandlerStub : public HydrogenCodeStub { virtual ExtraICState GetExtraICState() const { return kind(); } virtual InlineCacheState GetICState() const { return MONOMORPHIC; } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE; + + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE; protected: - explicit HandlerStub(Isolate* isolate) - : HydrogenCodeStub(isolate), bit_field_(0) {} - virtual int NotMissMinorKey() const { return bit_field_; } + explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} + virtual Code::Kind kind() const = 0; - int bit_field_; + + DEFINE_CODE_STUB_BASE(HandlerStub, HydrogenCodeStub); }; class LoadFieldStub: public HandlerStub { public: - LoadFieldStub(Isolate* isolate, FieldIndex index) - : HandlerStub(isolate), index_(index) { - int property_index_key = index_.GetFieldAccessStubKey(); - bit_field_ = EncodedLoadFieldByIndexBits::encode(property_index_key); + LoadFieldStub(Isolate* isolate, FieldIndex index) : HandlerStub(isolate) { + int property_index_key = index.GetFieldAccessStubKey(); + set_sub_minor_key(LoadFieldByIndexBits::encode(property_index_key)); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - FieldIndex index() const { return index_; } + FieldIndex index() const { + int property_index_key = LoadFieldByIndexBits::decode(sub_minor_key()); + return FieldIndex::FromFieldAccessStubKey(property_index_key); + } protected: - explicit LoadFieldStub(Isolate* isolate); virtual Code::Kind kind() const { return Code::LOAD_IC; } virtual Code::StubType GetStubType() { return Code::FAST; } private: - class EncodedLoadFieldByIndexBits : public BitField<int, 0, 13> {}; - virtual CodeStub::Major MajorKey() const { return LoadField; } - FieldIndex index_; + class LoadFieldByIndexBits : public BitField<int, 0, 13> {}; + + DEFINE_HANDLER_CODE_STUB(LoadField, HandlerStub); +}; + + +class KeyedLoadSloppyArgumentsStub : public HandlerStub { + public: + explicit KeyedLoadSloppyArgumentsStub(Isolate* isolate) + : HandlerStub(isolate) {} + + protected: + virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } + virtual Code::StubType GetStubType() { return Code::FAST; } + + private: + DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub); }; class LoadConstantStub : public HandlerStub { public: - LoadConstantStub(Isolate* isolate, int descriptor) : HandlerStub(isolate) { - bit_field_ = descriptor; + LoadConstantStub(Isolate* isolate, int constant_index) + : HandlerStub(isolate) { + set_sub_minor_key(ConstantIndexBits::encode(constant_index)); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - int descriptor() const { return bit_field_; } + int constant_index() const { + return ConstantIndexBits::decode(sub_minor_key()); + } protected: - explicit LoadConstantStub(Isolate* isolate); virtual Code::Kind kind() const { return Code::LOAD_IC; } virtual Code::StubType GetStubType() { return Code::FAST; } private: - virtual CodeStub::Major MajorKey() const { return LoadConstant; } + class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {}; + + DEFINE_HANDLER_CODE_STUB(LoadConstant, HandlerStub); }; class StringLengthStub: public HandlerStub { public: explicit StringLengthStub(Isolate* isolate) : HandlerStub(isolate) {} - virtual Handle<Code> GenerateCode() V8_OVERRIDE; protected: virtual Code::Kind kind() const { return Code::LOAD_IC; } virtual Code::StubType GetStubType() { return Code::FAST; } - private: - virtual CodeStub::Major MajorKey() const { return StringLength; } + DEFINE_HANDLER_CODE_STUB(StringLength, HandlerStub); }; @@ -980,30 +969,32 @@ class StoreFieldStub : public HandlerStub { public: StoreFieldStub(Isolate* isolate, FieldIndex index, Representation representation) - : HandlerStub(isolate), index_(index), representation_(representation) { - int property_index_key = index_.GetFieldAccessStubKey(); - bit_field_ = EncodedStoreFieldByIndexBits::encode(property_index_key) | - RepresentationBits::encode( - PropertyDetails::EncodeRepresentation(representation)); + : HandlerStub(isolate) { + int property_index_key = index.GetFieldAccessStubKey(); + uint8_t repr = PropertyDetails::EncodeRepresentation(representation); + set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) | + RepresentationBits::encode(repr)); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + FieldIndex index() const { + int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key()); + return FieldIndex::FromFieldAccessStubKey(property_index_key); + } - FieldIndex index() const { return index_; } - Representation representation() { return representation_; } - static void InstallDescriptors(Isolate* isolate); + Representation representation() { + uint8_t repr = RepresentationBits::decode(sub_minor_key()); + return PropertyDetails::DecodeRepresentation(repr); + } protected: - explicit StoreFieldStub(Isolate* isolate); virtual Code::Kind kind() const { return Code::STORE_IC; } virtual Code::StubType GetStubType() { return Code::FAST; } private: - class EncodedStoreFieldByIndexBits : public BitField<int, 0, 13> {}; - class RepresentationBits : public BitField<int, 13, 4> {}; - virtual CodeStub::Major MajorKey() const { return StoreField; } - FieldIndex index_; - Representation representation_; + class StoreFieldByIndexBits : public BitField<int, 0, 13> {}; + class RepresentationBits : public BitField<uint8_t, 13, 4> {}; + + DEFINE_HANDLER_CODE_STUB(StoreField, HandlerStub); }; @@ -1011,8 +1002,8 @@ class StoreGlobalStub : public HandlerStub { public: StoreGlobalStub(Isolate* isolate, bool is_constant, bool check_global) : HandlerStub(isolate) { - bit_field_ = IsConstantBits::encode(is_constant) | - CheckGlobalBits::encode(check_global); + set_sub_minor_key(IsConstantBits::encode(is_constant) | + CheckGlobalBits::encode(check_global)); } static Handle<HeapObject> global_placeholder(Isolate* isolate) { @@ -1036,33 +1027,29 @@ class StoreGlobalStub : public HandlerStub { virtual Code::Kind kind() const { return Code::STORE_IC; } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + bool is_constant() const { return IsConstantBits::decode(sub_minor_key()); } + + bool check_global() const { return CheckGlobalBits::decode(sub_minor_key()); } - bool is_constant() const { - return IsConstantBits::decode(bit_field_); - } - bool check_global() const { - return CheckGlobalBits::decode(bit_field_); - } void set_is_constant(bool value) { - bit_field_ = IsConstantBits::update(bit_field_, value); + set_sub_minor_key(IsConstantBits::update(sub_minor_key(), value)); } Representation representation() { - return Representation::FromKind(RepresentationBits::decode(bit_field_)); + return Representation::FromKind( + RepresentationBits::decode(sub_minor_key())); } + void set_representation(Representation r) { - bit_field_ = RepresentationBits::update(bit_field_, r.kind()); + set_sub_minor_key(RepresentationBits::update(sub_minor_key(), r.kind())); } private: - Major MajorKey() const { return StoreGlobal; } - class IsConstantBits: public BitField<bool, 0, 1> {}; class RepresentationBits: public BitField<Representation::Kind, 1, 8> {}; class CheckGlobalBits: public BitField<bool, 9, 1> {}; - DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub); + DEFINE_HANDLER_CODE_STUB(StoreGlobal, HandlerStub); }; @@ -1072,25 +1059,26 @@ class CallApiFunctionStub : public PlatformCodeStub { bool is_store, bool call_data_undefined, int argc) : PlatformCodeStub(isolate) { - bit_field_ = - IsStoreBits::encode(is_store) | - CallDataUndefinedBits::encode(call_data_undefined) | - ArgumentBits::encode(argc); + minor_key_ = IsStoreBits::encode(is_store) | + CallDataUndefinedBits::encode(call_data_undefined) | + ArgumentBits::encode(argc); DCHECK(!is_store || argc == 1); } private: - virtual void Generate(MacroAssembler* masm) V8_OVERRIDE; - virtual Major MajorKey() const V8_OVERRIDE { return CallApiFunction; } - virtual int MinorKey() const V8_OVERRIDE { return bit_field_; } + bool is_store() const { return IsStoreBits::decode(minor_key_); } + bool call_data_undefined() const { + return CallDataUndefinedBits::decode(minor_key_); + } + int argc() const { return ArgumentBits::decode(minor_key_); } class IsStoreBits: public BitField<bool, 0, 1> {}; class CallDataUndefinedBits: public BitField<bool, 1, 1> {}; class ArgumentBits: public BitField<int, 2, Code::kArgumentsBits> {}; + STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits); - int bit_field_; - - DISALLOW_COPY_AND_ASSIGN(CallApiFunctionStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction); + DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub); }; @@ -1098,12 +1086,8 @@ class CallApiGetterStub : public PlatformCodeStub { public: explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {} - private: - virtual void Generate(MacroAssembler* masm) V8_OVERRIDE; - virtual Major MajorKey() const V8_OVERRIDE { return CallApiGetter; } - virtual int MinorKey() const V8_OVERRIDE { return 0; } - - DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter); + DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub); }; @@ -1111,62 +1095,58 @@ class BinaryOpICStub : public HydrogenCodeStub { public: BinaryOpICStub(Isolate* isolate, Token::Value op, OverwriteMode mode = NO_OVERWRITE) - : HydrogenCodeStub(isolate, UNINITIALIZED), state_(isolate, op, mode) {} + : HydrogenCodeStub(isolate, UNINITIALIZED) { + BinaryOpICState state(isolate, op, mode); + set_sub_minor_key(state.GetExtraICState()); + } - explicit BinaryOpICStub(Isolate* isolate, const BinaryOpIC::State& state) - : HydrogenCodeStub(isolate), state_(state) {} + BinaryOpICStub(Isolate* isolate, const BinaryOpICState& state) + : HydrogenCodeStub(isolate) { + set_sub_minor_key(state.GetExtraICState()); + } static void GenerateAheadOfTime(Isolate* isolate); - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - - virtual Code::Kind GetCodeKind() const V8_OVERRIDE { + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; } - virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { - return state_.GetICState(); + virtual InlineCacheState GetICState() const FINAL OVERRIDE { + return state().GetICState(); } - virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { - return state_.GetExtraICState(); + virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { + return static_cast<ExtraICState>(sub_minor_key()); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - const BinaryOpIC::State& state() const { return state_; } - - virtual void PrintState(OStream& os) const V8_FINAL V8_OVERRIDE; // NOLINT - - virtual Major MajorKey() const V8_OVERRIDE { return BinaryOpIC; } - virtual int NotMissMinorKey() const V8_FINAL V8_OVERRIDE { - return GetExtraICState(); + BinaryOpICState state() const { + return BinaryOpICState(isolate(), GetExtraICState()); } + virtual void PrintState(OStream& os) const FINAL OVERRIDE; // NOLINT + // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kLeft = 0; static const int kRight = 1; private: static void GenerateAheadOfTime(Isolate* isolate, - const BinaryOpIC::State& state); - - BinaryOpIC::State state_; + const BinaryOpICState& state); - DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp); + DEFINE_HYDROGEN_CODE_STUB(BinaryOpIC, HydrogenCodeStub); }; // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail // call support for stubs in Hydrogen. -class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub { +class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub { public: BinaryOpICWithAllocationSiteStub(Isolate* isolate, - const BinaryOpIC::State& state) - : PlatformCodeStub(isolate), state_(state) {} + const BinaryOpICState& state) + : PlatformCodeStub(isolate) { + minor_key_ = state.GetExtraICState(); + } static void GenerateAheadOfTime(Isolate* isolate); @@ -1176,67 +1156,54 @@ class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub { return CodeStub::GetCodeCopy(pattern); } - virtual Code::Kind GetCodeKind() const V8_OVERRIDE { + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; } - virtual InlineCacheState GetICState() const V8_OVERRIDE { - return state_.GetICState(); + virtual InlineCacheState GetICState() const OVERRIDE { + return state().GetICState(); } - virtual ExtraICState GetExtraICState() const V8_OVERRIDE { - return state_.GetExtraICState(); + virtual ExtraICState GetExtraICState() const OVERRIDE { + return static_cast<ExtraICState>(minor_key_); } - virtual void Generate(MacroAssembler* masm) V8_OVERRIDE; - - virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT + virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT - virtual Major MajorKey() const V8_OVERRIDE { - return BinaryOpICWithAllocationSite; + private: + BinaryOpICState state() const { + return BinaryOpICState(isolate(), static_cast<ExtraICState>(minor_key_)); } - virtual int MinorKey() const V8_OVERRIDE { return GetExtraICState(); } - private: static void GenerateAheadOfTime(Isolate* isolate, - const BinaryOpIC::State& state); + const BinaryOpICState& state); - BinaryOpIC::State state_; - - DISALLOW_COPY_AND_ASSIGN(BinaryOpICWithAllocationSiteStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite); + DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub); }; -class BinaryOpWithAllocationSiteStub V8_FINAL : public BinaryOpICStub { +class BinaryOpWithAllocationSiteStub FINAL : public BinaryOpICStub { public: BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op, OverwriteMode mode) : BinaryOpICStub(isolate, op, mode) {} - BinaryOpWithAllocationSiteStub(Isolate* isolate, - const BinaryOpIC::State& state) + BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state) : BinaryOpICStub(isolate, state) {} - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - - virtual Code::Kind GetCodeKind() const V8_FINAL V8_OVERRIDE { + virtual Code::Kind GetCodeKind() const FINAL OVERRIDE { return Code::STUB; } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual Major MajorKey() const V8_OVERRIDE { - return BinaryOpWithAllocationSite; - } - // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kAllocationSite = 0; static const int kLeft = 1; static const int kRight = 2; + + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite); + DEFINE_HYDROGEN_CODE_STUB(BinaryOpWithAllocationSite, BinaryOpICStub); }; @@ -1252,30 +1219,23 @@ enum StringAddFlags { }; -class StringAddStub V8_FINAL : public HydrogenCodeStub { +class StringAddStub FINAL : public HydrogenCodeStub { public: - StringAddStub(Isolate* isolate, - StringAddFlags flags, + StringAddStub(Isolate* isolate, StringAddFlags flags, PretenureFlag pretenure_flag) - : HydrogenCodeStub(isolate), - bit_field_(StringAddFlagsBits::encode(flags) | - PretenureFlagBits::encode(pretenure_flag)) {} + : HydrogenCodeStub(isolate) { + set_sub_minor_key(StringAddFlagsBits::encode(flags) | + PretenureFlagBits::encode(pretenure_flag)); + } StringAddFlags flags() const { - return StringAddFlagsBits::decode(bit_field_); + return StringAddFlagsBits::decode(sub_minor_key()); } PretenureFlag pretenure_flag() const { - return PretenureFlagBits::decode(bit_field_); + return PretenureFlagBits::decode(sub_minor_key()); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate); - // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kLeft = 0; static const int kRight = 1; @@ -1283,51 +1243,41 @@ class StringAddStub V8_FINAL : public HydrogenCodeStub { private: class StringAddFlagsBits: public BitField<StringAddFlags, 0, 2> {}; class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {}; - uint32_t bit_field_; - virtual Major MajorKey() const V8_OVERRIDE { return StringAdd; } - virtual int NotMissMinorKey() const V8_OVERRIDE { return bit_field_; } + virtual void PrintBaseName(OStream& os) const OVERRIDE; // NOLINT - virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT - - DISALLOW_COPY_AND_ASSIGN(StringAddStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd); + DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub); }; -class ICCompareStub: public PlatformCodeStub { +class CompareICStub : public PlatformCodeStub { public: - ICCompareStub(Isolate* isolate, - Token::Value op, - CompareIC::State left, - CompareIC::State right, - CompareIC::State handler) - : PlatformCodeStub(isolate), - op_(op), - left_(left), - right_(right), - state_(handler) { + CompareICStub(Isolate* isolate, Token::Value op, CompareICState::State left, + CompareICState::State right, CompareICState::State state) + : PlatformCodeStub(isolate) { DCHECK(Token::IsCompareOp(op)); + minor_key_ = OpBits::encode(op - Token::EQ) | LeftStateBits::encode(left) | + RightStateBits::encode(right) | StateBits::encode(state); } - virtual void Generate(MacroAssembler* masm); - void set_known_map(Handle<Map> map) { known_map_ = map; } - static void DecodeKey(uint32_t stub_key, CompareIC::State* left_state, - CompareIC::State* right_state, - CompareIC::State* handler_state, Token::Value* op); - virtual InlineCacheState GetICState() const; - private: - class OpField: public BitField<int, 0, 3> { }; - class LeftStateField: public BitField<int, 3, 4> { }; - class RightStateField: public BitField<int, 7, 4> { }; - class HandlerStateField: public BitField<int, 11, 4> { }; + Token::Value op() const { + return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_)); + } - virtual CodeStub::Major MajorKey() const { return CompareIC; } - virtual int MinorKey() const; + CompareICState::State left() const { + return LeftStateBits::decode(minor_key_); + } + CompareICState::State right() const { + return RightStateBits::decode(minor_key_); + } + CompareICState::State state() const { return StateBits::decode(minor_key_); } + private: virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; } void GenerateSmis(MacroAssembler* masm); @@ -1340,18 +1290,24 @@ class ICCompareStub: public PlatformCodeStub { void GenerateKnownObjects(MacroAssembler* masm); void GenerateGeneric(MacroAssembler* masm); - bool strict() const { return op_ == Token::EQ_STRICT; } - Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } + bool strict() const { return op() == Token::EQ_STRICT; } + Condition GetCondition() const; virtual void AddToSpecialCache(Handle<Code> new_object); virtual bool FindCodeInSpecialCache(Code** code_out); - virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECT; } + virtual bool UseSpecialCache() { + return state() == CompareICState::KNOWN_OBJECT; + } + + class OpBits : public BitField<int, 0, 3> {}; + class LeftStateBits : public BitField<CompareICState::State, 3, 4> {}; + class RightStateBits : public BitField<CompareICState::State, 7, 4> {}; + class StateBits : public BitField<CompareICState::State, 11, 4> {}; - Token::Value op_; - CompareIC::State left_; - CompareIC::State right_; - CompareIC::State state_; Handle<Map> known_map_; + + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp); + DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub); }; @@ -1360,35 +1316,26 @@ class CompareNilICStub : public HydrogenCodeStub { Type* GetType(Zone* zone, Handle<Map> map = Handle<Map>()); Type* GetInputType(Zone* zone, Handle<Map> map); - CompareNilICStub(Isolate* isolate, NilValue nil) - : HydrogenCodeStub(isolate), nil_value_(nil) { } + CompareNilICStub(Isolate* isolate, NilValue nil) : HydrogenCodeStub(isolate) { + set_sub_minor_key(NilValueBits::encode(nil)); + } - CompareNilICStub(Isolate* isolate, - ExtraICState ic_state, + CompareNilICStub(Isolate* isolate, ExtraICState ic_state, InitializationState init_state = INITIALIZED) - : HydrogenCodeStub(isolate, init_state), - nil_value_(NilValueField::decode(ic_state)), - state_(State(TypesField::decode(ic_state))) { - } + : HydrogenCodeStub(isolate, init_state) { + set_sub_minor_key(ic_state); + } static Handle<Code> GetUninitialized(Isolate* isolate, NilValue nil) { return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode(); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - static void InstallDescriptors(Isolate* isolate) { - CompareNilICStub compare_stub(isolate, kNullValue, UNINITIALIZED); - compare_stub.InitializeInterfaceDescriptor( - isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); - } - virtual InlineCacheState GetICState() const { - if (state_.Contains(GENERIC)) { + State state = this->state(); + if (state.Contains(GENERIC)) { return MEGAMORPHIC; - } else if (state_.Contains(MONOMORPHIC_MAP)) { + } else if (state.Contains(MONOMORPHIC_MAP)) { return MONOMORPHIC; } else { return PREMONOMORPHIC; @@ -1397,24 +1344,27 @@ class CompareNilICStub : public HydrogenCodeStub { virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual ExtraICState GetExtraICState() const { - return NilValueField::encode(nil_value_) | - TypesField::encode(state_.ToIntegral()); - } + virtual ExtraICState GetExtraICState() const { return sub_minor_key(); } void UpdateStatus(Handle<Object> object); - bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } - NilValue GetNilValue() const { return nil_value_; } - void ClearState() { state_.RemoveAll(); } + bool IsMonomorphic() const { return state().Contains(MONOMORPHIC_MAP); } - virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT - virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT + NilValue nil_value() const { return NilValueBits::decode(sub_minor_key()); } + + void ClearState() { + set_sub_minor_key(TypesBits::update(sub_minor_key(), 0)); + } + + virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT + virtual void PrintBaseName(OStream& os) const OVERRIDE; // NOLINT private: - friend class CompareNilIC; + CompareNilICStub(Isolate* isolate, NilValue nil, + InitializationState init_state) + : HydrogenCodeStub(isolate, init_state) { + set_sub_minor_key(NilValueBits::encode(nil)); + } enum CompareNilType { UNDEFINED, @@ -1436,21 +1386,15 @@ class CompareNilICStub : public HydrogenCodeStub { }; friend OStream& operator<<(OStream& os, const State& s); - CompareNilICStub(Isolate* isolate, - NilValue nil, - InitializationState init_state) - : HydrogenCodeStub(isolate, init_state), nil_value_(nil) { } - - class NilValueField : public BitField<NilValue, 0, 1> {}; - class TypesField : public BitField<byte, 1, NUMBER_OF_TYPES> {}; + State state() const { return State(TypesBits::decode(sub_minor_key())); } - virtual CodeStub::Major MajorKey() const { return CompareNilIC; } - virtual int NotMissMinorKey() const { return GetExtraICState(); } + class NilValueBits : public BitField<NilValue, 0, 1> {}; + class TypesBits : public BitField<byte, 1, NUMBER_OF_TYPES> {}; - NilValue nil_value_; - State state_; + friend class CompareNilIC; - DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(CompareNil); + DEFINE_HYDROGEN_CODE_STUB(CompareNilIC, HydrogenCodeStub); }; @@ -1459,14 +1403,15 @@ OStream& operator<<(OStream& os, const CompareNilICStub::State& s); class CEntryStub : public PlatformCodeStub { public: - CEntryStub(Isolate* isolate, - int result_size, + CEntryStub(Isolate* isolate, int result_size, SaveFPRegsMode save_doubles = kDontSaveFPRegs) - : PlatformCodeStub(isolate), - result_size_(result_size), - save_doubles_(save_doubles) { } - - void Generate(MacroAssembler* masm); + : PlatformCodeStub(isolate) { + minor_key_ = SaveDoublesBits::encode(save_doubles == kSaveFPRegs); + DCHECK(result_size == 1 || result_size == 2); +#ifdef _WIN64 + minor_key_ = ResultSizeBits::update(minor_key_, result_size); +#endif // _WIN64 + } // The version of this stub that doesn't save doubles is generated ahead of // time, so it's OK to call it from other stubs that can't cope with GC during @@ -1475,48 +1420,47 @@ class CEntryStub : public PlatformCodeStub { static void GenerateAheadOfTime(Isolate* isolate); private: - // Number of pointers/values returned. - const int result_size_; - SaveFPRegsMode save_doubles_; - - Major MajorKey() const { return CEntry; } - int MinorKey() const; + bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); } +#ifdef _WIN64 + int result_size() const { return ResultSizeBits::decode(minor_key_); } +#endif // _WIN64 bool NeedsImmovableCode(); + + class SaveDoublesBits : public BitField<bool, 0, 1> {}; + class ResultSizeBits : public BitField<int, 1, 3> {}; + + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub); }; class JSEntryStub : public PlatformCodeStub { public: - explicit JSEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) { } - - void Generate(MacroAssembler* masm) { GenerateBody(masm, false); } - - protected: - void GenerateBody(MacroAssembler* masm, bool is_construct); + JSEntryStub(Isolate* isolate, StackFrame::Type type) + : PlatformCodeStub(isolate) { + DCHECK(type == StackFrame::ENTRY || type == StackFrame::ENTRY_CONSTRUCT); + minor_key_ = StackFrameTypeBits::encode(type); + } private: - Major MajorKey() const { return JSEntry; } - int MinorKey() const { return 0; } - virtual void FinishCode(Handle<Code> code); - int handler_offset_; -}; - + virtual void PrintName(OStream& os) const OVERRIDE { // NOLINT + os << (type() == StackFrame::ENTRY ? "JSEntryStub" + : "JSConstructEntryStub"); + } -class JSConstructEntryStub : public JSEntryStub { - public: - explicit JSConstructEntryStub(Isolate* isolate) : JSEntryStub(isolate) { } + StackFrame::Type type() const { + return StackFrameTypeBits::decode(minor_key_); + } - void Generate(MacroAssembler* masm) { GenerateBody(masm, true); } + class StackFrameTypeBits : public BitField<StackFrame::Type, 0, 5> {}; - private: - int MinorKey() const { return 1; } + int handler_offset_; - virtual void PrintName(OStream& os) const V8_OVERRIDE { // NOLINT - os << "JSConstructEntryStub"; - } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub); }; @@ -1529,22 +1473,30 @@ class ArgumentsAccessStub: public PlatformCodeStub { NEW_STRICT }; - ArgumentsAccessStub(Isolate* isolate, Type type) - : PlatformCodeStub(isolate), type_(type) { } + ArgumentsAccessStub(Isolate* isolate, Type type) : PlatformCodeStub(isolate) { + minor_key_ = TypeBits::encode(type); + } + + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (type() == READ_ELEMENT) { + return ArgumentsAccessReadDescriptor(isolate()); + } + return ContextOnlyDescriptor(isolate()); + } private: - Type type_; - - Major MajorKey() const { return ArgumentsAccess; } - int MinorKey() const { return type_; } + Type type() const { return TypeBits::decode(minor_key_); } - void Generate(MacroAssembler* masm); void GenerateReadElement(MacroAssembler* masm); void GenerateNewStrict(MacroAssembler* masm); void GenerateNewSloppyFast(MacroAssembler* masm); void GenerateNewSloppySlow(MacroAssembler* masm); - virtual void PrintName(OStream& os) const V8_OVERRIDE; // NOLINT + virtual void PrintName(OStream& os) const OVERRIDE; // NOLINT + + class TypeBits : public BitField<Type, 0, 2> {}; + + DEFINE_PLATFORM_CODE_STUB(ArgumentsAccess, PlatformCodeStub); }; @@ -1552,108 +1504,84 @@ class RegExpExecStub: public PlatformCodeStub { public: explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { } - private: - Major MajorKey() const { return RegExpExec; } - int MinorKey() const { return 0; } - - void Generate(MacroAssembler* masm); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); + DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub); }; -class RegExpConstructResultStub V8_FINAL : public HydrogenCodeStub { +class RegExpConstructResultStub FINAL : public HydrogenCodeStub { public: explicit RegExpConstructResultStub(Isolate* isolate) : HydrogenCodeStub(isolate) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - virtual Major MajorKey() const V8_OVERRIDE { return RegExpConstructResult; } - virtual int NotMissMinorKey() const V8_OVERRIDE { return 0; } - - static void InstallDescriptors(Isolate* isolate); - // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kLength = 0; static const int kIndex = 1; static const int kInput = 2; - private: - DISALLOW_COPY_AND_ASSIGN(RegExpConstructResultStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(RegExpConstructResult); + DEFINE_HYDROGEN_CODE_STUB(RegExpConstructResult, HydrogenCodeStub); }; class CallFunctionStub: public PlatformCodeStub { public: CallFunctionStub(Isolate* isolate, int argc, CallFunctionFlags flags) - : PlatformCodeStub(isolate), argc_(argc), flags_(flags) { - DCHECK(argc <= Code::kMaxArguments); + : PlatformCodeStub(isolate) { + DCHECK(argc >= 0 && argc <= Code::kMaxArguments); + minor_key_ = ArgcBits::encode(argc) | FlagBits::encode(flags); } - void Generate(MacroAssembler* masm); - static int ExtractArgcFromMinorKey(int minor_key) { return ArgcBits::decode(minor_key); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor); - private: - int argc_; - CallFunctionFlags flags_; + int argc() const { return ArgcBits::decode(minor_key_); } + int flags() const { return FlagBits::decode(minor_key_); } + + bool CallAsMethod() const { + return flags() == CALL_AS_METHOD || flags() == WRAP_AND_CALL; + } - virtual void PrintName(OStream& os) const V8_OVERRIDE; // NOLINT + bool NeedsChecks() const { return flags() != WRAP_AND_CALL; } + + virtual void PrintName(OStream& os) const OVERRIDE; // NOLINT // Minor key encoding in 32 bits with Bitfield <Type, shift, size>. - class FlagBits: public BitField<CallFunctionFlags, 0, 2> {}; + class FlagBits : public BitField<CallFunctionFlags, 0, 2> {}; class ArgcBits : public BitField<unsigned, 2, Code::kArgumentsBits> {}; - STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits); - Major MajorKey() const { return CallFunction; } - int MinorKey() const { - // Encode the parameters in a unique 32 bit value. - return FlagBits::encode(flags_) | ArgcBits::encode(argc_); - } - - bool CallAsMethod() { - return flags_ == CALL_AS_METHOD || flags_ == WRAP_AND_CALL; - } - - bool NeedsChecks() { - return flags_ != WRAP_AND_CALL; - } + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction); + DEFINE_PLATFORM_CODE_STUB(CallFunction, PlatformCodeStub); }; class CallConstructStub: public PlatformCodeStub { public: CallConstructStub(Isolate* isolate, CallConstructorFlags flags) - : PlatformCodeStub(isolate), flags_(flags) {} - - void Generate(MacroAssembler* masm); + : PlatformCodeStub(isolate) { + minor_key_ = FlagBits::encode(flags); + } virtual void FinishCode(Handle<Code> code) { code->set_has_function_cache(RecordCallTarget()); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor); - private: - CallConstructorFlags flags_; - - virtual void PrintName(OStream& os) const V8_OVERRIDE; // NOLINT - - Major MajorKey() const { return CallConstruct; } - int MinorKey() const { return flags_; } + CallConstructorFlags flags() const { return FlagBits::decode(minor_key_); } bool RecordCallTarget() const { - return (flags_ & RECORD_CONSTRUCTOR_TARGET) != 0; + return (flags() & RECORD_CONSTRUCTOR_TARGET) != 0; } + + virtual void PrintName(OStream& os) const OVERRIDE; // NOLINT + + class FlagBits : public BitField<CallConstructorFlags, 0, 1> {}; + + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallConstruct); + DEFINE_PLATFORM_CODE_STUB(CallConstruct, PlatformCodeStub); }; @@ -1836,98 +1764,150 @@ class LoadDictionaryElementStub : public HydrogenCodeStub { explicit LoadDictionaryElementStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub); +}; - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: - Major MajorKey() const { return LoadElement; } - int NotMissMinorKey() const { return DICTIONARY_ELEMENTS; } +class KeyedLoadGenericStub : public HydrogenCodeStub { + public: + explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} - DISALLOW_COPY_AND_ASSIGN(LoadDictionaryElementStub); + virtual Code::Kind GetCodeKind() const { return Code::KEYED_LOAD_IC; } + virtual InlineCacheState GetICState() const { return GENERIC; } + + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub); }; -class LoadDictionaryElementPlatformStub : public PlatformCodeStub { +class LoadICTrampolineStub : public PlatformCodeStub { public: - explicit LoadDictionaryElementPlatformStub(Isolate* isolate) - : PlatformCodeStub(isolate) {} + LoadICTrampolineStub(Isolate* isolate, const LoadICState& state) + : PlatformCodeStub(isolate) { + minor_key_ = state.GetExtraICState(); + } + + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; } - void Generate(MacroAssembler* masm); + virtual InlineCacheState GetICState() const FINAL OVERRIDE { + return GENERIC; + } + + virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { + return static_cast<ExtraICState>(minor_key_); + } private: - Major MajorKey() const { return LoadElement; } - int MinorKey() const { return DICTIONARY_ELEMENTS; } + LoadICState state() const { + return LoadICState(static_cast<ExtraICState>(minor_key_)); + } - DISALLOW_COPY_AND_ASSIGN(LoadDictionaryElementPlatformStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadICTrampoline); + DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub); }; -class KeyedLoadGenericStub : public HydrogenCodeStub { +class KeyedLoadICTrampolineStub : public LoadICTrampolineStub { public: - explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {} + explicit KeyedLoadICTrampolineStub(Isolate* isolate) + : LoadICTrampolineStub(isolate, LoadICState(0)) {} - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + virtual Code::Kind GetCodeKind() const OVERRIDE { + return Code::KEYED_LOAD_IC; + } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub); +}; - static void InstallDescriptors(Isolate* isolate); - virtual Code::Kind GetCodeKind() const { return Code::KEYED_LOAD_IC; } - virtual InlineCacheState GetICState() const { return GENERIC; } +class MegamorphicLoadStub : public HydrogenCodeStub { + public: + MegamorphicLoadStub(Isolate* isolate, const LoadICState& state) + : HydrogenCodeStub(isolate) { + set_sub_minor_key(state.GetExtraICState()); + } - private: - Major MajorKey() const { return KeyedLoadGeneric; } - int NotMissMinorKey() const { return 0; } + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; } + + virtual InlineCacheState GetICState() const FINAL OVERRIDE { + return MEGAMORPHIC; + } + + virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { + return static_cast<ExtraICState>(sub_minor_key()); + } - DISALLOW_COPY_AND_ASSIGN(KeyedLoadGenericStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_HYDROGEN_CODE_STUB(MegamorphicLoad, HydrogenCodeStub); }; -class DoubleToIStub : public PlatformCodeStub { +class VectorLoadStub : public HydrogenCodeStub { public: - DoubleToIStub(Isolate* isolate, - Register source, - Register destination, - int offset, - bool is_truncating, - bool skip_fastpath = false) - : PlatformCodeStub(isolate), bit_field_(0) { - bit_field_ = SourceRegisterBits::encode(source.code()) | - DestinationRegisterBits::encode(destination.code()) | - OffsetBits::encode(offset) | - IsTruncatingBits::encode(is_truncating) | - SkipFastPathBits::encode(skip_fastpath) | - SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0); + explicit VectorLoadStub(Isolate* isolate, const LoadICState& state) + : HydrogenCodeStub(isolate) { + set_sub_minor_key(state.GetExtraICState()); } - Register source() { - return Register::from_code(SourceRegisterBits::decode(bit_field_)); - } + virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; } - Register destination() { - return Register::from_code(DestinationRegisterBits::decode(bit_field_)); + virtual InlineCacheState GetICState() const FINAL OVERRIDE { + return GENERIC; } - bool is_truncating() { - return IsTruncatingBits::decode(bit_field_); + virtual ExtraICState GetExtraICState() const FINAL OVERRIDE { + return static_cast<ExtraICState>(sub_minor_key()); } - bool skip_fastpath() { - return SkipFastPathBits::decode(bit_field_); - } + private: + LoadICState state() const { return LoadICState(GetExtraICState()); } + + DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC); + DEFINE_HYDROGEN_CODE_STUB(VectorLoad, HydrogenCodeStub); +}; + + +class VectorKeyedLoadStub : public VectorLoadStub { + public: + explicit VectorKeyedLoadStub(Isolate* isolate) + : VectorLoadStub(isolate, LoadICState(0)) {} - int offset() { - return OffsetBits::decode(bit_field_); + virtual Code::Kind GetCodeKind() const OVERRIDE { + return Code::KEYED_LOAD_IC; } - void Generate(MacroAssembler* masm); + DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC); + DEFINE_HYDROGEN_CODE_STUB(VectorKeyedLoad, VectorLoadStub); +}; + + +class DoubleToIStub : public PlatformCodeStub { + public: + DoubleToIStub(Isolate* isolate, Register source, Register destination, + int offset, bool is_truncating, bool skip_fastpath = false) + : PlatformCodeStub(isolate) { + minor_key_ = SourceRegisterBits::encode(source.code()) | + DestinationRegisterBits::encode(destination.code()) | + OffsetBits::encode(offset) | + IsTruncatingBits::encode(is_truncating) | + SkipFastPathBits::encode(skip_fastpath) | + SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0); + } virtual bool SometimesSetsUpAFrame() { return false; } private: + Register source() const { + return Register::from_code(SourceRegisterBits::decode(minor_key_)); + } + Register destination() const { + return Register::from_code(DestinationRegisterBits::decode(minor_key_)); + } + bool is_truncating() const { return IsTruncatingBits::decode(minor_key_); } + bool skip_fastpath() const { return SkipFastPathBits::decode(minor_key_); } + int offset() const { return OffsetBits::decode(minor_key_); } + static const int kBitsPerRegisterNumber = 6; STATIC_ASSERT((1L << kBitsPerRegisterNumber) >= Register::kNumRegisters); class SourceRegisterBits: @@ -1944,12 +1924,8 @@ class DoubleToIStub : public PlatformCodeStub { class SSE3Bits: public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {}; // NOLINT - Major MajorKey() const { return DoubleToI; } - int MinorKey() const { return bit_field_; } - - int bit_field_; - - DISALLOW_COPY_AND_ASSIGN(DoubleToIStub); + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub); }; @@ -1958,32 +1934,22 @@ class LoadFastElementStub : public HydrogenCodeStub { LoadFastElementStub(Isolate* isolate, bool is_js_array, ElementsKind elements_kind) : HydrogenCodeStub(isolate) { - bit_field_ = ElementsKindBits::encode(elements_kind) | - IsJSArrayBits::encode(is_js_array); + set_sub_minor_key(ElementsKindBits::encode(elements_kind) | + IsJSArrayBits::encode(is_js_array)); } - bool is_js_array() const { - return IsJSArrayBits::decode(bit_field_); - } + bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); } ElementsKind elements_kind() const { - return ElementsKindBits::decode(bit_field_); + return ElementsKindBits::decode(sub_minor_key()); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; class IsJSArrayBits: public BitField<bool, 8, 1> {}; - uint32_t bit_field_; - Major MajorKey() const { return LoadElement; } - int NotMissMinorKey() const { return bit_field_; } - - DISALLOW_COPY_AND_ASSIGN(LoadFastElementStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); + DEFINE_HYDROGEN_CODE_STUB(LoadFastElement, HydrogenCodeStub); }; @@ -1992,38 +1958,28 @@ class StoreFastElementStub : public HydrogenCodeStub { StoreFastElementStub(Isolate* isolate, bool is_js_array, ElementsKind elements_kind, KeyedAccessStoreMode mode) : HydrogenCodeStub(isolate) { - bit_field_ = ElementsKindBits::encode(elements_kind) | - IsJSArrayBits::encode(is_js_array) | - StoreModeBits::encode(mode); + set_sub_minor_key(ElementsKindBits::encode(elements_kind) | + IsJSArrayBits::encode(is_js_array) | + StoreModeBits::encode(mode)); } - bool is_js_array() const { - return IsJSArrayBits::decode(bit_field_); - } + bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); } ElementsKind elements_kind() const { - return ElementsKindBits::decode(bit_field_); + return ElementsKindBits::decode(sub_minor_key()); } KeyedAccessStoreMode store_mode() const { - return StoreModeBits::decode(bit_field_); + return StoreModeBits::decode(sub_minor_key()); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; class StoreModeBits: public BitField<KeyedAccessStoreMode, 8, 4> {}; class IsJSArrayBits: public BitField<bool, 12, 1> {}; - uint32_t bit_field_; - Major MajorKey() const { return StoreElement; } - int NotMissMinorKey() const { return bit_field_; } - - DISALLOW_COPY_AND_ASSIGN(StoreFastElementStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(Store); + DEFINE_HYDROGEN_CODE_STUB(StoreFastElement, HydrogenCodeStub); }; @@ -2033,38 +1989,26 @@ class TransitionElementsKindStub : public HydrogenCodeStub { ElementsKind from_kind, ElementsKind to_kind, bool is_js_array) : HydrogenCodeStub(isolate) { - bit_field_ = FromKindBits::encode(from_kind) | - ToKindBits::encode(to_kind) | - IsJSArrayBits::encode(is_js_array); + set_sub_minor_key(FromKindBits::encode(from_kind) | + ToKindBits::encode(to_kind) | + IsJSArrayBits::encode(is_js_array)); } ElementsKind from_kind() const { - return FromKindBits::decode(bit_field_); - } - - ElementsKind to_kind() const { - return ToKindBits::decode(bit_field_); - } - - bool is_js_array() const { - return IsJSArrayBits::decode(bit_field_); + return FromKindBits::decode(sub_minor_key()); } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + ElementsKind to_kind() const { return ToKindBits::decode(sub_minor_key()); } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + bool is_js_array() const { return IsJSArrayBits::decode(sub_minor_key()); } private: class FromKindBits: public BitField<ElementsKind, 8, 8> {}; class ToKindBits: public BitField<ElementsKind, 0, 8> {}; class IsJSArrayBits: public BitField<bool, 16, 1> {}; - uint32_t bit_field_; - - Major MajorKey() const { return TransitionElementsKind; } - int NotMissMinorKey() const { return bit_field_; } - DISALLOW_COPY_AND_ASSIGN(TransitionElementsKindStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(TransitionElementsKind); + DEFINE_HYDROGEN_CODE_STUB(TransitionElementsKind, HydrogenCodeStub); }; @@ -2079,20 +2023,19 @@ class ArrayConstructorStubBase : public HydrogenCodeStub { // for an ElementsKind and the desired usage of the stub. DCHECK(override_mode != DISABLE_ALLOCATION_SITES || AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE); - bit_field_ = ElementsKindBits::encode(kind) | - AllocationSiteOverrideModeBits::encode(override_mode); + set_sub_minor_key(ElementsKindBits::encode(kind) | + AllocationSiteOverrideModeBits::encode(override_mode)); } ElementsKind elements_kind() const { - return ElementsKindBits::decode(bit_field_); + return ElementsKindBits::decode(sub_minor_key()); } AllocationSiteOverrideMode override_mode() const { - return AllocationSiteOverrideModeBits::decode(bit_field_); + return AllocationSiteOverrideModeBits::decode(sub_minor_key()); } static void GenerateStubsAheadOfTime(Isolate* isolate); - static void InstallDescriptors(Isolate* isolate); // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kConstructor = 0; @@ -2102,17 +2045,14 @@ class ArrayConstructorStubBase : public HydrogenCodeStub { OStream& BasePrintName(OStream& os, const char* name) const; // NOLINT private: - int NotMissMinorKey() const { return bit_field_; } - // Ensure data fits within available bits. STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1); class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; class AllocationSiteOverrideModeBits: public BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT - uint32_t bit_field_; - DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase); + DEFINE_CODE_STUB_BASE(ArrayConstructorStubBase, HydrogenCodeStub); }; @@ -2125,19 +2065,14 @@ class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase { : ArrayConstructorStubBase(isolate, kind, override_mode) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: - Major MajorKey() const { return ArrayNoArgumentConstructor; } - - virtual void PrintName(OStream& os) const V8_OVERRIDE { // NOLINT + virtual void PrintName(OStream& os) const OVERRIDE { // NOLINT BasePrintName(os, "ArrayNoArgumentConstructorStub"); } - DISALLOW_COPY_AND_ASSIGN(ArrayNoArgumentConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructorConstantArgCount); + DEFINE_HYDROGEN_CODE_STUB(ArrayNoArgumentConstructor, + ArrayConstructorStubBase); }; @@ -2150,19 +2085,14 @@ class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase { : ArrayConstructorStubBase(isolate, kind, override_mode) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: - Major MajorKey() const { return ArraySingleArgumentConstructor; } - virtual void PrintName(OStream& os) const { // NOLINT BasePrintName(os, "ArraySingleArgumentConstructorStub"); } - DISALLOW_COPY_AND_ASSIGN(ArraySingleArgumentConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor); + DEFINE_HYDROGEN_CODE_STUB(ArraySingleArgumentConstructor, + ArrayConstructorStubBase); }; @@ -2175,19 +2105,14 @@ class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase { : ArrayConstructorStubBase(isolate, kind, override_mode) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - private: - Major MajorKey() const { return ArrayNArgumentsConstructor; } - virtual void PrintName(OStream& os) const { // NOLINT BasePrintName(os, "ArrayNArgumentsConstructorStub"); } - DISALLOW_COPY_AND_ASSIGN(ArrayNArgumentsConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor); + DEFINE_HYDROGEN_CODE_STUB(ArrayNArgumentsConstructor, + ArrayConstructorStubBase); }; @@ -2195,23 +2120,22 @@ class InternalArrayConstructorStubBase : public HydrogenCodeStub { public: InternalArrayConstructorStubBase(Isolate* isolate, ElementsKind kind) : HydrogenCodeStub(isolate) { - kind_ = kind; + set_sub_minor_key(ElementsKindBits::encode(kind)); } static void GenerateStubsAheadOfTime(Isolate* isolate); - static void InstallDescriptors(Isolate* isolate); // Parameters accessed via CodeStubGraphBuilder::GetParameter() static const int kConstructor = 0; - ElementsKind elements_kind() const { return kind_; } + ElementsKind elements_kind() const { + return ElementsKindBits::decode(sub_minor_key()); + } private: - int NotMissMinorKey() const { return kind_; } + class ElementsKindBits : public BitField<ElementsKind, 0, 8> {}; - ElementsKind kind_; - - DISALLOW_COPY_AND_ASSIGN(InternalArrayConstructorStubBase); + DEFINE_CODE_STUB_BASE(InternalArrayConstructorStubBase, HydrogenCodeStub); }; @@ -2222,15 +2146,9 @@ class InternalArrayNoArgumentConstructorStub : public ElementsKind kind) : InternalArrayConstructorStubBase(isolate, kind) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - private: - Major MajorKey() const { return InternalArrayNoArgumentConstructor; } - - DISALLOW_COPY_AND_ASSIGN(InternalArrayNoArgumentConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructorConstantArgCount); + DEFINE_HYDROGEN_CODE_STUB(InternalArrayNoArgumentConstructor, + InternalArrayConstructorStubBase); }; @@ -2241,15 +2159,9 @@ class InternalArraySingleArgumentConstructorStub : public ElementsKind kind) : InternalArrayConstructorStubBase(isolate, kind) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - private: - Major MajorKey() const { return InternalArraySingleArgumentConstructor; } - - DISALLOW_COPY_AND_ASSIGN(InternalArraySingleArgumentConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor); + DEFINE_HYDROGEN_CODE_STUB(InternalArraySingleArgumentConstructor, + InternalArrayConstructorStubBase); }; @@ -2259,46 +2171,28 @@ class InternalArrayNArgumentsConstructorStub : public InternalArrayNArgumentsConstructorStub(Isolate* isolate, ElementsKind kind) : InternalArrayConstructorStubBase(isolate, kind) { } - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; - - private: - Major MajorKey() const { return InternalArrayNArgumentsConstructor; } - - DISALLOW_COPY_AND_ASSIGN(InternalArrayNArgumentsConstructorStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor); + DEFINE_HYDROGEN_CODE_STUB(InternalArrayNArgumentsConstructor, + InternalArrayConstructorStubBase); }; class StoreElementStub : public PlatformCodeStub { public: - StoreElementStub(Isolate* isolate, bool is_js_array, - ElementsKind elements_kind, KeyedAccessStoreMode store_mode) - : PlatformCodeStub(isolate), - is_js_array_(is_js_array), - elements_kind_(elements_kind), - store_mode_(store_mode) {} - - Major MajorKey() const { return StoreElement; } - int MinorKey() const { - return ElementsKindBits::encode(elements_kind_) | - IsJSArrayBits::encode(is_js_array_) | - StoreModeBits::encode(store_mode_); + StoreElementStub(Isolate* isolate, ElementsKind elements_kind) + : PlatformCodeStub(isolate) { + minor_key_ = ElementsKindBits::encode(elements_kind); } - void Generate(MacroAssembler* masm); - private: - class ElementsKindBits: public BitField<ElementsKind, 0, 8> {}; - class StoreModeBits: public BitField<KeyedAccessStoreMode, 8, 4> {}; - class IsJSArrayBits: public BitField<bool, 12, 1> {}; + ElementsKind elements_kind() const { + return ElementsKindBits::decode(minor_key_); + } - bool is_js_array_; - ElementsKind elements_kind_; - KeyedAccessStoreMode store_mode_; + class ElementsKindBits : public BitField<ElementsKind, 0, 8> {}; - DISALLOW_COPY_AND_ASSIGN(StoreElementStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(Store); + DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub); }; @@ -2341,39 +2235,34 @@ class ToBooleanStub: public HydrogenCodeStub { }; ToBooleanStub(Isolate* isolate, ResultMode mode, Types types = Types()) - : HydrogenCodeStub(isolate), types_(types), mode_(mode) {} + : HydrogenCodeStub(isolate) { + set_sub_minor_key(TypesBits::encode(types.ToByte()) | + ResultModeBits::encode(mode)); + } + ToBooleanStub(Isolate* isolate, ExtraICState state) - : HydrogenCodeStub(isolate), - types_(static_cast<byte>(state)), - mode_(RESULT_AS_SMI) {} + : HydrogenCodeStub(isolate) { + set_sub_minor_key(TypesBits::encode(static_cast<byte>(state)) | + ResultModeBits::encode(RESULT_AS_SMI)); + } bool UpdateStatus(Handle<Object> object); - Types GetTypes() { return types_; } - ResultMode GetMode() { return mode_; } - - virtual Handle<Code> GenerateCode() V8_OVERRIDE; - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + Types types() const { return Types(TypesBits::decode(sub_minor_key())); } + ResultMode mode() const { return ResultModeBits::decode(sub_minor_key()); } virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; } - virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT + virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT virtual bool SometimesSetsUpAFrame() { return false; } - static void InstallDescriptors(Isolate* isolate) { - ToBooleanStub stub(isolate, RESULT_AS_SMI); - stub.InitializeInterfaceDescriptor( - isolate->code_stub_interface_descriptor(CodeStub::ToBoolean)); - } - static Handle<Code> GetUninitialized(Isolate* isolate) { return ToBooleanStub(isolate, UNINITIALIZED).GetCode(); } - virtual ExtraICState GetExtraICState() const { return types_.ToIntegral(); } + virtual ExtraICState GetExtraICState() const { return types().ToIntegral(); } virtual InlineCacheState GetICState() const { - if (types_.IsEmpty()) { + if (types().IsEmpty()) { return ::v8::internal::UNINITIALIZED; } else { return MONOMORPHIC; @@ -2381,19 +2270,16 @@ class ToBooleanStub: public HydrogenCodeStub { } private: - class TypesBits : public BitField<byte, 0, NUMBER_OF_TYPES> {}; - class ResultModeBits : public BitField<ResultMode, NUMBER_OF_TYPES, 2> {}; - - Major MajorKey() const { return ToBoolean; } - int NotMissMinorKey() const { - return TypesBits::encode(types_.ToByte()) | ResultModeBits::encode(mode_); + ToBooleanStub(Isolate* isolate, InitializationState init_state) + : HydrogenCodeStub(isolate, init_state) { + set_sub_minor_key(ResultModeBits::encode(RESULT_AS_SMI)); } - ToBooleanStub(Isolate* isolate, InitializationState init_state) - : HydrogenCodeStub(isolate, init_state), mode_(RESULT_AS_SMI) {} + class TypesBits : public BitField<byte, 0, NUMBER_OF_TYPES> {}; + class ResultModeBits : public BitField<ResultMode, NUMBER_OF_TYPES, 2> {}; - Types types_; - ResultMode mode_; + DEFINE_CALL_INTERFACE_DESCRIPTOR(ToBoolean); + DEFINE_HYDROGEN_CODE_STUB(ToBoolean, HydrogenCodeStub); }; @@ -2402,26 +2288,21 @@ OStream& operator<<(OStream& os, const ToBooleanStub::Types& t); class ElementsTransitionAndStoreStub : public HydrogenCodeStub { public: - ElementsTransitionAndStoreStub(Isolate* isolate, - ElementsKind from_kind, - ElementsKind to_kind, - bool is_jsarray, + ElementsTransitionAndStoreStub(Isolate* isolate, ElementsKind from_kind, + ElementsKind to_kind, bool is_jsarray, KeyedAccessStoreMode store_mode) - : HydrogenCodeStub(isolate), - from_kind_(from_kind), - to_kind_(to_kind), - is_jsarray_(is_jsarray), - store_mode_(store_mode) {} - - ElementsKind from_kind() const { return from_kind_; } - ElementsKind to_kind() const { return to_kind_; } - bool is_jsarray() const { return is_jsarray_; } - KeyedAccessStoreMode store_mode() const { return store_mode_; } - - virtual Handle<Code> GenerateCode() V8_OVERRIDE; + : HydrogenCodeStub(isolate) { + set_sub_minor_key(FromBits::encode(from_kind) | ToBits::encode(to_kind) | + IsJSArrayBits::encode(is_jsarray) | + StoreModeBits::encode(store_mode)); + } - virtual void InitializeInterfaceDescriptor( - CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; + ElementsKind from_kind() const { return FromBits::decode(sub_minor_key()); } + ElementsKind to_kind() const { return ToBits::decode(sub_minor_key()); } + bool is_jsarray() const { return IsJSArrayBits::decode(sub_minor_key()); } + KeyedAccessStoreMode store_mode() const { + return StoreModeBits::decode(sub_minor_key()); + } // Parameters accessed via CodeStubGraphBuilder::GetParameter() enum ParameterIndices { @@ -2433,34 +2314,26 @@ class ElementsTransitionAndStoreStub : public HydrogenCodeStub { }; static const Register ValueRegister() { - return KeyedStoreIC::ValueRegister(); + return ElementTransitionAndStoreDescriptor::ValueRegister(); + } + static const Register MapRegister() { + return ElementTransitionAndStoreDescriptor::MapRegister(); + } + static const Register KeyRegister() { + return ElementTransitionAndStoreDescriptor::NameRegister(); } - static const Register MapRegister() { return KeyedStoreIC::MapRegister(); } - static const Register KeyRegister() { return KeyedStoreIC::NameRegister(); } static const Register ObjectRegister() { - return KeyedStoreIC::ReceiverRegister(); + return ElementTransitionAndStoreDescriptor::ReceiverRegister(); } private: - class FromBits: public BitField<ElementsKind, 0, 8> {}; - class ToBits: public BitField<ElementsKind, 8, 8> {}; - class IsJSArrayBits: public BitField<bool, 16, 1> {}; - class StoreModeBits: public BitField<KeyedAccessStoreMode, 17, 4> {}; - - Major MajorKey() const { return ElementsTransitionAndStore; } - int NotMissMinorKey() const { - return FromBits::encode(from_kind_) | - ToBits::encode(to_kind_) | - IsJSArrayBits::encode(is_jsarray_) | - StoreModeBits::encode(store_mode_); - } - - ElementsKind from_kind_; - ElementsKind to_kind_; - bool is_jsarray_; - KeyedAccessStoreMode store_mode_; + class FromBits : public BitField<ElementsKind, 0, 8> {}; + class ToBits : public BitField<ElementsKind, 8, 8> {}; + class IsJSArrayBits : public BitField<bool, 16, 1> {}; + class StoreModeBits : public BitField<KeyedAccessStoreMode, 17, 4> {}; - DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ElementTransitionAndStore); + DEFINE_HYDROGEN_CODE_STUB(ElementsTransitionAndStore, HydrogenCodeStub); }; @@ -2469,35 +2342,29 @@ class StoreArrayLiteralElementStub : public PlatformCodeStub { explicit StoreArrayLiteralElementStub(Isolate* isolate) : PlatformCodeStub(isolate) { } - private: - Major MajorKey() const { return StoreArrayLiteralElement; } - int MinorKey() const { return 0; } - - void Generate(MacroAssembler* masm); - - DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub); + DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreArrayLiteralElement); + DEFINE_PLATFORM_CODE_STUB(StoreArrayLiteralElement, PlatformCodeStub); }; class StubFailureTrampolineStub : public PlatformCodeStub { public: StubFailureTrampolineStub(Isolate* isolate, StubFunctionMode function_mode) - : PlatformCodeStub(isolate), - function_mode_(function_mode) {} + : PlatformCodeStub(isolate) { + minor_key_ = FunctionModeField::encode(function_mode); + } static void GenerateAheadOfTime(Isolate* isolate); private: - class FunctionModeField: public BitField<StubFunctionMode, 0, 1> {}; - - Major MajorKey() const { return StubFailureTrampoline; } - int MinorKey() const { return FunctionModeField::encode(function_mode_); } - - void Generate(MacroAssembler* masm); + StubFunctionMode function_mode() const { + return FunctionModeField::decode(minor_key_); + } - StubFunctionMode function_mode_; + class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {}; - DISALLOW_COPY_AND_ASSIGN(StubFailureTrampolineStub); + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub); }; @@ -2516,20 +2383,57 @@ class ProfileEntryHookStub : public PlatformCodeStub { intptr_t stack_pointer, Isolate* isolate); - Major MajorKey() const { return ProfileEntryHook; } - int MinorKey() const { return 0; } + // ProfileEntryHookStub is called at the start of a function, so it has the + // same register set. + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction) + DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub); +}; + + +class StoreBufferOverflowStub : public PlatformCodeStub { + public: + StoreBufferOverflowStub(Isolate* isolate, SaveFPRegsMode save_fp) + : PlatformCodeStub(isolate) { + minor_key_ = SaveDoublesBits::encode(save_fp == kSaveFPRegs); + } + + static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate); + virtual bool SometimesSetsUpAFrame() { return false; } + + private: + bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); } + + class SaveDoublesBits : public BitField<bool, 0, 1> {}; + + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub); +}; - void Generate(MacroAssembler* masm); - DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); +class SubStringStub : public PlatformCodeStub { + public: + explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); + DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub); }; -class CallDescriptors { +class StringCompareStub : public PlatformCodeStub { public: - static void InitializeForIsolate(Isolate* isolate); + explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); + DEFINE_PLATFORM_CODE_STUB(StringCompare, PlatformCodeStub); }; + +#undef DEFINE_CALL_INTERFACE_DESCRIPTOR +#undef DEFINE_PLATFORM_CODE_STUB +#undef DEFINE_HANDLER_CODE_STUB +#undef DEFINE_HYDROGEN_CODE_STUB +#undef DEFINE_CODE_STUB +#undef DEFINE_CODE_STUB_BASE } } // namespace v8::internal #endif // V8_CODE_STUBS_H_ |