| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 3562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3573 times_pointer_size, | 3573 times_pointer_size, |
| 3574 FixedArray::kHeaderSize)); | 3574 FixedArray::kHeaderSize)); |
| 3575 __ JumpIfSmi(string, &bailout); | 3575 __ JumpIfSmi(string, &bailout); |
| 3576 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); | 3576 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 3577 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3577 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3578 __ and_(scratch, Immediate( | 3578 __ and_(scratch, Immediate( |
| 3579 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); | 3579 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); |
| 3580 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); | 3580 __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); |
| 3581 __ j(not_equal, &bailout); | 3581 __ j(not_equal, &bailout); |
| 3582 __ add(string_length, | 3582 __ add(string_length, |
| 3583 FieldOperand(string, SeqAsciiString::kLengthOffset)); | 3583 FieldOperand(string, SeqOneByteString::kLengthOffset)); |
| 3584 __ j(overflow, &bailout); | 3584 __ j(overflow, &bailout); |
| 3585 __ add(index, Immediate(1)); | 3585 __ add(index, Immediate(1)); |
| 3586 __ cmp(index, array_length); | 3586 __ cmp(index, array_length); |
| 3587 __ j(less, &loop); | 3587 __ j(less, &loop); |
| 3588 | 3588 |
| 3589 // If array_length is 1, return elements[0], a string. | 3589 // If array_length is 1, return elements[0], a string. |
| 3590 __ cmp(array_length, 1); | 3590 __ cmp(array_length, 1); |
| 3591 __ j(not_equal, ¬_size_one_array); | 3591 __ j(not_equal, ¬_size_one_array); |
| 3592 __ mov(scratch, FieldOperand(elements, FixedArray::kHeaderSize)); | 3592 __ mov(scratch, FieldOperand(elements, FixedArray::kHeaderSize)); |
| 3593 __ mov(result_operand, scratch); | 3593 __ mov(result_operand, scratch); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3610 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 3610 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 3611 __ and_(scratch, Immediate( | 3611 __ and_(scratch, Immediate( |
| 3612 kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask | | 3612 kIsNotStringMask | kStringEncodingMask | kAsciiDataHintMask | |
| 3613 kStringRepresentationMask)); | 3613 kStringRepresentationMask)); |
| 3614 __ cmp(scratch, ASCII_STRING_TYPE); | 3614 __ cmp(scratch, ASCII_STRING_TYPE); |
| 3615 __ j(not_equal, &bailout); | 3615 __ j(not_equal, &bailout); |
| 3616 | 3616 |
| 3617 // Add (separator length times array_length) - separator length | 3617 // Add (separator length times array_length) - separator length |
| 3618 // to string_length. | 3618 // to string_length. |
| 3619 __ mov(scratch, separator_operand); | 3619 __ mov(scratch, separator_operand); |
| 3620 __ mov(scratch, FieldOperand(scratch, SeqAsciiString::kLengthOffset)); | 3620 __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); |
| 3621 __ sub(string_length, scratch); // May be negative, temporarily. | 3621 __ sub(string_length, scratch); // May be negative, temporarily. |
| 3622 __ imul(scratch, array_length_operand); | 3622 __ imul(scratch, array_length_operand); |
| 3623 __ j(overflow, &bailout); | 3623 __ j(overflow, &bailout); |
| 3624 __ add(string_length, scratch); | 3624 __ add(string_length, scratch); |
| 3625 __ j(overflow, &bailout); | 3625 __ j(overflow, &bailout); |
| 3626 | 3626 |
| 3627 __ shr(string_length, 1); | 3627 __ shr(string_length, 1); |
| 3628 // Live registers and stack values: | 3628 // Live registers and stack values: |
| 3629 // string_length | 3629 // string_length |
| 3630 // elements | 3630 // elements |
| 3631 __ AllocateAsciiString(result_pos, string_length, scratch, | 3631 __ AllocateAsciiString(result_pos, string_length, scratch, |
| 3632 index, string, &bailout); | 3632 index, string, &bailout); |
| 3633 __ mov(result_operand, result_pos); | 3633 __ mov(result_operand, result_pos); |
| 3634 __ lea(result_pos, FieldOperand(result_pos, SeqAsciiString::kHeaderSize)); | 3634 __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); |
| 3635 | 3635 |
| 3636 | 3636 |
| 3637 __ mov(string, separator_operand); | 3637 __ mov(string, separator_operand); |
| 3638 __ cmp(FieldOperand(string, SeqAsciiString::kLengthOffset), | 3638 __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), |
| 3639 Immediate(Smi::FromInt(1))); | 3639 Immediate(Smi::FromInt(1))); |
| 3640 __ j(equal, &one_char_separator); | 3640 __ j(equal, &one_char_separator); |
| 3641 __ j(greater, &long_separator); | 3641 __ j(greater, &long_separator); |
| 3642 | 3642 |
| 3643 | 3643 |
| 3644 // Empty separator case | 3644 // Empty separator case |
| 3645 __ mov(index, Immediate(0)); | 3645 __ mov(index, Immediate(0)); |
| 3646 __ jmp(&loop_1_condition); | 3646 __ jmp(&loop_1_condition); |
| 3647 // Loop condition: while (index < length). | 3647 // Loop condition: while (index < length). |
| 3648 __ bind(&loop_1); | 3648 __ bind(&loop_1); |
| 3649 // Each iteration of the loop concatenates one string to the result. | 3649 // Each iteration of the loop concatenates one string to the result. |
| 3650 // Live values in registers: | 3650 // Live values in registers: |
| 3651 // index: which element of the elements array we are adding to the result. | 3651 // index: which element of the elements array we are adding to the result. |
| 3652 // result_pos: the position to which we are currently copying characters. | 3652 // result_pos: the position to which we are currently copying characters. |
| 3653 // elements: the FixedArray of strings we are joining. | 3653 // elements: the FixedArray of strings we are joining. |
| 3654 | 3654 |
| 3655 // Get string = array[index]. | 3655 // Get string = array[index]. |
| 3656 __ mov(string, FieldOperand(elements, index, | 3656 __ mov(string, FieldOperand(elements, index, |
| 3657 times_pointer_size, | 3657 times_pointer_size, |
| 3658 FixedArray::kHeaderSize)); | 3658 FixedArray::kHeaderSize)); |
| 3659 __ mov(string_length, | 3659 __ mov(string_length, |
| 3660 FieldOperand(string, String::kLengthOffset)); | 3660 FieldOperand(string, String::kLengthOffset)); |
| 3661 __ shr(string_length, 1); | 3661 __ shr(string_length, 1); |
| 3662 __ lea(string, | 3662 __ lea(string, |
| 3663 FieldOperand(string, SeqAsciiString::kHeaderSize)); | 3663 FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3664 __ CopyBytes(string, result_pos, string_length, scratch); | 3664 __ CopyBytes(string, result_pos, string_length, scratch); |
| 3665 __ add(index, Immediate(1)); | 3665 __ add(index, Immediate(1)); |
| 3666 __ bind(&loop_1_condition); | 3666 __ bind(&loop_1_condition); |
| 3667 __ cmp(index, array_length_operand); | 3667 __ cmp(index, array_length_operand); |
| 3668 __ j(less, &loop_1); // End while (index < length). | 3668 __ j(less, &loop_1); // End while (index < length). |
| 3669 __ jmp(&done); | 3669 __ jmp(&done); |
| 3670 | 3670 |
| 3671 | 3671 |
| 3672 | 3672 |
| 3673 // One-character separator case | 3673 // One-character separator case |
| 3674 __ bind(&one_char_separator); | 3674 __ bind(&one_char_separator); |
| 3675 // Replace separator with its ASCII character value. | 3675 // Replace separator with its ASCII character value. |
| 3676 __ mov_b(scratch, FieldOperand(string, SeqAsciiString::kHeaderSize)); | 3676 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3677 __ mov_b(separator_operand, scratch); | 3677 __ mov_b(separator_operand, scratch); |
| 3678 | 3678 |
| 3679 __ Set(index, Immediate(0)); | 3679 __ Set(index, Immediate(0)); |
| 3680 // Jump into the loop after the code that copies the separator, so the first | 3680 // Jump into the loop after the code that copies the separator, so the first |
| 3681 // element is not preceded by a separator | 3681 // element is not preceded by a separator |
| 3682 __ jmp(&loop_2_entry); | 3682 __ jmp(&loop_2_entry); |
| 3683 // Loop condition: while (index < length). | 3683 // Loop condition: while (index < length). |
| 3684 __ bind(&loop_2); | 3684 __ bind(&loop_2); |
| 3685 // Each iteration of the loop concatenates one string to the result. | 3685 // Each iteration of the loop concatenates one string to the result. |
| 3686 // Live values in registers: | 3686 // Live values in registers: |
| 3687 // index: which element of the elements array we are adding to the result. | 3687 // index: which element of the elements array we are adding to the result. |
| 3688 // result_pos: the position to which we are currently copying characters. | 3688 // result_pos: the position to which we are currently copying characters. |
| 3689 | 3689 |
| 3690 // Copy the separator character to the result. | 3690 // Copy the separator character to the result. |
| 3691 __ mov_b(scratch, separator_operand); | 3691 __ mov_b(scratch, separator_operand); |
| 3692 __ mov_b(Operand(result_pos, 0), scratch); | 3692 __ mov_b(Operand(result_pos, 0), scratch); |
| 3693 __ inc(result_pos); | 3693 __ inc(result_pos); |
| 3694 | 3694 |
| 3695 __ bind(&loop_2_entry); | 3695 __ bind(&loop_2_entry); |
| 3696 // Get string = array[index]. | 3696 // Get string = array[index]. |
| 3697 __ mov(string, FieldOperand(elements, index, | 3697 __ mov(string, FieldOperand(elements, index, |
| 3698 times_pointer_size, | 3698 times_pointer_size, |
| 3699 FixedArray::kHeaderSize)); | 3699 FixedArray::kHeaderSize)); |
| 3700 __ mov(string_length, | 3700 __ mov(string_length, |
| 3701 FieldOperand(string, String::kLengthOffset)); | 3701 FieldOperand(string, String::kLengthOffset)); |
| 3702 __ shr(string_length, 1); | 3702 __ shr(string_length, 1); |
| 3703 __ lea(string, | 3703 __ lea(string, |
| 3704 FieldOperand(string, SeqAsciiString::kHeaderSize)); | 3704 FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3705 __ CopyBytes(string, result_pos, string_length, scratch); | 3705 __ CopyBytes(string, result_pos, string_length, scratch); |
| 3706 __ add(index, Immediate(1)); | 3706 __ add(index, Immediate(1)); |
| 3707 | 3707 |
| 3708 __ cmp(index, array_length_operand); | 3708 __ cmp(index, array_length_operand); |
| 3709 __ j(less, &loop_2); // End while (index < length). | 3709 __ j(less, &loop_2); // End while (index < length). |
| 3710 __ jmp(&done); | 3710 __ jmp(&done); |
| 3711 | 3711 |
| 3712 | 3712 |
| 3713 // Long separator case (separator is more than one character). | 3713 // Long separator case (separator is more than one character). |
| 3714 __ bind(&long_separator); | 3714 __ bind(&long_separator); |
| 3715 | 3715 |
| 3716 __ Set(index, Immediate(0)); | 3716 __ Set(index, Immediate(0)); |
| 3717 // Jump into the loop after the code that copies the separator, so the first | 3717 // Jump into the loop after the code that copies the separator, so the first |
| 3718 // element is not preceded by a separator | 3718 // element is not preceded by a separator |
| 3719 __ jmp(&loop_3_entry); | 3719 __ jmp(&loop_3_entry); |
| 3720 // Loop condition: while (index < length). | 3720 // Loop condition: while (index < length). |
| 3721 __ bind(&loop_3); | 3721 __ bind(&loop_3); |
| 3722 // Each iteration of the loop concatenates one string to the result. | 3722 // Each iteration of the loop concatenates one string to the result. |
| 3723 // Live values in registers: | 3723 // Live values in registers: |
| 3724 // index: which element of the elements array we are adding to the result. | 3724 // index: which element of the elements array we are adding to the result. |
| 3725 // result_pos: the position to which we are currently copying characters. | 3725 // result_pos: the position to which we are currently copying characters. |
| 3726 | 3726 |
| 3727 // Copy the separator to the result. | 3727 // Copy the separator to the result. |
| 3728 __ mov(string, separator_operand); | 3728 __ mov(string, separator_operand); |
| 3729 __ mov(string_length, | 3729 __ mov(string_length, |
| 3730 FieldOperand(string, String::kLengthOffset)); | 3730 FieldOperand(string, String::kLengthOffset)); |
| 3731 __ shr(string_length, 1); | 3731 __ shr(string_length, 1); |
| 3732 __ lea(string, | 3732 __ lea(string, |
| 3733 FieldOperand(string, SeqAsciiString::kHeaderSize)); | 3733 FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3734 __ CopyBytes(string, result_pos, string_length, scratch); | 3734 __ CopyBytes(string, result_pos, string_length, scratch); |
| 3735 | 3735 |
| 3736 __ bind(&loop_3_entry); | 3736 __ bind(&loop_3_entry); |
| 3737 // Get string = array[index]. | 3737 // Get string = array[index]. |
| 3738 __ mov(string, FieldOperand(elements, index, | 3738 __ mov(string, FieldOperand(elements, index, |
| 3739 times_pointer_size, | 3739 times_pointer_size, |
| 3740 FixedArray::kHeaderSize)); | 3740 FixedArray::kHeaderSize)); |
| 3741 __ mov(string_length, | 3741 __ mov(string_length, |
| 3742 FieldOperand(string, String::kLengthOffset)); | 3742 FieldOperand(string, String::kLengthOffset)); |
| 3743 __ shr(string_length, 1); | 3743 __ shr(string_length, 1); |
| 3744 __ lea(string, | 3744 __ lea(string, |
| 3745 FieldOperand(string, SeqAsciiString::kHeaderSize)); | 3745 FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 3746 __ CopyBytes(string, result_pos, string_length, scratch); | 3746 __ CopyBytes(string, result_pos, string_length, scratch); |
| 3747 __ add(index, Immediate(1)); | 3747 __ add(index, Immediate(1)); |
| 3748 | 3748 |
| 3749 __ cmp(index, array_length_operand); | 3749 __ cmp(index, array_length_operand); |
| 3750 __ j(less, &loop_3); // End while (index < length). | 3750 __ j(less, &loop_3); // End while (index < length). |
| 3751 __ jmp(&done); | 3751 __ jmp(&done); |
| 3752 | 3752 |
| 3753 | 3753 |
| 3754 __ bind(&bailout); | 3754 __ bind(&bailout); |
| 3755 __ mov(result_operand, isolate()->factory()->undefined_value()); | 3755 __ mov(result_operand, isolate()->factory()->undefined_value()); |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4498 *stack_depth = 0; | 4498 *stack_depth = 0; |
| 4499 *context_length = 0; | 4499 *context_length = 0; |
| 4500 return previous_; | 4500 return previous_; |
| 4501 } | 4501 } |
| 4502 | 4502 |
| 4503 #undef __ | 4503 #undef __ |
| 4504 | 4504 |
| 4505 } } // namespace v8::internal | 4505 } } // namespace v8::internal |
| 4506 | 4506 |
| 4507 #endif // V8_TARGET_ARCH_IA32 | 4507 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |