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(); |