Index: src/ic.h |
diff --git a/src/ic.h b/src/ic.h |
index fa7ed6dbc1381f60aee70703a65d34566179dfba..9dd06f7cb6d6fe513c824b06ac1af9c6d6a35ce5 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 IsContextual(); |
} else { |
- ASSERT(!SlowIsUndeclaredGlobal()); |
+ ASSERT(!IsContextual()); |
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,12 @@ 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()); |
+ } |
+ |
+ bool IsContextual() const { return contextual_mode() == CONTEXTUAL; } |
+ |
protected: |
// Get the call-site target; used for determining the state. |
Handle<Code> target() const { return target_; } |
@@ -255,7 +266,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 +290,8 @@ class IC { |
State state_; |
bool target_set_; |
+ ExtraICState extra_ic_state_; |
+ |
DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
}; |
@@ -299,7 +315,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 +375,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 +401,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 +432,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,10 +443,12 @@ 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); |
+ static Handle<Code> initialize_stub(Isolate* isolate, ContextualMode mode); |
+ |
MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, |
Handle<String> name); |
@@ -448,9 +459,7 @@ class LoadIC: public IC { |
return isolate()->builtins()->LoadIC_Slow(); |
} |
- virtual Handle<Code> megamorphic_stub() { |
- return isolate()->builtins()->LoadIC_Megamorphic(); |
- } |
+ virtual Handle<Code> megamorphic_stub(); |
// Update the inline cache and the global stub cache based on the |
// lookup result. |
@@ -466,16 +475,11 @@ 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); |
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 +541,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 +566,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 +586,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); |
@@ -600,6 +607,10 @@ class StoreIC: public IC { |
static void GenerateRuntimeSetProperty(MacroAssembler* masm, |
StrictModeFlag strict_mode); |
+ static Handle<Code> initialize_stub(Isolate* isolate, |
+ StrictModeFlag strict_mode, |
+ ContextualMode mode); |
+ |
MUST_USE_RESULT MaybeObject* Store( |
Handle<Object> object, |
Handle<String> name, |
@@ -609,38 +620,22 @@ class StoreIC: public IC { |
protected: |
virtual Code::Kind kind() const { return Code::STORE_IC; } |
- virtual Handle<Code> megamorphic_stub() { |
- if (strict_mode() == kStrictMode) { |
- return isolate()->builtins()->StoreIC_Megamorphic_Strict(); |
- } else { |
- return isolate()->builtins()->StoreIC_Megamorphic(); |
- } |
- } |
+ virtual Handle<Code> megamorphic_stub(); |
+ |
// Stub accessors. |
- virtual Handle<Code> generic_stub() const { |
- if (strict_mode() == kStrictMode) { |
- return isolate()->builtins()->StoreIC_Generic_Strict(); |
- } else { |
- return isolate()->builtins()->StoreIC_Generic(); |
- } |
- } |
+ virtual Handle<Code> generic_stub() const; |
virtual Handle<Code> slow_stub() const { |
return isolate()->builtins()->StoreIC_Slow(); |
} |
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) { |
- if (strict_mode == kStrictMode) { |
- return isolate->builtins()->StoreIC_PreMonomorphic_Strict(); |
- } else { |
- return isolate->builtins()->StoreIC_PreMonomorphic(); |
- } |
- } |
+ StrictModeFlag strict_mode, |
+ ContextualMode contextual_mode); |
// Update the inline cache and the global stub cache based on the |
// lookup result. |
@@ -654,31 +649,19 @@ 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. |
ASSERT(GetStrictMode(code->extra_ic_state()) == |
GetStrictMode(target()->extra_ic_state())); |
+ // As must the contextual mode |
+ ASSERT(GetContextualMode(code->extra_ic_state()) == |
+ GetContextualMode(target()->extra_ic_state())); |
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 +683,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 +722,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 +755,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(); |