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

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

Issue 326943002: Simplify string copy in SubStringStub. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comment Created 6 years, 6 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
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_IA32 7 #if V8_TARGET_ARCH_IA32
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 3162 matching lines...) Expand 10 before | Expand all | Expand 10 after
3173 if (!result_.is(eax)) { 3173 if (!result_.is(eax)) {
3174 __ mov(result_, eax); 3174 __ mov(result_, eax);
3175 } 3175 }
3176 call_helper.AfterCall(masm); 3176 call_helper.AfterCall(masm);
3177 __ jmp(&exit_); 3177 __ jmp(&exit_);
3178 3178
3179 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 3179 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
3180 } 3180 }
3181 3181
3182 3182
3183 void StringHelper::GenerateCopyCharactersREP(MacroAssembler* masm, 3183 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
3184 Register dest, 3184 Register dest,
3185 Register src, 3185 Register src,
3186 Register count, 3186 Register count,
3187 Register scratch, 3187 Register scratch,
3188 bool ascii) { 3188 String::Encoding encoding) {
3189 // Copy characters using rep movs of doublewords.
3190 // The destination is aligned on a 4 byte boundary because we are
3191 // copying to the beginning of a newly allocated string.
3192 ASSERT(dest.is(edi)); // rep movs destination
3193 ASSERT(src.is(esi)); // rep movs source
3194 ASSERT(count.is(ecx)); // rep movs count
3195 ASSERT(!scratch.is(dest)); 3189 ASSERT(!scratch.is(dest));
3196 ASSERT(!scratch.is(src)); 3190 ASSERT(!scratch.is(src));
3197 ASSERT(!scratch.is(count)); 3191 ASSERT(!scratch.is(count));
3198 3192
3199 // Nothing to do for zero characters. 3193 // Nothing to do for zero characters.
3200 Label done; 3194 Label done;
3201 __ test(count, count); 3195 __ test(count, count);
3202 __ j(zero, &done); 3196 __ j(zero, &done);
3203 3197
3204 // Make count the number of bytes to copy. 3198 // Make count the number of bytes to copy.
3205 if (!ascii) { 3199 if (encoding == String::TWO_BYTE_ENCODING) {
3206 __ shl(count, 1); 3200 __ shl(count, 1);
3207 } 3201 }
3208 3202
3209 // Don't enter the rep movs if there are less than 4 bytes to copy.
3210 Label last_bytes;
3211 __ test(count, Immediate(~3));
3212 __ j(zero, &last_bytes, Label::kNear);
3213
3214 // Copy from edi to esi using rep movs instruction.
3215 __ mov(scratch, count);
3216 __ sar(count, 2); // Number of doublewords to copy.
3217 __ cld();
3218 __ rep_movs();
3219
3220 // Find number of bytes left.
3221 __ mov(count, scratch);
3222 __ and_(count, 3);
3223
3224 // Check if there are more bytes to copy.
3225 __ bind(&last_bytes);
3226 __ test(count, count);
3227 __ j(zero, &done);
3228
3229 // Copy remaining characters.
3230 Label loop; 3203 Label loop;
3231 __ bind(&loop); 3204 __ bind(&loop);
3232 __ mov_b(scratch, Operand(src, 0)); 3205 __ mov_b(scratch, Operand(src, 0));
3233 __ mov_b(Operand(dest, 0), scratch); 3206 __ mov_b(Operand(dest, 0), scratch);
3234 __ add(src, Immediate(1)); 3207 __ inc(src);
3235 __ add(dest, Immediate(1)); 3208 __ inc(dest);
3236 __ sub(count, Immediate(1)); 3209 __ dec(count);
3237 __ j(not_zero, &loop); 3210 __ j(not_zero, &loop);
3238 3211
3239 __ bind(&done); 3212 __ bind(&done);
3240 } 3213 }
3241 3214
3242 3215
3243 void StringHelper::GenerateHashInit(MacroAssembler* masm, 3216 void StringHelper::GenerateHashInit(MacroAssembler* masm,
3244 Register hash, 3217 Register hash,
3245 Register character, 3218 Register character,
3246 Register scratch) { 3219 Register scratch) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
3455 __ SmiUntag(ecx); 3428 __ SmiUntag(ecx);
3456 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3429 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
3457 __ test_b(ebx, kStringEncodingMask); 3430 __ test_b(ebx, kStringEncodingMask);
3458 __ j(zero, &two_byte_sequential); 3431 __ j(zero, &two_byte_sequential);
3459 3432
3460 // Sequential ASCII string. Allocate the result. 3433 // Sequential ASCII string. Allocate the result.
3461 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime_drop_two); 3434 __ AllocateAsciiString(eax, ecx, ebx, edx, edi, &runtime_drop_two);
3462 3435
3463 // eax: result string 3436 // eax: result string
3464 // ecx: result string length 3437 // ecx: result string length
3465 __ mov(edx, esi); // esi used by following code.
3466 // Locate first character of result. 3438 // Locate first character of result.
3467 __ mov(edi, eax); 3439 __ mov(edi, eax);
3468 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3440 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3469 // Load string argument and locate character of sub string start. 3441 // Load string argument and locate character of sub string start.
3470 __ pop(esi); 3442 __ pop(edx);
3471 __ pop(ebx); 3443 __ pop(ebx);
3472 __ SmiUntag(ebx); 3444 __ SmiUntag(ebx);
3473 __ lea(esi, FieldOperand(esi, ebx, times_1, SeqOneByteString::kHeaderSize)); 3445 __ lea(edx, FieldOperand(edx, ebx, times_1, SeqOneByteString::kHeaderSize));
3474 3446
3475 // eax: result string 3447 // eax: result string
3476 // ecx: result length 3448 // ecx: result length
3477 // edx: original value of esi
3478 // edi: first character of result 3449 // edi: first character of result
3479 // esi: character of sub string start 3450 // edx: character of sub string start
3480 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true); 3451 StringHelper::GenerateCopyCharacters(
3481 __ mov(esi, edx); // Restore esi. 3452 masm, edi, edx, ecx, ebx, String::ONE_BYTE_ENCODING);
3482 __ IncrementCounter(counters->sub_string_native(), 1); 3453 __ IncrementCounter(counters->sub_string_native(), 1);
3483 __ ret(3 * kPointerSize); 3454 __ ret(3 * kPointerSize);
3484 3455
3485 __ bind(&two_byte_sequential); 3456 __ bind(&two_byte_sequential);
3486 // Sequential two-byte string. Allocate the result. 3457 // Sequential two-byte string. Allocate the result.
3487 __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two); 3458 __ AllocateTwoByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two);
3488 3459
3489 // eax: result string 3460 // eax: result string
3490 // ecx: result string length 3461 // ecx: result string length
3491 __ mov(edx, esi); // esi used by following code.
3492 // Locate first character of result. 3462 // Locate first character of result.
3493 __ mov(edi, eax); 3463 __ mov(edi, eax);
3494 __ add(edi, 3464 __ add(edi,
3495 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 3465 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
3496 // Load string argument and locate character of sub string start. 3466 // Load string argument and locate character of sub string start.
3497 __ pop(esi); 3467 __ pop(edx);
3498 __ pop(ebx); 3468 __ pop(ebx);
3499 // As from is a smi it is 2 times the value which matches the size of a two 3469 // As from is a smi it is 2 times the value which matches the size of a two
3500 // byte character. 3470 // byte character.
3501 STATIC_ASSERT(kSmiTag == 0); 3471 STATIC_ASSERT(kSmiTag == 0);
3502 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 3472 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
3503 __ lea(esi, FieldOperand(esi, ebx, times_1, SeqTwoByteString::kHeaderSize)); 3473 __ lea(edx, FieldOperand(edx, ebx, times_1, SeqTwoByteString::kHeaderSize));
3504 3474
3505 // eax: result string 3475 // eax: result string
3506 // ecx: result length 3476 // ecx: result length
3507 // edx: original value of esi
3508 // edi: first character of result 3477 // edi: first character of result
3509 // esi: character of sub string start 3478 // edx: character of sub string start
3510 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false); 3479 StringHelper::GenerateCopyCharacters(
3511 __ mov(esi, edx); // Restore esi. 3480 masm, edi, edx, ecx, ebx, String::TWO_BYTE_ENCODING);
3512 __ IncrementCounter(counters->sub_string_native(), 1); 3481 __ IncrementCounter(counters->sub_string_native(), 1);
3513 __ ret(3 * kPointerSize); 3482 __ ret(3 * kPointerSize);
3514 3483
3515 // Drop pushed values on the stack before tail call. 3484 // Drop pushed values on the stack before tail call.
3516 __ bind(&runtime_drop_two); 3485 __ bind(&runtime_drop_two);
3517 __ Drop(2); 3486 __ Drop(2);
3518 3487
3519 // Just jump to runtime to create the sub string. 3488 // Just jump to runtime to create the sub string.
3520 __ bind(&runtime); 3489 __ bind(&runtime);
3521 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); 3490 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1);
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after
5106 Operand(ebp, 7 * kPointerSize), 5075 Operand(ebp, 7 * kPointerSize),
5107 NULL); 5076 NULL);
5108 } 5077 }
5109 5078
5110 5079
5111 #undef __ 5080 #undef __
5112 5081
5113 } } // namespace v8::internal 5082 } } // namespace v8::internal
5114 5083
5115 #endif // V8_TARGET_ARCH_IA32 5084 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698