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 |