| Index: src/ic.h
|
| diff --git a/src/ic.h b/src/ic.h
|
| index b1a47e2b2171b3d52de6d00e7d0c17aec60e3a63..6ef38ad1e5f7c23fb4e0a79404ab7b3d59d8b563 100644
|
| --- a/src/ic.h
|
| +++ b/src/ic.h
|
| @@ -87,6 +87,20 @@ class IC {
|
| EXTRA_CALL_FRAME = 1
|
| };
|
|
|
| + // ExtraICState shared by all ICs.
|
| + class Contextual: public BitField<ContextualMode, 0, 1> {};
|
| + STATIC_ASSERT(static_cast<int>(NOT_CONTEXTUAL) == 0);
|
| + static ExtraICState ComputeExtraICState(ContextualMode mode) {
|
| + return Contextual::encode(mode);
|
| + }
|
| +
|
| + static ContextualMode GetContextualMode(ExtraICState state) {
|
| + return Contextual::decode(state);
|
| + }
|
| +
|
| + static const ExtraICState kContextualState =
|
| + static_cast<int>(CONTEXTUAL) << Contextual::kShift;
|
| +
|
| // Construct the IC structure with the given number of extra
|
| // JavaScript frames on the stack.
|
| IC(FrameDepth depth, Isolate* isolate);
|
| @@ -104,26 +118,17 @@ class IC {
|
| // Clear the inline cache to initial state.
|
| static void Clear(Isolate* isolate, Address address);
|
|
|
| - // Computes the reloc info for this IC. This is a fairly expensive
|
| - // operation as it has to search through the heap to find the code
|
| - // object that contains this IC site.
|
| - RelocInfo::Mode ComputeMode();
|
| -
|
| // Returns if this IC is for contextual (no explicit receiver)
|
| // access to properties.
|
| bool IsUndeclaredGlobal(Handle<Object> receiver) {
|
| if (receiver->IsGlobalObject()) {
|
| - return SlowIsUndeclaredGlobal();
|
| + return contextual_mode();
|
| } else {
|
| - ASSERT(!SlowIsUndeclaredGlobal());
|
| + ASSERT(!contextual_mode());
|
| return false;
|
| }
|
| }
|
|
|
| - bool SlowIsUndeclaredGlobal() {
|
| - return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
|
| - }
|
| -
|
| #ifdef DEBUG
|
| bool IsLoadStub() {
|
| return target()->is_load_stub() || target()->is_keyed_load_stub();
|
| @@ -167,6 +172,10 @@ class IC {
|
| static Type* MapToType(Handle<Map> type);
|
| static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate);
|
|
|
| + ContextualMode contextual_mode() const {
|
| + return Contextual::decode(extra_ic_state());
|
| + }
|
| +
|
| protected:
|
| // Get the call-site target; used for determining the state.
|
| Handle<Code> target() const { return target_; }
|
| @@ -255,7 +264,10 @@ class IC {
|
| Handle<String> name);
|
| void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
|
|
|
| - virtual ExtraICState extra_ic_state() { return kNoExtraICState; }
|
| + ExtraICState extra_ic_state() const { return extra_ic_state_; }
|
| + void set_extra_ic_state(ExtraICState state) {
|
| + extra_ic_state_ = state;
|
| + }
|
|
|
| private:
|
| Code* raw_target() const { return GetTargetAtAddress(address()); }
|
| @@ -276,6 +288,8 @@ class IC {
|
| State state_;
|
| bool target_set_;
|
|
|
| + ExtraICState extra_ic_state_;
|
| +
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
|
| };
|
|
|
| @@ -299,7 +313,6 @@ class IC_Utility {
|
| class CallICBase: public IC {
|
| public:
|
| // ExtraICState bits
|
| - class Contextual: public BitField<ContextualMode, 0, 1> {};
|
| class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
|
| static ExtraICState ComputeExtraICState(ContextualMode mode,
|
| StringStubFeedback feedback) {
|
| @@ -360,8 +373,7 @@ class CallICBase: public IC {
|
| class CallIC: public CallICBase {
|
| public:
|
| explicit CallIC(Isolate* isolate)
|
| - : CallICBase(Code::CALL_IC, isolate),
|
| - extra_ic_state_(target()->extra_ic_state()) {
|
| + : CallICBase(Code::CALL_IC, isolate) {
|
| ASSERT(target()->is_call_stub());
|
| }
|
|
|
| @@ -387,12 +399,6 @@ class CallIC: public CallICBase {
|
| GenerateMiss(masm, argc, kNoExtraICState);
|
| }
|
| bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object);
|
| -
|
| - protected:
|
| - virtual ExtraICState extra_ic_state() { return extra_ic_state_; }
|
| -
|
| - private:
|
| - ExtraICState extra_ic_state_;
|
| };
|
|
|
|
|
| @@ -424,7 +430,8 @@ class KeyedCallIC: public CallICBase {
|
|
|
| class LoadIC: public IC {
|
| public:
|
| - explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
|
| + explicit LoadIC(FrameDepth depth, Isolate* isolate)
|
| + : IC(depth, isolate) {
|
| ASSERT(IsLoadStub());
|
| }
|
|
|
| @@ -434,7 +441,7 @@ class LoadIC: public IC {
|
| GenerateMiss(masm);
|
| }
|
| static void GenerateMiss(MacroAssembler* masm);
|
| - static void GenerateMegamorphic(MacroAssembler* masm);
|
| + static void GenerateMegamorphic(MacroAssembler* masm, ContextualMode mode);
|
| static void GenerateNormal(MacroAssembler* masm);
|
| static void GenerateRuntimeGetProperty(MacroAssembler* masm);
|
|
|
| @@ -449,7 +456,11 @@ class LoadIC: public IC {
|
| }
|
|
|
| virtual Handle<Code> megamorphic_stub() {
|
| - return isolate()->builtins()->LoadIC_Megamorphic();
|
| + if (contextual_mode() == CONTEXTUAL) {
|
| + return isolate()->builtins()->LoadIC_Megamorphic_Contextual();
|
| + } else {
|
| + return isolate()->builtins()->LoadIC_Megamorphic();
|
| + }
|
| }
|
|
|
| // Update the inline cache and the global stub cache based on the
|
| @@ -466,16 +477,15 @@ class LoadIC: public IC {
|
|
|
| private:
|
| // Stub accessors.
|
| - static Handle<Code> initialize_stub(Isolate* isolate) {
|
| - return isolate->builtins()->LoadIC_Initialize();
|
| - }
|
| -
|
| - static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
|
| - return isolate->builtins()->LoadIC_PreMonomorphic();
|
| + static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
|
| + ContextualMode mode) {
|
| + return mode == CONTEXTUAL
|
| + ? isolate->builtins()->LoadIC_PreMonomorphic_Contextual()
|
| + : isolate->builtins()->LoadIC_PreMonomorphic();
|
| }
|
|
|
| virtual Handle<Code> pre_monomorphic_stub() {
|
| - return pre_monomorphic_stub(isolate());
|
| + return pre_monomorphic_stub(isolate(), contextual_mode());
|
| }
|
|
|
| Handle<Code> SimpleFieldLoad(int offset,
|
| @@ -537,9 +547,6 @@ class KeyedLoadIC: public LoadIC {
|
|
|
| private:
|
| // Stub accessors.
|
| - static Handle<Code> initialize_stub(Isolate* isolate) {
|
| - return isolate->builtins()->KeyedLoadIC_Initialize();
|
| - }
|
| static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
|
| return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
|
| }
|
| @@ -565,11 +572,16 @@ class KeyedLoadIC: public LoadIC {
|
| class StoreIC: public IC {
|
| public:
|
| // ExtraICState bits
|
| - class StrictModeState: public BitField<StrictModeFlag, 0, 1> {};
|
| + class StrictModeState: public BitField<StrictModeFlag, 1, 1> {};
|
| static ExtraICState ComputeExtraICState(StrictModeFlag flag) {
|
| return StrictModeState::encode(flag);
|
| }
|
|
|
| + static ExtraICState ComputeExtraICState(StrictModeFlag flag,
|
| + ContextualMode mode) {
|
| + return StrictModeState::encode(flag) | Contextual::encode(mode);
|
| + }
|
| +
|
| static StrictModeFlag GetStrictMode(ExtraICState state) {
|
| return StrictModeState::decode(state);
|
| }
|
| @@ -580,12 +592,13 @@ class StoreIC: public IC {
|
| 1 << StrictModeState::kShift;
|
|
|
| StoreIC(FrameDepth depth, Isolate* isolate)
|
| - : IC(depth, isolate),
|
| - strict_mode_(GetStrictMode(target()->extra_ic_state())) {
|
| + : IC(depth, isolate) {
|
| ASSERT(IsStoreStub());
|
| }
|
|
|
| - StrictModeFlag strict_mode() const { return strict_mode_; }
|
| + StrictModeFlag strict_mode() const {
|
| + return StrictModeState::decode(extra_ic_state());
|
| + }
|
|
|
| // Code generators for stub routines. Only called once at startup.
|
| static void GenerateSlow(MacroAssembler* masm);
|
| @@ -595,7 +608,8 @@ class StoreIC: public IC {
|
| }
|
| static void GenerateMiss(MacroAssembler* masm);
|
| static void GenerateMegamorphic(MacroAssembler* masm,
|
| - StrictModeFlag strict_mode);
|
| + StrictModeFlag strict_mode,
|
| + ContextualMode mode);
|
| static void GenerateNormal(MacroAssembler* masm);
|
| static void GenerateRuntimeSetProperty(MacroAssembler* masm,
|
| StrictModeFlag strict_mode);
|
| @@ -611,8 +625,13 @@ class StoreIC: public IC {
|
| virtual Code::Kind kind() const { return Code::STORE_IC; }
|
| virtual Handle<Code> megamorphic_stub() {
|
| if (strict_mode() == kStrictMode) {
|
| - return isolate()->builtins()->StoreIC_Megamorphic_Strict();
|
| + if (contextual_mode() == CONTEXTUAL) {
|
| + return isolate()->builtins()->StoreIC_Megamorphic_Contextual_Strict();
|
| + } else {
|
| + return isolate()->builtins()->StoreIC_Megamorphic_Strict();
|
| + }
|
| } else {
|
| + ASSERT(contextual_mode() != CONTEXTUAL);
|
| return isolate()->builtins()->StoreIC_Megamorphic();
|
| }
|
| }
|
| @@ -630,14 +649,18 @@ class StoreIC: public IC {
|
| }
|
|
|
| virtual Handle<Code> pre_monomorphic_stub() {
|
| - return pre_monomorphic_stub(isolate(), strict_mode());
|
| + return pre_monomorphic_stub(isolate(), strict_mode(), contextual_mode());
|
| }
|
|
|
| static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
|
| - StrictModeFlag strict_mode) {
|
| + StrictModeFlag strict_mode,
|
| + ContextualMode contextual_mode) {
|
| if (strict_mode == kStrictMode) {
|
| - return isolate->builtins()->StoreIC_PreMonomorphic_Strict();
|
| + return contextual_mode == CONTEXTUAL
|
| + ? isolate->builtins()->StoreIC_PreMonomorphic_Contextual_Strict()
|
| + : isolate->builtins()->StoreIC_PreMonomorphic_Strict();
|
| } else {
|
| + ASSERT(contextual_mode != CONTEXTUAL);
|
| return isolate->builtins()->StoreIC_PreMonomorphic();
|
| }
|
| }
|
| @@ -654,10 +677,6 @@ class StoreIC: public IC {
|
| Handle<Object> value,
|
| InlineCacheHolderFlag cache_holder);
|
|
|
| - virtual ExtraICState extra_ic_state() {
|
| - return ComputeExtraICState(strict_mode());
|
| - }
|
| -
|
| private:
|
| void set_target(Code* code) {
|
| // Strict mode must be preserved across IC patching.
|
| @@ -666,19 +685,8 @@ class StoreIC: public IC {
|
| IC::set_target(code);
|
| }
|
|
|
| - static Handle<Code> initialize_stub(Isolate* isolate,
|
| - StrictModeFlag strict_mode) {
|
| - if (strict_mode == kStrictMode) {
|
| - return isolate->builtins()->StoreIC_Initialize_Strict();
|
| - } else {
|
| - return isolate->builtins()->StoreIC_Initialize();
|
| - }
|
| - }
|
| -
|
| static void Clear(Isolate* isolate, Address address, Code* target);
|
|
|
| - StrictModeFlag strict_mode_;
|
| -
|
| friend class IC;
|
| };
|
|
|
| @@ -700,10 +708,10 @@ class KeyedStoreIC: public StoreIC {
|
| // ExtraICState bits (building on IC)
|
| // ExtraICState bits
|
| class ExtraICStateKeyedAccessStoreMode:
|
| - public BitField<KeyedAccessStoreMode, 1, 4> {}; // NOLINT
|
| + public BitField<KeyedAccessStoreMode, 2, 4> {}; // NOLINT
|
|
|
| static ExtraICState ComputeExtraICState(StrictModeFlag flag,
|
| - KeyedAccessStoreMode mode) {
|
| + KeyedAccessStoreMode mode) {
|
| return StrictModeState::encode(flag) |
|
| ExtraICStateKeyedAccessStoreMode::encode(mode);
|
| }
|
| @@ -739,10 +747,6 @@ class KeyedStoreIC: public StoreIC {
|
|
|
| virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
|
|
|
| - virtual ExtraICState extra_ic_state() {
|
| - return ComputeExtraICState(strict_mode(), STANDARD_STORE);
|
| - }
|
| -
|
| virtual Handle<Code> pre_monomorphic_stub() {
|
| return pre_monomorphic_stub(isolate(), strict_mode());
|
| }
|
| @@ -776,15 +780,6 @@ class KeyedStoreIC: public StoreIC {
|
| }
|
|
|
| // Stub accessors.
|
| - static Handle<Code> initialize_stub(Isolate* isolate,
|
| - StrictModeFlag strict_mode) {
|
| - if (strict_mode == kStrictMode) {
|
| - return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
|
| - } else {
|
| - return isolate->builtins()->KeyedStoreIC_Initialize();
|
| - }
|
| - }
|
| -
|
| virtual Handle<Code> generic_stub() const {
|
| if (strict_mode() == kStrictMode) {
|
| return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
|
|
|