OLD | NEW |
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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 2837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2848 if (!result_.is(eax)) { | 2848 if (!result_.is(eax)) { |
2849 __ mov(result_, eax); | 2849 __ mov(result_, eax); |
2850 } | 2850 } |
2851 call_helper.AfterCall(masm); | 2851 call_helper.AfterCall(masm); |
2852 __ jmp(&exit_); | 2852 __ jmp(&exit_); |
2853 | 2853 |
2854 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); | 2854 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); |
2855 } | 2855 } |
2856 | 2856 |
2857 | 2857 |
2858 void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm, | 2858 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, |
2859 Register dest, | 2859 Register dest, |
2860 Register src, | 2860 Register src, |
2861 Register count, | 2861 Register count, |
2862 Register scratch, | 2862 Register scratch, |
2863 bool ascii) { | 2863 String::Encoding encoding) { |
2864 // Copy characters using rep movs of doublewords. | |
2865 // The destination is aligned on a 4 byte boundary because we are | |
2866 // copying to the beginning of a newly allocated string. | |
2867 ASSERT(dest.is(edi)); // rep movs destination | |
2868 ASSERT(src.is(esi)); // rep movs source | |
2869 ASSERT(count.is(ecx)); // rep movs count | |
2870 ASSERT(!scratch.is(dest)); | 2864 ASSERT(!scratch.is(dest)); |
2871 ASSERT(!scratch.is(src)); | 2865 ASSERT(!scratch.is(src)); |
2872 ASSERT(!scratch.is(count)); | 2866 ASSERT(!scratch.is(count)); |
2873 | 2867 |
2874 // Nothing to do for zero characters. | 2868 // Nothing to do for zero characters. |
2875 Label done; | 2869 Label done; |
2876 __ test(count, count); | 2870 __ test(count, count); |
2877 __ j(zero, &done); | 2871 __ j(zero, &done); |
2878 | 2872 |
2879 // Make count the number of bytes to copy. | 2873 // Make count the number of bytes to copy. |
2880 if (!ascii) { | 2874 if (encoding == String::TWO_BYTE_ENCODING) { |
2881 __ shl(count, 1); | 2875 __ shl(count, 1); |
2882 } | 2876 } |
2883 | 2877 |
2884 // Don't enter the rep movs if there are less than 4 bytes to copy. | |
2885 Label last_bytes; | |
2886 __ test(count, Immediate(~3)); | |
2887 __ j(zero, &last_bytes, Label::kNear); | |
2888 | |
2889 // Copy from edi to esi using rep movs instruction. | |
2890 __ mov(scratch, count); | |
2891 __ sar(count, 2); // Number of doublewords to copy. | |
2892 __ cld(); | |
2893 __ rep_movs(); | |
2894 | |
2895 // Find number of bytes left. | |
2896 __ mov(count, scratch); | |
2897 __ and_(count, 3); | |
2898 | |
2899 // Check if there are more bytes to copy. | |
2900 __ bind(&last_bytes); | |
2901 __ test(count, count); | |
2902 __ j(zero, &done); | |
2903 | |
2904 // Copy remaining characters. | |
2905 Label loop; | 2878 Label loop; |
2906 __ bind(&loop); | 2879 __ bind(&loop); |
2907 __ mov_b(scratch, Operand(src, 0)); | 2880 __ mov_b(scratch, Operand(src, 0)); |
2908 __ mov_b(Operand(dest, 0), scratch); | 2881 __ mov_b(Operand(dest, 0), scratch); |
2909 __ add(src, Immediate(1)); | 2882 __ inc(src); |
2910 __ add(dest, Immediate(1)); | 2883 __ inc(dest); |
2911 __ sub(count, Immediate(1)); | 2884 __ dec(count); |
2912 __ j(not_zero, &loop); | 2885 __ j(not_zero, &loop); |
2913 | 2886 |
2914 __ bind(&done); | 2887 __ bind(&done); |
2915 } | 2888 } |
2916 | 2889 |
2917 | 2890 |
2918 void StringHelper::GenerateHashInit(MacroAssembler* masm, | 2891 void StringHelper::GenerateHashInit(MacroAssembler* masm, |
2919 Register hash, | 2892 Register hash, |
2920 Register character, | 2893 Register character, |
2921 Register scratch) { | 2894 Register scratch) { |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3130 __ SmiUntag(ecx); | 3103 __ SmiUntag(ecx); |
3131 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); | 3104 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); |
3132 __ test_b(ebx, kStringEncodingMask); | 3105 __ test_b(ebx, kStringEncodingMask); |
3133 __ j(zero, &two_byte_sequential); | 3106 __ j(zero, &two_byte_sequential); |
3134 | 3107 |
3135 // Sequential ASCII string. Allocate the result. | 3108 // Sequential ASCII string. Allocate the result. |
3136 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime_drop_two); | 3109 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime_drop_two); |
3137 | 3110 |
3138 // eax: result string | 3111 // eax: result string |
3139 // ecx: result string length | 3112 // ecx: result string length |
3140 __ mov(edx, esi); // esi used by following code. | |
3141 // Locate first character of result. | 3113 // Locate first character of result. |
3142 __ mov(edi, eax); | 3114 __ mov(edi, eax); |
3143 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3115 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
3144 // Load string argument and locate character of sub string start. | 3116 // Load string argument and locate character of sub string start. |
3145 __ pop(esi); | 3117 __ pop(edx); |
3146 __ pop(ebx); | 3118 __ pop(ebx); |
3147 __ SmiUntag(ebx); | 3119 __ SmiUntag(ebx); |
3148 __ lea(esi, FieldOperand(esi, ebx, times_1, SeqOneByteString::kHeaderSize)); | 3120 __ lea(edx, FieldOperand(edx, ebx, times_1, SeqOneByteString::kHeaderSize)); |
3149 | 3121 |
3150 // eax: result string | 3122 // eax: result string |
3151 // ecx: result length | 3123 // ecx: result length |
3152 // edx: original value of esi | |
3153 // edi: first character of result | 3124 // edi: first character of result |
3154 // esi: character of sub string start | 3125 // edx: character of sub string start |
3155 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true); | 3126 StringHelper::GenerateCopyCharacters( |
3156 __ mov(esi, edx); // Restore esi. | 3127 masm, edi, edx, ecx, ebx, String::ONE_BYTE_ENCODING); |
3157 __ IncrementCounter(counters->sub_string_native(), 1); | 3128 __ IncrementCounter(counters->sub_string_native(), 1); |
3158 __ ret(3 * kPointerSize); | 3129 __ ret(3 * kPointerSize); |
3159 | 3130 |
3160 __ bind(&two_byte_sequential); | 3131 __ bind(&two_byte_sequential); |
3161 // Sequential two-byte string. Allocate the result. | 3132 // Sequential two-byte string. Allocate the result. |
3162 __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two); | 3133 __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two); |
3163 | 3134 |
3164 // eax: result string | 3135 // eax: result string |
3165 // ecx: result string length | 3136 // ecx: result string length |
3166 __ mov(edx, esi); // esi used by following code. | |
3167 // Locate first character of result. | 3137 // Locate first character of result. |
3168 __ mov(edi, eax); | 3138 __ mov(edi, eax); |
3169 __ add(edi, | 3139 __ add(edi, |
3170 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 3140 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
3171 // Load string argument and locate character of sub string start. | 3141 // Load string argument and locate character of sub string start. |
3172 __ pop(esi); | 3142 __ pop(edx); |
3173 __ pop(ebx); | 3143 __ pop(ebx); |
3174 // As from is a smi it is 2 times the value which matches the size of a two | 3144 // As from is a smi it is 2 times the value which matches the size of a two |
3175 // byte character. | 3145 // byte character. |
3176 STATIC_ASSERT(kSmiTag == 0); | 3146 STATIC_ASSERT(kSmiTag == 0); |
3177 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); | 3147 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); |
3178 __ lea(esi, FieldOperand(esi, ebx, times_1, SeqTwoByteString::kHeaderSize)); | 3148 __ lea(edx, FieldOperand(edx, ebx, times_1, SeqTwoByteString::kHeaderSize)); |
3179 | 3149 |
3180 // eax: result string | 3150 // eax: result string |
3181 // ecx: result length | 3151 // ecx: result length |
3182 // edx: original value of esi | |
3183 // edi: first character of result | 3152 // edi: first character of result |
3184 // esi: character of sub string start | 3153 // edx: character of sub string start |
3185 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false); | 3154 StringHelper::GenerateCopyCharacters( |
3186 __ mov(esi, edx); // Restore esi. | 3155 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING); |
3187 __ IncrementCounter(counters->sub_string_native(), 1); | 3156 __ IncrementCounter(counters->sub_string_native(), 1); |
3188 __ ret(3 * kPointerSize); | 3157 __ ret(3 * kPointerSize); |
3189 | 3158 |
3190 // Drop pushed values on the stack before tail call. | 3159 // Drop pushed values on the stack before tail call. |
3191 __ bind(&runtime_drop_two); | 3160 __ bind(&runtime_drop_two); |
3192 __ Drop(2); | 3161 __ Drop(2); |
3193 | 3162 |
3194 // Just jump to runtime to create the sub string. | 3163 // Just jump to runtime to create the sub string. |
3195 __ bind(&runtime); | 3164 __ bind(&runtime); |
3196 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); | 3165 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); |
(...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4746 Operand(ebp, 7 * kPointerSize), | 4715 Operand(ebp, 7 * kPointerSize), |
4747 NULL); | 4716 NULL); |
4748 } | 4717 } |
4749 | 4718 |
4750 | 4719 |
4751 #undef __ | 4720 #undef __ |
4752 | 4721 |
4753 } } // namespace v8::internal | 4722 } } // namespace v8::internal |
4754 | 4723 |
4755 #endif // V8_TARGET_ARCH_X87 | 4724 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |