Chromium Code Reviews| Index: src/ia32/code-stubs-ia32.cc |
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
| index 23bea4f8568ce2cebeccf8212be82343e75e4d29..62e59737923bed6cf04de1a8e9de3a7c32d1bd16 100644 |
| --- a/src/ia32/code-stubs-ia32.cc |
| +++ b/src/ia32/code-stubs-ia32.cc |
| @@ -231,70 +231,36 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) { |
| } |
| -void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
| - // Stack layout on entry: |
| - // |
| - // [esp + kPointerSize]: constant elements. |
| - // [esp + (2 * kPointerSize)]: literal index. |
| - // [esp + (3 * kPointerSize)]: literals array. |
| +static void GenerateFastCloneShallowArrayCommon( |
| + MacroAssembler* masm, |
| + int length, |
| + FastCloneShallowArrayStub::Mode mode, |
|
Jakob Kummerow
2011/11/17 12:31:36
Just to be explicit, please add an ASSERT(mode !=
danno
2011/11/17 13:51:23
Done.
|
| + Label* fail) { |
| + // eax: literal index. |
| + // ecx: literals array. |
| // 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 +268,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 +288,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); |