| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 3736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3747 | 3747 |
| 3748 __ AssertString(eax); | 3748 __ AssertString(eax); |
| 3749 | 3749 |
| 3750 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); | 3750 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); |
| 3751 __ IndexFromHash(eax, eax); | 3751 __ IndexFromHash(eax, eax); |
| 3752 | 3752 |
| 3753 context()->Plug(eax); | 3753 context()->Plug(eax); |
| 3754 } | 3754 } |
| 3755 | 3755 |
| 3756 | 3756 |
| 3757 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { | 3757 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { |
| 3758 Label bailout, done, one_char_separator, long_separator, | 3758 Label bailout, done, one_char_separator, long_separator, |
| 3759 non_trivial_array, not_size_one_array, loop, | 3759 non_trivial_array, not_size_one_array, loop, |
| 3760 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; | 3760 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; |
| 3761 | 3761 |
| 3762 ZoneList<Expression*>* args = expr->arguments(); | 3762 ZoneList<Expression*>* args = expr->arguments(); |
| 3763 DCHECK(args->length() == 2); | 3763 DCHECK(args->length() == 2); |
| 3764 // We will leave the separator on the stack until the end of the function. | 3764 // We will leave the separator on the stack until the end of the function. |
| 3765 VisitForStackValue(args->at(1)); | 3765 VisitForStackValue(args->at(1)); |
| 3766 // Load this to eax (= array) | 3766 // Load this to eax (= array) |
| 3767 VisitForAccumulatorValue(args->at(0)); | 3767 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3805 __ bind(&non_trivial_array); | 3805 __ bind(&non_trivial_array); |
| 3806 __ mov(array_length_operand, array_length); | 3806 __ mov(array_length_operand, array_length); |
| 3807 | 3807 |
| 3808 // Save the FixedArray containing array's elements. | 3808 // Save the FixedArray containing array's elements. |
| 3809 // End of array's live range. | 3809 // End of array's live range. |
| 3810 elements = array; | 3810 elements = array; |
| 3811 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); | 3811 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); |
| 3812 array = no_reg; | 3812 array = no_reg; |
| 3813 | 3813 |
| 3814 | 3814 |
| 3815 // Check that all array elements are sequential ASCII strings, and | 3815 // Check that all array elements are sequential one-byte strings, and |
| 3816 // accumulate the sum of their lengths, as a smi-encoded value. | 3816 // accumulate the sum of their lengths, as a smi-encoded value. |
| 3817 __ Move(index, Immediate(0)); | 3817 __ Move(index, Immediate(0)); |
| 3818 __ Move(string_length, Immediate(0)); | 3818 __ Move(string_length, Immediate(0)); |
| 3819 // Loop condition: while (index < length). | 3819 // Loop condition: while (index < length). |
| 3820 // Live loop registers: index, array_length, string, | 3820 // Live loop registers: index, array_length, string, |
| 3821 // scratch, string_length, elements. | 3821 // scratch, string_length, elements. |
| 3822 if (generate_debug_code_) { | 3822 if (generate_debug_code_) { |
| 3823 __ cmp(index, array_length); | 3823 __ cmp(index, array_length); |
| 3824 __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); | 3824 __ Assert(less, kNoEmptyArraysHereInEmitFastOneByteArrayJoin); |
| 3825 } | 3825 } |
| 3826 __ bind(&loop); | 3826 __ bind(&loop); |
| 3827 __ mov(string, FieldOperand(elements, | 3827 __ mov(string, FieldOperand(elements, |
| 3828 index, | 3828 index, |
| 3829 times_pointer_size, | 3829 times_pointer_size, |
| 3830 FixedArray::kHeaderSize)); | 3830 FixedArray::kHeaderSize)); |
| 3831 __ JumpIfSmi(string, &bailout); | 3831 __ JumpIfSmi(string, &bailout); |
| 3832 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); | 3832 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 3833 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3833 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3834 __ and_(scratch, Immediate( | 3834 __ and_(scratch, Immediate( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3852 __ bind(¬_size_one_array); | 3852 __ bind(¬_size_one_array); |
| 3853 | 3853 |
| 3854 // End of array_length live range. | 3854 // End of array_length live range. |
| 3855 result_pos = array_length; | 3855 result_pos = array_length; |
| 3856 array_length = no_reg; | 3856 array_length = no_reg; |
| 3857 | 3857 |
| 3858 // Live registers: | 3858 // Live registers: |
| 3859 // string_length: Sum of string lengths, as a smi. | 3859 // string_length: Sum of string lengths, as a smi. |
| 3860 // elements: FixedArray of strings. | 3860 // elements: FixedArray of strings. |
| 3861 | 3861 |
| 3862 // Check that the separator is a flat ASCII string. | 3862 // Check that the separator is a flat one-byte string. |
| 3863 __ mov(string, separator_operand); | 3863 __ mov(string, separator_operand); |
| 3864 __ JumpIfSmi(string, &bailout); | 3864 __ JumpIfSmi(string, &bailout); |
| 3865 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); | 3865 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 3866 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3866 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3867 __ and_(scratch, Immediate( | 3867 __ and_(scratch, Immediate( |
| 3868 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 3868 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); |
| 3869 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); | 3869 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); |
| 3870 __ j(not_equal, &bailout); | 3870 __ j(not_equal, &bailout); |
| 3871 | 3871 |
| 3872 // Add (separator length times array_length) - separator length | 3872 // Add (separator length times array_length) - separator length |
| 3873 // to string_length. | 3873 // to string_length. |
| 3874 __ mov(scratch, separator_operand); | 3874 __ mov(scratch, separator_operand); |
| 3875 __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); | 3875 __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); |
| 3876 __ sub(string_length, scratch); // May be negative, temporarily. | 3876 __ sub(string_length, scratch); // May be negative, temporarily. |
| 3877 __ imul(scratch, array_length_operand); | 3877 __ imul(scratch, array_length_operand); |
| 3878 __ j(overflow, &bailout); | 3878 __ j(overflow, &bailout); |
| 3879 __ add(string_length, scratch); | 3879 __ add(string_length, scratch); |
| 3880 __ j(overflow, &bailout); | 3880 __ j(overflow, &bailout); |
| 3881 | 3881 |
| 3882 __ shr(string_length, 1); | 3882 __ shr(string_length, 1); |
| 3883 // Live registers and stack values: | 3883 // Live registers and stack values: |
| 3884 // string_length | 3884 // string_length |
| 3885 // elements | 3885 // elements |
| 3886 __ AllocateAsciiString(result_pos, string_length, scratch, | 3886 __ AllocateOneByteString(result_pos, string_length, scratch, index, string, |
| 3887 index, string, &bailout); | 3887 &bailout); |
| 3888 __ mov(result_operand, result_pos); | 3888 __ mov(result_operand, result_pos); |
| 3889 __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); | 3889 __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); |
| 3890 | 3890 |
| 3891 | 3891 |
| 3892 __ mov(string, separator_operand); | 3892 __ mov(string, separator_operand); |
| 3893 __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), | 3893 __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), |
| 3894 Immediate(Smi::FromInt(1))); | 3894 Immediate(Smi::FromInt(1))); |
| 3895 __ j(equal, &one_char_separator); | 3895 __ j(equal, &one_char_separator); |
| 3896 __ j(greater, &long_separator); | 3896 __ j(greater, &long_separator); |
| 3897 | 3897 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3920 __ add(index, Immediate(1)); | 3920 __ add(index, Immediate(1)); |
| 3921 __ bind(&loop_1_condition); | 3921 __ bind(&loop_1_condition); |
| 3922 __ cmp(index, array_length_operand); | 3922 __ cmp(index, array_length_operand); |
| 3923 __ j(less, &loop_1); // End while (index < length). | 3923 __ j(less, &loop_1); // End while (index < length). |
| 3924 __ jmp(&done); | 3924 __ jmp(&done); |
| 3925 | 3925 |
| 3926 | 3926 |
| 3927 | 3927 |
| 3928 // One-character separator case | 3928 // One-character separator case |
| 3929 __ bind(&one_char_separator); | 3929 __ bind(&one_char_separator); |
| 3930 // Replace separator with its ASCII character value. | 3930 // Replace separator with its one-byte character value. |
| 3931 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); | 3931 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3932 __ mov_b(separator_operand, scratch); | 3932 __ mov_b(separator_operand, scratch); |
| 3933 | 3933 |
| 3934 __ Move(index, Immediate(0)); | 3934 __ Move(index, Immediate(0)); |
| 3935 // Jump into the loop after the code that copies the separator, so the first | 3935 // Jump into the loop after the code that copies the separator, so the first |
| 3936 // element is not preceded by a separator | 3936 // element is not preceded by a separator |
| 3937 __ jmp(&loop_2_entry); | 3937 __ jmp(&loop_2_entry); |
| 3938 // Loop condition: while (index < length). | 3938 // Loop condition: while (index < length). |
| 3939 __ bind(&loop_2); | 3939 __ bind(&loop_2); |
| 3940 // Each iteration of the loop concatenates one string to the result. | 3940 // Each iteration of the loop concatenates one string to the result. |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4826 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4826 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4827 Assembler::target_address_at(call_target_address, | 4827 Assembler::target_address_at(call_target_address, |
| 4828 unoptimized_code)); | 4828 unoptimized_code)); |
| 4829 return OSR_AFTER_STACK_CHECK; | 4829 return OSR_AFTER_STACK_CHECK; |
| 4830 } | 4830 } |
| 4831 | 4831 |
| 4832 | 4832 |
| 4833 } } // namespace v8::internal | 4833 } } // namespace v8::internal |
| 4834 | 4834 |
| 4835 #endif // V8_TARGET_ARCH_IA32 | 4835 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |