Commit 14547ef4 authored by antonm@chromium.org's avatar antonm@chromium.org

Just grow elements if they happen to be at the edge of new space.

Review URL: http://codereview.chromium.org/945002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4133 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cf3219bc
...@@ -1251,7 +1251,8 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object, ...@@ -1251,7 +1251,8 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
__ j(not_equal, &miss); __ j(not_equal, &miss);
if (argc == 1) { // Otherwise fall through to call builtin. if (argc == 1) { // Otherwise fall through to call builtin.
Label call_builtin, exit, with_rset_update; Label call_builtin, exit, with_rset_update,
attempt_to_grow_elements, finish_push;
// Get the array's length into eax and calculate new length. // Get the array's length into eax and calculate new length.
__ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
...@@ -1263,9 +1264,9 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object, ...@@ -1263,9 +1264,9 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
__ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
__ SmiTag(ecx); __ SmiTag(ecx);
// Check if we could survive without allocation, go to builtin otherwise. // Check if we could survive without allocation.
__ cmp(eax, Operand(ecx)); __ cmp(eax, Operand(ecx));
__ j(greater, &call_builtin); __ j(greater, &attempt_to_grow_elements);
// Save new length. // Save new length.
__ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
...@@ -1277,6 +1278,8 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object, ...@@ -1277,6 +1278,8 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
__ mov(ecx, Operand(esp, argc * kPointerSize)); __ mov(ecx, Operand(esp, argc * kPointerSize));
__ mov(Operand(edx, 0), ecx); __ mov(Operand(edx, 0), ecx);
__ bind(&finish_push);
// Check if value is a smi. // Check if value is a smi.
__ test(ecx, Immediate(kSmiTagMask)); __ test(ecx, Immediate(kSmiTagMask));
__ j(not_zero, &with_rset_update); __ j(not_zero, &with_rset_update);
...@@ -1292,6 +1295,45 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object, ...@@ -1292,6 +1295,45 @@ Object* CallStubCompiler::CompileArrayPushCall(Object* object,
__ CallStub(&stub); __ CallStub(&stub);
__ ret((argc + 1) * kPointerSize); __ ret((argc + 1) * kPointerSize);
__ bind(&attempt_to_grow_elements);
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address();
ExternalReference new_space_allocation_limit =
ExternalReference::new_space_allocation_limit_address();
const int kAllocationDelta = 4;
// Load top.
__ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
// Check if it's the end of elements.
__ lea(edx, FieldOperand(ebx,
eax, times_half_pointer_size,
FixedArray::kHeaderSize - argc * kPointerSize));
__ cmp(edx, Operand(ecx));
__ j(not_equal, &call_builtin);
__ add(Operand(ecx), Immediate(kAllocationDelta * kPointerSize));
__ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
__ j(greater, &call_builtin);
// We fit and could grow elements.
__ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
__ mov(ecx, Operand(esp, argc * kPointerSize));
__ mov(Operand(edx, 0), ecx);
for (int i = 1; i < kAllocationDelta; i++) {
__ mov(Operand(edx, i * kPointerSize),
Immediate(Factory::undefined_value()));
}
// Restore receiver to edx as finish sequence assumes it's here.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
// Increment element's and array's sizes.
__ add(FieldOperand(ebx, FixedArray::kLengthOffset),
Immediate(kAllocationDelta));
__ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
__ jmp(&finish_push);
__ bind(&call_builtin); __ bind(&call_builtin);
} }
......
...@@ -66,3 +66,40 @@ ...@@ -66,3 +66,40 @@
"after .push(22, 23, 24, 25, 26, 27, 28)"); "after .push(22, 23, 24, 25, 26, 27, 28)");
} }
})(); })();
// Excerises various pushes to the array at the end of new space.
(function() {
var a = undefined;
for (var i = 0; i < 7; i++) {
a = [];
assertEquals(1, a.push(1));
assertEquals(2, a.push(2));
assertEquals(3, a.push(3));
assertEquals(4, a.push(4));
assertEquals(5, a.push(5));
assertEquals(6, a.push(6));
assertEquals(7, a.push(7));
assertEquals(8, a.push(8));
assertEquals(9, a.push(9));
assertEquals(10, a.push(10));
assertEquals(11, a.push(11));
assertEquals(12, a.push(12));
assertEquals(13, a.push(13));
assertEquals(14, a.push(14));
assertEquals(15, a.push(15));
assertEquals(16, a.push(16));
assertEquals(17, a.push(17));
assertEquals(18, a.push(18));
assertEquals(19, a.push(19));
assertEquals(20, a.push(20));
assertEquals(21, a.push(21));
assertEquals(22, a.push(22));
assertEquals(23, a.push(23));
assertEquals(24, a.push(24));
assertEquals(25, a.push(25));
assertEquals(26, a.push(26));
assertEquals(27, a.push(27));
assertEquals(28, a.push(28));
assertEquals(29, a.push(29));
}
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment