| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 3834)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -2495,17 +2495,19 @@
|
| // Load the literals array of the function.
|
| __ movq(literals.reg(),
|
| FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
|
| - // Literal array.
|
| +
|
| frame_->Push(&literals);
|
| - // Literal index.
|
| frame_->Push(Smi::FromInt(node->literal_index()));
|
| - // Constant elements.
|
| frame_->Push(node->constant_elements());
|
| + int length = node->values()->length();
|
| Result clone;
|
| if (node->depth() > 1) {
|
| clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| + } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
|
| + clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| } else {
|
| - clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| + FastCloneShallowArrayStub stub(length);
|
| + clone = frame_->CallStub(&stub, 3);
|
| }
|
| frame_->Push(&clone);
|
|
|
| @@ -6260,6 +6262,63 @@
|
| }
|
|
|
|
|
| +void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
| + // Stack layout on entry:
|
| + //
|
| + // [rsp + kPointerSize]: constant elements.
|
| + // [rsp + (2 * kPointerSize)]: literal index.
|
| + // [rsp + (3 * kPointerSize)]: literals array.
|
| +
|
| + // All sizes here are multiples of kPointerSize.
|
| + int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
|
| + int size = JSArray::kSize + elements_size;
|
| +
|
| + // Load boilerplate object into rcx and check if we need to create a
|
| + // boilerplate.
|
| + Label slow_case;
|
| + __ movq(rcx, Operand(rsp, 3 * kPointerSize));
|
| + __ movq(rax, Operand(rsp, 2 * kPointerSize));
|
| + SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
|
| + __ movq(rcx,
|
| + FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize));
|
| + __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
|
| + __ j(equal, &slow_case);
|
| +
|
| + // Allocate both the JS array and the elements array in one big
|
| + // allocation. This avoids multiple limit checks.
|
| + __ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT);
|
| +
|
| + // Copy the JS array part.
|
| + for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
| + if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
|
| + __ movq(rbx, FieldOperand(rcx, i));
|
| + __ movq(FieldOperand(rax, i), rbx);
|
| + }
|
| + }
|
| +
|
| + if (length_ > 0) {
|
| + // Get hold of the elements array of the boilerplate and setup the
|
| + // elements pointer in the resulting object.
|
| + __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
|
| + __ lea(rdx, Operand(rax, JSArray::kSize));
|
| + __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);
|
| +
|
| + // Copy the elements array.
|
| + for (int i = 0; i < elements_size; i += kPointerSize) {
|
| + __ movq(rbx, FieldOperand(rcx, i));
|
| + __ movq(FieldOperand(rdx, i), rbx);
|
| + }
|
| + }
|
| +
|
| + // Return and remove the on-stack parameters.
|
| + __ ret(3 * kPointerSize);
|
| +
|
| + __ bind(&slow_case);
|
| + ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
|
| + __ TailCallRuntime(runtime, 3, 1);
|
| +}
|
| +
|
| +
|
| void ToBooleanStub::Generate(MacroAssembler* masm) {
|
| Label false_result, true_result, not_string;
|
| __ movq(rax, Operand(rsp, 1 * kPointerSize));
|
|
|