Commit e832badd authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Simplify string copy in SubStringStub.

Port r21756 (3d58e58)

Original commit message:
The optimizations are unnecessary since the maximum
string length they operate on is currently 12.

BUG=352155
LOG=N
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/326413002

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21773 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 38d1b5c7
...@@ -3498,119 +3498,42 @@ enum CopyCharactersFlags { ...@@ -3498,119 +3498,42 @@ enum CopyCharactersFlags {
}; };
void StringHelper::GenerateCopyCharactersLong(MacroAssembler* masm, void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
Register dest, Register dest,
Register src, Register src,
Register count, Register count,
Register scratch1, Register scratch,
Register scratch2, String::Encoding encoding) {
Register scratch3, if (FLAG_debug_code) {
Register scratch4, // Check that destination is word aligned.
Register scratch5, __ And(scratch, dest, Operand(kPointerAlignmentMask));
int flags) {
bool ascii = (flags & COPY_ASCII) != 0;
bool dest_always_aligned = (flags & DEST_ALWAYS_ALIGNED) != 0;
if (dest_always_aligned && FLAG_debug_code) {
// Check that destination is actually word aligned if the flag says
// that it is.
__ And(scratch4, dest, Operand(kPointerAlignmentMask));
__ Check(eq, __ Check(eq,
kDestinationOfCopyNotAligned, kDestinationOfCopyNotAligned,
scratch4, scratch,
Operand(zero_reg)); Operand(zero_reg));
} }
const int kReadAlignment = 4;
const int kReadAlignmentMask = kReadAlignment - 1;
// Ensure that reading an entire aligned word containing the last character
// of a string will not read outside the allocated area (because we pad up
// to kObjectAlignment).
STATIC_ASSERT(kObjectAlignment >= kReadAlignment);
// Assumes word reads and writes are little endian. // Assumes word reads and writes are little endian.
// Nothing to do for zero characters. // Nothing to do for zero characters.
Label done; Label done;
if (!ascii) { if (encoding == String::TWO_BYTE_ENCODING) {
__ addu(count, count, count); __ Addu(count, count, count);
}
__ Branch(&done, eq, count, Operand(zero_reg));
Label byte_loop;
// Must copy at least eight bytes, otherwise just do it one byte at a time.
__ Subu(scratch1, count, Operand(8));
__ Addu(count, dest, Operand(count));
Register limit = count; // Read until src equals this.
__ Branch(&byte_loop, lt, scratch1, Operand(zero_reg));
if (!dest_always_aligned) {
// Align dest by byte copying. Copies between zero and three bytes.
__ And(scratch4, dest, Operand(kReadAlignmentMask));
Label dest_aligned;
__ Branch(&dest_aligned, eq, scratch4, Operand(zero_reg));
Label aligned_loop;
__ bind(&aligned_loop);
__ lbu(scratch1, MemOperand(src));
__ addiu(src, src, 1);
__ sb(scratch1, MemOperand(dest));
__ addiu(dest, dest, 1);
__ addiu(scratch4, scratch4, 1);
__ Branch(&aligned_loop, le, scratch4, Operand(kReadAlignmentMask));
__ bind(&dest_aligned);
} }
Label simple_loop; Register limit = count; // Read until dest equals this.
__ Addu(limit, dest, Operand(count));
__ And(scratch4, src, Operand(kReadAlignmentMask));
__ Branch(&simple_loop, eq, scratch4, Operand(zero_reg));
// Loop for src/dst that are not aligned the same way.
// This loop uses lwl and lwr instructions. These instructions
// depend on the endianness, and the implementation assumes little-endian.
{
Label loop;
__ bind(&loop);
if (kArchEndian == kBig) {
__ lwl(scratch1, MemOperand(src));
__ Addu(src, src, Operand(kReadAlignment));
__ lwr(scratch1, MemOperand(src, -1));
} else {
__ lwr(scratch1, MemOperand(src));
__ Addu(src, src, Operand(kReadAlignment));
__ lwl(scratch1, MemOperand(src, -1));
}
__ sw(scratch1, MemOperand(dest));
__ Addu(dest, dest, Operand(kReadAlignment));
__ Subu(scratch2, limit, dest);
__ Branch(&loop, ge, scratch2, Operand(kReadAlignment));
}
__ Branch(&byte_loop);
// Simple loop.
// Copy words from src to dest, until less than four bytes left.
// Both src and dest are word aligned.
__ bind(&simple_loop);
{
Label loop;
__ bind(&loop);
__ lw(scratch1, MemOperand(src));
__ Addu(src, src, Operand(kReadAlignment));
__ sw(scratch1, MemOperand(dest));
__ Addu(dest, dest, Operand(kReadAlignment));
__ Subu(scratch2, limit, dest);
__ Branch(&loop, ge, scratch2, Operand(kReadAlignment));
}
Label loop_entry, loop;
// Copy bytes from src to dest until dest hits limit. // Copy bytes from src to dest until dest hits limit.
__ bind(&byte_loop); __ Branch(&loop_entry);
// Test if dest has already reached the limit. __ bind(&loop);
__ Branch(&done, ge, dest, Operand(limit)); __ lbu(scratch, MemOperand(src));
__ lbu(scratch1, MemOperand(src)); __ Addu(src, src, Operand(1));
__ addiu(src, src, 1); __ sb(scratch, MemOperand(dest));
__ sb(scratch1, MemOperand(dest)); __ Addu(dest, dest, Operand(1));
__ addiu(dest, dest, 1); __ bind(&loop_entry);
__ Branch(&byte_loop); __ Branch(&loop, lt, dest, Operand(limit));
__ bind(&done); __ bind(&done);
} }
...@@ -3844,8 +3767,8 @@ void SubStringStub::Generate(MacroAssembler* masm) { ...@@ -3844,8 +3767,8 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// a2: result string length // a2: result string length
// t1: first character of substring to copy // t1: first character of substring to copy
STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
StringHelper::GenerateCopyCharactersLong( StringHelper::GenerateCopyCharacters(
masm, a1, t1, a2, a3, t0, t2, t3, t4, COPY_ASCII | DEST_ALWAYS_ALIGNED); masm, a1, t1, a2, a3, String::ONE_BYTE_ENCODING);
__ jmp(&return_v0); __ jmp(&return_v0);
// Allocate and copy the resulting two-byte string. // Allocate and copy the resulting two-byte string.
...@@ -3864,8 +3787,8 @@ void SubStringStub::Generate(MacroAssembler* masm) { ...@@ -3864,8 +3787,8 @@ void SubStringStub::Generate(MacroAssembler* masm) {
// a2: result length. // a2: result length.
// t1: first character of substring to copy. // t1: first character of substring to copy.
STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
StringHelper::GenerateCopyCharactersLong( StringHelper::GenerateCopyCharacters(
masm, a1, t1, a2, a3, t0, t2, t3, t4, DEST_ALWAYS_ALIGNED); masm, a1, t1, a2, a3, String::TWO_BYTE_ENCODING);
__ bind(&return_v0); __ bind(&return_v0);
Counters* counters = isolate()->counters(); Counters* counters = isolate()->counters();
......
...@@ -39,16 +39,12 @@ class StringHelper : public AllStatic { ...@@ -39,16 +39,12 @@ class StringHelper : public AllStatic {
// is allowed to spend extra time setting up conditions to make copying // is allowed to spend extra time setting up conditions to make copying
// faster. Copying of overlapping regions is not supported. // faster. Copying of overlapping regions is not supported.
// Dest register ends at the position after the last character written. // Dest register ends at the position after the last character written.
static void GenerateCopyCharactersLong(MacroAssembler* masm, static void GenerateCopyCharacters(MacroAssembler* masm,
Register dest, Register dest,
Register src, Register src,
Register count, Register count,
Register scratch1, Register scratch,
Register scratch2, String::Encoding encoding);
Register scratch3,
Register scratch4,
Register scratch5,
int flags);
// Generate string hash. // Generate string hash.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment