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