| Index: src/x64/builtins-x64.cc
|
| ===================================================================
|
| --- src/x64/builtins-x64.cc (revision 9808)
|
| +++ src/x64/builtins-x64.cc (working copy)
|
| @@ -670,7 +670,7 @@
|
| __ testq(rax, rax);
|
| __ j(not_zero, &done);
|
| __ pop(rbx);
|
| - __ Push(FACTORY->undefined_value());
|
| + __ Push(masm->isolate()->factory()->undefined_value());
|
| __ push(rbx);
|
| __ incq(rax);
|
| __ bind(&done);
|
| @@ -993,10 +993,6 @@
|
| }
|
|
|
|
|
| -// Number of empty elements to allocate for an empty array.
|
| -static const int kPreallocatedArrayElements = 4;
|
| -
|
| -
|
| // Allocate an empty JSArray. The allocated array is put into the result
|
| // register. If the parameter initial_capacity is larger than zero an elements
|
| // backing store is allocated with this size and filled with the hole values.
|
| @@ -1007,9 +1003,9 @@
|
| Register scratch1,
|
| Register scratch2,
|
| Register scratch3,
|
| - int initial_capacity,
|
| Label* gc_required) {
|
| - ASSERT(initial_capacity >= 0);
|
| + const int initial_capacity = JSArray::kPreallocatedArrayElements;
|
| + STATIC_ASSERT(initial_capacity >= 0);
|
|
|
| // Load the initial map from the array function.
|
| __ movq(scratch1, FieldOperand(array_function,
|
| @@ -1033,9 +1029,10 @@
|
| // result: JSObject
|
| // scratch1: initial map
|
| // scratch2: start of next object
|
| + Factory* factory = masm->isolate()->factory();
|
| __ movq(FieldOperand(result, JSObject::kMapOffset), scratch1);
|
| __ Move(FieldOperand(result, JSArray::kPropertiesOffset),
|
| - FACTORY->empty_fixed_array());
|
| + factory->empty_fixed_array());
|
| // Field JSArray::kElementsOffset is initialized later.
|
| __ Move(FieldOperand(result, JSArray::kLengthOffset), Smi::FromInt(0));
|
|
|
| @@ -1043,7 +1040,7 @@
|
| // fixed array.
|
| if (initial_capacity == 0) {
|
| __ Move(FieldOperand(result, JSArray::kElementsOffset),
|
| - FACTORY->empty_fixed_array());
|
| + factory->empty_fixed_array());
|
| return;
|
| }
|
|
|
| @@ -1060,15 +1057,14 @@
|
| // scratch1: elements array
|
| // scratch2: start of next object
|
| __ Move(FieldOperand(scratch1, HeapObject::kMapOffset),
|
| - FACTORY->fixed_array_map());
|
| + factory->fixed_array_map());
|
| __ Move(FieldOperand(scratch1, FixedArray::kLengthOffset),
|
| Smi::FromInt(initial_capacity));
|
|
|
| // Fill the FixedArray with the hole value. Inline the code if short.
|
| // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
|
| static const int kLoopUnfoldLimit = 4;
|
| - ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit);
|
| - __ Move(scratch3, FACTORY->the_hole_value());
|
| + __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
|
| if (initial_capacity <= kLoopUnfoldLimit) {
|
| // Use a scratch register here to have only one reloc info when unfolding
|
| // the loop.
|
| @@ -1101,38 +1097,25 @@
|
| // 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;
|
| -
|
| // Load the initial map from the array function.
|
| __ movq(elements_array,
|
| FieldOperand(array_function,
|
| JSFunction::kPrototypeOrInitialMapOffset));
|
|
|
| - // Check whether an empty sized array is requested.
|
| - __ testq(array_size, array_size);
|
| - __ j(not_zero, ¬_empty);
|
| + if (FLAG_debug_code) { // Assert that array size is not zero.
|
| + __ testq(array_size, array_size);
|
| + __ Assert(not_zero, "array size is unexpectedly 0");
|
| + }
|
|
|
| - // 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(¬_empty);
|
| SmiIndex index =
|
| masm->SmiToIndex(kScratchRegister, array_size, kPointerSizeLog2);
|
| __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize,
|
| @@ -1150,9 +1133,9 @@
|
| // elements_array: initial map
|
| // elements_array_end: start of next object
|
| // array_size: size of array (smi)
|
| - __ bind(&allocated);
|
| + Factory* factory = masm->isolate()->factory();
|
| __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array);
|
| - __ Move(elements_array, FACTORY->empty_fixed_array());
|
| + __ Move(elements_array, factory->empty_fixed_array());
|
| __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
|
| // Field JSArray::kElementsOffset is initialized later.
|
| __ movq(FieldOperand(result, JSArray::kLengthOffset), array_size);
|
| @@ -1171,16 +1154,7 @@
|
| // elements_array_end: start of next object
|
| // array_size: size of array (smi)
|
| __ Move(FieldOperand(elements_array, JSObject::kMapOffset),
|
| - FACTORY->fixed_array_map());
|
| - Label not_empty_2, fill_array;
|
| - __ SmiTest(array_size);
|
| - __ j(not_zero, ¬_empty_2);
|
| - // Length of the FixedArray is the number of pre-allocated elements even
|
| - // though the actual JSArray has length 0.
|
| - __ Move(FieldOperand(elements_array, FixedArray::kLengthOffset),
|
| - Smi::FromInt(kPreallocatedArrayElements));
|
| - __ jmp(&fill_array);
|
| - __ bind(¬_empty_2);
|
| + factory->fixed_array_map());
|
| // For non-empty JSArrays the length of the FixedArray and the JSArray is the
|
| // same.
|
| __ movq(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
|
| @@ -1189,10 +1163,9 @@
|
| // result: JSObject
|
| // elements_array: elements array
|
| // elements_array_end: start of next object
|
| - __ bind(&fill_array);
|
| if (fill_with_hole) {
|
| Label loop, entry;
|
| - __ Move(scratch, FACTORY->the_hole_value());
|
| + __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
|
| __ lea(elements_array, Operand(elements_array,
|
| FixedArray::kHeaderSize - kHeapObjectTag));
|
| __ jmp(&entry);
|
| @@ -1222,12 +1195,13 @@
|
| // a construct call and a normal call.
|
| static void ArrayNativeCode(MacroAssembler* masm,
|
| Label *call_generic_code) {
|
| - Label argc_one_or_more, argc_two_or_more;
|
| + Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array;
|
|
|
| // Check for array construction with zero arguments.
|
| __ testq(rax, rax);
|
| __ j(not_zero, &argc_one_or_more);
|
|
|
| + __ bind(&empty_array);
|
| // Handle construction of an empty array.
|
| AllocateEmptyJSArray(masm,
|
| rdi,
|
| @@ -1235,7 +1209,6 @@
|
| rcx,
|
| rdx,
|
| r8,
|
| - kPreallocatedArrayElements,
|
| call_generic_code);
|
| Counters* counters = masm->isolate()->counters();
|
| __ IncrementCounter(counters->array_function_native(), 1);
|
| @@ -1248,6 +1221,16 @@
|
| __ cmpq(rax, Immediate(1));
|
| __ j(not_equal, &argc_two_or_more);
|
| __ movq(rdx, Operand(rsp, kPointerSize)); // Get the argument from the stack.
|
| +
|
| + __ SmiTest(rdx);
|
| + __ j(not_zero, ¬_empty_array);
|
| + __ pop(r8); // Adjust stack.
|
| + __ Drop(1);
|
| + __ push(r8);
|
| + __ movq(rax, Immediate(0)); // Treat this as a call with argc of zero.
|
| + __ jmp(&empty_array);
|
| +
|
| + __ bind(¬_empty_array);
|
| __ JumpUnlessNonNegativeSmi(rdx, call_generic_code);
|
|
|
| // Handle construction of an empty array of a certain size. Bail out if size
|
|
|