| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 2683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2694 Bind(&loop); | 2694 Bind(&loop); |
| 2695 Stp(filler, filler, MemOperand(field_ptr, 2 * kPointerSize, PostIndex)); | 2695 Stp(filler, filler, MemOperand(field_ptr, 2 * kPointerSize, PostIndex)); |
| 2696 Subs(counter, counter, 2); | 2696 Subs(counter, counter, 2); |
| 2697 Bind(&entry); | 2697 Bind(&entry); |
| 2698 B(gt, &loop); | 2698 B(gt, &loop); |
| 2699 | 2699 |
| 2700 Bind(&done); | 2700 Bind(&done); |
| 2701 } | 2701 } |
| 2702 | 2702 |
| 2703 | 2703 |
| 2704 void MacroAssembler::JumpIfEitherIsNotSequentialAsciiStrings( | 2704 void MacroAssembler::JumpIfEitherIsNotSequentialOneByteStrings( |
| 2705 Register first, | 2705 Register first, Register second, Register scratch1, Register scratch2, |
| 2706 Register second, | 2706 Label* failure, SmiCheckType smi_check) { |
| 2707 Register scratch1, | |
| 2708 Register scratch2, | |
| 2709 Label* failure, | |
| 2710 SmiCheckType smi_check) { | |
| 2711 | |
| 2712 if (smi_check == DO_SMI_CHECK) { | 2707 if (smi_check == DO_SMI_CHECK) { |
| 2713 JumpIfEitherSmi(first, second, failure); | 2708 JumpIfEitherSmi(first, second, failure); |
| 2714 } else if (emit_debug_code()) { | 2709 } else if (emit_debug_code()) { |
| 2715 DCHECK(smi_check == DONT_DO_SMI_CHECK); | 2710 DCHECK(smi_check == DONT_DO_SMI_CHECK); |
| 2716 Label not_smi; | 2711 Label not_smi; |
| 2717 JumpIfEitherSmi(first, second, NULL, ¬_smi); | 2712 JumpIfEitherSmi(first, second, NULL, ¬_smi); |
| 2718 | 2713 |
| 2719 // At least one input is a smi, but the flags indicated a smi check wasn't | 2714 // At least one input is a smi, but the flags indicated a smi check wasn't |
| 2720 // needed. | 2715 // needed. |
| 2721 Abort(kUnexpectedSmi); | 2716 Abort(kUnexpectedSmi); |
| 2722 | 2717 |
| 2723 Bind(¬_smi); | 2718 Bind(¬_smi); |
| 2724 } | 2719 } |
| 2725 | 2720 |
| 2726 // Test that both first and second are sequential ASCII strings. | 2721 // Test that both first and second are sequential one-byte strings. |
| 2727 Ldr(scratch1, FieldMemOperand(first, HeapObject::kMapOffset)); | 2722 Ldr(scratch1, FieldMemOperand(first, HeapObject::kMapOffset)); |
| 2728 Ldr(scratch2, FieldMemOperand(second, HeapObject::kMapOffset)); | 2723 Ldr(scratch2, FieldMemOperand(second, HeapObject::kMapOffset)); |
| 2729 Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); | 2724 Ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); |
| 2730 Ldrb(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); | 2725 Ldrb(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset)); |
| 2731 | 2726 |
| 2732 JumpIfEitherInstanceTypeIsNotSequentialAscii(scratch1, | 2727 JumpIfEitherInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, scratch1, |
| 2733 scratch2, | 2728 scratch2, failure); |
| 2734 scratch1, | |
| 2735 scratch2, | |
| 2736 failure); | |
| 2737 } | 2729 } |
| 2738 | 2730 |
| 2739 | 2731 |
| 2740 void MacroAssembler::JumpIfEitherInstanceTypeIsNotSequentialAscii( | 2732 void MacroAssembler::JumpIfEitherInstanceTypeIsNotSequentialOneByte( |
| 2741 Register first, | 2733 Register first, Register second, Register scratch1, Register scratch2, |
| 2742 Register second, | |
| 2743 Register scratch1, | |
| 2744 Register scratch2, | |
| 2745 Label* failure) { | 2734 Label* failure) { |
| 2746 DCHECK(!AreAliased(scratch1, second)); | 2735 DCHECK(!AreAliased(scratch1, second)); |
| 2747 DCHECK(!AreAliased(scratch1, scratch2)); | 2736 DCHECK(!AreAliased(scratch1, scratch2)); |
| 2748 static const int kFlatAsciiStringMask = | 2737 static const int kFlatOneByteStringMask = |
| 2749 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2738 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 2750 static const int kFlatAsciiStringTag = ASCII_STRING_TYPE; | 2739 static const int kFlatOneByteStringTag = ONE_BYTE_STRING_TYPE; |
| 2751 And(scratch1, first, kFlatAsciiStringMask); | 2740 And(scratch1, first, kFlatOneByteStringMask); |
| 2752 And(scratch2, second, kFlatAsciiStringMask); | 2741 And(scratch2, second, kFlatOneByteStringMask); |
| 2753 Cmp(scratch1, kFlatAsciiStringTag); | 2742 Cmp(scratch1, kFlatOneByteStringTag); |
| 2754 Ccmp(scratch2, kFlatAsciiStringTag, NoFlag, eq); | 2743 Ccmp(scratch2, kFlatOneByteStringTag, NoFlag, eq); |
| 2755 B(ne, failure); | 2744 B(ne, failure); |
| 2756 } | 2745 } |
| 2757 | 2746 |
| 2758 | 2747 |
| 2759 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii(Register type, | 2748 void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type, |
| 2760 Register scratch, | 2749 Register scratch, |
| 2761 Label* failure) { | 2750 Label* failure) { |
| 2762 const int kFlatAsciiStringMask = | 2751 const int kFlatOneByteStringMask = |
| 2763 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2752 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 2764 const int kFlatAsciiStringTag = | 2753 const int kFlatOneByteStringTag = |
| 2765 kStringTag | kOneByteStringTag | kSeqStringTag; | 2754 kStringTag | kOneByteStringTag | kSeqStringTag; |
| 2766 And(scratch, type, kFlatAsciiStringMask); | 2755 And(scratch, type, kFlatOneByteStringMask); |
| 2767 Cmp(scratch, kFlatAsciiStringTag); | 2756 Cmp(scratch, kFlatOneByteStringTag); |
| 2768 B(ne, failure); | 2757 B(ne, failure); |
| 2769 } | 2758 } |
| 2770 | 2759 |
| 2771 | 2760 |
| 2772 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( | 2761 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
| 2773 Register first, | 2762 Register first, Register second, Register scratch1, Register scratch2, |
| 2774 Register second, | |
| 2775 Register scratch1, | |
| 2776 Register scratch2, | |
| 2777 Label* failure) { | 2763 Label* failure) { |
| 2778 DCHECK(!AreAliased(first, second, scratch1, scratch2)); | 2764 DCHECK(!AreAliased(first, second, scratch1, scratch2)); |
| 2779 const int kFlatAsciiStringMask = | 2765 const int kFlatOneByteStringMask = |
| 2780 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2766 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
| 2781 const int kFlatAsciiStringTag = | 2767 const int kFlatOneByteStringTag = |
| 2782 kStringTag | kOneByteStringTag | kSeqStringTag; | 2768 kStringTag | kOneByteStringTag | kSeqStringTag; |
| 2783 And(scratch1, first, kFlatAsciiStringMask); | 2769 And(scratch1, first, kFlatOneByteStringMask); |
| 2784 And(scratch2, second, kFlatAsciiStringMask); | 2770 And(scratch2, second, kFlatOneByteStringMask); |
| 2785 Cmp(scratch1, kFlatAsciiStringTag); | 2771 Cmp(scratch1, kFlatOneByteStringTag); |
| 2786 Ccmp(scratch2, kFlatAsciiStringTag, NoFlag, eq); | 2772 Ccmp(scratch2, kFlatOneByteStringTag, NoFlag, eq); |
| 2787 B(ne, failure); | 2773 B(ne, failure); |
| 2788 } | 2774 } |
| 2789 | 2775 |
| 2790 | 2776 |
| 2791 void MacroAssembler::JumpIfNotUniqueName(Register type, | 2777 void MacroAssembler::JumpIfNotUniqueName(Register type, |
| 2792 Label* not_unique_name) { | 2778 Label* not_unique_name) { |
| 2793 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); | 2779 STATIC_ASSERT((kInternalizedTag == 0) && (kStringTag == 0)); |
| 2794 // if ((type is string && type is internalized) || type == SYMBOL_TYPE) { | 2780 // if ((type is string && type is internalized) || type == SYMBOL_TYPE) { |
| 2795 // continue | 2781 // continue |
| 2796 // } else { | 2782 // } else { |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3568 | 3554 |
| 3569 // Set the map, length and hash field. | 3555 // Set the map, length and hash field. |
| 3570 InitializeNewString(result, | 3556 InitializeNewString(result, |
| 3571 length, | 3557 length, |
| 3572 Heap::kStringMapRootIndex, | 3558 Heap::kStringMapRootIndex, |
| 3573 scratch1, | 3559 scratch1, |
| 3574 scratch2); | 3560 scratch2); |
| 3575 } | 3561 } |
| 3576 | 3562 |
| 3577 | 3563 |
| 3578 void MacroAssembler::AllocateAsciiString(Register result, | 3564 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
| 3579 Register length, | 3565 Register scratch1, Register scratch2, |
| 3580 Register scratch1, | 3566 Register scratch3, |
| 3581 Register scratch2, | 3567 Label* gc_required) { |
| 3582 Register scratch3, | |
| 3583 Label* gc_required) { | |
| 3584 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); | 3568 DCHECK(!AreAliased(result, length, scratch1, scratch2, scratch3)); |
| 3585 // Calculate the number of bytes needed for the characters in the string while | 3569 // Calculate the number of bytes needed for the characters in the string while |
| 3586 // observing object alignment. | 3570 // observing object alignment. |
| 3587 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 3571 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 3588 STATIC_ASSERT(kCharSize == 1); | 3572 STATIC_ASSERT(kCharSize == 1); |
| 3589 Add(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); | 3573 Add(scratch1, length, kObjectAlignmentMask + SeqOneByteString::kHeaderSize); |
| 3590 Bic(scratch1, scratch1, kObjectAlignmentMask); | 3574 Bic(scratch1, scratch1, kObjectAlignmentMask); |
| 3591 | 3575 |
| 3592 // Allocate ASCII string in new space. | 3576 // Allocate one-byte string in new space. |
| 3593 Allocate(scratch1, | 3577 Allocate(scratch1, |
| 3594 result, | 3578 result, |
| 3595 scratch2, | 3579 scratch2, |
| 3596 scratch3, | 3580 scratch3, |
| 3597 gc_required, | 3581 gc_required, |
| 3598 TAG_OBJECT); | 3582 TAG_OBJECT); |
| 3599 | 3583 |
| 3600 // Set the map, length and hash field. | 3584 // Set the map, length and hash field. |
| 3601 InitializeNewString(result, | 3585 InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex, |
| 3602 length, | 3586 scratch1, scratch2); |
| 3603 Heap::kAsciiStringMapRootIndex, | |
| 3604 scratch1, | |
| 3605 scratch2); | |
| 3606 } | 3587 } |
| 3607 | 3588 |
| 3608 | 3589 |
| 3609 void MacroAssembler::AllocateTwoByteConsString(Register result, | 3590 void MacroAssembler::AllocateTwoByteConsString(Register result, |
| 3610 Register length, | 3591 Register length, |
| 3611 Register scratch1, | 3592 Register scratch1, |
| 3612 Register scratch2, | 3593 Register scratch2, |
| 3613 Label* gc_required) { | 3594 Label* gc_required) { |
| 3614 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 3595 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 3615 TAG_OBJECT); | 3596 TAG_OBJECT); |
| 3616 | 3597 |
| 3617 InitializeNewString(result, | 3598 InitializeNewString(result, |
| 3618 length, | 3599 length, |
| 3619 Heap::kConsStringMapRootIndex, | 3600 Heap::kConsStringMapRootIndex, |
| 3620 scratch1, | 3601 scratch1, |
| 3621 scratch2); | 3602 scratch2); |
| 3622 } | 3603 } |
| 3623 | 3604 |
| 3624 | 3605 |
| 3625 void MacroAssembler::AllocateAsciiConsString(Register result, | 3606 void MacroAssembler::AllocateOneByteConsString(Register result, Register length, |
| 3626 Register length, | 3607 Register scratch1, |
| 3627 Register scratch1, | 3608 Register scratch2, |
| 3628 Register scratch2, | 3609 Label* gc_required) { |
| 3629 Label* gc_required) { | |
| 3630 Allocate(ConsString::kSize, | 3610 Allocate(ConsString::kSize, |
| 3631 result, | 3611 result, |
| 3632 scratch1, | 3612 scratch1, |
| 3633 scratch2, | 3613 scratch2, |
| 3634 gc_required, | 3614 gc_required, |
| 3635 TAG_OBJECT); | 3615 TAG_OBJECT); |
| 3636 | 3616 |
| 3637 InitializeNewString(result, | 3617 InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex, |
| 3638 length, | 3618 scratch1, scratch2); |
| 3639 Heap::kConsAsciiStringMapRootIndex, | |
| 3640 scratch1, | |
| 3641 scratch2); | |
| 3642 } | 3619 } |
| 3643 | 3620 |
| 3644 | 3621 |
| 3645 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 3622 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
| 3646 Register length, | 3623 Register length, |
| 3647 Register scratch1, | 3624 Register scratch1, |
| 3648 Register scratch2, | 3625 Register scratch2, |
| 3649 Label* gc_required) { | 3626 Label* gc_required) { |
| 3650 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | 3627 DCHECK(!AreAliased(result, length, scratch1, scratch2)); |
| 3651 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 3628 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 3652 TAG_OBJECT); | 3629 TAG_OBJECT); |
| 3653 | 3630 |
| 3654 InitializeNewString(result, | 3631 InitializeNewString(result, |
| 3655 length, | 3632 length, |
| 3656 Heap::kSlicedStringMapRootIndex, | 3633 Heap::kSlicedStringMapRootIndex, |
| 3657 scratch1, | 3634 scratch1, |
| 3658 scratch2); | 3635 scratch2); |
| 3659 } | 3636 } |
| 3660 | 3637 |
| 3661 | 3638 |
| 3662 void MacroAssembler::AllocateAsciiSlicedString(Register result, | 3639 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
| 3663 Register length, | 3640 Register length, |
| 3664 Register scratch1, | 3641 Register scratch1, |
| 3665 Register scratch2, | 3642 Register scratch2, |
| 3666 Label* gc_required) { | 3643 Label* gc_required) { |
| 3667 DCHECK(!AreAliased(result, length, scratch1, scratch2)); | 3644 DCHECK(!AreAliased(result, length, scratch1, scratch2)); |
| 3668 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 3645 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 3669 TAG_OBJECT); | 3646 TAG_OBJECT); |
| 3670 | 3647 |
| 3671 InitializeNewString(result, | 3648 InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex, |
| 3672 length, | 3649 scratch1, scratch2); |
| 3673 Heap::kSlicedAsciiStringMapRootIndex, | |
| 3674 scratch1, | |
| 3675 scratch2); | |
| 3676 } | 3650 } |
| 3677 | 3651 |
| 3678 | 3652 |
| 3679 // Allocates a heap number or jumps to the need_gc label if the young space | 3653 // Allocates a heap number or jumps to the need_gc label if the young space |
| 3680 // is full and a scavenge is needed. | 3654 // is full and a scavenge is needed. |
| 3681 void MacroAssembler::AllocateHeapNumber(Register result, | 3655 void MacroAssembler::AllocateHeapNumber(Register result, |
| 3682 Label* gc_required, | 3656 Label* gc_required, |
| 3683 Register scratch1, | 3657 Register scratch1, |
| 3684 Register scratch2, | 3658 Register scratch2, |
| 3685 CPURegister value, | 3659 CPURegister value, |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4786 // It's a non-indirect (non-cons and non-slice) string. | 4760 // It's a non-indirect (non-cons and non-slice) string. |
| 4787 // If it's external, the length is just ExternalString::kSize. | 4761 // If it's external, the length is just ExternalString::kSize. |
| 4788 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). | 4762 // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). |
| 4789 // External strings are the only ones with the kExternalStringTag bit | 4763 // External strings are the only ones with the kExternalStringTag bit |
| 4790 // set. | 4764 // set. |
| 4791 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); | 4765 DCHECK_EQ(0, kSeqStringTag & kExternalStringTag); |
| 4792 DCHECK_EQ(0, kConsStringTag & kExternalStringTag); | 4766 DCHECK_EQ(0, kConsStringTag & kExternalStringTag); |
| 4793 Mov(length_scratch, ExternalString::kSize); | 4767 Mov(length_scratch, ExternalString::kSize); |
| 4794 TestAndBranchIfAnySet(instance_type, kExternalStringTag, &is_data_object); | 4768 TestAndBranchIfAnySet(instance_type, kExternalStringTag, &is_data_object); |
| 4795 | 4769 |
| 4796 // Sequential string, either ASCII or UC16. | 4770 // Sequential string, either Latin1 or UC16. |
| 4797 // For ASCII (char-size of 1) we shift the smi tag away to get the length. | 4771 // For Latin1 (char-size of 1) we shift the smi tag away to get the length. |
| 4798 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby | 4772 // For UC16 (char-size of 2) we just leave the smi tag in place, thereby |
| 4799 // getting the length multiplied by 2. | 4773 // getting the length multiplied by 2. |
| 4800 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4); | 4774 DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4); |
| 4801 Ldrsw(length_scratch, UntagSmiFieldMemOperand(value, | 4775 Ldrsw(length_scratch, UntagSmiFieldMemOperand(value, |
| 4802 String::kLengthOffset)); | 4776 String::kLengthOffset)); |
| 4803 Tst(instance_type, kStringEncodingMask); | 4777 Tst(instance_type, kStringEncodingMask); |
| 4804 Cset(load_scratch, eq); | 4778 Cset(load_scratch, eq); |
| 4805 Lsl(length_scratch, length_scratch, load_scratch); | 4779 Lsl(length_scratch, length_scratch, load_scratch); |
| 4806 Add(length_scratch, | 4780 Add(length_scratch, |
| 4807 length_scratch, | 4781 length_scratch, |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5428 } | 5402 } |
| 5429 } | 5403 } |
| 5430 | 5404 |
| 5431 | 5405 |
| 5432 #undef __ | 5406 #undef __ |
| 5433 | 5407 |
| 5434 | 5408 |
| 5435 } } // namespace v8::internal | 5409 } } // namespace v8::internal |
| 5436 | 5410 |
| 5437 #endif // V8_TARGET_ARCH_ARM64 | 5411 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |