| Index: src/code-stubs.h
|
| diff --git a/src/code-stubs.h b/src/code-stubs.h
|
| index 232bb362099f294d6477ce66cb4e750e6249bafb..e63997dbd1a32c296cfdf838dc8495b5f778ee46 100644
|
| --- a/src/code-stubs.h
|
| +++ b/src/code-stubs.h
|
| @@ -66,6 +66,7 @@ namespace internal {
|
| V(FastNewBlockContext) \
|
| V(FastCloneShallowArray) \
|
| V(FastCloneShallowObject) \
|
| + V(CreateAllocationSite) \
|
| V(ToBoolean) \
|
| V(ToNumber) \
|
| V(ArgumentsAccess) \
|
| @@ -90,19 +91,20 @@ namespace internal {
|
| V(ArrayConstructor) \
|
| V(InternalArrayConstructor) \
|
| V(ProfileEntryHook) \
|
| + V(StoreGlobal) \
|
| /* IC Handler stubs */ \
|
| V(LoadField) \
|
| V(KeyedLoadField)
|
|
|
| // List of code stubs only used on ARM platforms.
|
| -#if defined(V8_TARGET_ARCH_ARM)
|
| +#if V8_TARGET_ARCH_ARM
|
| #define CODE_STUB_LIST_ARM(V) \
|
| V(GetProperty) \
|
| V(SetProperty) \
|
| V(InvokeBuiltin) \
|
| V(RegExpCEntry) \
|
| V(DirectCEntry)
|
| -#elif defined(V8_TARGET_ARCH_A64)
|
| +#elif V8_TARGET_ARCH_A64
|
| #define CODE_STUB_LIST_ARM(V) \
|
| V(GetProperty) \
|
| V(SetProperty) \
|
| @@ -113,7 +115,7 @@ namespace internal {
|
| #endif
|
|
|
| // List of code stubs only used on MIPS platforms.
|
| -#ifdef V8_TARGET_ARCH_MIPS
|
| +#if V8_TARGET_ARCH_MIPS
|
| #define CODE_STUB_LIST_MIPS(V) \
|
| V(RegExpCEntry) \
|
| V(DirectCEntry)
|
| @@ -129,8 +131,6 @@ namespace internal {
|
|
|
| // Mode to overwrite BinaryExpression values.
|
| enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
|
| -enum UnaryOverwriteMode { UNARY_OVERWRITE, UNARY_NO_OVERWRITE };
|
| -
|
|
|
| // Stub is base classes of all stubs.
|
| class CodeStub BASE_EMBEDDED {
|
| @@ -146,6 +146,8 @@ class CodeStub BASE_EMBEDDED {
|
| // Retrieve the code for the stub. Generate the code if needed.
|
| Handle<Code> GetCode(Isolate* isolate);
|
|
|
| + // Retrieve the code for the stub, make and return a copy of the code.
|
| + Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate);
|
| static Major MajorKeyFromKey(uint32_t key) {
|
| return static_cast<Major>(MajorKeyBits::decode(key));
|
| }
|
| @@ -203,6 +205,8 @@ class CodeStub BASE_EMBEDDED {
|
| return -1;
|
| }
|
|
|
| + virtual void PrintName(StringStream* stream);
|
| +
|
| protected:
|
| static bool CanUseFPRegisters();
|
|
|
| @@ -214,6 +218,11 @@ class CodeStub BASE_EMBEDDED {
|
| // a fixed (non-moveable) code object.
|
| virtual bool NeedsImmovableCode() { return false; }
|
|
|
| + // Returns a name for logging/debugging purposes.
|
| + SmartArrayPointer<const char> GetName();
|
| + virtual void PrintBaseName(StringStream* stream);
|
| + virtual void PrintState(StringStream* stream) { }
|
| +
|
| private:
|
| // Perform bookkeeping required after code generation when stub code is
|
| // initially generated.
|
| @@ -242,10 +251,6 @@ class CodeStub BASE_EMBEDDED {
|
| // If a stub uses a special cache override this.
|
| virtual bool UseSpecialCache() { return false; }
|
|
|
| - // Returns a name for logging/debugging purposes.
|
| - SmartArrayPointer<const char> GetName();
|
| - virtual void PrintName(StringStream* stream);
|
| -
|
| // Computes the key based on major and minor.
|
| uint32_t GetKey() {
|
| ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
|
| @@ -360,6 +365,9 @@ class HydrogenCodeStub : public CodeStub {
|
|
|
| Handle<Code> GenerateLightweightMissCode(Isolate* isolate);
|
|
|
| + 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> {};
|
| @@ -527,6 +535,117 @@ class FastNewBlockContextStub : public PlatformCodeStub {
|
| int MinorKey() { return slots_; }
|
| };
|
|
|
| +class StoreGlobalStub : public HydrogenCodeStub {
|
| + public:
|
| + StoreGlobalStub(StrictModeFlag strict_mode, bool is_constant) {
|
| + bit_field_ = StrictModeBits::encode(strict_mode) |
|
| + IsConstantBits::encode(is_constant);
|
| + }
|
| +
|
| + virtual Handle<Code> GenerateCode();
|
| +
|
| + virtual void InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor);
|
| +
|
| + virtual Code::Kind GetCodeKind() const { return Code::STORE_IC; }
|
| + virtual InlineCacheState GetICState() { return MONOMORPHIC; }
|
| + virtual Code::ExtraICState GetExtraICState() { return bit_field_; }
|
| +
|
| + bool is_constant() {
|
| + return IsConstantBits::decode(bit_field_);
|
| + }
|
| + void set_is_constant(bool value) {
|
| + bit_field_ = IsConstantBits::update(bit_field_, value);
|
| + }
|
| +
|
| + Representation representation() {
|
| + return Representation::FromKind(RepresentationBits::decode(bit_field_));
|
| + }
|
| + void set_representation(Representation r) {
|
| + bit_field_ = RepresentationBits::update(bit_field_, r.kind());
|
| + }
|
| +
|
| + private:
|
| + virtual int NotMissMinorKey() { return GetExtraICState(); }
|
| + Major MajorKey() { return StoreGlobal; }
|
| +
|
| + class StrictModeBits: public BitField<StrictModeFlag, 0, 1> {};
|
| + class IsConstantBits: public BitField<bool, 1, 1> {};
|
| + class RepresentationBits: public BitField<Representation::Kind, 2, 8> {};
|
| +
|
| + int bit_field_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
|
| +};
|
| +
|
| +
|
| +class UnaryOpStub : public HydrogenCodeStub {
|
| + public:
|
| + // Stub without type info available -> construct uninitialized
|
| + explicit UnaryOpStub(Token::Value operation)
|
| + : HydrogenCodeStub(UNINITIALIZED), operation_(operation) { }
|
| + explicit UnaryOpStub(Code::ExtraICState ic_state) :
|
| + state_(StateBits::decode(ic_state)),
|
| + operation_(OperatorBits::decode(ic_state)) { }
|
| +
|
| + virtual void InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor);
|
| +
|
| + virtual Code::Kind GetCodeKind() const { return Code::UNARY_OP_IC; }
|
| + virtual InlineCacheState GetICState() {
|
| + if (state_.Contains(GENERIC)) {
|
| + return MEGAMORPHIC;
|
| + } else if (state_.IsEmpty()) {
|
| + return PREMONOMORPHIC;
|
| + } else {
|
| + return MONOMORPHIC;
|
| + }
|
| + }
|
| + virtual Code::ExtraICState GetExtraICState() {
|
| + return OperatorBits::encode(operation_) |
|
| + StateBits::encode(state_.ToIntegral());
|
| + }
|
| +
|
| + Token::Value operation() { return operation_; }
|
| + Handle<JSFunction> ToJSFunction(Isolate* isolate);
|
| + Builtins::JavaScript ToJSBuiltin();
|
| +
|
| + void UpdateStatus(Handle<Object> object);
|
| + MaybeObject* Result(Handle<Object> object, Isolate* isolate);
|
| + Handle<Code> GenerateCode();
|
| + Handle<Type> GetType(Isolate* isolate);
|
| +
|
| + protected:
|
| + void PrintState(StringStream* stream);
|
| + void PrintBaseName(StringStream* stream);
|
| +
|
| + private:
|
| + enum UnaryOpType {
|
| + SMI,
|
| + HEAP_NUMBER,
|
| + GENERIC,
|
| + NUMBER_OF_TYPES
|
| + };
|
| +
|
| + class State : public EnumSet<UnaryOpType, byte> {
|
| + public:
|
| + State() : EnumSet<UnaryOpType, byte>() { }
|
| + explicit State(byte bits) : EnumSet<UnaryOpType, byte>(bits) { }
|
| + void Print(StringStream* stream) const;
|
| + };
|
| +
|
| + class StateBits : public BitField<int, 0, NUMBER_OF_TYPES> { };
|
| + class OperatorBits : public BitField<Token::Value, NUMBER_OF_TYPES, 8> { };
|
| +
|
| + State state_;
|
| + Token::Value operation_;
|
| +
|
| + virtual CodeStub::Major MajorKey() { return UnaryOp; }
|
| + virtual int NotMissMinorKey() { return GetExtraICState(); }
|
| +};
|
| +
|
|
|
| class FastCloneShallowArrayStub : public HydrogenCodeStub {
|
| public:
|
| @@ -628,6 +747,28 @@ class FastCloneShallowObjectStub : public HydrogenCodeStub {
|
| };
|
|
|
|
|
| +class CreateAllocationSiteStub : public HydrogenCodeStub {
|
| + public:
|
| + explicit CreateAllocationSiteStub() { }
|
| +
|
| + virtual Handle<Code> GenerateCode();
|
| +
|
| + virtual bool IsPregenerated() { return true; }
|
| +
|
| + static void GenerateAheadOfTime(Isolate* isolate);
|
| +
|
| + virtual void InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor);
|
| +
|
| + private:
|
| + Major MajorKey() { return CreateAllocationSite; }
|
| + int NotMissMinorKey() { return 0; }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CreateAllocationSiteStub);
|
| +};
|
| +
|
| +
|
| class InstanceofStub: public PlatformCodeStub {
|
| public:
|
| enum Flags {
|
| @@ -1151,7 +1292,6 @@ class CompareNilICStub : public HydrogenCodeStub {
|
| }
|
|
|
| void Print(StringStream* stream) const;
|
| - void TraceTransition(State to) const;
|
| };
|
|
|
| static Handle<Type> StateToType(
|
| @@ -1214,14 +1354,15 @@ class CompareNilICStub : public HydrogenCodeStub {
|
| return NilValueField::decode(state);
|
| }
|
|
|
| - void Record(Handle<Object> object);
|
| + void UpdateStatus(Handle<Object> object);
|
|
|
| bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); }
|
| NilValue GetNilValue() const { return nil_value_; }
|
| State GetState() const { return state_; }
|
| void ClearState() { state_.RemoveAll(); }
|
|
|
| - virtual void PrintName(StringStream* stream);
|
| + virtual void PrintState(StringStream* stream);
|
| + virtual void PrintBaseName(StringStream* stream);
|
|
|
| private:
|
| friend class CompareNilIC;
|
| @@ -1741,27 +1882,51 @@ class TransitionElementsKindStub : public HydrogenCodeStub {
|
| };
|
|
|
|
|
| +enum ContextCheckMode {
|
| + CONTEXT_CHECK_REQUIRED,
|
| + CONTEXT_CHECK_NOT_REQUIRED,
|
| + LAST_CONTEXT_CHECK_MODE = CONTEXT_CHECK_NOT_REQUIRED
|
| +};
|
| +
|
| +
|
| +enum AllocationSiteOverrideMode {
|
| + DONT_OVERRIDE,
|
| + DISABLE_ALLOCATION_SITES,
|
| + LAST_ALLOCATION_SITE_OVERRIDE_MODE = DISABLE_ALLOCATION_SITES
|
| +};
|
| +
|
| +
|
| class ArrayConstructorStubBase : public HydrogenCodeStub {
|
| public:
|
| - ArrayConstructorStubBase(ElementsKind kind, bool disable_allocation_sites) {
|
| + ArrayConstructorStubBase(ElementsKind kind, ContextCheckMode context_mode,
|
| + AllocationSiteOverrideMode override_mode) {
|
| // It only makes sense to override local allocation site behavior
|
| // if there is a difference between the global allocation site policy
|
| // for an ElementsKind and the desired usage of the stub.
|
| - ASSERT(!disable_allocation_sites ||
|
| - AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
|
| + ASSERT(override_mode != DISABLE_ALLOCATION_SITES ||
|
| + AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
|
| bit_field_ = ElementsKindBits::encode(kind) |
|
| - DisableAllocationSitesBits::encode(disable_allocation_sites);
|
| + AllocationSiteOverrideModeBits::encode(override_mode) |
|
| + ContextCheckModeBits::encode(context_mode);
|
| }
|
|
|
| ElementsKind elements_kind() const {
|
| return ElementsKindBits::decode(bit_field_);
|
| }
|
|
|
| - bool disable_allocation_sites() const {
|
| - return DisableAllocationSitesBits::decode(bit_field_);
|
| + AllocationSiteOverrideMode override_mode() const {
|
| + return AllocationSiteOverrideModeBits::decode(bit_field_);
|
| + }
|
| +
|
| + ContextCheckMode context_mode() const {
|
| + return ContextCheckModeBits::decode(bit_field_);
|
| + }
|
| +
|
| + virtual bool IsPregenerated() {
|
| + // We only pre-generate stubs that verify correct context
|
| + return context_mode() == CONTEXT_CHECK_REQUIRED;
|
| }
|
|
|
| - virtual bool IsPregenerated() { return true; }
|
| static void GenerateStubsAheadOfTime(Isolate* isolate);
|
| static void InstallDescriptors(Isolate* isolate);
|
|
|
| @@ -1772,8 +1937,14 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
|
| private:
|
| int NotMissMinorKey() { return bit_field_; }
|
|
|
| + // Ensure data fits within available bits.
|
| + STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
|
| + STATIC_ASSERT(LAST_CONTEXT_CHECK_MODE == 1);
|
| +
|
| class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
|
| - class DisableAllocationSitesBits: public BitField<bool, 8, 1> {};
|
| + class AllocationSiteOverrideModeBits: public
|
| + BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
|
| + class ContextCheckModeBits: public BitField<ContextCheckMode, 9, 1> {};
|
| uint32_t bit_field_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase);
|
| @@ -1784,8 +1955,9 @@ class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
|
| public:
|
| ArrayNoArgumentConstructorStub(
|
| ElementsKind kind,
|
| - bool disable_allocation_sites = false)
|
| - : ArrayConstructorStubBase(kind, disable_allocation_sites) {
|
| + ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
|
| + AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
|
| + : ArrayConstructorStubBase(kind, context_mode, override_mode) {
|
| }
|
|
|
| virtual Handle<Code> GenerateCode();
|
| @@ -1805,8 +1977,9 @@ class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
|
| public:
|
| ArraySingleArgumentConstructorStub(
|
| ElementsKind kind,
|
| - bool disable_allocation_sites = false)
|
| - : ArrayConstructorStubBase(kind, disable_allocation_sites) {
|
| + ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
|
| + AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
|
| + : ArrayConstructorStubBase(kind, context_mode, override_mode) {
|
| }
|
|
|
| virtual Handle<Code> GenerateCode();
|
| @@ -1826,8 +1999,9 @@ class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
|
| public:
|
| ArrayNArgumentsConstructorStub(
|
| ElementsKind kind,
|
| - bool disable_allocation_sites = false)
|
| - : ArrayConstructorStubBase(kind, disable_allocation_sites) {
|
| + ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
|
| + AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
|
| + : ArrayConstructorStubBase(kind, context_mode, override_mode) {
|
| }
|
|
|
| virtual Handle<Code> GenerateCode();
|
| @@ -1984,8 +2158,7 @@ class ToBooleanStub: public HydrogenCodeStub {
|
|
|
| byte ToByte() const { return ToIntegral(); }
|
| void Print(StringStream* stream) const;
|
| - void TraceTransition(Types to) const;
|
| - bool Record(Handle<Object> object);
|
| + bool UpdateStatus(Handle<Object> object);
|
| bool NeedsMap() const;
|
| bool CanBeUndetectable() const;
|
| bool IsGeneric() const { return ToIntegral() == Generic().ToIntegral(); }
|
| @@ -1998,7 +2171,7 @@ class ToBooleanStub: public HydrogenCodeStub {
|
| explicit ToBooleanStub(Code::ExtraICState state)
|
| : types_(static_cast<byte>(state)) { }
|
|
|
| - bool Record(Handle<Object> object);
|
| + bool UpdateStatus(Handle<Object> object);
|
| Types GetTypes() { return types_; }
|
|
|
| virtual Handle<Code> GenerateCode();
|
| @@ -2007,7 +2180,7 @@ class ToBooleanStub: public HydrogenCodeStub {
|
| CodeStubInterfaceDescriptor* descriptor);
|
|
|
| virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; }
|
| - virtual void PrintName(StringStream* stream);
|
| + virtual void PrintState(StringStream* stream);
|
|
|
| virtual bool SometimesSetsUpAFrame() { return false; }
|
|
|
| @@ -2143,13 +2316,6 @@ class ProfileEntryHookStub : public PlatformCodeStub {
|
| // Generates a call to the entry hook if it's enabled.
|
| static void MaybeCallEntryHook(MacroAssembler* masm);
|
|
|
| - // Sets or unsets the entry hook function. Returns true on success,
|
| - // false on an attempt to replace a non-NULL entry hook with another
|
| - // non-NULL hook.
|
| - static bool SetFunctionEntryHook(FunctionEntryHook entry_hook);
|
| -
|
| - static bool HasEntryHook() { return entry_hook_ != NULL; }
|
| -
|
| private:
|
| static void EntryHookTrampoline(intptr_t function,
|
| intptr_t stack_pointer);
|
| @@ -2159,9 +2325,6 @@ class ProfileEntryHookStub : public PlatformCodeStub {
|
|
|
| void Generate(MacroAssembler* masm);
|
|
|
| - // The current function entry hook.
|
| - static FunctionEntryHook entry_hook_;
|
| -
|
| DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
|
| };
|
|
|
|
|