| 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 |