From 3d8b0a606a34eaaa0f4630e06b14e9f9e00efbc4 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Tue, 8 Nov 2011 10:10:24 +0000 Subject: [PATCH] Create stub and runtime function for x64 full-codegen array literal element initialization. R=svenpanne@chromium.org BUG=none TEST=none Review URL: http://codereview.chromium.org/8493024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9903 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/code-stubs-x64.cc | 83 +++++++++++++++++++++++++++++++++++++ src/x64/full-codegen-x64.cc | 60 +++------------------------ 2 files changed, 89 insertions(+), 54 deletions(-) diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 8a00b89874..672be58db3 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -5702,6 +5702,8 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { { rdx, r11, r15, EMIT_REMEMBERED_SET}, // ElementsTransitionGenerator::GenerateDoubleToObject { r11, rax, r15, EMIT_REMEMBERED_SET}, + // StoreArrayLiteralElementStub::Generate + { rbx, rax, rcx, EMIT_REMEMBERED_SET}, // Null termination. { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} }; @@ -5949,6 +5951,87 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( // Fall through when we need to inform the incremental marker. } + +void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- rax : element value to store + // -- rbx : array literal + // -- rdi : map of array literal + // -- rcx : element index as smi + // -- rdx : array literal index in function + // -- rsp[0] : return address + // ----------------------------------- + + Label element_done; + Label double_elements; + Label smi_element; + Label slow_elements; + Label fast_elements; + + if (!FLAG_trace_elements_transitions) { + __ CheckFastElements(rdi, &double_elements); + + // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS + __ JumpIfSmi(rax, &smi_element); + __ CheckFastSmiOnlyElements(rdi, &fast_elements); + + // Store into the array literal requires a elements transition. Call into + // the runtime. + } + + __ bind(&slow_elements); + __ pop(rdi); // Pop return address and remember to put back later for tail + // call. + __ push(rbx); + __ push(rcx); + __ push(rax); + __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); + __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset)); + __ push(rdx); + __ push(rdi); // 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); + + __ movq(r9, FieldOperand(rbx, JSObject::kElementsOffset)); + __ SmiToInteger32(r10, rcx); + __ StoreNumberToDoubleElements(rax, + r9, + r10, + xmm0, + &slow_elements); + __ jmp(&element_done); + + // Array literal has ElementsKind of FAST_ELEMENTS and value is an object. + __ bind(&fast_elements); + __ SmiToInteger32(r10, rcx); + __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); + __ lea(rcx, FieldOperand(rbx, r10, times_pointer_size, + FixedArrayBase::kHeaderSize)); + __ movq(Operand(rcx, 0), rax); + // Update the write barrier for the array store. + __ RecordWrite(rbx, rcx, rax, + 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); + __ SmiToInteger32(r10, rcx); + __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); + __ movq(FieldOperand(rbx, r10, times_pointer_size, + FixedArrayBase::kHeaderSize), rax); + // Fall through + __ bind(&element_done); + __ ret(0); + } +} + #undef __ } } // namespace v8::internal diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index a80a8b792e..55c70d425a 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1493,60 +1493,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForAccumulatorValue(subexpr); // Store the subexpression value in the array's elements. - __ movq(r8, Operand(rsp, 0)); // Copy of array literal. - __ movq(rdi, FieldOperand(r8, JSObject::kMapOffset)); - __ movq(rbx, FieldOperand(r8, JSObject::kElementsOffset)); - int offset = FixedArray::kHeaderSize + (i * kPointerSize); - - Label element_done; - Label double_elements; - Label smi_element; - Label slow_elements; - Label fast_elements; - __ CheckFastElements(rdi, &double_elements); - - // FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS - __ JumpIfSmi(result_register(), &smi_element); - __ CheckFastSmiOnlyElements(rdi, &fast_elements); - - // Store into the array literal requires a elements transition. Call into - // the runtime. - __ bind(&slow_elements); - __ push(r8); // Copy of array literal. - __ Push(Smi::FromInt(i)); - __ push(result_register()); - __ Push(Smi::FromInt(NONE)); // PropertyAttributes - __ Push(Smi::FromInt(strict_mode_flag())); // Strict mode. - __ CallRuntime(Runtime::kSetProperty, 5); - __ jmp(&element_done); - - // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS. - __ bind(&double_elements); - __ movq(rcx, Immediate(i)); - __ StoreNumberToDoubleElements(result_register(), - rbx, - rcx, - xmm0, - &slow_elements); - __ jmp(&element_done); - - // Array literal has ElementsKind of FAST_ELEMENTS and value is an object. - __ bind(&fast_elements); - __ movq(FieldOperand(rbx, offset), result_register()); - // Update the write barrier for the array store. - __ RecordWriteField(rbx, offset, result_register(), rcx, - 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); - __ movq(FieldOperand(rbx, offset), result_register()); - // Fall through - - __ bind(&element_done); + __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. + __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset)); + __ Move(rcx, Smi::FromInt(i)); + __ movq(rdx, Immediate(expr->literal_index())); + StoreArrayLiteralElementStub stub; + __ CallStub(&stub); PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); }