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
This commit is contained in:
svenpanne@chromium.org 2013-06-14 06:06:00 +00:00
parent c4224f09a2
commit bcf5912b3f
9 changed files with 51 additions and 31 deletions

View File

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

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

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

View File

@ -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

View File

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