| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index 9b8f096621b5b2710f5c4f18c726e1ba0f139df4..277f97b0c8b8d74da30348325da635d8f208b3a1 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -2759,6 +2759,62 @@ 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 -------------
|
| + // -- eax : value
|
| + // -- ecx : key
|
| + // -- edx : receiver
|
| + // -- esp[0] : return address
|
| + // -----------------------------------
|
| +
|
| + // 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_jsarray = transitioned_map->instance_type() == JS_ARRAY_TYPE;
|
| + MaybeObject* maybe_stub =
|
| + KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode();
|
| + if (!maybe_stub->To(¬ransition_stub)) return maybe_stub;
|
| +
|
| + Label just_store, miss;
|
| + __ JumpIfSmi(edx, &miss, Label::kNear);
|
| + __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
|
| + // ebx: receiver->map().
|
| + __ cmp(ebx, Handle<Map>(transitioned_map));
|
| + __ j(equal, &just_store);
|
| + ASSERT_NE(untransitioned_map_1, NULL);
|
| + __ cmp(ebx, Handle<Map>(untransitioned_map_1));
|
| + // TODO(jkummerow): When we have specialized code to do the transition,
|
| + // call that code here, then jump to just_store when the call returns.
|
| + // <temporary: just use the generic stub>
|
| + Code* generic_stub = (strict_mode_ == kStrictMode)
|
| + ? isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic_Strict)
|
| + : isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic);
|
| + __ j(equal, Handle<Code>(generic_stub));
|
| + // </temporary>
|
| + if (untransitioned_map_2 != NULL) {
|
| + __ cmp(ebx, Handle<Map>(untransitioned_map_2));
|
| + // <temporary: see above, same here>
|
| + __ j(equal, Handle<Code>(generic_stub));
|
| + // </temporary>
|
| + }
|
| + __ bind(&miss);
|
| + Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
|
| + __ jmp(ic, RelocInfo::CODE_TARGET);
|
| +
|
| + __ bind(&just_store);
|
| + __ jmp(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) {
|
| @@ -3910,7 +3966,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| // -- edx : receiver
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| - Label miss_force_generic;
|
| + Label miss_force_generic, transition_elements_kind;
|
|
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
| @@ -3935,7 +3991,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| }
|
|
|
| if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
|
| - __ JumpIfNotSmi(eax, &miss_force_generic);
|
| + __ JumpIfNotSmi(eax, &transition_elements_kind);
|
| // ecx is a smi, use times_half_pointer_size instead of
|
| // times_pointer_size
|
| __ mov(FieldOperand(edi,
|
| @@ -3965,6 +4021,11 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement(
|
| Handle<Code> ic_force_generic =
|
| masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
|
| +
|
| + // Handle transition to other elements kinds without using the generic stub.
|
| + __ bind(&transition_elements_kind);
|
| + Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
|
| + __ jmp(ic_miss, RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
| @@ -3977,7 +4038,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
| // -- edx : receiver
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| - Label miss_force_generic;
|
| + Label miss_force_generic, transition_elements_kind;
|
|
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
| @@ -4003,7 +4064,7 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
| ecx,
|
| edx,
|
| xmm0,
|
| - &miss_force_generic,
|
| + &transition_elements_kind,
|
| true);
|
| __ ret(0);
|
|
|
| @@ -4012,6 +4073,11 @@ void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
|
| Handle<Code> ic_force_generic =
|
| masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
|
| __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
|
| +
|
| + // Handle transition to other elements kinds without using the generic stub.
|
| + __ bind(&transition_elements_kind);
|
| + Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
|
| + __ jmp(ic_miss, RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
|
|