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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 623 |
624 // Check for both being sequential ASCII strings, and inline if that is the | 624 // Check for both being sequential ASCII strings, and inline if that is the |
625 // case. | 625 // case. |
626 __ Bind(&flat_string_check); | 626 __ Bind(&flat_string_check); |
627 __ JumpIfBothInstanceTypesAreNotSequentialAscii(lhs_type, rhs_type, x14, | 627 __ JumpIfBothInstanceTypesAreNotSequentialAscii(lhs_type, rhs_type, x14, |
628 x15, &slow); | 628 x15, &slow); |
629 | 629 |
630 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10, | 630 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10, |
631 x11); | 631 x11); |
632 if (cond == eq) { | 632 if (cond == eq) { |
633 StringCompareStub::GenerateFlatAsciiStringEquals(masm, lhs, rhs, | 633 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, x10, x11, x12); |
634 x10, x11, x12); | |
635 } else { | 634 } else { |
636 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, | 635 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, x10, x11, x12, |
637 x10, x11, x12, x13); | 636 x13); |
638 } | 637 } |
639 | 638 |
640 // Never fall through to here. | 639 // Never fall through to here. |
641 if (FLAG_debug_code) { | 640 if (FLAG_debug_code) { |
642 __ Unreachable(); | 641 __ Unreachable(); |
643 } | 642 } |
644 | 643 |
645 __ Bind(&slow); | 644 __ Bind(&slow); |
646 | 645 |
647 __ Push(lhs, rhs); | 646 __ Push(lhs, rhs); |
(...skipping 29 matching lines...) Expand all Loading... |
677 | 676 |
678 // We don't allow a GC during a store buffer overflow so there is no need to | 677 // We don't allow a GC during a store buffer overflow so there is no need to |
679 // store the registers in any particular way, but we do have to store and | 678 // store the registers in any particular way, but we do have to store and |
680 // restore them. | 679 // restore them. |
681 | 680 |
682 // We don't care if MacroAssembler scratch registers are corrupted. | 681 // We don't care if MacroAssembler scratch registers are corrupted. |
683 saved_regs.Remove(*(masm->TmpList())); | 682 saved_regs.Remove(*(masm->TmpList())); |
684 saved_fp_regs.Remove(*(masm->FPTmpList())); | 683 saved_fp_regs.Remove(*(masm->FPTmpList())); |
685 | 684 |
686 __ PushCPURegList(saved_regs); | 685 __ PushCPURegList(saved_regs); |
687 if (save_doubles_ == kSaveFPRegs) { | 686 if (save_doubles()) { |
688 __ PushCPURegList(saved_fp_regs); | 687 __ PushCPURegList(saved_fp_regs); |
689 } | 688 } |
690 | 689 |
691 AllowExternalCallThatCantCauseGC scope(masm); | 690 AllowExternalCallThatCantCauseGC scope(masm); |
692 __ Mov(x0, ExternalReference::isolate_address(isolate())); | 691 __ Mov(x0, ExternalReference::isolate_address(isolate())); |
693 __ CallCFunction( | 692 __ CallCFunction( |
694 ExternalReference::store_buffer_overflow_function(isolate()), 1, 0); | 693 ExternalReference::store_buffer_overflow_function(isolate()), 1, 0); |
695 | 694 |
696 if (save_doubles_ == kSaveFPRegs) { | 695 if (save_doubles()) { |
697 __ PopCPURegList(saved_fp_regs); | 696 __ PopCPURegList(saved_fp_regs); |
698 } | 697 } |
699 __ PopCPURegList(saved_regs); | 698 __ PopCPURegList(saved_regs); |
700 __ Ret(); | 699 __ Ret(); |
701 } | 700 } |
702 | 701 |
703 | 702 |
704 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( | 703 void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime( |
705 Isolate* isolate) { | 704 Isolate* isolate) { |
706 StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs); | 705 StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs); |
(...skipping 2716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3423 __ Bind(¬_internalized_strings); | 3422 __ Bind(¬_internalized_strings); |
3424 } | 3423 } |
3425 | 3424 |
3426 // Check that both strings are sequential ASCII. | 3425 // Check that both strings are sequential ASCII. |
3427 Label runtime; | 3426 Label runtime; |
3428 __ JumpIfBothInstanceTypesAreNotSequentialAscii( | 3427 __ JumpIfBothInstanceTypesAreNotSequentialAscii( |
3429 lhs_type, rhs_type, x12, x13, &runtime); | 3428 lhs_type, rhs_type, x12, x13, &runtime); |
3430 | 3429 |
3431 // Compare flat ASCII strings. Returns when done. | 3430 // Compare flat ASCII strings. Returns when done. |
3432 if (equality) { | 3431 if (equality) { |
3433 StringCompareStub::GenerateFlatAsciiStringEquals( | 3432 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, x10, x11, x12); |
3434 masm, lhs, rhs, x10, x11, x12); | |
3435 } else { | 3433 } else { |
3436 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3434 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, x10, x11, x12, |
3437 masm, lhs, rhs, x10, x11, x12, x13); | 3435 x13); |
3438 } | 3436 } |
3439 | 3437 |
3440 // Handle more complex cases in runtime. | 3438 // Handle more complex cases in runtime. |
3441 __ Bind(&runtime); | 3439 __ Bind(&runtime); |
3442 __ Push(lhs, rhs); | 3440 __ Push(lhs, rhs); |
3443 if (equality) { | 3441 if (equality) { |
3444 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3442 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3445 } else { | 3443 } else { |
3446 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3444 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3447 } | 3445 } |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3844 StringCharAtGenerator generator( | 3842 StringCharAtGenerator generator( |
3845 input_string, from, result_length, x0, | 3843 input_string, from, result_length, x0, |
3846 &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3844 &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3847 generator.GenerateFast(masm); | 3845 generator.GenerateFast(masm); |
3848 __ Drop(3); | 3846 __ Drop(3); |
3849 __ Ret(); | 3847 __ Ret(); |
3850 generator.SkipSlow(masm, &runtime); | 3848 generator.SkipSlow(masm, &runtime); |
3851 } | 3849 } |
3852 | 3850 |
3853 | 3851 |
3854 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3852 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
3855 Register left, | 3853 Register left, Register right, |
3856 Register right, | 3854 Register scratch1, |
3857 Register scratch1, | 3855 Register scratch2, |
3858 Register scratch2, | 3856 Register scratch3) { |
3859 Register scratch3) { | |
3860 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3)); | 3857 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3)); |
3861 Register result = x0; | 3858 Register result = x0; |
3862 Register left_length = scratch1; | 3859 Register left_length = scratch1; |
3863 Register right_length = scratch2; | 3860 Register right_length = scratch2; |
3864 | 3861 |
3865 // Compare lengths. If lengths differ, strings can't be equal. Lengths are | 3862 // Compare lengths. If lengths differ, strings can't be equal. Lengths are |
3866 // smis, and don't need to be untagged. | 3863 // smis, and don't need to be untagged. |
3867 Label strings_not_equal, check_zero_length; | 3864 Label strings_not_equal, check_zero_length; |
3868 __ Ldr(left_length, FieldMemOperand(left, String::kLengthOffset)); | 3865 __ Ldr(left_length, FieldMemOperand(left, String::kLengthOffset)); |
3869 __ Ldr(right_length, FieldMemOperand(right, String::kLengthOffset)); | 3866 __ Ldr(right_length, FieldMemOperand(right, String::kLengthOffset)); |
(...skipping 16 matching lines...) Expand all Loading... |
3886 __ Bind(&compare_chars); | 3883 __ Bind(&compare_chars); |
3887 GenerateAsciiCharsCompareLoop(masm, left, right, left_length, scratch2, | 3884 GenerateAsciiCharsCompareLoop(masm, left, right, left_length, scratch2, |
3888 scratch3, &strings_not_equal); | 3885 scratch3, &strings_not_equal); |
3889 | 3886 |
3890 // Characters in strings are equal. | 3887 // Characters in strings are equal. |
3891 __ Mov(result, Smi::FromInt(EQUAL)); | 3888 __ Mov(result, Smi::FromInt(EQUAL)); |
3892 __ Ret(); | 3889 __ Ret(); |
3893 } | 3890 } |
3894 | 3891 |
3895 | 3892 |
3896 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3893 void StringHelper::GenerateCompareFlatAsciiStrings( |
3897 Register left, | 3894 MacroAssembler* masm, Register left, Register right, Register scratch1, |
3898 Register right, | 3895 Register scratch2, Register scratch3, Register scratch4) { |
3899 Register scratch1, | |
3900 Register scratch2, | |
3901 Register scratch3, | |
3902 Register scratch4) { | |
3903 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4)); | 3896 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4)); |
3904 Label result_not_equal, compare_lengths; | 3897 Label result_not_equal, compare_lengths; |
3905 | 3898 |
3906 // Find minimum length and length difference. | 3899 // Find minimum length and length difference. |
3907 Register length_delta = scratch3; | 3900 Register length_delta = scratch3; |
3908 __ Ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 3901 __ Ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
3909 __ Ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3902 __ Ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3910 __ Subs(length_delta, scratch1, scratch2); | 3903 __ Subs(length_delta, scratch1, scratch2); |
3911 | 3904 |
3912 Register min_length = scratch1; | 3905 Register min_length = scratch1; |
(...skipping 18 matching lines...) Expand all Loading... |
3931 Register greater = x10; | 3924 Register greater = x10; |
3932 Register less = x11; | 3925 Register less = x11; |
3933 __ Mov(greater, Smi::FromInt(GREATER)); | 3926 __ Mov(greater, Smi::FromInt(GREATER)); |
3934 __ Mov(less, Smi::FromInt(LESS)); | 3927 __ Mov(less, Smi::FromInt(LESS)); |
3935 __ CmovX(result, greater, gt); | 3928 __ CmovX(result, greater, gt); |
3936 __ CmovX(result, less, lt); | 3929 __ CmovX(result, less, lt); |
3937 __ Ret(); | 3930 __ Ret(); |
3938 } | 3931 } |
3939 | 3932 |
3940 | 3933 |
3941 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3934 void StringHelper::GenerateAsciiCharsCompareLoop( |
3942 MacroAssembler* masm, | 3935 MacroAssembler* masm, Register left, Register right, Register length, |
3943 Register left, | 3936 Register scratch1, Register scratch2, Label* chars_not_equal) { |
3944 Register right, | |
3945 Register length, | |
3946 Register scratch1, | |
3947 Register scratch2, | |
3948 Label* chars_not_equal) { | |
3949 DCHECK(!AreAliased(left, right, length, scratch1, scratch2)); | 3937 DCHECK(!AreAliased(left, right, length, scratch1, scratch2)); |
3950 | 3938 |
3951 // Change index to run from -length to -1 by adding length to string | 3939 // Change index to run from -length to -1 by adding length to string |
3952 // start. This means that loop ends when index reaches zero, which | 3940 // start. This means that loop ends when index reaches zero, which |
3953 // doesn't need an additional compare. | 3941 // doesn't need an additional compare. |
3954 __ SmiUntag(length); | 3942 __ SmiUntag(length); |
3955 __ Add(scratch1, length, SeqOneByteString::kHeaderSize - kHeapObjectTag); | 3943 __ Add(scratch1, length, SeqOneByteString::kHeaderSize - kHeapObjectTag); |
3956 __ Add(left, left, scratch1); | 3944 __ Add(left, left, scratch1); |
3957 __ Add(right, right, scratch1); | 3945 __ Add(right, right, scratch1); |
3958 | 3946 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3992 __ Ret(); | 3980 __ Ret(); |
3993 | 3981 |
3994 __ Bind(¬_same); | 3982 __ Bind(¬_same); |
3995 | 3983 |
3996 // Check that both objects are sequential ASCII strings. | 3984 // Check that both objects are sequential ASCII strings. |
3997 __ JumpIfEitherIsNotSequentialAsciiStrings(left, right, x12, x13, &runtime); | 3985 __ JumpIfEitherIsNotSequentialAsciiStrings(left, right, x12, x13, &runtime); |
3998 | 3986 |
3999 // Compare flat ASCII strings natively. Remove arguments from stack first, | 3987 // Compare flat ASCII strings natively. Remove arguments from stack first, |
4000 // as this function will generate a return. | 3988 // as this function will generate a return. |
4001 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4); | 3989 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4); |
4002 GenerateCompareFlatAsciiStrings(masm, left, right, x12, x13, x14, x15); | 3990 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, x12, x13, |
| 3991 x14, x15); |
4003 | 3992 |
4004 __ Bind(&runtime); | 3993 __ Bind(&runtime); |
4005 | 3994 |
4006 // Push arguments back on to the stack. | 3995 // Push arguments back on to the stack. |
4007 // sp[0] = right string | 3996 // sp[0] = right string |
4008 // sp[8] = left string. | 3997 // sp[8] = left string. |
4009 __ Push(left, right); | 3998 __ Push(left, right); |
4010 | 3999 |
4011 // Call the runtime. | 4000 // Call the runtime. |
4012 // Returns -1 (less), 0 (equal), or 1 (greater) tagged as a small integer. | 4001 // Returns -1 (less), 0 (equal), or 1 (greater) tagged as a small integer. |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5141 MemOperand(fp, 6 * kPointerSize), | 5130 MemOperand(fp, 6 * kPointerSize), |
5142 NULL); | 5131 NULL); |
5143 } | 5132 } |
5144 | 5133 |
5145 | 5134 |
5146 #undef __ | 5135 #undef __ |
5147 | 5136 |
5148 } } // namespace v8::internal | 5137 } } // namespace v8::internal |
5149 | 5138 |
5150 #endif // V8_TARGET_ARCH_ARM64 | 5139 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |