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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 3817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3828 | 3828 |
3829 __ AssertString(v0); | 3829 __ AssertString(v0); |
3830 | 3830 |
3831 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset)); | 3831 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset)); |
3832 __ IndexFromHash(v0, v0); | 3832 __ IndexFromHash(v0, v0); |
3833 | 3833 |
3834 context()->Plug(v0); | 3834 context()->Plug(v0); |
3835 } | 3835 } |
3836 | 3836 |
3837 | 3837 |
3838 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { | 3838 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { |
3839 Label bailout, done, one_char_separator, long_separator, | 3839 Label bailout, done, one_char_separator, long_separator, |
3840 non_trivial_array, not_size_one_array, loop, | 3840 non_trivial_array, not_size_one_array, loop, |
3841 empty_separator_loop, one_char_separator_loop, | 3841 empty_separator_loop, one_char_separator_loop, |
3842 one_char_separator_loop_entry, long_separator_loop; | 3842 one_char_separator_loop_entry, long_separator_loop; |
3843 ZoneList<Expression*>* args = expr->arguments(); | 3843 ZoneList<Expression*>* args = expr->arguments(); |
3844 DCHECK(args->length() == 2); | 3844 DCHECK(args->length() == 2); |
3845 VisitForStackValue(args->at(1)); | 3845 VisitForStackValue(args->at(1)); |
3846 VisitForAccumulatorValue(args->at(0)); | 3846 VisitForAccumulatorValue(args->at(0)); |
3847 | 3847 |
3848 // All aliases of the same register have disjoint lifetimes. | 3848 // All aliases of the same register have disjoint lifetimes. |
(...skipping 29 matching lines...) Expand all Loading... |
3878 __ LoadRoot(v0, Heap::kempty_stringRootIndex); | 3878 __ LoadRoot(v0, Heap::kempty_stringRootIndex); |
3879 __ Branch(&done); | 3879 __ Branch(&done); |
3880 | 3880 |
3881 __ bind(&non_trivial_array); | 3881 __ bind(&non_trivial_array); |
3882 | 3882 |
3883 // Get the FixedArray containing array's elements. | 3883 // Get the FixedArray containing array's elements. |
3884 elements = array; | 3884 elements = array; |
3885 __ lw(elements, FieldMemOperand(array, JSArray::kElementsOffset)); | 3885 __ lw(elements, FieldMemOperand(array, JSArray::kElementsOffset)); |
3886 array = no_reg; // End of array's live range. | 3886 array = no_reg; // End of array's live range. |
3887 | 3887 |
3888 // Check that all array elements are sequential ASCII strings, and | 3888 // Check that all array elements are sequential one-byte strings, and |
3889 // accumulate the sum of their lengths, as a smi-encoded value. | 3889 // accumulate the sum of their lengths, as a smi-encoded value. |
3890 __ mov(string_length, zero_reg); | 3890 __ mov(string_length, zero_reg); |
3891 __ Addu(element, | 3891 __ Addu(element, |
3892 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3892 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
3893 __ sll(elements_end, array_length, kPointerSizeLog2); | 3893 __ sll(elements_end, array_length, kPointerSizeLog2); |
3894 __ Addu(elements_end, element, elements_end); | 3894 __ Addu(elements_end, element, elements_end); |
3895 // Loop condition: while (element < elements_end). | 3895 // Loop condition: while (element < elements_end). |
3896 // Live values in registers: | 3896 // Live values in registers: |
3897 // elements: Fixed array of strings. | 3897 // elements: Fixed array of strings. |
3898 // array_length: Length of the fixed array of strings (not smi) | 3898 // array_length: Length of the fixed array of strings (not smi) |
3899 // separator: Separator string | 3899 // separator: Separator string |
3900 // string_length: Accumulated sum of string lengths (smi). | 3900 // string_length: Accumulated sum of string lengths (smi). |
3901 // element: Current array element. | 3901 // element: Current array element. |
3902 // elements_end: Array end. | 3902 // elements_end: Array end. |
3903 if (generate_debug_code_) { | 3903 if (generate_debug_code_) { |
3904 __ Assert(gt, kNoEmptyArraysHereInEmitFastAsciiArrayJoin, | 3904 __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin, array_length, |
3905 array_length, Operand(zero_reg)); | 3905 Operand(zero_reg)); |
3906 } | 3906 } |
3907 __ bind(&loop); | 3907 __ bind(&loop); |
3908 __ lw(string, MemOperand(element)); | 3908 __ lw(string, MemOperand(element)); |
3909 __ Addu(element, element, kPointerSize); | 3909 __ Addu(element, element, kPointerSize); |
3910 __ JumpIfSmi(string, &bailout); | 3910 __ JumpIfSmi(string, &bailout); |
3911 __ lw(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); | 3911 __ lw(scratch1, FieldMemOperand(string, HeapObject::kMapOffset)); |
3912 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 3912 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
3913 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); | 3913 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout); |
3914 __ lw(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); | 3914 __ lw(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset)); |
3915 __ AdduAndCheckForOverflow(string_length, string_length, scratch1, scratch3); | 3915 __ AdduAndCheckForOverflow(string_length, string_length, scratch1, scratch3); |
3916 __ BranchOnOverflow(&bailout, scratch3); | 3916 __ BranchOnOverflow(&bailout, scratch3); |
3917 __ Branch(&loop, lt, element, Operand(elements_end)); | 3917 __ Branch(&loop, lt, element, Operand(elements_end)); |
3918 | 3918 |
3919 // If array_length is 1, return elements[0], a string. | 3919 // If array_length is 1, return elements[0], a string. |
3920 __ Branch(¬_size_one_array, ne, array_length, Operand(1)); | 3920 __ Branch(¬_size_one_array, ne, array_length, Operand(1)); |
3921 __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize)); | 3921 __ lw(v0, FieldMemOperand(elements, FixedArray::kHeaderSize)); |
3922 __ Branch(&done); | 3922 __ Branch(&done); |
3923 | 3923 |
3924 __ bind(¬_size_one_array); | 3924 __ bind(¬_size_one_array); |
3925 | 3925 |
3926 // Live values in registers: | 3926 // Live values in registers: |
3927 // separator: Separator string | 3927 // separator: Separator string |
3928 // array_length: Length of the array. | 3928 // array_length: Length of the array. |
3929 // string_length: Sum of string lengths (smi). | 3929 // string_length: Sum of string lengths (smi). |
3930 // elements: FixedArray of strings. | 3930 // elements: FixedArray of strings. |
3931 | 3931 |
3932 // Check that the separator is a flat ASCII string. | 3932 // Check that the separator is a flat one-byte string. |
3933 __ JumpIfSmi(separator, &bailout); | 3933 __ JumpIfSmi(separator, &bailout); |
3934 __ lw(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset)); | 3934 __ lw(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset)); |
3935 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 3935 __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
3936 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch1, scratch2, &bailout); | 3936 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout); |
3937 | 3937 |
3938 // Add (separator length times array_length) - separator length to the | 3938 // Add (separator length times array_length) - separator length to the |
3939 // string_length to get the length of the result string. array_length is not | 3939 // string_length to get the length of the result string. array_length is not |
3940 // smi but the other values are, so the result is a smi. | 3940 // smi but the other values are, so the result is a smi. |
3941 __ lw(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); | 3941 __ lw(scratch1, FieldMemOperand(separator, SeqOneByteString::kLengthOffset)); |
3942 __ Subu(string_length, string_length, Operand(scratch1)); | 3942 __ Subu(string_length, string_length, Operand(scratch1)); |
3943 __ Mul(scratch3, scratch2, array_length, scratch1); | 3943 __ Mul(scratch3, scratch2, array_length, scratch1); |
3944 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are | 3944 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are |
3945 // zero. | 3945 // zero. |
3946 __ Branch(&bailout, ne, scratch3, Operand(zero_reg)); | 3946 __ Branch(&bailout, ne, scratch3, Operand(zero_reg)); |
3947 __ And(scratch3, scratch2, Operand(0x80000000)); | 3947 __ And(scratch3, scratch2, Operand(0x80000000)); |
3948 __ Branch(&bailout, ne, scratch3, Operand(zero_reg)); | 3948 __ Branch(&bailout, ne, scratch3, Operand(zero_reg)); |
3949 __ AdduAndCheckForOverflow(string_length, string_length, scratch2, scratch3); | 3949 __ AdduAndCheckForOverflow(string_length, string_length, scratch2, scratch3); |
3950 __ BranchOnOverflow(&bailout, scratch3); | 3950 __ BranchOnOverflow(&bailout, scratch3); |
3951 __ SmiUntag(string_length); | 3951 __ SmiUntag(string_length); |
3952 | 3952 |
3953 // Get first element in the array to free up the elements register to be used | 3953 // Get first element in the array to free up the elements register to be used |
3954 // for the result. | 3954 // for the result. |
3955 __ Addu(element, | 3955 __ Addu(element, |
3956 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3956 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
3957 result = elements; // End of live range for elements. | 3957 result = elements; // End of live range for elements. |
3958 elements = no_reg; | 3958 elements = no_reg; |
3959 // Live values in registers: | 3959 // Live values in registers: |
3960 // element: First array element | 3960 // element: First array element |
3961 // separator: Separator string | 3961 // separator: Separator string |
3962 // string_length: Length of result string (not smi) | 3962 // string_length: Length of result string (not smi) |
3963 // array_length: Length of the array. | 3963 // array_length: Length of the array. |
3964 __ AllocateAsciiString(result, | 3964 __ AllocateOneByteString(result, string_length, scratch1, scratch2, |
3965 string_length, | 3965 elements_end, &bailout); |
3966 scratch1, | |
3967 scratch2, | |
3968 elements_end, | |
3969 &bailout); | |
3970 // Prepare for looping. Set up elements_end to end of the array. Set | 3966 // Prepare for looping. Set up elements_end to end of the array. Set |
3971 // result_pos to the position of the result where to write the first | 3967 // result_pos to the position of the result where to write the first |
3972 // character. | 3968 // character. |
3973 __ sll(elements_end, array_length, kPointerSizeLog2); | 3969 __ sll(elements_end, array_length, kPointerSizeLog2); |
3974 __ Addu(elements_end, element, elements_end); | 3970 __ Addu(elements_end, element, elements_end); |
3975 result_pos = array_length; // End of live range for array_length. | 3971 result_pos = array_length; // End of live range for array_length. |
3976 array_length = no_reg; | 3972 array_length = no_reg; |
3977 __ Addu(result_pos, | 3973 __ Addu(result_pos, |
3978 result, | 3974 result, |
3979 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3975 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
(...skipping 18 matching lines...) Expand all Loading... |
3998 __ SmiUntag(string_length); | 3994 __ SmiUntag(string_length); |
3999 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); | 3995 __ Addu(string, string, SeqOneByteString::kHeaderSize - kHeapObjectTag); |
4000 __ CopyBytes(string, result_pos, string_length, scratch1); | 3996 __ CopyBytes(string, result_pos, string_length, scratch1); |
4001 // End while (element < elements_end). | 3997 // End while (element < elements_end). |
4002 __ Branch(&empty_separator_loop, lt, element, Operand(elements_end)); | 3998 __ Branch(&empty_separator_loop, lt, element, Operand(elements_end)); |
4003 DCHECK(result.is(v0)); | 3999 DCHECK(result.is(v0)); |
4004 __ Branch(&done); | 4000 __ Branch(&done); |
4005 | 4001 |
4006 // One-character separator case. | 4002 // One-character separator case. |
4007 __ bind(&one_char_separator); | 4003 __ bind(&one_char_separator); |
4008 // Replace separator with its ASCII character value. | 4004 // Replace separator with its one-byte character value. |
4009 __ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); | 4005 __ lbu(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize)); |
4010 // Jump into the loop after the code that copies the separator, so the first | 4006 // Jump into the loop after the code that copies the separator, so the first |
4011 // element is not preceded by a separator. | 4007 // element is not preceded by a separator. |
4012 __ jmp(&one_char_separator_loop_entry); | 4008 __ jmp(&one_char_separator_loop_entry); |
4013 | 4009 |
4014 __ bind(&one_char_separator_loop); | 4010 __ bind(&one_char_separator_loop); |
4015 // Live values in registers: | 4011 // Live values in registers: |
4016 // result_pos: the position to which we are currently copying characters. | 4012 // result_pos: the position to which we are currently copying characters. |
4017 // element: Current array element. | 4013 // element: Current array element. |
4018 // elements_end: Array end. | 4014 // elements_end: Array end. |
4019 // separator: Single separator ASCII char (in lower byte). | 4015 // separator: Single separator one-byte char (in lower byte). |
4020 | 4016 |
4021 // Copy the separator character to the result. | 4017 // Copy the separator character to the result. |
4022 __ sb(separator, MemOperand(result_pos)); | 4018 __ sb(separator, MemOperand(result_pos)); |
4023 __ Addu(result_pos, result_pos, 1); | 4019 __ Addu(result_pos, result_pos, 1); |
4024 | 4020 |
4025 // Copy next array element to the result. | 4021 // Copy next array element to the result. |
4026 __ bind(&one_char_separator_loop_entry); | 4022 __ bind(&one_char_separator_loop_entry); |
4027 __ lw(string, MemOperand(element)); | 4023 __ lw(string, MemOperand(element)); |
4028 __ Addu(element, element, kPointerSize); | 4024 __ Addu(element, element, kPointerSize); |
4029 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset)); | 4025 __ lw(string_length, FieldMemOperand(string, String::kLengthOffset)); |
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4877 Assembler::target_address_at(pc_immediate_load_address)) == | 4873 Assembler::target_address_at(pc_immediate_load_address)) == |
4878 reinterpret_cast<uint32_t>( | 4874 reinterpret_cast<uint32_t>( |
4879 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4875 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4880 return OSR_AFTER_STACK_CHECK; | 4876 return OSR_AFTER_STACK_CHECK; |
4881 } | 4877 } |
4882 | 4878 |
4883 | 4879 |
4884 } } // namespace v8::internal | 4880 } } // namespace v8::internal |
4885 | 4881 |
4886 #endif // V8_TARGET_ARCH_MIPS | 4882 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |