Index: src/ic.h |
diff --git a/src/ic.h b/src/ic.h |
index 784512a1c49f8b2f421495dc93cee5d1a1fafadb..aeb58bf8142787e1013d3649628f916802f0b7ce 100644 |
--- a/src/ic.h |
+++ b/src/ic.h |
@@ -132,63 +132,7 @@ class IC { |
static inline JSObject* GetCodeCacheHolder(Object* object, |
InlineCacheHolderFlag holder); |
- MUST_USE_RESULT MaybeObject* Load(State state, |
- Handle<Object> object, |
- Handle<String> name); |
- |
- MUST_USE_RESULT MaybeObject* Store( |
- State state, |
- StrictModeFlag strict_mode, |
- Handle<Object> object, |
- Handle<String> name, |
- Handle<Object> value, |
- JSReceiver::StoreFromKeyed store_mode = |
- JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); |
- |
protected: |
- virtual Handle<Code> pre_monomorphic_stub() { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- virtual Handle<Code> megamorphic_stub() { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- virtual Handle<Code> megamorphic_stub_strict() { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- virtual Handle<Code> generic_stub() const { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- virtual Code::Kind kind() const { |
- UNREACHABLE(); |
- return Code::STUB; |
- } |
- virtual Handle<Code> global_proxy_stub() { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- virtual Handle<Code> global_proxy_stub_strict() { |
- UNREACHABLE(); |
- return Handle<Code>::null(); |
- } |
- |
- virtual void UpdateLoadCaches(LookupResult* lookup, |
- State state, |
- Handle<Object> object, |
- Handle<String> name) { |
- UNREACHABLE(); |
- } |
- virtual void UpdateStoreCaches(LookupResult* lookup, |
- State state, |
- StrictModeFlag strict_mode, |
- Handle<JSObject> receiver, |
- Handle<String> name, |
- Handle<Object> value) { |
- UNREACHABLE(); |
- } |
Address fp() const { return fp_; } |
Address pc() const { return *pc_address_; } |
Isolate* isolate() const { return isolate_; } |
@@ -376,7 +320,7 @@ class KeyedCallIC: public CallICBase { |
class LoadIC: public IC { |
public: |
explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
- ASSERT(target()->is_load_stub()); |
+ ASSERT(target()->is_load_stub() || target()->is_keyed_load_stub()); |
} |
// Code generator routines. |
@@ -392,9 +336,18 @@ class LoadIC: public IC { |
static void GenerateArrayLength(MacroAssembler* masm); |
static void GenerateFunctionPrototype(MacroAssembler* masm); |
+ MUST_USE_RESULT MaybeObject* Load(State state, |
+ Handle<Object> object, |
+ Handle<String> name); |
+ |
protected: |
virtual Code::Kind kind() const { return Code::LOAD_IC; } |
+ virtual Handle<Code> generic_stub() const { |
+ UNREACHABLE(); |
+ return Handle<Code>::null(); |
+ } |
+ |
virtual Handle<Code> megamorphic_stub() { |
return isolate()->builtins()->LoadIC_Megamorphic(); |
} |
@@ -421,119 +374,15 @@ class LoadIC: public IC { |
}; |
-class KeyedIC: public IC { |
- public: |
- enum StubKind { |
- LOAD, |
- STORE_NO_TRANSITION, |
- STORE_TRANSITION_SMI_TO_OBJECT, |
- STORE_TRANSITION_SMI_TO_DOUBLE, |
- STORE_TRANSITION_DOUBLE_TO_OBJECT, |
- STORE_TRANSITION_HOLEY_SMI_TO_OBJECT, |
- STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE, |
- STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, |
- STORE_AND_GROW_NO_TRANSITION, |
- STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, |
- STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, |
- STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, |
- STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, |
- STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, |
- STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT |
- }; |
- |
- static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - |
- STORE_NO_TRANSITION; |
- STATIC_ASSERT(kGrowICDelta == |
- STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - |
- STORE_TRANSITION_SMI_TO_OBJECT); |
- STATIC_ASSERT(kGrowICDelta == |
- STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - |
- STORE_TRANSITION_SMI_TO_DOUBLE); |
- STATIC_ASSERT(kGrowICDelta == |
- STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT - |
- STORE_TRANSITION_DOUBLE_TO_OBJECT); |
- |
- explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} |
- virtual ~KeyedIC() {} |
- |
- static inline KeyedAccessGrowMode GetGrowModeFromStubKind( |
- StubKind stub_kind) { |
- return (stub_kind >= STORE_AND_GROW_NO_TRANSITION) |
- ? ALLOW_JSARRAY_GROWTH |
- : DO_NOT_ALLOW_JSARRAY_GROWTH; |
- } |
- |
- static inline StubKind GetGrowStubKind(StubKind stub_kind) { |
- ASSERT(stub_kind != LOAD); |
- if (stub_kind < STORE_AND_GROW_NO_TRANSITION) { |
- stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) + |
- kGrowICDelta); |
- } |
- return stub_kind; |
- } |
- |
- virtual Handle<Code> GetElementStubWithoutMapCheck( |
- bool is_js_array, |
- ElementsKind elements_kind, |
- KeyedAccessGrowMode grow_mode) = 0; |
- |
- protected: |
- virtual Handle<Code> string_stub() { |
- return Handle<Code>::null(); |
- } |
- |
- Handle<Code> ComputeStub(Handle<JSObject> receiver, |
- StubKind stub_kind, |
- StrictModeFlag strict_mode, |
- Handle<Code> default_stub); |
- |
- virtual Handle<Code> ComputePolymorphicStub( |
- MapHandleList* receiver_maps, |
- StrictModeFlag strict_mode, |
- KeyedAccessGrowMode grow_mode) = 0; |
- |
- Handle<Code> ComputeMonomorphicStubWithoutMapCheck( |
- Handle<Map> receiver_map, |
- StrictModeFlag strict_mode, |
- KeyedAccessGrowMode grow_mode); |
- |
- private: |
- void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result); |
- |
- Handle<Code> ComputeMonomorphicStub(Handle<Map> receiver_map, |
- StubKind stub_kind, |
- StrictModeFlag strict_mode, |
- Handle<Code> default_stub); |
- |
- Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, |
- StubKind stub_kind); |
- |
- static bool IsTransitionStubKind(StubKind stub_kind) { |
- return stub_kind > STORE_NO_TRANSITION && |
- stub_kind != STORE_AND_GROW_NO_TRANSITION; |
- } |
- |
- static bool IsGrowStubKind(StubKind stub_kind) { |
- return stub_kind >= STORE_AND_GROW_NO_TRANSITION; |
- } |
- |
- static StubKind GetNoTransitionStubKind(StubKind stub_kind) { |
- if (!IsTransitionStubKind(stub_kind)) return stub_kind; |
- if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION; |
- return STORE_NO_TRANSITION; |
- } |
-}; |
- |
- |
enum ICMissMode { |
MISS_FORCE_GENERIC, |
MISS |
}; |
-class KeyedLoadIC: public KeyedIC { |
+class KeyedLoadIC: public LoadIC { |
public: |
- explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { |
+ explicit KeyedLoadIC(Isolate* isolate) : LoadIC(isolate) { |
ASSERT(target()->is_keyed_load_stub()); |
} |
@@ -563,14 +412,11 @@ class KeyedLoadIC: public KeyedIC { |
static const int kSlowCaseBitFieldMask = |
(1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); |
- virtual Handle<Code> GetElementStubWithoutMapCheck( |
- bool is_js_array, |
- ElementsKind elements_kind, |
- KeyedAccessGrowMode grow_mode); |
- |
protected: |
virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } |
+ Handle<Code> LoadElementStub(Handle<JSObject> receiver); |
+ |
virtual Handle<Code> megamorphic_stub() { |
return isolate()->builtins()->KeyedLoadIC_Generic(); |
} |
@@ -578,14 +424,6 @@ class KeyedLoadIC: public KeyedIC { |
return isolate()->builtins()->KeyedLoadIC_Generic(); |
} |
- virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, |
- StrictModeFlag strict_mode, |
- KeyedAccessGrowMode grow_mode); |
- |
- virtual Handle<Code> string_stub() { |
- return isolate()->builtins()->KeyedLoadIC_String(); |
- } |
- |
// Update the inline cache. |
virtual void UpdateLoadCaches(LookupResult* lookup, |
State state, |
@@ -606,6 +444,9 @@ class KeyedLoadIC: public KeyedIC { |
Handle<Code> non_strict_arguments_stub() { |
return isolate()->builtins()->KeyedLoadIC_NonStrictArguments(); |
} |
+ Handle<Code> string_stub() { |
+ return isolate()->builtins()->KeyedLoadIC_String(); |
+ } |
static void Clear(Address address, Code* target); |
@@ -616,7 +457,7 @@ class KeyedLoadIC: public KeyedIC { |
class StoreIC: public IC { |
public: |
explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { |
- ASSERT(target()->is_store_stub()); |
+ ASSERT(target()->is_store_stub() || target()->is_keyed_store_stub()); |
} |
// Code generators for stub routines. Only called once at startup. |
@@ -629,6 +470,15 @@ class StoreIC: public IC { |
static void GenerateGlobalProxy(MacroAssembler* masm, |
StrictModeFlag strict_mode); |
+ MUST_USE_RESULT MaybeObject* Store( |
+ State state, |
+ StrictModeFlag strict_mode, |
+ Handle<Object> object, |
+ Handle<String> name, |
+ Handle<Object> value, |
+ JSReceiver::StoreFromKeyed store_mode = |
+ JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); |
+ |
protected: |
virtual Code::Kind kind() const { return Code::STORE_IC; } |
virtual Handle<Code> megamorphic_stub() { |
@@ -687,9 +537,46 @@ enum KeyedStoreIncrementLength { |
}; |
-class KeyedStoreIC: public KeyedIC { |
+class KeyedStoreIC: public StoreIC { |
public: |
- explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) { |
+ enum StubKind { |
+ STORE_NO_TRANSITION, |
+ STORE_TRANSITION_SMI_TO_OBJECT, |
+ STORE_TRANSITION_SMI_TO_DOUBLE, |
+ STORE_TRANSITION_DOUBLE_TO_OBJECT, |
+ STORE_TRANSITION_HOLEY_SMI_TO_OBJECT, |
+ STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE, |
+ STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, |
+ STORE_AND_GROW_NO_TRANSITION, |
+ STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, |
+ STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, |
+ STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, |
+ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, |
+ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, |
+ STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT |
+ }; |
+ |
+ static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - |
+ STORE_NO_TRANSITION; |
+ STATIC_ASSERT(kGrowICDelta == |
+ STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - |
+ STORE_TRANSITION_SMI_TO_OBJECT); |
+ STATIC_ASSERT(kGrowICDelta == |
+ STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - |
+ STORE_TRANSITION_SMI_TO_DOUBLE); |
+ STATIC_ASSERT(kGrowICDelta == |
+ STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT - |
+ STORE_TRANSITION_DOUBLE_TO_OBJECT); |
+ |
+ static inline StubKind GetGrowStubKind(StubKind stub_kind) { |
+ if (stub_kind < STORE_AND_GROW_NO_TRANSITION) { |
+ stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) + |
+ kGrowICDelta); |
+ } |
+ return stub_kind; |
+ } |
+ |
+ explicit KeyedStoreIC(Isolate* isolate) : StoreIC(isolate) { |
ASSERT(target()->is_keyed_store_stub()); |
} |
@@ -713,18 +600,9 @@ class KeyedStoreIC: public KeyedIC { |
static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm); |
static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm); |
- virtual Handle<Code> GetElementStubWithoutMapCheck( |
- bool is_js_array, |
- ElementsKind elements_kind, |
- KeyedAccessGrowMode grow_mode); |
- |
protected: |
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } |
- virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, |
- StrictModeFlag strict_mode, |
- KeyedAccessGrowMode grow_mode); |
- |
// Update the inline cache. |
virtual void UpdateStoreCaches(LookupResult* lookup, |
State state, |
@@ -740,6 +618,10 @@ class KeyedStoreIC: public KeyedIC { |
return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); |
} |
+ Handle<Code> StoreElementStub(Handle<JSObject> receiver, |
+ StubKind stub_kind, |
+ StrictModeFlag strict_mode); |
+ |
private: |
void set_target(Code* code) { |
// Strict mode must be preserved across IC patching. |
@@ -771,6 +653,24 @@ class KeyedStoreIC: public KeyedIC { |
Handle<Object> key, |
Handle<Object> value); |
+ static bool IsTransitionStubKind(StubKind stub_kind) { |
+ return stub_kind > STORE_NO_TRANSITION && |
+ stub_kind != STORE_AND_GROW_NO_TRANSITION; |
+ } |
+ |
+ static bool IsGrowStubKind(StubKind stub_kind) { |
+ return stub_kind >= STORE_AND_GROW_NO_TRANSITION; |
+ } |
+ |
+ static StubKind GetNoTransitionStubKind(StubKind stub_kind) { |
+ if (!IsTransitionStubKind(stub_kind)) return stub_kind; |
+ if (IsGrowStubKind(stub_kind)) return STORE_AND_GROW_NO_TRANSITION; |
+ return STORE_NO_TRANSITION; |
+ } |
+ |
+ Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, |
+ StubKind stub_kind); |
+ |
friend class IC; |
}; |