From bcf5912b3f547efe13d101cbd4fa349239f3295e Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Fri, 14 Jun 2013 06:06:00 +0000 Subject: [PATCH] Reduce the amount of full code generated to fill out array literals. This is achieved by tuning the calling convention of StoreArrayLiteralStub: * The map of the array literal can be loaded in the stub from the array literal itself, there is no need to pass it at all. * The array literal is already on the stack, so there is no need to pass it again via a register. * The literal index is unchanged while filling the literal, so we can push it on the stack once and avoid passing it every time. Note that we need to mirror this change in the stack layout in crankshaft, too. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/16950004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15138 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 11 ++++++++--- src/arm/full-codegen-arm.cc | 7 +++---- src/hydrogen.cc | 4 ++++ src/ia32/code-stubs-ia32.cc | 11 ++++++++--- src/ia32/full-codegen-ia32.cc | 9 ++++----- src/mips/code-stubs-mips.cc | 11 ++++++++--- src/mips/full-codegen-mips.cc | 9 ++++----- src/x64/code-stubs-x64.cc | 11 ++++++++--- src/x64/full-codegen-x64.cc | 9 ++++----- 9 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 52efd5fb52..e75e7f7081 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -7055,10 +7055,10 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0 : element value to store - // -- r1 : array literal - // -- r2 : map of array literal // -- r3 : element index as smi - // -- r4 : array literal index in function as smi + // -- sp[0] : array literal index in function as smi + // -- sp[4] : array literal + // clobbers r1, r2, r4 // ----------------------------------- Label element_done; @@ -7067,6 +7067,11 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { Label slow_elements; Label fast_elements; + // Get array literal index, array literal and its map. + __ ldr(r4, MemOperand(sp, 0 * kPointerSize)); + __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); + __ ldr(r2, FieldMemOperand(r1, JSObject::kMapOffset)); + __ CheckFastElements(r2, r5, &double_elements); // FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS __ JumpIfSmi(r0, &smi_element); diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 468fa77753..7c2d4743f0 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -1836,13 +1836,14 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { if (!result_saved) { __ push(r0); + __ Push(Smi::FromInt(expr->literal_index())); result_saved = true; } VisitForAccumulatorValue(subexpr); if (IsFastObjectElementsKind(constant_elements_kind)) { int offset = FixedArray::kHeaderSize + (i * kPointerSize); - __ ldr(r6, MemOperand(sp)); // Copy of array literal. + __ ldr(r6, MemOperand(sp, kPointerSize)); // Copy of array literal. __ ldr(r1, FieldMemOperand(r6, JSObject::kElementsOffset)); __ str(result_register(), FieldMemOperand(r1, offset)); // Update the write barrier for the array store. @@ -1850,10 +1851,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { kLRHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); } else { - __ ldr(r1, MemOperand(sp)); // Copy of array literal. - __ ldr(r2, FieldMemOperand(r1, JSObject::kMapOffset)); __ mov(r3, Operand(Smi::FromInt(i))); - __ mov(r4, Operand(Smi::FromInt(expr->literal_index()))); StoreArrayLiteralElementStub stub; __ CallStub(&stub); } @@ -1862,6 +1860,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (result_saved) { + __ pop(); // literal index context()->PlugTOS(); } else { context()->Plug(r0); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index e7fbabae1d..01766bdb7d 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -6073,6 +6073,8 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { // The array is expected in the bailout environment during computation // of the property values and is the value of the entire expression. Push(literal); + // The literal index is on the stack, too. + Push(AddInstruction(new(zone()) HConstant(expr->literal_index()))); HInstruction* elements = NULL; @@ -6110,6 +6112,8 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { AddSimulate(expr->GetIdForElement(i)); } + + Drop(1); // array literal index return ast_context()->ReturnValue(Pop()); } diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index aa4b8a2237..1e9c330df9 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -7661,11 +7661,11 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( 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 + // -- esp[4] : array literal index in function + // -- esp[8] : array literal + // clobbers ebx, edx, edi // ----------------------------------- Label element_done; @@ -7675,6 +7675,11 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { Label slow_elements_from_double; Label fast_elements; + // Get array literal index, array literal and its map. + __ mov(edx, Operand(esp, 1 * kPointerSize)); + __ mov(ebx, Operand(esp, 2 * kPointerSize)); + __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset)); + __ CheckFastElements(edi, &double_elements); // Check for FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS elements diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index c4c1e87a23..24054c6ce0 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -1788,7 +1788,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (!result_saved) { - __ push(eax); + __ push(eax); // array literal. + __ push(Immediate(Smi::FromInt(expr->literal_index()))); result_saved = true; } VisitForAccumulatorValue(subexpr); @@ -1797,7 +1798,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they // cannot transition and don't need to call the runtime stub. int offset = FixedArray::kHeaderSize + (i * kPointerSize); - __ mov(ebx, Operand(esp, 0)); // Copy of array literal. + __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal. __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); // Store the subexpression value in the array's elements. __ mov(FieldOperand(ebx, offset), result_register()); @@ -1808,10 +1809,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { INLINE_SMI_CHECK); } else { // Store the subexpression value in the array's elements. - __ mov(ebx, Operand(esp, 0)); // Copy of array literal. - __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset)); __ mov(ecx, Immediate(Smi::FromInt(i))); - __ mov(edx, Immediate(Smi::FromInt(expr->literal_index()))); StoreArrayLiteralElementStub stub; __ CallStub(&stub); } @@ -1820,6 +1818,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (result_saved) { + __ add(esp, Immediate(kPointerSize)); // literal index context()->PlugTOS(); } else { context()->Plug(eax); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index fca0b9a03e..f09e9c3b2d 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -7482,10 +7482,10 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- a0 : element value to store - // -- a1 : array literal - // -- a2 : map of array literal // -- a3 : element index as smi - // -- t0 : array literal index in function as smi + // -- sp[0] : array literal index in function as smi + // -- sp[4] : array literal + // clobbers a1, a2, t0 // ----------------------------------- Label element_done; @@ -7494,6 +7494,11 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { Label slow_elements; Label fast_elements; + // Get array literal index, array literal and its map. + __ lw(t0, MemOperand(sp, 0 * kPointerSize)); + __ lw(a1, MemOperand(sp, 1 * kPointerSize)); + __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset)); + __ CheckFastElements(a2, t1, &double_elements); // Check for FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS elements __ JumpIfSmi(a0, &smi_element); diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 223242082d..64d0e39aa4 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -1840,7 +1840,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (!result_saved) { - __ push(v0); + __ push(v0); // array literal + __ Push(Smi::FromInt(expr->literal_index())); result_saved = true; } @@ -1848,7 +1849,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { if (IsFastObjectElementsKind(constant_elements_kind)) { int offset = FixedArray::kHeaderSize + (i * kPointerSize); - __ lw(t2, MemOperand(sp)); // Copy of array literal. + __ lw(t2, MemOperand(sp, kPointerSize)); // Copy of array literal. __ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset)); __ sw(result_register(), FieldMemOperand(a1, offset)); // Update the write barrier for the array store. @@ -1856,10 +1857,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { kRAHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); } else { - __ lw(a1, MemOperand(sp)); // Copy of array literal. - __ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset)); __ li(a3, Operand(Smi::FromInt(i))); - __ li(t0, Operand(Smi::FromInt(expr->literal_index()))); __ mov(a0, result_register()); StoreArrayLiteralElementStub stub; __ CallStub(&stub); @@ -1868,6 +1866,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); } if (result_saved) { + __ Pop(); // literal index context()->PlugTOS(); } else { context()->Plug(v0); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 40025d3437..8868c7a88a 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -6636,11 +6636,11 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker( 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 + // -- rsp[8] : array literal index in function + // -- rsp[16]: array literal + // clobbers rbx, rdx, rdi // ----------------------------------- Label element_done; @@ -6649,6 +6649,11 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { Label slow_elements; Label fast_elements; + // Get array literal index, array literal and its map. + __ movq(rdx, Operand(rsp, 1 * kPointerSize)); + __ movq(rbx, Operand(rsp, 2 * kPointerSize)); + __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset)); + __ CheckFastElements(rdi, &double_elements); // FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 4afcadbd2d..3b1fc93b5f 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -1812,7 +1812,8 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (!result_saved) { - __ push(rax); + __ push(rax); // array literal + __ Push(Smi::FromInt(expr->literal_index())); result_saved = true; } VisitForAccumulatorValue(subexpr); @@ -1821,7 +1822,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they // cannot transition and don't need to call the runtime stub. int offset = FixedArray::kHeaderSize + (i * kPointerSize); - __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. + __ movq(rbx, Operand(rsp, kPointerSize)); // Copy of array literal. __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); // Store the subexpression value in the array's elements. __ movq(FieldOperand(rbx, offset), result_register()); @@ -1832,10 +1833,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { INLINE_SMI_CHECK); } else { // Store the subexpression value in the array's elements. - __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. - __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset)); __ Move(rcx, Smi::FromInt(i)); - __ Move(rdx, Smi::FromInt(expr->literal_index())); StoreArrayLiteralElementStub stub; __ CallStub(&stub); } @@ -1844,6 +1842,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { } if (result_saved) { + __ addq(rsp, Immediate(kPointerSize)); // literal index context()->PlugTOS(); } else { context()->Plug(rax);