| Index: src/x64/stub-cache-x64.cc
|
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
|
| index 7aaeab793d3d01d307b574fed7ed1d9ef3039212..e0644cd63b0578ae303d356123cf6149a65fe141 100644
|
| --- a/src/x64/stub-cache-x64.cc
|
| +++ b/src/x64/stub-cache-x64.cc
|
| @@ -1084,16 +1084,18 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset));
|
| __ ret((argc + 1) * kPointerSize);
|
| } else {
|
| + Label call_builtin;
|
| +
|
| // Get the elements array of the object.
|
| __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
|
|
|
| - // Check that the elements are in fast mode (not dictionary).
|
| + // Check that the elements are in fast mode and writable.
|
| __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
|
| Factory::fixed_array_map());
|
| - __ j(not_equal, &miss);
|
| + __ j(not_equal, &call_builtin);
|
|
|
| if (argc == 1) { // Otherwise fall through to call builtin.
|
| - Label call_builtin, exit, with_write_barrier, attempt_to_grow_elements;
|
| + Label exit, with_write_barrier, attempt_to_grow_elements;
|
|
|
| // Get the array's length into rax and calculate new length.
|
| __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset));
|
| @@ -1164,7 +1166,7 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| // Push the argument...
|
| __ movq(Operand(rdx, 0), rcx);
|
| // ... and fill the rest with holes.
|
| - __ Move(kScratchRegister, Factory::the_hole_value());
|
| + __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
| for (int i = 1; i < kAllocationDelta; i++) {
|
| __ movq(Operand(rdx, i * kPointerSize), kScratchRegister);
|
| }
|
| @@ -1175,15 +1177,16 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| // Increment element's and array's sizes.
|
| __ SmiAddConstant(FieldOperand(rbx, FixedArray::kLengthOffset),
|
| Smi::FromInt(kAllocationDelta));
|
| +
|
| // Make new length a smi before returning it.
|
| __ Integer32ToSmi(rax, rax);
|
| __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax);
|
| +
|
| // Elements are in new space, so write barrier is not required.
|
| __ ret((argc + 1) * kPointerSize);
|
| -
|
| - __ bind(&call_builtin);
|
| }
|
|
|
| + __ bind(&call_builtin);
|
| __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush),
|
| argc + 1,
|
| 1);
|
| @@ -1204,11 +1207,11 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object,
|
| String* name,
|
| CheckType check) {
|
| // ----------- S t a t e -------------
|
| - // -- ecx : name
|
| - // -- esp[0] : return address
|
| - // -- esp[(argc - n) * 4] : arg[n] (zero-based)
|
| + // -- rcx : name
|
| + // -- rsp[0] : return address
|
| + // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
|
| // -- ...
|
| - // -- esp[(argc + 1) * 4] : receiver
|
| + // -- rsp[(argc + 1) * 8] : receiver
|
| // -----------------------------------
|
| ASSERT(check == RECEIVER_MAP_CHECK);
|
|
|
| @@ -1235,9 +1238,10 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object,
|
| // Get the elements array of the object.
|
| __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset));
|
|
|
| - // Check that the elements are in fast mode (not dictionary).
|
| - __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), Factory::fixed_array_map());
|
| - __ j(not_equal, &miss);
|
| + // Check that the elements are in fast mode and writable.
|
| + __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
|
| + Heap::kFixedArrayMapRootIndex);
|
| + __ j(not_equal, &call_builtin);
|
|
|
| // Get the array's length into rcx and calculate new length.
|
| __ SmiToInteger32(rcx, FieldOperand(rdx, JSArray::kLengthOffset));
|
| @@ -1245,7 +1249,7 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object,
|
| __ j(negative, &return_undefined);
|
|
|
| // Get the last element.
|
| - __ Move(r9, Factory::the_hole_value());
|
| + __ LoadRoot(r9, Heap::kTheHoleValueRootIndex);
|
| __ movq(rax, FieldOperand(rbx,
|
| rcx, times_pointer_size,
|
| FixedArray::kHeaderSize));
|
| @@ -1265,14 +1269,14 @@ Object* CallStubCompiler::CompileArrayPopCall(Object* object,
|
| __ ret((argc + 1) * kPointerSize);
|
|
|
| __ bind(&return_undefined);
|
| -
|
| - __ Move(rax, Factory::undefined_value());
|
| + __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
| __ ret((argc + 1) * kPointerSize);
|
|
|
| __ bind(&call_builtin);
|
| __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop),
|
| argc + 1,
|
| 1);
|
| +
|
| __ bind(&miss);
|
| Object* obj = GenerateMissBranch();
|
| if (obj->IsFailure()) return obj;
|
|
|