Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 8d30447b94d424ce7dcf3e7ad229fb6fb0ad00e8..9ccbc9ce7d58c31ac9cf5002ff60d3f967a12967 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -231,70 +231,42 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) { |
} |
-void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
- // Stack layout on entry: |
+static void GenerateFastCloneShallowArrayCommon( |
+ MacroAssembler* masm, |
+ int length, |
+ FastCloneShallowArrayStub::Mode mode, |
+ Label* fail) { |
+ // Stack and register layout on entry: |
// |
// [esp + kPointerSize]: constant elements. |
// [esp + (2 * kPointerSize)]: literal index. |
// [esp + (3 * kPointerSize)]: literals array. |
+ // eax: literal index. |
+ // ecx: literals array. |
+ ASSERT(mode != FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS); |
// All sizes here are multiples of kPointerSize. |
int elements_size = 0; |
- if (length_ > 0) { |
- elements_size = mode_ == CLONE_DOUBLE_ELEMENTS |
- ? FixedDoubleArray::SizeFor(length_) |
- : FixedArray::SizeFor(length_); |
+ if (length > 0) { |
+ elements_size = mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
+ ? FixedDoubleArray::SizeFor(length) |
+ : FixedArray::SizeFor(length); |
} |
int size = JSArray::kSize + elements_size; |
- // Load boilerplate object into ecx and check if we need to create a |
- // boilerplate. |
- Label slow_case; |
- __ mov(ecx, Operand(esp, 3 * kPointerSize)); |
- __ mov(eax, Operand(esp, 2 * kPointerSize)); |
- STATIC_ASSERT(kPointerSize == 4); |
- STATIC_ASSERT(kSmiTagSize == 1); |
- STATIC_ASSERT(kSmiTag == 0); |
- __ mov(ecx, FieldOperand(ecx, eax, times_half_pointer_size, |
- FixedArray::kHeaderSize)); |
- Factory* factory = masm->isolate()->factory(); |
- __ cmp(ecx, factory->undefined_value()); |
- __ j(equal, &slow_case); |
- |
- if (FLAG_debug_code) { |
- const char* message; |
- Handle<Map> expected_map; |
- if (mode_ == CLONE_ELEMENTS) { |
- message = "Expected (writable) fixed array"; |
- expected_map = factory->fixed_array_map(); |
- } else if (mode_ == CLONE_DOUBLE_ELEMENTS) { |
- message = "Expected (writable) fixed double array"; |
- expected_map = factory->fixed_double_array_map(); |
- } else { |
- ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS); |
- message = "Expected copy-on-write fixed array"; |
- expected_map = factory->fixed_cow_array_map(); |
- } |
- __ push(ecx); |
- __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset)); |
- __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), expected_map); |
- __ Assert(equal, message); |
- __ pop(ecx); |
- } |
- |
// Allocate both the JS array and the elements array in one big |
// allocation. This avoids multiple limit checks. |
- __ AllocateInNewSpace(size, eax, ebx, edx, &slow_case, TAG_OBJECT); |
+ __ AllocateInNewSpace(size, eax, ebx, edx, fail, TAG_OBJECT); |
// Copy the JS array part. |
for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
- if ((i != JSArray::kElementsOffset) || (length_ == 0)) { |
+ if ((i != JSArray::kElementsOffset) || (length == 0)) { |
__ mov(ebx, FieldOperand(ecx, i)); |
__ mov(FieldOperand(eax, i), ebx); |
} |
} |
- if (length_ > 0) { |
+ if (length > 0) { |
// Get hold of the elements array of the boilerplate and setup the |
// elements pointer in the resulting object. |
__ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset)); |
@@ -302,13 +274,13 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
__ mov(FieldOperand(eax, JSArray::kElementsOffset), edx); |
// Copy the elements array. |
- if (mode_ == CLONE_ELEMENTS) { |
+ if (mode == FastCloneShallowArrayStub::CLONE_ELEMENTS) { |
for (int i = 0; i < elements_size; i += kPointerSize) { |
__ mov(ebx, FieldOperand(ecx, i)); |
__ mov(FieldOperand(edx, i), ebx); |
} |
} else { |
- ASSERT(mode_ == CLONE_DOUBLE_ELEMENTS); |
+ ASSERT(mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS); |
int i; |
for (i = 0; i < FixedDoubleArray::kHeaderSize; i += kPointerSize) { |
__ mov(ebx, FieldOperand(ecx, i)); |
@@ -322,7 +294,75 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
ASSERT(i == elements_size); |
} |
} |
+} |
+ |
+ |
+void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
+ // Stack layout on entry: |
+ // |
+ // [esp + kPointerSize]: constant elements. |
+ // [esp + (2 * kPointerSize)]: literal index. |
+ // [esp + (3 * kPointerSize)]: literals array. |
+ |
+ // Load boilerplate object into ecx and check if we need to create a |
+ // boilerplate. |
+ __ mov(ecx, Operand(esp, 3 * kPointerSize)); |
+ __ mov(eax, Operand(esp, 2 * kPointerSize)); |
+ STATIC_ASSERT(kPointerSize == 4); |
+ STATIC_ASSERT(kSmiTagSize == 1); |
+ STATIC_ASSERT(kSmiTag == 0); |
+ __ mov(ecx, FieldOperand(ecx, eax, times_half_pointer_size, |
+ FixedArray::kHeaderSize)); |
+ Factory* factory = masm->isolate()->factory(); |
+ __ cmp(ecx, factory->undefined_value()); |
+ Label slow_case; |
+ __ j(equal, &slow_case); |
+ |
+ FastCloneShallowArrayStub::Mode mode = mode_; |
+ // ecx is boilerplate object. |
+ if (mode == CLONE_ANY_ELEMENTS) { |
+ Label double_elements, check_fast_elements; |
+ __ mov(ebx, FieldOperand(ecx, JSArray::kElementsOffset)); |
+ __ CheckMap(ebx, factory->fixed_cow_array_map(), |
+ &check_fast_elements, DONT_DO_SMI_CHECK); |
+ GenerateFastCloneShallowArrayCommon(masm, 0, |
+ COPY_ON_WRITE_ELEMENTS, &slow_case); |
+ __ ret(3 * kPointerSize); |
+ |
+ __ bind(&check_fast_elements); |
+ __ CheckMap(ebx, factory->fixed_array_map(), |
+ &double_elements, DONT_DO_SMI_CHECK); |
+ GenerateFastCloneShallowArrayCommon(masm, length_, |
+ CLONE_ELEMENTS, &slow_case); |
+ __ ret(3 * kPointerSize); |
+ |
+ __ bind(&double_elements); |
+ mode = CLONE_DOUBLE_ELEMENTS; |
+ // Fall through to generate the code to handle double elements. |
+ } |
+ |
+ if (FLAG_debug_code) { |
+ const char* message; |
+ Handle<Map> expected_map; |
+ if (mode == CLONE_ELEMENTS) { |
+ message = "Expected (writable) fixed array"; |
+ expected_map = factory->fixed_array_map(); |
+ } else if (mode == CLONE_DOUBLE_ELEMENTS) { |
+ message = "Expected (writable) fixed double array"; |
+ expected_map = factory->fixed_double_array_map(); |
+ } else { |
+ ASSERT(mode == COPY_ON_WRITE_ELEMENTS); |
+ message = "Expected copy-on-write fixed array"; |
+ expected_map = factory->fixed_cow_array_map(); |
+ } |
+ __ push(ecx); |
+ __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset)); |
+ __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), expected_map); |
+ __ Assert(equal, message); |
+ __ pop(ecx); |
+ } |
+ GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case); |
// Return and remove the on-stack parameters. |
__ ret(3 * kPointerSize); |