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

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

Issue 326413002: MIPS: Simplify string copy in SubStringStub. (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: 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
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | no next file » | 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_MIPS 7 #if V8_TARGET_ARCH_MIPS
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 3480 matching lines...) Expand 10 before | Expand all | Expand 10 after
3491 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 3491 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
3492 } 3492 }
3493 3493
3494 3494
3495 enum CopyCharactersFlags { 3495 enum CopyCharactersFlags {
3496 COPY_ASCII = 1, 3496 COPY_ASCII = 1,
3497 DEST_ALWAYS_ALIGNED = 2 3497 DEST_ALWAYS_ALIGNED = 2
3498 }; 3498 };
3499 3499
3500 3500
3501 void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm, 3501 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
3502 Register dest, 3502 Register dest,
3503 Register src, 3503 Register src,
3504 Register count, 3504 Register count,
3505 Register scratch1, 3505 Register scratch,
3506 Register scratch2, 3506 String::Encoding encoding) {
3507 Register scratch3, 3507 if (FLAG_debug_code) {
3508 Register scratch4, 3508 // Check that destination is word aligned.
3509 Register scratch5, 3509 __ And(scratch, dest, Operand(kPointerAlignmentMask));
3510 int flags) {
3511 bool ascii = (flags & COPY_ASCII) != 0;
3512 bool dest_always_aligned = (flags & DEST_ALWAYS_ALIGNED) != 0;
3513
3514 if (dest_always_aligned && FLAG_debug_code) {
3515 // Check that destination is actually word aligned if the flag says
3516 // that it is.
3517 __ And(scratch4, dest, Operand(kPointerAlignmentMask));
3518 __ Check(eq, 3510 __ Check(eq,
3519 kDestinationOfCopyNotAligned, 3511 kDestinationOfCopyNotAligned,
3520 scratch4, 3512 scratch,
3521 Operand(zero_reg)); 3513 Operand(zero_reg));
3522 } 3514 }
3523 3515
3524 const int kReadAlignment = 4;
3525 const int kReadAlignmentMask = kReadAlignment - 1;
3526 // Ensure that reading an entire aligned word containing the last character
3527 // of a string will not read outside the allocated area (because we pad up
3528 // to kObjectAlignment).
3529 STATIC_ASSERT(kObjectAlignment >= kReadAlignment);
3530 // Assumes word reads and writes are little endian. 3516 // Assumes word reads and writes are little endian.
3531 // Nothing to do for zero characters. 3517 // Nothing to do for zero characters.
3532 Label done; 3518 Label done;
3533 3519
3534 if (!ascii) { 3520 if (encoding == String::TWO_BYTE_ENCODING) {
3535 __ addu(count, count, count); 3521 __ Addu(count, count, count);
3536 }
3537 __ Branch(&done, eq, count, Operand(zero_reg));
3538
3539 Label byte_loop;
3540 // Must copy at least eight bytes, otherwise just do it one byte at a time.
3541 __ Subu(scratch1, count, Operand(8));
3542 __ Addu(count, dest, Operand(count));
3543 Register limit = count; // Read until src equals this.
3544 __ Branch(&byte_loop, lt, scratch1, Operand(zero_reg));
3545
3546 if (!dest_always_aligned) {
3547 // Align dest by byte copying. Copies between zero and three bytes.
3548 __ And(scratch4, dest, Operand(kReadAlignmentMask));
3549 Label dest_aligned;
3550 __ Branch(&dest_aligned, eq, scratch4, Operand(zero_reg));
3551 Label aligned_loop;
3552 __ bind(&aligned_loop);
3553 __ lbu(scratch1, MemOperand(src));
3554 __ addiu(src, src, 1);
3555 __ sb(scratch1, MemOperand(dest));
3556 __ addiu(dest, dest, 1);
3557 __ addiu(scratch4, scratch4, 1);
3558 __ Branch(&aligned_loop, le, scratch4, Operand(kReadAlignmentMask));
3559 __ bind(&dest_aligned);
3560 } 3522 }
3561 3523
3562 Label simple_loop; 3524 Register limit = count; // Read until dest equals this.
3525 __ Addu(limit, dest, Operand(count));
3563 3526
3564 __ And(scratch4, src, Operand(kReadAlignmentMask)); 3527 Label loop_entry, loop;
3565 __ Branch(&simple_loop, eq, scratch4, Operand(zero_reg));
3566
3567 // Loop for src/dst that are not aligned the same way.
3568 // This loop uses lwl and lwr instructions. These instructions
3569 // depend on the endianness, and the implementation assumes little-endian.
3570 {
3571 Label loop;
3572 __ bind(&loop);
3573 if (kArchEndian == kBig) {
3574 __ lwl(scratch1, MemOperand(src));
3575 __ Addu(src, src, Operand(kReadAlignment));
3576 __ lwr(scratch1, MemOperand(src, -1));
3577 } else {
3578 __ lwr(scratch1, MemOperand(src));
3579 __ Addu(src, src, Operand(kReadAlignment));
3580 __ lwl(scratch1, MemOperand(src, -1));
3581 }
3582 __ sw(scratch1, MemOperand(dest));
3583 __ Addu(dest, dest, Operand(kReadAlignment));
3584 __ Subu(scratch2, limit, dest);
3585 __ Branch(&loop, ge, scratch2, Operand(kReadAlignment));
3586 }
3587
3588 __ Branch(&byte_loop);
3589
3590 // Simple loop.
3591 // Copy words from src to dest, until less than four bytes left.
3592 // Both src and dest are word aligned.
3593 __ bind(&simple_loop);
3594 {
3595 Label loop;
3596 __ bind(&loop);
3597 __ lw(scratch1, MemOperand(src));
3598 __ Addu(src, src, Operand(kReadAlignment));
3599 __ sw(scratch1, MemOperand(dest));
3600 __ Addu(dest, dest, Operand(kReadAlignment));
3601 __ Subu(scratch2, limit, dest);
3602 __ Branch(&loop, ge, scratch2, Operand(kReadAlignment));
3603 }
3604
3605 // Copy bytes from src to dest until dest hits limit. 3528 // Copy bytes from src to dest until dest hits limit.
3606 __ bind(&byte_loop); 3529 __ Branch(&loop_entry);
3607 // Test if dest has already reached the limit. 3530 __ bind(&loop);
3608 __ Branch(&done, ge, dest, Operand(limit)); 3531 __ lbu(scratch, MemOperand(src));
3609 __ lbu(scratch1, MemOperand(src)); 3532 __ Addu(src, src, Operand(1));
3610 __ addiu(src, src, 1); 3533 __ sb(scratch, MemOperand(dest));
3611 __ sb(scratch1, MemOperand(dest)); 3534 __ Addu(dest, dest, Operand(1));
3612 __ addiu(dest, dest, 1); 3535 __ bind(&loop_entry);
3613 __ Branch(&byte_loop); 3536 __ Branch(&loop, lt, dest, Operand(limit));
3614 3537
3615 __ bind(&done); 3538 __ bind(&done);
3616 } 3539 }
3617 3540
3618 3541
3619 void StringHelper::GenerateHashInit(MacroAssembler* masm, 3542 void StringHelper::GenerateHashInit(MacroAssembler* masm,
3620 Register hash, 3543 Register hash,
3621 Register character) { 3544 Register character) {
3622 // hash = seed + character + ((seed + character) << 10); 3545 // hash = seed + character + ((seed + character) << 10);
3623 __ LoadRoot(hash, Heap::kHashSeedRootIndex); 3546 __ LoadRoot(hash, Heap::kHashSeedRootIndex);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
3837 __ Addu(t1, t1, a3); 3760 __ Addu(t1, t1, a3);
3838 3761
3839 // Locate first character of result. 3762 // Locate first character of result.
3840 __ Addu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3763 __ Addu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3841 3764
3842 // v0: result string 3765 // v0: result string
3843 // a1: first character of result string 3766 // a1: first character of result string
3844 // a2: result string length 3767 // a2: result string length
3845 // t1: first character of substring to copy 3768 // t1: first character of substring to copy
3846 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); 3769 STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3847 StringHelper::GenerateCopyCharactersLong( 3770 StringHelper::GenerateCopyCharacters(
3848 masm, a1, t1, a2, a3, t0, t2, t3, t4, COPY_ASCII | DEST_ALWAYS_ALIGNED); 3771 masm, a1, t1, a2, a3, String::ONE_BYTE_ENCODING);
3849 __ jmp(&return_v0); 3772 __ jmp(&return_v0);
3850 3773
3851 // Allocate and copy the resulting two-byte string. 3774 // Allocate and copy the resulting two-byte string.
3852 __ bind(&two_byte_sequential); 3775 __ bind(&two_byte_sequential);
3853 __ AllocateTwoByteString(v0, a2, t0, t2, t3, &runtime); 3776 __ AllocateTwoByteString(v0, a2, t0, t2, t3, &runtime);
3854 3777
3855 // Locate first character of substring to copy. 3778 // Locate first character of substring to copy.
3856 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 3779 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
3857 __ sll(t0, a3, 1); 3780 __ sll(t0, a3, 1);
3858 __ Addu(t1, t1, t0); 3781 __ Addu(t1, t1, t0);
3859 // Locate first character of result. 3782 // Locate first character of result.
3860 __ Addu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 3783 __ Addu(a1, v0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
3861 3784
3862 // v0: result string. 3785 // v0: result string.
3863 // a1: first character of result. 3786 // a1: first character of result.
3864 // a2: result length. 3787 // a2: result length.
3865 // t1: first character of substring to copy. 3788 // t1: first character of substring to copy.
3866 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 3789 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
3867 StringHelper::GenerateCopyCharactersLong( 3790 StringHelper::GenerateCopyCharacters(
3868 masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED); 3791 masm, a1, t1, a2, a3, String::TWO_BYTE_ENCODING);
3869 3792
3870 __ bind(&return_v0); 3793 __ bind(&return_v0);
3871 Counters* counters = isolate()->counters(); 3794 Counters* counters = isolate()->counters();
3872 __ IncrementCounter(counters->sub_string_native(), 1, a3, t0); 3795 __ IncrementCounter(counters->sub_string_native(), 1, a3, t0);
3873 __ DropAndRet(3); 3796 __ DropAndRet(3);
3874 3797
3875 // Just jump to runtime to create the sub string. 3798 // Just jump to runtime to create the sub string.
3876 __ bind(&runtime); 3799 __ bind(&runtime);
3877 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1); 3800 __ TailCallRuntime(Runtime::kHiddenSubString, 3, 1);
3878 3801
(...skipping 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after
5474 MemOperand(fp, 6 * kPointerSize), 5397 MemOperand(fp, 6 * kPointerSize),
5475 NULL); 5398 NULL);
5476 } 5399 }
5477 5400
5478 5401
5479 #undef __ 5402 #undef __
5480 5403
5481 } } // namespace v8::internal 5404 } } // namespace v8::internal
5482 5405
5483 #endif // V8_TARGET_ARCH_MIPS 5406 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698