Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Unified Diff: src/ia32/builtins-ia32.cc

Issue 661245: Faster filling newly allocated arrays with the holes from the Array construction stub. (Closed)
Patch Set: scons -> stos as spotted by Soren Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/disasm-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/builtins-ia32.cc
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 0ff5077565b564c8c5cce155fd59063e200be451..888b5b8552e39562ea00b61503c89f464efb8b05 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -797,38 +797,23 @@ static void AllocateEmptyJSArray(MacroAssembler* masm,
// register elements_array is scratched.
static void AllocateJSArray(MacroAssembler* masm,
Register array_function, // Array function.
- Register array_size, // As a smi.
+ Register array_size, // As a smi, cannot be 0.
Register result,
Register elements_array,
Register elements_array_end,
Register scratch,
bool fill_with_hole,
Label* gc_required) {
- Label not_empty, allocated;
+ ASSERT(scratch.is(edi)); // rep stos destination
+ ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count
// Load the initial map from the array function.
__ mov(elements_array,
FieldOperand(array_function,
JSFunction::kPrototypeOrInitialMapOffset));
- // Check whether an empty sized array is requested.
- __ test(array_size, Operand(array_size));
- __ j(not_zero, &not_empty);
-
- // If an empty array is requested allocate a small elements array anyway. This
- // keeps the code below free of special casing for the empty array.
- int size = JSArray::kSize + FixedArray::SizeFor(kPreallocatedArrayElements);
- __ AllocateInNewSpace(size,
- result,
- elements_array_end,
- scratch,
- gc_required,
- TAG_OBJECT);
- __ jmp(&allocated);
-
// Allocate the JSArray object together with space for a FixedArray with the
// requested elements.
- __ bind(&not_empty);
ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
__ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
times_half_pointer_size, // array_size is a smi.
@@ -845,7 +830,6 @@ static void AllocateJSArray(MacroAssembler* masm,
// elements_array: initial map
// elements_array_end: start of next object
// array_size: size of array (smi)
- __ bind(&allocated);
__ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
__ mov(elements_array, Factory::empty_fixed_array());
__ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
@@ -869,15 +853,6 @@ static void AllocateJSArray(MacroAssembler* masm,
__ SmiUntag(array_size); // Convert from smi to value.
__ mov(FieldOperand(elements_array, JSObject::kMapOffset),
Factory::fixed_array_map());
- Label not_empty_2, fill_array;
- __ test(array_size, Operand(array_size));
- __ j(not_zero, &not_empty_2);
- // Length of the FixedArray is the number of pre-allocated elements even
- // though the actual JSArray has length 0.
- __ mov(FieldOperand(elements_array, Array::kLengthOffset),
- Immediate(kPreallocatedArrayElements));
- __ jmp(&fill_array);
- __ bind(&not_empty_2);
// For non-empty JSArrays the length of the FixedArray and the JSArray is the
// same.
__ mov(FieldOperand(elements_array, Array::kLengthOffset), array_size);
@@ -885,20 +860,18 @@ static void AllocateJSArray(MacroAssembler* masm,
// Fill the allocated FixedArray with the hole value if requested.
// result: JSObject
// elements_array: elements array
- // elements_array_end: start of next object
- __ bind(&fill_array);
if (fill_with_hole) {
- Label loop, entry;
- __ mov(scratch, Factory::the_hole_value());
- __ lea(elements_array, Operand(elements_array,
- FixedArray::kHeaderSize - kHeapObjectTag));
- __ jmp(&entry);
- __ bind(&loop);
- __ mov(Operand(elements_array, 0), scratch);
- __ add(Operand(elements_array), Immediate(kPointerSize));
- __ bind(&entry);
- __ cmp(elements_array, Operand(elements_array_end));
- __ j(below, &loop);
+ __ lea(edi, Operand(elements_array,
+ FixedArray::kHeaderSize - kHeapObjectTag));
+
+ __ push(eax);
+ __ mov(eax, Factory::the_hole_value());
+
+ __ cld();
+ __ rep_stos();
+
+ // Restore saved registers.
+ __ pop(eax);
}
}
@@ -920,7 +893,8 @@ static void AllocateJSArray(MacroAssembler* masm,
static void ArrayNativeCode(MacroAssembler* masm,
bool construct_call,
Label* call_generic_code) {
- Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call;
+ Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call,
+ empty_array, not_empty_array;
// Push the constructor and argc. No need to tag argc as a smi, as there will
// be no garbage collection with this on the stack.
@@ -936,6 +910,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ test(eax, Operand(eax));
__ j(not_zero, &argc_one_or_more);
+ __ bind(&empty_array);
// Handle construction of an empty array.
AllocateEmptyJSArray(masm,
edi,
@@ -958,30 +933,41 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ cmp(eax, 1);
__ j(not_equal, &argc_two_or_more);
ASSERT(kSmiTag == 0);
- __ test(Operand(esp, (push_count + 1) * kPointerSize),
- Immediate(kIntptrSignBit | kSmiTagMask));
+ __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize));
+ __ test(ecx, Operand(ecx));
+ __ j(not_zero, &not_empty_array);
+
+ // Case above assumes there is only a single slot to drop in
+ // ret, but we have two.
+ for (int i = push_count; i >= 0; i--) {
+ __ mov(eax, Operand(esp, i * kPointerSize));
+ __ mov(Operand(esp, (i + 1) * kPointerSize), eax);
+ }
+ __ add(Operand(esp), Immediate(kPointerSize));
+ __ jmp(&empty_array);
+
+ __ bind(&not_empty_array);
+ __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask));
__ j(not_zero, &prepare_generic_code_call);
// Handle construction of an empty array of a certain size. Get the size from
// the stack and bail out if size is to large to actually allocate an elements
// array.
- __ mov(edx, Operand(esp, (push_count + 1) * kPointerSize));
- ASSERT(kSmiTag == 0);
- __ cmp(edx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
+ __ cmp(ecx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
__ j(greater_equal, &prepare_generic_code_call);
// edx: array_size (smi)
// edi: constructor
- // esp[0]: argc
+ // esp[0]: argc (cannot be 0 here)
// esp[4]: constructor (only if construct_call)
// esp[8]: return address
// esp[C]: argument
AllocateJSArray(masm,
edi,
- edx,
+ ecx,
eax,
ebx,
- ecx,
+ edx,
edi,
true,
&prepare_generic_code_call);
« no previous file with comments | « src/ia32/assembler-ia32.cc ('k') | src/ia32/disasm-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698