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