Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index a1fbc9927701388f1f2300847c3b33fc7d52e1b5..02ea5b0455deee01a3c2fe33d7f476fd3bb562ec 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -4660,13 +4660,38 @@ bool String::IsEqualTo(Vector<const char> str) { |
} |
+template <typename schar> |
+static inline uint32_t HashSequentialString(const schar* chars, int length) { |
+ StringHasher hasher(length); |
+ if (!hasher.has_trivial_hash()) { |
+ int i; |
+ for (i = 0; hasher.is_array_index() && (i < length); i++) { |
+ hasher.AddCharacter(chars[i]); |
+ } |
+ for (; i < length; i++) { |
+ hasher.AddCharacterNoIndex(chars[i]); |
+ } |
+ } |
+ return hasher.GetHashField(); |
+} |
+ |
+ |
uint32_t String::ComputeAndSetHash() { |
// Should only be called if hash code has not yet been computed. |
ASSERT(!(hash_field() & kHashComputedMask)); |
+ const int len = length(); |
+ |
// Compute the hash code. |
- StringInputBuffer buffer(this); |
- uint32_t field = ComputeHashField(&buffer, length()); |
+ uint32_t field = 0; |
+ if (StringShape(this).IsSequentialAscii()) { |
+ field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); |
+ } else if (StringShape(this).IsSequentialTwoByte()) { |
+ field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len); |
+ } else { |
+ StringInputBuffer buffer(this); |
+ field = ComputeHashField(&buffer, len); |
+ } |
// Store the hash code in the object. |
set_hash_field(field); |