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