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_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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |