Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index bfcedb262e711a3678302e8508ec114ddf2857bd..b286c7a1763a11afeca2ab75c7e04eb2601ad6c1 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -3646,6 +3646,33 @@ static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) { |
| } |
| +// Compares the contents of two strings by reading and comparing |
| +// int-sized blocks of characters. |
| +template <typename Char> |
| +static inline bool CompareRawStringContents(Vector<Char> a, Vector<Char> b) { |
|
bak
2008/10/20 10:50:42
How about an assert checking a.length() == b.lengt
|
| + // Lint complains about taking sizeof a type rather than a variable. |
| + // That's just idiotic in this case so I'm turning it off here. |
| + const int kStepSize = sizeof(int) / sizeof(Char); // NOLINT |
| + int length = a.length(); |
| + int endpoint = length - kStepSize; |
| + const Char* pa = a.start(); |
| + const Char* pb = b.start(); |
| + int i; |
| + // Compare blocks until we reach near the end of the string. |
| + for (i = 0; i <= endpoint; i += kStepSize) { |
|
Erik Corry
2008/10/20 09:40:04
If length = 3 then endpoint = 1, so we get into th
Christian Plesner Hansen
2008/10/20 09:52:09
If sizeof(Char) is 2 then endpoint is indeed 1 but
|
| + uint32_t wa = *reinterpret_cast<const uint32_t*>(pa + i); |
| + uint32_t wb = *reinterpret_cast<const uint32_t*>(pb + i); |
| + if (wa != wb) |
|
bak
2008/10/20 10:50:42
Move return false to previous line or add {}.
|
| + return false; |
| + } |
| + // Compare the remaining characters that didn't fit into a block. |
| + for (; i < length; i++) |
|
bak
2008/10/20 10:50:42
Missing {}
|
| + if (a[i] != b[i]) |
| + return false; |
| + return true; |
| +} |
| + |
| + |
| static StringInputBuffer string_compare_buffer_b; |
| @@ -3681,13 +3708,46 @@ bool String::SlowEquals(String* other) { |
| if (Hash() != other->Hash()) return false; |
| } |
| + if (this->IsSeqAsciiString() && other->IsSeqAsciiString()) { |
| + const char* str1 = SeqAsciiString::cast(this)->GetChars(); |
| + const char* str2 = SeqAsciiString::cast(other)->GetChars(); |
| + return CompareRawStringContents(Vector<const char>(str1, len), |
| + Vector<const char>(str2, len)); |
| + } |
| + |
| if (this->IsFlat()) { |
| if (this->IsAsciiRepresentation()) { |
| - VectorIterator<char> buf1(this->ToAsciiVector()); |
| - return CompareStringContentsPartial(&buf1, other); |
| + Vector<const char> vec1 = this->ToAsciiVector(); |
| + if (other->IsFlat()) { |
| + if (other->IsAsciiRepresentation()) { |
| + Vector<const char> vec2 = other->ToAsciiVector(); |
| + return CompareRawStringContents(vec1, vec2); |
| + } else { |
| + VectorIterator<char> buf1(vec1); |
| + VectorIterator<uc16> ib(other->ToUC16Vector()); |
| + return CompareStringContents(&buf1, &ib); |
| + } |
| + } else { |
| + VectorIterator<char> buf1(vec1); |
| + string_compare_buffer_b.Reset(0, other); |
| + return CompareStringContents(&buf1, &string_compare_buffer_b); |
| + } |
| } else { |
| - VectorIterator<uc16> buf1(this->ToUC16Vector()); |
| - return CompareStringContentsPartial(&buf1, other); |
| + Vector<const uc16> vec1 = this->ToUC16Vector(); |
| + if (other->IsFlat()) { |
| + if (other->IsAsciiRepresentation()) { |
| + VectorIterator<uc16> buf1(vec1); |
| + VectorIterator<char> ib(other->ToAsciiVector()); |
| + return CompareStringContents(&buf1, &ib); |
| + } else { |
| + Vector<const uc16> vec2(other->ToUC16Vector()); |
| + return CompareRawStringContents(vec1, vec2); |
| + } |
| + } else { |
| + VectorIterator<uc16> buf1(vec1); |
| + string_compare_buffer_b.Reset(0, other); |
| + return CompareStringContents(&buf1, &string_compare_buffer_b); |
| + } |
| } |
| } else { |
| string_compare_buffer_a.Reset(0, this); |