Index: src/x64/stub-cache-x64.cc |
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc |
index 584c549f287b4b350aaae2b0b2f46de28c6685e1..7e005c4c3f060eda6197ba59353b29e55414e4b3 100644 |
--- a/src/x64/stub-cache-x64.cc |
+++ b/src/x64/stub-cache-x64.cc |
@@ -1442,28 +1442,42 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
__ cmpl(rax, rcx); |
__ j(greater, &attempt_to_grow_elements); |
+ // Check if value is a smi. |
+ __ movq(rcx, Operand(rsp, argc * kPointerSize)); |
+ __ JumpIfNotSmi(rcx, &with_write_barrier); |
+ |
// Save new length. |
__ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); |
// Push the element. |
- __ movq(rcx, Operand(rsp, argc * kPointerSize)); |
__ lea(rdx, FieldOperand(rbx, |
rax, times_pointer_size, |
FixedArray::kHeaderSize - argc * kPointerSize)); |
__ movq(Operand(rdx, 0), rcx); |
- // Check if value is a smi. |
__ Integer32ToSmi(rax, rax); // Return new length as smi. |
- |
- __ JumpIfNotSmi(rcx, &with_write_barrier); |
- |
__ ret((argc + 1) * kPointerSize); |
__ bind(&with_write_barrier); |
+ if (FLAG_smi_only_arrays) { |
+ __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); |
+ __ CheckFastObjectElements(rdi, &call_builtin); |
+ } |
+ |
+ // Save new length. |
+ __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); |
+ |
+ // Push the element. |
+ __ lea(rdx, FieldOperand(rbx, |
+ rax, times_pointer_size, |
+ FixedArray::kHeaderSize - argc * kPointerSize)); |
+ __ movq(Operand(rdx, 0), rcx); |
+ |
__ RecordWrite( |
rbx, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
+ __ Integer32ToSmi(rax, rax); // Return new length as smi. |
__ ret((argc + 1) * kPointerSize); |
__ bind(&attempt_to_grow_elements); |
@@ -1471,6 +1485,17 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
__ jmp(&call_builtin); |
} |
+ __ movq(rdi, Operand(rsp, argc * kPointerSize)); |
+ if (FLAG_smi_only_arrays) { |
+ // Growing elements that are SMI-only requires special handling in case |
+ // the new element is non-Smi. For now, delegate to the builtin. |
+ Label no_fast_elements_check; |
+ __ JumpIfSmi(rdi, &no_fast_elements_check); |
+ __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset)); |
+ __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar); |
+ __ bind(&no_fast_elements_check); |
+ } |
+ |
ExternalReference new_space_allocation_top = |
ExternalReference::new_space_allocation_top_address(isolate()); |
ExternalReference new_space_allocation_limit = |
@@ -1497,7 +1522,7 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
__ movq(rcx, Operand(rsp, argc * kPointerSize)); |
William Hesse
2011/09/23 13:25:22
Is this move to rcx now a dead value? If so, remo
Yang
2011/09/23 14:19:12
Done.
|
// Push the argument... |
- __ movq(Operand(rdx, 0), rcx); |
+ __ movq(Operand(rdx, 0), rdi); |
// ... and fill the rest with holes. |
__ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); |
for (int i = 1; i < kAllocationDelta; i++) { |
@@ -1509,7 +1534,7 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
// tell the incremental marker to rescan the object that we just grew. We |
// don't need to worry about the holes because they are in old space and |
// already marked black. |
- __ RecordWrite(rbx, rdx, rcx, kDontSaveFPRegs, OMIT_REMEMBERED_SET); |
+ __ RecordWrite(rbx, rdx, rdi, kDontSaveFPRegs, OMIT_REMEMBERED_SET); |
// Restore receiver to rdx as finish sequence assumes it's here. |
__ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
@@ -3699,13 +3724,19 @@ void KeyedStoreStubCompiler::GenerateStoreFastElement( |
// Do the store and update the write barrier. |
__ SmiToInteger32(rcx, rcx); |
- __ lea(rcx, |
- FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize)); |
- __ movq(Operand(rcx, 0), rax); |
- // Make sure to preserve the value in register rax. |
- __ movq(rdx, rax); |
- ASSERT(elements_kind == FAST_ELEMENTS); |
- __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs); |
+ if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
+ __ JumpIfNotSmi(rax, &miss_force_generic); |
+ __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), |
+ rax); |
+ } else { |
+ ASSERT(elements_kind == FAST_ELEMENTS); |
+ __ lea(rcx, |
+ FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize)); |
+ __ movq(Operand(rcx, 0), rax); |
+ // Make sure to preserve the value in register rax. |
+ __ movq(rdx, rax); |
+ __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs); |
+ } |
// Done. |
__ ret(0); |