| 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 |