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

Side by Side Diff: src/arm/code-stubs-arm.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 // In the strict case the EmitStrictTwoHeapObjectCompare already took care of 681 // In the strict case the EmitStrictTwoHeapObjectCompare already took care of
682 // internalized strings. 682 // internalized strings.
683 if (cc == eq && !strict()) { 683 if (cc == eq && !strict()) {
684 // Returns an answer for two internalized strings or two detectable objects. 684 // Returns an answer for two internalized strings or two detectable objects.
685 // Otherwise jumps to string case or not both strings case. 685 // Otherwise jumps to string case or not both strings case.
686 // Assumes that r2 is the type of rhs_ on entry. 686 // Assumes that r2 is the type of rhs_ on entry.
687 EmitCheckForInternalizedStringsOrObjects( 687 EmitCheckForInternalizedStringsOrObjects(
688 masm, lhs, rhs, &flat_string_check, &slow); 688 masm, lhs, rhs, &flat_string_check, &slow);
689 } 689 }
690 690
691 // Check for both being sequential ASCII strings, and inline if that is the 691 // Check for both being sequential one-byte strings,
692 // case. 692 // and inline if that is the case.
693 __ bind(&flat_string_check); 693 __ bind(&flat_string_check);
694 694
695 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); 695 __ JumpIfNonSmisNotBothSequentialOneByteStrings(lhs, rhs, r2, r3, &slow);
696 696
697 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2, 697 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2,
698 r3); 698 r3);
699 if (cc == eq) { 699 if (cc == eq) {
700 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, r2, r3, r4); 700 StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, r2, r3, r4);
701 } else { 701 } else {
702 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, r2, r3, r4, 702 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, r2, r3, r4,
703 r5); 703 r5);
704 } 704 }
705 // Never falls through to here. 705 // Never falls through to here.
706 706
707 __ bind(&slow); 707 __ bind(&slow);
708 708
709 __ Push(lhs, rhs); 709 __ Push(lhs, rhs);
710 // Figure out which native to call and setup the arguments. 710 // Figure out which native to call and setup the arguments.
711 Builtins::JavaScript native; 711 Builtins::JavaScript native;
712 if (cc == eq) { 712 if (cc == eq) {
713 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 713 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 __ JumpIfNotSmi(r1, &runtime); 2030 __ JumpIfNotSmi(r1, &runtime);
2031 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset)); 2031 __ ldr(r3, FieldMemOperand(r3, String::kLengthOffset));
2032 __ cmp(r3, Operand(r1)); 2032 __ cmp(r3, Operand(r1));
2033 __ b(ls, &runtime); 2033 __ b(ls, &runtime);
2034 __ SmiUntag(r1); 2034 __ SmiUntag(r1);
2035 2035
2036 STATIC_ASSERT(4 == kOneByteStringTag); 2036 STATIC_ASSERT(4 == kOneByteStringTag);
2037 STATIC_ASSERT(kTwoByteStringTag == 0); 2037 STATIC_ASSERT(kTwoByteStringTag == 0);
2038 __ and_(r0, r0, Operand(kStringEncodingMask)); 2038 __ and_(r0, r0, Operand(kStringEncodingMask));
2039 __ mov(r3, Operand(r0, ASR, 2), SetCC); 2039 __ mov(r3, Operand(r0, ASR, 2), SetCC);
2040 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset), ne); 2040 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset),
2041 ne);
2041 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq); 2042 __ ldr(r6, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset), eq);
2042 2043
2043 // (E) Carry on. String handling is done. 2044 // (E) Carry on. String handling is done.
2044 // r6: irregexp code 2045 // r6: irregexp code
2045 // Check that the irregexp code has been generated for the actual string 2046 // Check that the irregexp code has been generated for the actual string
2046 // encoding. If it has, the field contains a code object otherwise it contains 2047 // encoding. If it has, the field contains a code object otherwise it contains
2047 // a smi (code flushing support). 2048 // a smi (code flushing support).
2048 __ JumpIfSmi(r6, &runtime); 2049 __ JumpIfSmi(r6, &runtime);
2049 2050
2050 // r1: previous index 2051 // r1: previous index
2051 // r3: encoding of subject string (1 if ASCII, 0 if two_byte); 2052 // r3: encoding of subject string (1 if one_byte, 0 if two_byte);
2052 // r6: code 2053 // r6: code
2053 // subject: Subject string 2054 // subject: Subject string
2054 // regexp_data: RegExp data (FixedArray) 2055 // regexp_data: RegExp data (FixedArray)
2055 // All checks done. Now push arguments for native regexp code. 2056 // All checks done. Now push arguments for native regexp code.
2056 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, r0, r2); 2057 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, r0, r2);
2057 2058
2058 // Isolates: note we add an additional parameter here (isolate pointer). 2059 // Isolates: note we add an additional parameter here (isolate pointer).
2059 const int kRegExpExecuteArguments = 9; 2060 const int kRegExpExecuteArguments = 9;
2060 const int kParameterRegisters = 4; 2061 const int kParameterRegisters = 4;
2061 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); 2062 __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
(...skipping 22 matching lines...) Expand all
2084 __ mov(r0, Operand::Zero()); 2085 __ mov(r0, Operand::Zero());
2085 __ str(r0, MemOperand(sp, 2 * kPointerSize)); 2086 __ str(r0, MemOperand(sp, 2 * kPointerSize));
2086 2087
2087 // Argument 5 (sp[4]): static offsets vector buffer. 2088 // Argument 5 (sp[4]): static offsets vector buffer.
2088 __ mov(r0, 2089 __ mov(r0,
2089 Operand(ExternalReference::address_of_static_offsets_vector( 2090 Operand(ExternalReference::address_of_static_offsets_vector(
2090 isolate()))); 2091 isolate())));
2091 __ str(r0, MemOperand(sp, 1 * kPointerSize)); 2092 __ str(r0, MemOperand(sp, 1 * kPointerSize));
2092 2093
2093 // For arguments 4 and 3 get string length, calculate start of string data and 2094 // For arguments 4 and 3 get string length, calculate start of string data and
2094 // calculate the shift of the index (0 for ASCII and 1 for two byte). 2095 // calculate the shift of the index (0 for one-byte and 1 for two-byte).
2095 __ add(r7, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag)); 2096 __ add(r7, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
2096 __ eor(r3, r3, Operand(1)); 2097 __ eor(r3, r3, Operand(1));
2097 // Load the length from the original subject string from the previous stack 2098 // Load the length from the original subject string from the previous stack
2098 // frame. Therefore we have to use fp, which points exactly to two pointer 2099 // frame. Therefore we have to use fp, which points exactly to two pointer
2099 // sizes below the previous sp. (Because creating a new stack frame pushes 2100 // sizes below the previous sp. (Because creating a new stack frame pushes
2100 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) 2101 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
2101 __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); 2102 __ ldr(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
2102 // If slice offset is not 0, load the length from the original sliced string. 2103 // If slice offset is not 0, load the length from the original sliced string.
2103 // Argument 4, r3: End of string data 2104 // Argument 4, r3: End of string data
2104 // Argument 3, r2: Start of string data 2105 // Argument 3, r2: Start of string data
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 __ CallExternalReference(miss, 4); 2718 __ CallExternalReference(miss, 4);
2718 2719
2719 // Move result to edi and exit the internal frame. 2720 // Move result to edi and exit the internal frame.
2720 __ mov(r1, r0); 2721 __ mov(r1, r0);
2721 } 2722 }
2722 } 2723 }
2723 2724
2724 2725
2725 // StringCharCodeAtGenerator 2726 // StringCharCodeAtGenerator
2726 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2727 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2727 Label flat_string;
2728 Label ascii_string;
2729 Label got_char_code;
2730 Label sliced_string;
2731
2732 // If the receiver is a smi trigger the non-string case. 2728 // If the receiver is a smi trigger the non-string case.
2733 __ JumpIfSmi(object_, receiver_not_string_); 2729 __ JumpIfSmi(object_, receiver_not_string_);
2734 2730
2735 // Fetch the instance type of the receiver into result register. 2731 // Fetch the instance type of the receiver into result register.
2736 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 2732 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
2737 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 2733 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
2738 // If the receiver is not a string trigger the non-string case. 2734 // If the receiver is not a string trigger the non-string case.
2739 __ tst(result_, Operand(kIsNotStringMask)); 2735 __ tst(result_, Operand(kIsNotStringMask));
2740 __ b(ne, receiver_not_string_); 2736 __ b(ne, receiver_not_string_);
2741 2737
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2820 // Fast case of Heap::LookupSingleCharacterStringFromCode. 2816 // Fast case of Heap::LookupSingleCharacterStringFromCode.
2821 STATIC_ASSERT(kSmiTag == 0); 2817 STATIC_ASSERT(kSmiTag == 0);
2822 STATIC_ASSERT(kSmiShiftSize == 0); 2818 STATIC_ASSERT(kSmiShiftSize == 0);
2823 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1)); 2819 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
2824 __ tst(code_, 2820 __ tst(code_,
2825 Operand(kSmiTagMask | 2821 Operand(kSmiTagMask |
2826 ((~String::kMaxOneByteCharCode) << kSmiTagSize))); 2822 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
2827 __ b(ne, &slow_case_); 2823 __ b(ne, &slow_case_);
2828 2824
2829 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 2825 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
2830 // At this point code register contains smi tagged ASCII char code. 2826 // At this point code register contains smi tagged one-byte char code.
2831 __ add(result_, result_, Operand::PointerOffsetFromSmiKey(code_)); 2827 __ add(result_, result_, Operand::PointerOffsetFromSmiKey(code_));
2832 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 2828 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
2833 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex); 2829 __ CompareRoot(result_, Heap::kUndefinedValueRootIndex);
2834 __ b(eq, &slow_case_); 2830 __ b(eq, &slow_case_);
2835 __ bind(&exit_); 2831 __ bind(&exit_);
2836 } 2832 }
2837 2833
2838 2834
2839 void StringCharFromCodeGenerator::GenerateSlow( 2835 void StringCharFromCodeGenerator::GenerateSlow(
2840 MacroAssembler* masm, 2836 MacroAssembler* masm,
2841 const RuntimeCallHelper& call_helper) { 2837 const RuntimeCallHelper& call_helper) {
2842 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); 2838 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
2843 2839
2844 __ bind(&slow_case_); 2840 __ bind(&slow_case_);
2845 call_helper.BeforeCall(masm); 2841 call_helper.BeforeCall(masm);
2846 __ push(code_); 2842 __ push(code_);
2847 __ CallRuntime(Runtime::kCharFromCode, 1); 2843 __ CallRuntime(Runtime::kCharFromCode, 1);
2848 __ Move(result_, r0); 2844 __ Move(result_, r0);
2849 call_helper.AfterCall(masm); 2845 call_helper.AfterCall(masm);
2850 __ jmp(&exit_); 2846 __ jmp(&exit_);
2851 2847
2852 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 2848 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
2853 } 2849 }
2854 2850
2855 2851
2856 enum CopyCharactersFlags { 2852 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 };
2857 COPY_ASCII = 1,
2858 DEST_ALWAYS_ALIGNED = 2
2859 };
2860 2853
2861 2854
2862 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 2855 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
2863 Register dest, 2856 Register dest,
2864 Register src, 2857 Register src,
2865 Register count, 2858 Register count,
2866 Register scratch, 2859 Register scratch,
2867 String::Encoding encoding) { 2860 String::Encoding encoding) {
2868 if (FLAG_debug_code) { 2861 if (FLAG_debug_code) {
2869 // Check that destination is word aligned. 2862 // Check that destination is word aligned.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3010 // Allocate new sliced string. At this point we do not reload the instance 3003 // Allocate new sliced string. At this point we do not reload the instance
3011 // type including the string encoding because we simply rely on the info 3004 // type including the string encoding because we simply rely on the info
3012 // provided by the original string. It does not matter if the original 3005 // provided by the original string. It does not matter if the original
3013 // string's encoding is wrong because we always have to recheck encoding of 3006 // string's encoding is wrong because we always have to recheck encoding of
3014 // the newly created string's parent anyways due to externalized strings. 3007 // the newly created string's parent anyways due to externalized strings.
3015 Label two_byte_slice, set_slice_header; 3008 Label two_byte_slice, set_slice_header;
3016 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 3009 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
3017 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 3010 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
3018 __ tst(r1, Operand(kStringEncodingMask)); 3011 __ tst(r1, Operand(kStringEncodingMask));
3019 __ b(eq, &two_byte_slice); 3012 __ b(eq, &two_byte_slice);
3020 __ AllocateAsciiSlicedString(r0, r2, r6, r4, &runtime); 3013 __ AllocateOneByteSlicedString(r0, r2, r6, r4, &runtime);
3021 __ jmp(&set_slice_header); 3014 __ jmp(&set_slice_header);
3022 __ bind(&two_byte_slice); 3015 __ bind(&two_byte_slice);
3023 __ AllocateTwoByteSlicedString(r0, r2, r6, r4, &runtime); 3016 __ AllocateTwoByteSlicedString(r0, r2, r6, r4, &runtime);
3024 __ bind(&set_slice_header); 3017 __ bind(&set_slice_header);
3025 __ mov(r3, Operand(r3, LSL, 1)); 3018 __ mov(r3, Operand(r3, LSL, 1));
3026 __ str(r5, FieldMemOperand(r0, SlicedString::kParentOffset)); 3019 __ str(r5, FieldMemOperand(r0, SlicedString::kParentOffset));
3027 __ str(r3, FieldMemOperand(r0, SlicedString::kOffsetOffset)); 3020 __ str(r3, FieldMemOperand(r0, SlicedString::kOffsetOffset));
3028 __ jmp(&return_r0); 3021 __ jmp(&return_r0);
3029 3022
3030 __ bind(&copy_routine); 3023 __ bind(&copy_routine);
(...skipping 22 matching lines...) Expand all
3053 // Locate first character of underlying subject string. 3046 // Locate first character of underlying subject string.
3054 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 3047 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3055 __ add(r5, r5, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3048 __ add(r5, r5, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3056 3049
3057 __ bind(&allocate_result); 3050 __ bind(&allocate_result);
3058 // Sequential acii string. Allocate the result. 3051 // Sequential acii string. Allocate the result.
3059 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3052 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
3060 __ tst(r1, Operand(kStringEncodingMask)); 3053 __ tst(r1, Operand(kStringEncodingMask));
3061 __ b(eq, &two_byte_sequential); 3054 __ b(eq, &two_byte_sequential);
3062 3055
3063 // Allocate and copy the resulting ASCII string. 3056 // Allocate and copy the resulting one-byte string.
3064 __ AllocateAsciiString(r0, r2, r4, r6, r1, &runtime); 3057 __ AllocateOneByteString(r0, r2, r4, r6, r1, &runtime);
3065 3058
3066 // Locate first character of substring to copy. 3059 // Locate first character of substring to copy.
3067 __ add(r5, r5, r3); 3060 __ add(r5, r5, r3);
3068 // Locate first character of result. 3061 // Locate first character of result.
3069 __ add(r1, r0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3062 __ add(r1, r0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3070 3063
3071 // r0: result string 3064 // r0: result string
3072 // r1: first character of result string 3065 // r1: first character of result string
3073 // r2: result string length 3066 // r2: result string length
3074 // r5: first character of substring to copy 3067 // r5: first character of substring to copy
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3113 __ SmiTag(r3, r3); 3106 __ SmiTag(r3, r3);
3114 StringCharAtGenerator generator( 3107 StringCharAtGenerator generator(
3115 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 3108 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
3116 generator.GenerateFast(masm); 3109 generator.GenerateFast(masm);
3117 __ Drop(3); 3110 __ Drop(3);
3118 __ Ret(); 3111 __ Ret();
3119 generator.SkipSlow(masm, &runtime); 3112 generator.SkipSlow(masm, &runtime);
3120 } 3113 }
3121 3114
3122 3115
3123 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 3116 void StringHelper::GenerateFlatOneByteStringEquals(
3124 Register left, Register right, 3117 MacroAssembler* masm, Register left, Register right, Register scratch1,
3125 Register scratch1, 3118 Register scratch2, Register scratch3) {
3126 Register scratch2,
3127 Register scratch3) {
3128 Register length = scratch1; 3119 Register length = scratch1;
3129 3120
3130 // Compare lengths. 3121 // Compare lengths.
3131 Label strings_not_equal, check_zero_length; 3122 Label strings_not_equal, check_zero_length;
3132 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); 3123 __ ldr(length, FieldMemOperand(left, String::kLengthOffset));
3133 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3124 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
3134 __ cmp(length, scratch2); 3125 __ cmp(length, scratch2);
3135 __ b(eq, &check_zero_length); 3126 __ b(eq, &check_zero_length);
3136 __ bind(&strings_not_equal); 3127 __ bind(&strings_not_equal);
3137 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); 3128 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL)));
3138 __ Ret(); 3129 __ Ret();
3139 3130
3140 // Check if the length is zero. 3131 // Check if the length is zero.
3141 Label compare_chars; 3132 Label compare_chars;
3142 __ bind(&check_zero_length); 3133 __ bind(&check_zero_length);
3143 STATIC_ASSERT(kSmiTag == 0); 3134 STATIC_ASSERT(kSmiTag == 0);
3144 __ cmp(length, Operand::Zero()); 3135 __ cmp(length, Operand::Zero());
3145 __ b(ne, &compare_chars); 3136 __ b(ne, &compare_chars);
3146 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 3137 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
3147 __ Ret(); 3138 __ Ret();
3148 3139
3149 // Compare characters. 3140 // Compare characters.
3150 __ bind(&compare_chars); 3141 __ bind(&compare_chars);
3151 GenerateAsciiCharsCompareLoop(masm, 3142 GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
3152 left, right, length, scratch2, scratch3, 3143 &strings_not_equal);
3153 &strings_not_equal);
3154 3144
3155 // Characters are equal. 3145 // Characters are equal.
3156 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 3146 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
3157 __ Ret(); 3147 __ Ret();
3158 } 3148 }
3159 3149
3160 3150
3161 void StringHelper::GenerateCompareFlatAsciiStrings( 3151 void StringHelper::GenerateCompareFlatOneByteStrings(
3162 MacroAssembler* masm, Register left, Register right, Register scratch1, 3152 MacroAssembler* masm, Register left, Register right, Register scratch1,
3163 Register scratch2, Register scratch3, Register scratch4) { 3153 Register scratch2, Register scratch3, Register scratch4) {
3164 Label result_not_equal, compare_lengths; 3154 Label result_not_equal, compare_lengths;
3165 // Find minimum length and length difference. 3155 // Find minimum length and length difference.
3166 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); 3156 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
3167 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3157 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
3168 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); 3158 __ sub(scratch3, scratch1, Operand(scratch2), SetCC);
3169 Register length_delta = scratch3; 3159 Register length_delta = scratch3;
3170 __ mov(scratch1, scratch2, LeaveCC, gt); 3160 __ mov(scratch1, scratch2, LeaveCC, gt);
3171 Register min_length = scratch1; 3161 Register min_length = scratch1;
3172 STATIC_ASSERT(kSmiTag == 0); 3162 STATIC_ASSERT(kSmiTag == 0);
3173 __ cmp(min_length, Operand::Zero()); 3163 __ cmp(min_length, Operand::Zero());
3174 __ b(eq, &compare_lengths); 3164 __ b(eq, &compare_lengths);
3175 3165
3176 // Compare loop. 3166 // Compare loop.
3177 GenerateAsciiCharsCompareLoop(masm, 3167 GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
3178 left, right, min_length, scratch2, scratch4, 3168 scratch4, &result_not_equal);
3179 &result_not_equal);
3180 3169
3181 // Compare lengths - strings up to min-length are equal. 3170 // Compare lengths - strings up to min-length are equal.
3182 __ bind(&compare_lengths); 3171 __ bind(&compare_lengths);
3183 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0)); 3172 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
3184 // Use length_delta as result if it's zero. 3173 // Use length_delta as result if it's zero.
3185 __ mov(r0, Operand(length_delta), SetCC); 3174 __ mov(r0, Operand(length_delta), SetCC);
3186 __ bind(&result_not_equal); 3175 __ bind(&result_not_equal);
3187 // Conditionally update the result based either on length_delta or 3176 // Conditionally update the result based either on length_delta or
3188 // the last comparion performed in the loop above. 3177 // the last comparion performed in the loop above.
3189 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); 3178 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt);
3190 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); 3179 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt);
3191 __ Ret(); 3180 __ Ret();
3192 } 3181 }
3193 3182
3194 3183
3195 void StringHelper::GenerateAsciiCharsCompareLoop( 3184 void StringHelper::GenerateOneByteCharsCompareLoop(
3196 MacroAssembler* masm, Register left, Register right, Register length, 3185 MacroAssembler* masm, Register left, Register right, Register length,
3197 Register scratch1, Register scratch2, Label* chars_not_equal) { 3186 Register scratch1, Register scratch2, Label* chars_not_equal) {
3198 // Change index to run from -length to -1 by adding length to string 3187 // Change index to run from -length to -1 by adding length to string
3199 // start. This means that loop ends when index reaches zero, which 3188 // start. This means that loop ends when index reaches zero, which
3200 // doesn't need an additional compare. 3189 // doesn't need an additional compare.
3201 __ SmiUntag(length); 3190 __ SmiUntag(length);
3202 __ add(scratch1, length, 3191 __ add(scratch1, length,
3203 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3192 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3204 __ add(left, left, Operand(scratch1)); 3193 __ add(left, left, Operand(scratch1));
3205 __ add(right, right, Operand(scratch1)); 3194 __ add(right, right, Operand(scratch1));
(...skipping 27 matching lines...) Expand all
3233 __ b(ne, &not_same); 3222 __ b(ne, &not_same);
3234 STATIC_ASSERT(EQUAL == 0); 3223 STATIC_ASSERT(EQUAL == 0);
3235 STATIC_ASSERT(kSmiTag == 0); 3224 STATIC_ASSERT(kSmiTag == 0);
3236 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 3225 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
3237 __ IncrementCounter(counters->string_compare_native(), 1, r1, r2); 3226 __ IncrementCounter(counters->string_compare_native(), 1, r1, r2);
3238 __ add(sp, sp, Operand(2 * kPointerSize)); 3227 __ add(sp, sp, Operand(2 * kPointerSize));
3239 __ Ret(); 3228 __ Ret();
3240 3229
3241 __ bind(&not_same); 3230 __ bind(&not_same);
3242 3231
3243 // Check that both objects are sequential ASCII strings. 3232 // Check that both objects are sequential one-byte strings.
3244 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); 3233 __ JumpIfNotBothSequentialOneByteStrings(r1, r0, r2, r3, &runtime);
3245 3234
3246 // Compare flat ASCII strings natively. Remove arguments from stack first. 3235 // Compare flat one-byte strings natively. Remove arguments from stack first.
3247 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3); 3236 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3);
3248 __ add(sp, sp, Operand(2 * kPointerSize)); 3237 __ add(sp, sp, Operand(2 * kPointerSize));
3249 StringHelper::GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); 3238 StringHelper::GenerateCompareFlatOneByteStrings(masm, r1, r0, r2, r3, r4, r5);
3250 3239
3251 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 3240 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
3252 // tagged as a small integer. 3241 // tagged as a small integer.
3253 __ bind(&runtime); 3242 __ bind(&runtime);
3254 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3243 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3255 } 3244 }
3256 3245
3257 3246
3258 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3247 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3259 // ----------- S t a t e ------------- 3248 // ----------- S t a t e -------------
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
3505 DCHECK(GetCondition() == eq); 3494 DCHECK(GetCondition() == eq);
3506 STATIC_ASSERT(kInternalizedTag == 0); 3495 STATIC_ASSERT(kInternalizedTag == 0);
3507 __ orr(tmp3, tmp1, Operand(tmp2)); 3496 __ orr(tmp3, tmp1, Operand(tmp2));
3508 __ tst(tmp3, Operand(kIsNotInternalizedMask)); 3497 __ tst(tmp3, Operand(kIsNotInternalizedMask));
3509 // Make sure r0 is non-zero. At this point input operands are 3498 // Make sure r0 is non-zero. At this point input operands are
3510 // guaranteed to be non-zero. 3499 // guaranteed to be non-zero.
3511 DCHECK(right.is(r0)); 3500 DCHECK(right.is(r0));
3512 __ Ret(eq); 3501 __ Ret(eq);
3513 } 3502 }
3514 3503
3515 // Check that both strings are sequential ASCII. 3504 // Check that both strings are sequential one-byte.
3516 Label runtime; 3505 Label runtime;
3517 __ JumpIfBothInstanceTypesAreNotSequentialAscii( 3506 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
3518 tmp1, tmp2, tmp3, tmp4, &runtime); 3507 &runtime);
3519 3508
3520 // Compare flat ASCII strings. Returns when done. 3509 // Compare flat one-byte strings. Returns when done.
3521 if (equality) { 3510 if (equality) {
3522 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, 3511 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, tmp2,
3523 tmp3); 3512 tmp3);
3524 } else { 3513 } else {
3525 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, 3514 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1,
3526 tmp3, tmp4); 3515 tmp2, tmp3, tmp4);
3527 } 3516 }
3528 3517
3529 // Handle more complex cases in runtime. 3518 // Handle more complex cases in runtime.
3530 __ bind(&runtime); 3519 __ bind(&runtime);
3531 __ Push(left, right); 3520 __ Push(left, right);
3532 if (equality) { 3521 if (equality) {
3533 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3522 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3534 } else { 3523 } else {
3535 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3524 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3536 } 3525 }
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4655 MemOperand(fp, 6 * kPointerSize), 4644 MemOperand(fp, 6 * kPointerSize),
4656 NULL); 4645 NULL);
4657 } 4646 }
4658 4647
4659 4648
4660 #undef __ 4649 #undef __
4661 4650
4662 } } // namespace v8::internal 4651 } } // namespace v8::internal
4663 4652
4664 #endif // V8_TARGET_ARCH_ARM 4653 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | src/jsregexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698