Index: src/arm/stub-cache-arm.cc |
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc |
index 5b1f12c74d305a8b137cbeb3bfdc19d306e9bf14..dfa33587c2f97002b98c94b223618dfe970286ed 100644 |
--- a/src/arm/stub-cache-arm.cc |
+++ b/src/arm/stub-cache-arm.cc |
@@ -3278,6 +3278,61 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) { |
} |
+MaybeObject* KeyedStoreStubCompiler::CompileStoreElementWithTransition( |
+ Map* transitioned_map, |
+ Map* untransitioned_map_1, |
+ Map* untransitioned_map_2) { |
+ // ----------- S t a t e ------------- |
+ // -- r0 : value |
+ // -- r1 : key |
+ // -- r2 : receiver |
+ // -- lr : return address |
+ // -- r3 : scratch |
+ // ----------------------------------- |
+ |
+ // The order of map occurrences in the generated code below is important. |
+ // Both IC code and Crankshaft rely on |transitioned_map| being the first |
+ // map in the stub. |
+ |
+ Code* notransition_stub; |
+ ElementsKind elements_kind = transitioned_map->elements_kind(); |
+ bool is_js_array = transitioned_map->instance_type() == JS_ARRAY_TYPE; |
+ MaybeObject* maybe_stub = |
+ KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); |
+ if (!maybe_stub->To(¬ransition_stub)) return maybe_stub; |
+ |
+ Label just_store, miss; |
+ __ JumpIfSmi(r2, &miss); |
+ __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); |
+ // r3: receiver->map(). |
+ __ mov(ip, Operand(Handle<Map>(transitioned_map))); |
+ __ cmp(r3, ip); |
+ __ b(eq, &just_store); |
+ ASSERT_NE(untransitioned_map_1, NULL); |
+ __ mov(ip, Operand(Handle<Map>(untransitioned_map_1))); |
+ __ cmp(r3, ip); |
+ Code* generic_stub = (strict_mode_ == kStrictMode) |
+ ? isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic_Strict) |
+ : isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic); |
+ __ Jump(Handle<Code>(generic_stub), RelocInfo::CODE_TARGET, eq); |
+ if (untransitioned_map_2 != NULL) { |
+ __ mov(ip, Operand(Handle<Map>(untransitioned_map_2))); |
+ __ cmp(r3, ip); |
+ __ Jump(Handle<Code>(generic_stub), RelocInfo::CODE_TARGET, eq); |
+ } |
+ |
+ __ bind(&miss); |
+ Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
+ __ Jump(ic, RelocInfo::CODE_TARGET); |
+ |
+ __ bind(&just_store); |
+ __ Jump(Handle<Code>(notransition_stub), RelocInfo::CODE_TARGET); |
+ |
+ // Return the generated code. |
+ return GetCode(NORMAL, NULL, MEGAMORPHIC); |
+} |
+ |
+ |
MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic( |
MapList* receiver_maps, |
CodeList* handler_ics) { |
@@ -4317,7 +4372,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( |
// -- r3 : scratch |
// -- r4 : scratch (elements) |
// ----------------------------------- |
- Label miss_force_generic; |
+ Label miss_force_generic, transition_elements_kind; |
Register value_reg = r0; |
Register key_reg = r1; |
@@ -4351,7 +4406,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( |
__ b(hs, &miss_force_generic); |
if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
- __ JumpIfNotSmi(value_reg, &miss_force_generic); |
+ __ JumpIfNotSmi(value_reg, &transition_elements_kind); |
__ add(scratch, |
elements_reg, |
Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
@@ -4385,6 +4440,10 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( |
Handle<Code> ic = |
masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
__ Jump(ic, RelocInfo::CODE_TARGET); |
+ |
+ __ bind(&transition_elements_kind); |
+ Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
+ __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
} |
@@ -4400,7 +4459,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
// -- r4 : scratch |
// -- r5 : scratch |
// ----------------------------------- |
- Label miss_force_generic; |
+ Label miss_force_generic, transition_elements_kind; |
Register value_reg = r0; |
Register key_reg = r1; |
@@ -4438,7 +4497,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
scratch2, |
scratch3, |
scratch4, |
- &miss_force_generic); |
+ &transition_elements_kind); |
__ Ret(); |
// Handle store cache miss, replacing the ic with the generic stub. |
@@ -4446,6 +4505,10 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
Handle<Code> ic = |
masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
__ Jump(ic, RelocInfo::CODE_TARGET); |
+ |
+ __ bind(&transition_elements_kind); |
+ Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
+ __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
} |