| 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_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 3727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3738 | 3738 |
| 3739 __ AssertString(eax); | 3739 __ AssertString(eax); |
| 3740 | 3740 |
| 3741 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); | 3741 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); |
| 3742 __ IndexFromHash(eax, eax); | 3742 __ IndexFromHash(eax, eax); |
| 3743 | 3743 |
| 3744 context()->Plug(eax); | 3744 context()->Plug(eax); |
| 3745 } | 3745 } |
| 3746 | 3746 |
| 3747 | 3747 |
| 3748 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { | 3748 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { |
| 3749 Label bailout, done, one_char_separator, long_separator, | 3749 Label bailout, done, one_char_separator, long_separator, |
| 3750 non_trivial_array, not_size_one_array, loop, | 3750 non_trivial_array, not_size_one_array, loop, |
| 3751 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; | 3751 loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; |
| 3752 | 3752 |
| 3753 ZoneList<Expression*>* args = expr->arguments(); | 3753 ZoneList<Expression*>* args = expr->arguments(); |
| 3754 DCHECK(args->length() == 2); | 3754 DCHECK(args->length() == 2); |
| 3755 // We will leave the separator on the stack until the end of the function. | 3755 // We will leave the separator on the stack until the end of the function. |
| 3756 VisitForStackValue(args->at(1)); | 3756 VisitForStackValue(args->at(1)); |
| 3757 // Load this to eax (= array) | 3757 // Load this to eax (= array) |
| 3758 VisitForAccumulatorValue(args->at(0)); | 3758 VisitForAccumulatorValue(args->at(0)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3796 __ bind(&non_trivial_array); | 3796 __ bind(&non_trivial_array); |
| 3797 __ mov(array_length_operand, array_length); | 3797 __ mov(array_length_operand, array_length); |
| 3798 | 3798 |
| 3799 // Save the FixedArray containing array's elements. | 3799 // Save the FixedArray containing array's elements. |
| 3800 // End of array's live range. | 3800 // End of array's live range. |
| 3801 elements = array; | 3801 elements = array; |
| 3802 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); | 3802 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); |
| 3803 array = no_reg; | 3803 array = no_reg; |
| 3804 | 3804 |
| 3805 | 3805 |
| 3806 // Check that all array elements are sequential ASCII strings, and | 3806 // Check that all array elements are sequential one-byte strings, and |
| 3807 // accumulate the sum of their lengths, as a smi-encoded value. | 3807 // accumulate the sum of their lengths, as a smi-encoded value. |
| 3808 __ Move(index, Immediate(0)); | 3808 __ Move(index, Immediate(0)); |
| 3809 __ Move(string_length, Immediate(0)); | 3809 __ Move(string_length, Immediate(0)); |
| 3810 // Loop condition: while (index < length). | 3810 // Loop condition: while (index < length). |
| 3811 // Live loop registers: index, array_length, string, | 3811 // Live loop registers: index, array_length, string, |
| 3812 // scratch, string_length, elements. | 3812 // scratch, string_length, elements. |
| 3813 if (generate_debug_code_) { | 3813 if (generate_debug_code_) { |
| 3814 __ cmp(index, array_length); | 3814 __ cmp(index, array_length); |
| 3815 __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); | 3815 __ Assert(less, kNoEmptyArraysHereInEmitFastOneByteArrayJoin); |
| 3816 } | 3816 } |
| 3817 __ bind(&loop); | 3817 __ bind(&loop); |
| 3818 __ mov(string, FieldOperand(elements, | 3818 __ mov(string, FieldOperand(elements, |
| 3819 index, | 3819 index, |
| 3820 times_pointer_size, | 3820 times_pointer_size, |
| 3821 FixedArray::kHeaderSize)); | 3821 FixedArray::kHeaderSize)); |
| 3822 __ JumpIfSmi(string, &bailout); | 3822 __ JumpIfSmi(string, &bailout); |
| 3823 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); | 3823 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 3824 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3824 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3825 __ and_(scratch, Immediate( | 3825 __ and_(scratch, Immediate( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3843 __ bind(¬_size_one_array); | 3843 __ bind(¬_size_one_array); |
| 3844 | 3844 |
| 3845 // End of array_length live range. | 3845 // End of array_length live range. |
| 3846 result_pos = array_length; | 3846 result_pos = array_length; |
| 3847 array_length = no_reg; | 3847 array_length = no_reg; |
| 3848 | 3848 |
| 3849 // Live registers: | 3849 // Live registers: |
| 3850 // string_length: Sum of string lengths, as a smi. | 3850 // string_length: Sum of string lengths, as a smi. |
| 3851 // elements: FixedArray of strings. | 3851 // elements: FixedArray of strings. |
| 3852 | 3852 |
| 3853 // Check that the separator is a flat ASCII string. | 3853 // Check that the separator is a flat one-byte string. |
| 3854 __ mov(string, separator_operand); | 3854 __ mov(string, separator_operand); |
| 3855 __ JumpIfSmi(string, &bailout); | 3855 __ JumpIfSmi(string, &bailout); |
| 3856 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); | 3856 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 3857 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3857 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3858 __ and_(scratch, Immediate( | 3858 __ and_(scratch, Immediate( |
| 3859 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 3859 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); |
| 3860 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); | 3860 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); |
| 3861 __ j(not_equal, &bailout); | 3861 __ j(not_equal, &bailout); |
| 3862 | 3862 |
| 3863 // Add (separator length times array_length) - separator length | 3863 // Add (separator length times array_length) - separator length |
| 3864 // to string_length. | 3864 // to string_length. |
| 3865 __ mov(scratch, separator_operand); | 3865 __ mov(scratch, separator_operand); |
| 3866 __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); | 3866 __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); |
| 3867 __ sub(string_length, scratch); // May be negative, temporarily. | 3867 __ sub(string_length, scratch); // May be negative, temporarily. |
| 3868 __ imul(scratch, array_length_operand); | 3868 __ imul(scratch, array_length_operand); |
| 3869 __ j(overflow, &bailout); | 3869 __ j(overflow, &bailout); |
| 3870 __ add(string_length, scratch); | 3870 __ add(string_length, scratch); |
| 3871 __ j(overflow, &bailout); | 3871 __ j(overflow, &bailout); |
| 3872 | 3872 |
| 3873 __ shr(string_length, 1); | 3873 __ shr(string_length, 1); |
| 3874 // Live registers and stack values: | 3874 // Live registers and stack values: |
| 3875 // string_length | 3875 // string_length |
| 3876 // elements | 3876 // elements |
| 3877 __ AllocateAsciiString(result_pos, string_length, scratch, | 3877 __ AllocateOneByteString(result_pos, string_length, scratch, index, string, |
| 3878 index, string, &bailout); | 3878 &bailout); |
| 3879 __ mov(result_operand, result_pos); | 3879 __ mov(result_operand, result_pos); |
| 3880 __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); | 3880 __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); |
| 3881 | 3881 |
| 3882 | 3882 |
| 3883 __ mov(string, separator_operand); | 3883 __ mov(string, separator_operand); |
| 3884 __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), | 3884 __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), |
| 3885 Immediate(Smi::FromInt(1))); | 3885 Immediate(Smi::FromInt(1))); |
| 3886 __ j(equal, &one_char_separator); | 3886 __ j(equal, &one_char_separator); |
| 3887 __ j(greater, &long_separator); | 3887 __ j(greater, &long_separator); |
| 3888 | 3888 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3911 __ add(index, Immediate(1)); | 3911 __ add(index, Immediate(1)); |
| 3912 __ bind(&loop_1_condition); | 3912 __ bind(&loop_1_condition); |
| 3913 __ cmp(index, array_length_operand); | 3913 __ cmp(index, array_length_operand); |
| 3914 __ j(less, &loop_1); // End while (index < length). | 3914 __ j(less, &loop_1); // End while (index < length). |
| 3915 __ jmp(&done); | 3915 __ jmp(&done); |
| 3916 | 3916 |
| 3917 | 3917 |
| 3918 | 3918 |
| 3919 // One-character separator case | 3919 // One-character separator case |
| 3920 __ bind(&one_char_separator); | 3920 __ bind(&one_char_separator); |
| 3921 // Replace separator with its ASCII character value. | 3921 // Replace separator with its one-byte character value. |
| 3922 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); | 3922 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3923 __ mov_b(separator_operand, scratch); | 3923 __ mov_b(separator_operand, scratch); |
| 3924 | 3924 |
| 3925 __ Move(index, Immediate(0)); | 3925 __ Move(index, Immediate(0)); |
| 3926 // Jump into the loop after the code that copies the separator, so the first | 3926 // Jump into the loop after the code that copies the separator, so the first |
| 3927 // element is not preceded by a separator | 3927 // element is not preceded by a separator |
| 3928 __ jmp(&loop_2_entry); | 3928 __ jmp(&loop_2_entry); |
| 3929 // Loop condition: while (index < length). | 3929 // Loop condition: while (index < length). |
| 3930 __ bind(&loop_2); | 3930 __ bind(&loop_2); |
| 3931 // Each iteration of the loop concatenates one string to the result. | 3931 // Each iteration of the loop concatenates one string to the result. |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4817 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4817 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4818 Assembler::target_address_at(call_target_address, | 4818 Assembler::target_address_at(call_target_address, |
| 4819 unoptimized_code)); | 4819 unoptimized_code)); |
| 4820 return OSR_AFTER_STACK_CHECK; | 4820 return OSR_AFTER_STACK_CHECK; |
| 4821 } | 4821 } |
| 4822 | 4822 |
| 4823 | 4823 |
| 4824 } } // namespace v8::internal | 4824 } } // namespace v8::internal |
| 4825 | 4825 |
| 4826 #endif // V8_TARGET_ARCH_X87 | 4826 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |