Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/arm64/code-stubs-arm64.cc

Issue 559913002: Rename ascii to one-byte where applicable. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // In the strict case, the EmitStrictTwoHeapObjectCompare already took care 596 // In the strict case, the EmitStrictTwoHeapObjectCompare already took care
597 // of internalized strings. 597 // of internalized strings.
598 if ((cond == eq) && !strict()) { 598 if ((cond == eq) && !strict()) {
599 // Returns an answer for two internalized strings or two detectable objects. 599 // Returns an answer for two internalized strings or two detectable objects.
600 // Otherwise branches to the string case or not both strings case. 600 // Otherwise branches to the string case or not both strings case.
601 EmitCheckForInternalizedStringsOrObjects(masm, lhs, rhs, lhs_map, rhs_map, 601 EmitCheckForInternalizedStringsOrObjects(masm, lhs, rhs, lhs_map, rhs_map,
602 lhs_type, rhs_type, 602 lhs_type, rhs_type,
603 &flat_string_check, &slow); 603 &flat_string_check, &slow);
604 } 604 }
605 605
606 // Check for both being sequential ASCII strings, and inline if that is the 606 // Check for both being sequential one-byte strings,
607 // case. 607 // and inline if that is the case.
608 __ Bind(&flat_string_check); 608 __ Bind(&flat_string_check);
609 __ JumpIfBothInstanceTypesAreNotSequentialAscii(lhs_type, rhs_type, x14, 609 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(lhs_type, rhs_type, x14,
610 x15, &slow); 610 x15, &slow);
611 611
612 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10, 612 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10,
613 x11); 613 x11);
614 if (cond == eq) { 614 if (cond == eq) {
615 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, x10, x11, x12); 615 StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, x10, x11,
616 x12);
616 } else { 617 } else {
617 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, x10, x11, x12, 618 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, x10, x11,
618 x13); 619 x12, x13);
619 } 620 }
620 621
621 // Never fall through to here. 622 // Never fall through to here.
622 if (FLAG_debug_code) { 623 if (FLAG_debug_code) {
623 __ Unreachable(); 624 __ Unreachable();
624 } 625 }
625 626
626 __ Bind(&slow); 627 __ Bind(&slow);
627 628
628 __ Push(lhs, rhs); 629 __ Push(lhs, rhs);
(...skipping 1470 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 // jssp[24]: JSRegExp object 2100 // jssp[24]: JSRegExp object
2100 Label runtime; 2101 Label runtime;
2101 2102
2102 // Use of registers for this function. 2103 // Use of registers for this function.
2103 2104
2104 // Variable registers: 2105 // Variable registers:
2105 // x10-x13 used as scratch registers 2106 // x10-x13 used as scratch registers
2106 // w0 string_type type of subject string 2107 // w0 string_type type of subject string
2107 // x2 jsstring_length subject string length 2108 // x2 jsstring_length subject string length
2108 // x3 jsregexp_object JSRegExp object 2109 // x3 jsregexp_object JSRegExp object
2109 // w4 string_encoding ASCII or UC16 2110 // w4 string_encoding Latin1 or UC16
2110 // w5 sliced_string_offset if the string is a SlicedString 2111 // w5 sliced_string_offset if the string is a SlicedString
2111 // offset to the underlying string 2112 // offset to the underlying string
2112 // w6 string_representation groups attributes of the string: 2113 // w6 string_representation groups attributes of the string:
2113 // - is a string 2114 // - is a string
2114 // - type of the string 2115 // - type of the string
2115 // - is a short external string 2116 // - is a short external string
2116 Register string_type = w0; 2117 Register string_type = w0;
2117 Register jsstring_length = x2; 2118 Register jsstring_length = x2;
2118 Register jsregexp_object = x3; 2119 Register jsregexp_object = x3;
2119 Register string_encoding = w4; 2120 Register string_encoding = w4;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2297 // Argument 2 (x1): We need to load argument 2 (the previous index) into x1 2298 // Argument 2 (x1): We need to load argument 2 (the previous index) into x1
2298 // before entering the exit frame. 2299 // before entering the exit frame.
2299 __ SmiUntag(x1, x10); 2300 __ SmiUntag(x1, x10);
2300 2301
2301 // The third bit determines the string encoding in string_type. 2302 // The third bit determines the string encoding in string_type.
2302 STATIC_ASSERT(kOneByteStringTag == 0x04); 2303 STATIC_ASSERT(kOneByteStringTag == 0x04);
2303 STATIC_ASSERT(kTwoByteStringTag == 0x00); 2304 STATIC_ASSERT(kTwoByteStringTag == 0x00);
2304 STATIC_ASSERT(kStringEncodingMask == 0x04); 2305 STATIC_ASSERT(kStringEncodingMask == 0x04);
2305 2306
2306 // Find the code object based on the assumptions above. 2307 // Find the code object based on the assumptions above.
2307 // kDataAsciiCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset 2308 // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset
2308 // of kPointerSize to reach the latter. 2309 // of kPointerSize to reach the latter.
2309 DCHECK_EQ(JSRegExp::kDataAsciiCodeOffset + kPointerSize, 2310 DCHECK_EQ(JSRegExp::kDataOneByteCodeOffset + kPointerSize,
2310 JSRegExp::kDataUC16CodeOffset); 2311 JSRegExp::kDataUC16CodeOffset);
2311 __ Mov(x10, kPointerSize); 2312 __ Mov(x10, kPointerSize);
2312 // We will need the encoding later: ASCII = 0x04 2313 // We will need the encoding later: Latin1 = 0x04
2313 // UC16 = 0x00 2314 // UC16 = 0x00
2314 __ Ands(string_encoding, string_type, kStringEncodingMask); 2315 __ Ands(string_encoding, string_type, kStringEncodingMask);
2315 __ CzeroX(x10, ne); 2316 __ CzeroX(x10, ne);
2316 __ Add(x10, regexp_data, x10); 2317 __ Add(x10, regexp_data, x10);
2317 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataAsciiCodeOffset)); 2318 __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset));
2318 2319
2319 // (E) Carry on. String handling is done. 2320 // (E) Carry on. String handling is done.
2320 2321
2321 // Check that the irregexp code has been generated for the actual string 2322 // Check that the irregexp code has been generated for the actual string
2322 // encoding. If it has, the field contains a code object otherwise it contains 2323 // encoding. If it has, the field contains a code object otherwise it contains
2323 // a smi (code flushing support). 2324 // a smi (code flushing support).
2324 __ JumpIfSmi(code_object, &runtime); 2325 __ JumpIfSmi(code_object, &runtime);
2325 2326
2326 // All checks done. Now push arguments for native regexp code. 2327 // All checks done. Now push arguments for native regexp code.
2327 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, 2328 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1,
(...skipping 22 matching lines...) Expand all
2350 // Load start of the subject string. 2351 // Load start of the subject string.
2351 __ Add(start, subject, SeqString::kHeaderSize - kHeapObjectTag); 2352 __ Add(start, subject, SeqString::kHeaderSize - kHeapObjectTag);
2352 // Load the length from the original subject string from the previous stack 2353 // Load the length from the original subject string from the previous stack
2353 // frame. Therefore we have to use fp, which points exactly to two pointer 2354 // frame. Therefore we have to use fp, which points exactly to two pointer
2354 // sizes below the previous sp. (Because creating a new stack frame pushes 2355 // sizes below the previous sp. (Because creating a new stack frame pushes
2355 // the previous fp onto the stack and decrements sp by 2 * kPointerSize.) 2356 // the previous fp onto the stack and decrements sp by 2 * kPointerSize.)
2356 __ Ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); 2357 __ Ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
2357 __ Ldr(length, UntagSmiFieldMemOperand(subject, String::kLengthOffset)); 2358 __ Ldr(length, UntagSmiFieldMemOperand(subject, String::kLengthOffset));
2358 2359
2359 // Handle UC16 encoding, two bytes make one character. 2360 // Handle UC16 encoding, two bytes make one character.
2360 // string_encoding: if ASCII: 0x04 2361 // string_encoding: if Latin1: 0x04
2361 // if UC16: 0x00 2362 // if UC16: 0x00
2362 STATIC_ASSERT(kStringEncodingMask == 0x04); 2363 STATIC_ASSERT(kStringEncodingMask == 0x04);
2363 __ Ubfx(string_encoding, string_encoding, 2, 1); 2364 __ Ubfx(string_encoding, string_encoding, 2, 1);
2364 __ Eor(string_encoding, string_encoding, 1); 2365 __ Eor(string_encoding, string_encoding, 1);
2365 // string_encoding: if ASCII: 0 2366 // string_encoding: if Latin1: 0
2366 // if UC16: 1 2367 // if UC16: 1
2367 2368
2368 // Convert string positions from characters to bytes. 2369 // Convert string positions from characters to bytes.
2369 // Previous index is in x1. 2370 // Previous index is in x1.
2370 __ Lsl(previous_index_in_bytes, w1, string_encoding); 2371 __ Lsl(previous_index_in_bytes, w1, string_encoding);
2371 __ Lsl(length, length, string_encoding); 2372 __ Lsl(length, length, string_encoding);
2372 __ Lsl(sliced_string_offset, sliced_string_offset, string_encoding); 2373 __ Lsl(sliced_string_offset, sliced_string_offset, string_encoding);
2373 2374
2374 // Argument 1 (x0): Subject string. 2375 // Argument 1 (x0): Subject string.
2375 __ Mov(x0, subject); 2376 __ Mov(x0, subject);
2376 2377
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
3152 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); 3153 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase);
3153 } 3154 }
3154 3155
3155 3156
3156 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { 3157 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
3157 __ JumpIfNotSmi(code_, &slow_case_); 3158 __ JumpIfNotSmi(code_, &slow_case_);
3158 __ Cmp(code_, Smi::FromInt(String::kMaxOneByteCharCode)); 3159 __ Cmp(code_, Smi::FromInt(String::kMaxOneByteCharCode));
3159 __ B(hi, &slow_case_); 3160 __ B(hi, &slow_case_);
3160 3161
3161 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 3162 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
3162 // At this point code register contains smi tagged ASCII char code. 3163 // At this point code register contains smi tagged one-byte char code.
3163 __ Add(result_, result_, Operand::UntagSmiAndScale(code_, kPointerSizeLog2)); 3164 __ Add(result_, result_, Operand::UntagSmiAndScale(code_, kPointerSizeLog2));
3164 __ Ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 3165 __ Ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
3165 __ JumpIfRoot(result_, Heap::kUndefinedValueRootIndex, &slow_case_); 3166 __ JumpIfRoot(result_, Heap::kUndefinedValueRootIndex, &slow_case_);
3166 __ Bind(&exit_); 3167 __ Bind(&exit_);
3167 } 3168 }
3168 3169
3169 3170
3170 void StringCharFromCodeGenerator::GenerateSlow( 3171 void StringCharFromCodeGenerator::GenerateSlow(
3171 MacroAssembler* masm, 3172 MacroAssembler* masm,
3172 const RuntimeCallHelper& call_helper) { 3173 const RuntimeCallHelper& call_helper) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3398 STATIC_ASSERT(kInternalizedTag == 0); 3399 STATIC_ASSERT(kInternalizedTag == 0);
3399 Label not_internalized_strings; 3400 Label not_internalized_strings;
3400 __ Orr(x12, lhs_type, rhs_type); 3401 __ Orr(x12, lhs_type, rhs_type);
3401 __ TestAndBranchIfAnySet( 3402 __ TestAndBranchIfAnySet(
3402 x12, kIsNotInternalizedMask, &not_internalized_strings); 3403 x12, kIsNotInternalizedMask, &not_internalized_strings);
3403 // Result is in rhs (x0), and not EQUAL, as rhs is not a smi. 3404 // Result is in rhs (x0), and not EQUAL, as rhs is not a smi.
3404 __ Ret(); 3405 __ Ret();
3405 __ Bind(&not_internalized_strings); 3406 __ Bind(&not_internalized_strings);
3406 } 3407 }
3407 3408
3408 // Check that both strings are sequential ASCII. 3409 // Check that both strings are sequential one-byte.
3409 Label runtime; 3410 Label runtime;
3410 __ JumpIfBothInstanceTypesAreNotSequentialAscii( 3411 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(lhs_type, rhs_type, x12,
3411 lhs_type, rhs_type, x12, x13, &runtime); 3412 x13, &runtime);
3412 3413
3413 // Compare flat ASCII strings. Returns when done. 3414 // Compare flat one-byte strings. Returns when done.
3414 if (equality) { 3415 if (equality) {
3415 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, x10, x11, x12); 3416 StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, x10, x11,
3417 x12);
3416 } else { 3418 } else {
3417 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, x10, x11, x12, 3419 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, x10, x11,
3418 x13); 3420 x12, x13);
3419 } 3421 }
3420 3422
3421 // Handle more complex cases in runtime. 3423 // Handle more complex cases in runtime.
3422 __ Bind(&runtime); 3424 __ Bind(&runtime);
3423 __ Push(lhs, rhs); 3425 __ Push(lhs, rhs);
3424 if (equality) { 3426 if (equality) {
3425 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3427 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3426 } else { 3428 } else {
3427 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3429 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3428 } 3430 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
3655 __ B(lt, &copy_routine); 3657 __ B(lt, &copy_routine);
3656 // Allocate new sliced string. At this point we do not reload the instance 3658 // Allocate new sliced string. At this point we do not reload the instance
3657 // type including the string encoding because we simply rely on the info 3659 // type including the string encoding because we simply rely on the info
3658 // provided by the original string. It does not matter if the original 3660 // provided by the original string. It does not matter if the original
3659 // string's encoding is wrong because we always have to recheck encoding of 3661 // string's encoding is wrong because we always have to recheck encoding of
3660 // the newly created string's parent anyway due to externalized strings. 3662 // the newly created string's parent anyway due to externalized strings.
3661 Label two_byte_slice, set_slice_header; 3663 Label two_byte_slice, set_slice_header;
3662 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 3664 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
3663 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 3665 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
3664 __ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_slice); 3666 __ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_slice);
3665 __ AllocateAsciiSlicedString(result_string, result_length, x3, x4, 3667 __ AllocateOneByteSlicedString(result_string, result_length, x3, x4,
3666 &runtime); 3668 &runtime);
3667 __ B(&set_slice_header); 3669 __ B(&set_slice_header);
3668 3670
3669 __ Bind(&two_byte_slice); 3671 __ Bind(&two_byte_slice);
3670 __ AllocateTwoByteSlicedString(result_string, result_length, x3, x4, 3672 __ AllocateTwoByteSlicedString(result_string, result_length, x3, x4,
3671 &runtime); 3673 &runtime);
3672 3674
3673 __ Bind(&set_slice_header); 3675 __ Bind(&set_slice_header);
3674 __ SmiTag(from); 3676 __ SmiTag(from);
3675 __ Str(from, FieldMemOperand(result_string, SlicedString::kOffsetOffset)); 3677 __ Str(from, FieldMemOperand(result_string, SlicedString::kOffsetOffset));
3676 __ Str(unpacked_string, 3678 __ Str(unpacked_string,
(...skipping 29 matching lines...) Expand all
3706 // unpacked_char0 points to the first character of the underlying string. 3708 // unpacked_char0 points to the first character of the underlying string.
3707 __ B(&allocate_result); 3709 __ B(&allocate_result);
3708 3710
3709 __ Bind(&sequential_string); 3711 __ Bind(&sequential_string);
3710 // Locate first character of underlying subject string. 3712 // Locate first character of underlying subject string.
3711 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 3713 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3712 __ Add(unpacked_char0, unpacked_string, 3714 __ Add(unpacked_char0, unpacked_string,
3713 SeqOneByteString::kHeaderSize - kHeapObjectTag); 3715 SeqOneByteString::kHeaderSize - kHeapObjectTag);
3714 3716
3715 __ Bind(&allocate_result); 3717 __ Bind(&allocate_result);
3716 // Sequential ASCII string. Allocate the result. 3718 // Sequential one-byte string. Allocate the result.
3717 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3719 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
3718 __ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_sequential); 3720 __ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_sequential);
3719 3721
3720 // Allocate and copy the resulting ASCII string. 3722 // Allocate and copy the resulting one-byte string.
3721 __ AllocateAsciiString(result_string, result_length, x3, x4, x5, &runtime); 3723 __ AllocateOneByteString(result_string, result_length, x3, x4, x5, &runtime);
3722 3724
3723 // Locate first character of substring to copy. 3725 // Locate first character of substring to copy.
3724 __ Add(substring_char0, unpacked_char0, from); 3726 __ Add(substring_char0, unpacked_char0, from);
3725 3727
3726 // Locate first character of result. 3728 // Locate first character of result.
3727 __ Add(result_char0, result_string, 3729 __ Add(result_char0, result_string,
3728 SeqOneByteString::kHeaderSize - kHeapObjectTag); 3730 SeqOneByteString::kHeaderSize - kHeapObjectTag);
3729 3731
3730 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); 3732 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3731 __ CopyBytes(result_char0, substring_char0, result_length, x3, kCopyLong); 3733 __ CopyBytes(result_char0, substring_char0, result_length, x3, kCopyLong);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3764 StringCharAtGenerator generator( 3766 StringCharAtGenerator generator(
3765 input_string, from, result_length, x0, 3767 input_string, from, result_length, x0,
3766 &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 3768 &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
3767 generator.GenerateFast(masm); 3769 generator.GenerateFast(masm);
3768 __ Drop(3); 3770 __ Drop(3);
3769 __ Ret(); 3771 __ Ret();
3770 generator.SkipSlow(masm, &runtime); 3772 generator.SkipSlow(masm, &runtime);
3771 } 3773 }
3772 3774
3773 3775
3774 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 3776 void StringHelper::GenerateFlatOneByteStringEquals(
3775 Register left, Register right, 3777 MacroAssembler* masm, Register left, Register right, Register scratch1,
3776 Register scratch1, 3778 Register scratch2, Register scratch3) {
3777 Register scratch2,
3778 Register scratch3) {
3779 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3)); 3779 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3));
3780 Register result = x0; 3780 Register result = x0;
3781 Register left_length = scratch1; 3781 Register left_length = scratch1;
3782 Register right_length = scratch2; 3782 Register right_length = scratch2;
3783 3783
3784 // Compare lengths. If lengths differ, strings can't be equal. Lengths are 3784 // Compare lengths. If lengths differ, strings can't be equal. Lengths are
3785 // smis, and don't need to be untagged. 3785 // smis, and don't need to be untagged.
3786 Label strings_not_equal, check_zero_length; 3786 Label strings_not_equal, check_zero_length;
3787 __ Ldr(left_length, FieldMemOperand(left, String::kLengthOffset)); 3787 __ Ldr(left_length, FieldMemOperand(left, String::kLengthOffset));
3788 __ Ldr(right_length, FieldMemOperand(right, String::kLengthOffset)); 3788 __ Ldr(right_length, FieldMemOperand(right, String::kLengthOffset));
3789 __ Cmp(left_length, right_length); 3789 __ Cmp(left_length, right_length);
3790 __ B(eq, &check_zero_length); 3790 __ B(eq, &check_zero_length);
3791 3791
3792 __ Bind(&strings_not_equal); 3792 __ Bind(&strings_not_equal);
3793 __ Mov(result, Smi::FromInt(NOT_EQUAL)); 3793 __ Mov(result, Smi::FromInt(NOT_EQUAL));
3794 __ Ret(); 3794 __ Ret();
3795 3795
3796 // Check if the length is zero. If so, the strings must be equal (and empty.) 3796 // Check if the length is zero. If so, the strings must be equal (and empty.)
3797 Label compare_chars; 3797 Label compare_chars;
3798 __ Bind(&check_zero_length); 3798 __ Bind(&check_zero_length);
3799 STATIC_ASSERT(kSmiTag == 0); 3799 STATIC_ASSERT(kSmiTag == 0);
3800 __ Cbnz(left_length, &compare_chars); 3800 __ Cbnz(left_length, &compare_chars);
3801 __ Mov(result, Smi::FromInt(EQUAL)); 3801 __ Mov(result, Smi::FromInt(EQUAL));
3802 __ Ret(); 3802 __ Ret();
3803 3803
3804 // Compare characters. Falls through if all characters are equal. 3804 // Compare characters. Falls through if all characters are equal.
3805 __ Bind(&compare_chars); 3805 __ Bind(&compare_chars);
3806 GenerateAsciiCharsCompareLoop(masm, left, right, left_length, scratch2, 3806 GenerateOneByteCharsCompareLoop(masm, left, right, left_length, scratch2,
3807 scratch3, &strings_not_equal); 3807 scratch3, &strings_not_equal);
3808 3808
3809 // Characters in strings are equal. 3809 // Characters in strings are equal.
3810 __ Mov(result, Smi::FromInt(EQUAL)); 3810 __ Mov(result, Smi::FromInt(EQUAL));
3811 __ Ret(); 3811 __ Ret();
3812 } 3812 }
3813 3813
3814 3814
3815 void StringHelper::GenerateCompareFlatAsciiStrings( 3815 void StringHelper::GenerateCompareFlatOneByteStrings(
3816 MacroAssembler* masm, Register left, Register right, Register scratch1, 3816 MacroAssembler* masm, Register left, Register right, Register scratch1,
3817 Register scratch2, Register scratch3, Register scratch4) { 3817 Register scratch2, Register scratch3, Register scratch4) {
3818 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4)); 3818 DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4));
3819 Label result_not_equal, compare_lengths; 3819 Label result_not_equal, compare_lengths;
3820 3820
3821 // Find minimum length and length difference. 3821 // Find minimum length and length difference.
3822 Register length_delta = scratch3; 3822 Register length_delta = scratch3;
3823 __ Ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); 3823 __ Ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
3824 __ Ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3824 __ Ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
3825 __ Subs(length_delta, scratch1, scratch2); 3825 __ Subs(length_delta, scratch1, scratch2);
3826 3826
3827 Register min_length = scratch1; 3827 Register min_length = scratch1;
3828 __ Csel(min_length, scratch2, scratch1, gt); 3828 __ Csel(min_length, scratch2, scratch1, gt);
3829 __ Cbz(min_length, &compare_lengths); 3829 __ Cbz(min_length, &compare_lengths);
3830 3830
3831 // Compare loop. 3831 // Compare loop.
3832 GenerateAsciiCharsCompareLoop(masm, 3832 GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
3833 left, right, min_length, scratch2, scratch4, 3833 scratch4, &result_not_equal);
3834 &result_not_equal);
3835 3834
3836 // Compare lengths - strings up to min-length are equal. 3835 // Compare lengths - strings up to min-length are equal.
3837 __ Bind(&compare_lengths); 3836 __ Bind(&compare_lengths);
3838 3837
3839 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0)); 3838 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
3840 3839
3841 // Use length_delta as result if it's zero. 3840 // Use length_delta as result if it's zero.
3842 Register result = x0; 3841 Register result = x0;
3843 __ Subs(result, length_delta, 0); 3842 __ Subs(result, length_delta, 0);
3844 3843
3845 __ Bind(&result_not_equal); 3844 __ Bind(&result_not_equal);
3846 Register greater = x10; 3845 Register greater = x10;
3847 Register less = x11; 3846 Register less = x11;
3848 __ Mov(greater, Smi::FromInt(GREATER)); 3847 __ Mov(greater, Smi::FromInt(GREATER));
3849 __ Mov(less, Smi::FromInt(LESS)); 3848 __ Mov(less, Smi::FromInt(LESS));
3850 __ CmovX(result, greater, gt); 3849 __ CmovX(result, greater, gt);
3851 __ CmovX(result, less, lt); 3850 __ CmovX(result, less, lt);
3852 __ Ret(); 3851 __ Ret();
3853 } 3852 }
3854 3853
3855 3854
3856 void StringHelper::GenerateAsciiCharsCompareLoop( 3855 void StringHelper::GenerateOneByteCharsCompareLoop(
3857 MacroAssembler* masm, Register left, Register right, Register length, 3856 MacroAssembler* masm, Register left, Register right, Register length,
3858 Register scratch1, Register scratch2, Label* chars_not_equal) { 3857 Register scratch1, Register scratch2, Label* chars_not_equal) {
3859 DCHECK(!AreAliased(left, right, length, scratch1, scratch2)); 3858 DCHECK(!AreAliased(left, right, length, scratch1, scratch2));
3860 3859
3861 // Change index to run from -length to -1 by adding length to string 3860 // Change index to run from -length to -1 by adding length to string
3862 // start. This means that loop ends when index reaches zero, which 3861 // start. This means that loop ends when index reaches zero, which
3863 // doesn't need an additional compare. 3862 // doesn't need an additional compare.
3864 __ SmiUntag(length); 3863 __ SmiUntag(length);
3865 __ Add(scratch1, length, SeqOneByteString::kHeaderSize - kHeapObjectTag); 3864 __ Add(scratch1, length, SeqOneByteString::kHeaderSize - kHeapObjectTag);
3866 __ Add(left, left, scratch1); 3865 __ Add(left, left, scratch1);
(...skipping 29 matching lines...) Expand all
3896 3895
3897 Label not_same; 3896 Label not_same;
3898 __ Subs(result, right, left); 3897 __ Subs(result, right, left);
3899 __ B(ne, &not_same); 3898 __ B(ne, &not_same);
3900 STATIC_ASSERT(EQUAL == 0); 3899 STATIC_ASSERT(EQUAL == 0);
3901 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4); 3900 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4);
3902 __ Ret(); 3901 __ Ret();
3903 3902
3904 __ Bind(&not_same); 3903 __ Bind(&not_same);
3905 3904
3906 // Check that both objects are sequential ASCII strings. 3905 // Check that both objects are sequential one-byte strings.
3907 __ JumpIfEitherIsNotSequentialAsciiStrings(left, right, x12, x13, &runtime); 3906 __ JumpIfEitherIsNotSequentialOneByteStrings(left, right, x12, x13, &runtime);
3908 3907
3909 // Compare flat ASCII strings natively. Remove arguments from stack first, 3908 // Compare flat one-byte strings natively. Remove arguments from stack first,
3910 // as this function will generate a return. 3909 // as this function will generate a return.
3911 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4); 3910 __ IncrementCounter(counters->string_compare_native(), 1, x3, x4);
3912 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, x12, x13, 3911 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, x12, x13,
3913 x14, x15); 3912 x14, x15);
3914 3913
3915 __ Bind(&runtime); 3914 __ Bind(&runtime);
3916 3915
3917 // Push arguments back on to the stack. 3916 // Push arguments back on to the stack.
3918 // sp[0] = right string 3917 // sp[0] = right string
3919 // sp[8] = left string. 3918 // sp[8] = left string.
3920 __ Push(left, right); 3919 __ Push(left, right);
3921 3920
3922 // Call the runtime. 3921 // Call the runtime.
3923 // Returns -1 (less), 0 (equal), or 1 (greater) tagged as a small integer. 3922 // Returns -1 (less), 0 (equal), or 1 (greater) tagged as a small integer.
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after
5041 MemOperand(fp, 6 * kPointerSize), 5040 MemOperand(fp, 6 * kPointerSize),
5042 NULL); 5041 NULL);
5043 } 5042 }
5044 5043
5045 5044
5046 #undef __ 5045 #undef __
5047 5046
5048 } } // namespace v8::internal 5047 } } // namespace v8::internal
5049 5048
5050 #endif // V8_TARGET_ARCH_ARM64 5049 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/code-stubs-arm64.h ('k') | src/arm64/codegen-arm64.cc » ('j') | src/jsregexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698