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
This commit is contained in:
parent
4627023b38
commit
3d8b0a606a
@ -5702,6 +5702,8 @@ struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = {
|
|||||||
{ rdx, r11, r15, EMIT_REMEMBERED_SET},
|
{ rdx, r11, r15, EMIT_REMEMBERED_SET},
|
||||||
// ElementsTransitionGenerator::GenerateDoubleToObject
|
// ElementsTransitionGenerator::GenerateDoubleToObject
|
||||||
{ r11, rax, r15, EMIT_REMEMBERED_SET},
|
{ r11, rax, r15, EMIT_REMEMBERED_SET},
|
||||||
|
// StoreArrayLiteralElementStub::Generate
|
||||||
|
{ rbx, rax, rcx, EMIT_REMEMBERED_SET},
|
||||||
// Null termination.
|
// Null termination.
|
||||||
{ no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET}
|
{ 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.
|
// 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 __
|
#undef __
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
@ -1493,60 +1493,12 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
|||||||
VisitForAccumulatorValue(subexpr);
|
VisitForAccumulatorValue(subexpr);
|
||||||
|
|
||||||
// Store the subexpression value in the array's elements.
|
// Store the subexpression value in the array's elements.
|
||||||
__ movq(r8, Operand(rsp, 0)); // Copy of array literal.
|
__ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
|
||||||
__ movq(rdi, FieldOperand(r8, JSObject::kMapOffset));
|
__ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
|
||||||
__ movq(rbx, FieldOperand(r8, JSObject::kElementsOffset));
|
__ Move(rcx, Smi::FromInt(i));
|
||||||
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
|
__ movq(rdx, Immediate(expr->literal_index()));
|
||||||
|
StoreArrayLiteralElementStub stub;
|
||||||
Label element_done;
|
__ CallStub(&stub);
|
||||||
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);
|
|
||||||
|
|
||||||
PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
|
PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user