Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 7b6eb8faf95cebdc0b61452cdef150359e050390..ba5a7b87456a7d19391c53356aea04ae53bdfc9b 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -6782,6 +6782,8 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { |
// ElementsTransitionGenerator::GenerateDoubleToObject |
{ eax, edx, esi, EMIT_REMEMBERED_SET}, |
{ edx, eax, edi, EMIT_REMEMBERED_SET}, |
+ // StoreArrayLiteralElementStub::Generate |
+ { ebx, eax, ecx, EMIT_REMEMBERED_SET}, |
// Null termination. |
{ no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} |
}; |
@@ -7024,6 +7026,93 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( |
// Fall through when we need to inform the incremental marker. |
} |
+ |
+void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { |
+ // ----------- S t a t e ------------- |
+ // -- eax : element value to store |
+ // -- ebx : array literal |
+ // -- edi : map of array literal |
+ // -- ecx : element index as smi |
+ // -- edx : array literal index in function |
+ // -- esp[0] : return address |
+ // ----------------------------------- |
+ |
+ Label element_done; |
+ Label double_elements; |
+ Label smi_element; |
+ Label slow_elements; |
+ Label slow_elements_from_double; |
+ Label fast_elements; |
+ |
+ if (!FLAG_trace_elements_transitions) { |
+ __ CheckFastElements(edi, &double_elements); |
+ |
+ // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS |
+ __ JumpIfSmi(eax, &smi_element); |
+ __ CheckFastSmiOnlyElements(edi, &fast_elements, Label::kNear); |
+ |
+ // Store into the array literal requires a elements transition. Call into |
+ // the runtime. |
+ } |
+ |
+ __ bind(&slow_elements); |
+ __ pop(edi); // Pop return address and remember to put back later for tail |
+ // call. |
+ __ push(ebx); |
+ __ push(ecx); |
+ __ push(eax); |
+ __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
+ __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); |
+ __ push(edx); |
+ __ push(edi); // Return return address so that tail call returns to right |
+ // place. |
+ __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1); |
+ |
+ if (!FLAG_trace_elements_transitions) { |
+ // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS. |
+ __ bind(&double_elements); |
+ |
+ __ push(edx); |
+ __ mov(edx, FieldOperand(ebx, JSObject::kElementsOffset)); |
+ __ StoreNumberToDoubleElements(eax, |
+ edx, |
+ ecx, |
+ edi, |
+ xmm0, |
+ &slow_elements_from_double, |
+ false); |
+ __ pop(edx); |
+ __ jmp(&element_done); |
+ |
+ __ bind(&slow_elements_from_double); |
+ __ pop(edx); |
+ __ jmp(&slow_elements); |
+ |
+ // Array literal has ElementsKind of FAST_ELEMENTS and value is an object. |
+ __ bind(&fast_elements); |
+ __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); |
+ __ lea(ecx, FieldOperand(ebx, ecx, times_half_pointer_size, |
+ FixedArrayBase::kHeaderSize)); |
+ __ mov(Operand(ecx, 0), eax); |
+ // Update the write barrier for the array store. |
+ __ RecordWrite(ebx, ecx, eax, |
+ kDontSaveFPRegs, |
+ EMIT_REMEMBERED_SET, |
+ OMIT_SMI_CHECK); |
+ __ jmp(&element_done); |
+ |
+ // Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or |
+ // FAST_ELEMENTS, and value is Smi. |
+ __ bind(&smi_element); |
+ __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); |
+ __ mov(FieldOperand(ebx, ecx, times_half_pointer_size, |
+ FixedArrayBase::kHeaderSize), eax); |
+ // Fall through |
+ __ bind(&element_done); |
+ __ ret(0); |
+ } |
+} |
+ |
#undef __ |
} } // namespace v8::internal |