Chromium Code Reviews| Index: src/objects.cc |
| =================================================================== |
| --- src/objects.cc (revision 7898) |
| +++ src/objects.cc (working copy) |
| @@ -5467,8 +5467,16 @@ |
| bool String::IsAsciiEqualTo(Vector<const char> str) { |
| int slen = length(); |
| if (str.length() != slen) return false; |
| - for (int i = 0; i < slen; i++) { |
| - if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
| + if (this->IsSeqAsciiString()) { |
| + SeqAsciiString* seq = SeqAsciiString::cast(this); |
| + char* ch = seq->GetChars(); |
| + for (int i = 0; i < slen; i++, ch++) { |
| + if (*ch != str[i]) return false; |
| + } |
| + } else { |
| + for (int i = 0; i < slen; i++) { |
| + if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
|
Lasse Reichstein
2011/05/19 07:27:40
Potentially unnecessarily slow for deeply nested c
Rico
2011/05/23 18:18:12
This is the existing version, so I will leave as i
|
| + } |
| } |
| return true; |
| } |
| @@ -8696,6 +8704,71 @@ |
| }; |
| +class SubStringAsciiSymbolKey : public HashTableKey { |
| + public: |
| + explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, |
| + int from, |
| + int length) |
| + : string_(string), from_(from), length_(length) { } |
| + |
| + uint32_t Hash() { |
| + ASSERT(length_ >= 0); |
| + ASSERT(from_ + length_ <= string_->length()); |
| + StringHasher hasher(length_); |
| + |
| + // Very long strings have a trivial hash that doesn't inspect the |
| + // string contents. |
| + if (hasher.has_trivial_hash()) { |
| + hash_field_ = hasher.GetHashField(); |
| + } else { |
| + int i = 0; |
| + // Do the iterative array index computation as long as there is a |
| + // chance this is an array index. |
| + while (i < length_ && hasher.is_array_index()) { |
| + hasher.AddCharacter(static_cast<uc32>( |
| + string_->SeqAsciiStringGet(i + from_))); |
| + i++; |
| + } |
| + |
| + // Process the remaining characters without updating the array |
| + // index. |
| + while (i < length_) { |
| + hasher.AddCharacterNoIndex(static_cast<uc32>( |
| + string_->SeqAsciiStringGet(i + from_))); |
| + i++; |
| + } |
| + hash_field_ = hasher.GetHashField(); |
| + } |
| + |
| + uint32_t result = hash_field_ >> String::kHashShift; |
| + ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| + return result; |
| + } |
| + |
| + |
| + uint32_t HashForObject(Object* other) { |
| + return String::cast(other)->Hash(); |
| + } |
| + |
| + bool IsMatch(Object* string) { |
| + Vector<const char> chars(string_->GetChars() + from_, length_); |
| + return String::cast(string)->IsAsciiEqualTo(chars); |
| + } |
| + |
| + MaybeObject* AsObject() { |
| + if (hash_field_ == 0) Hash(); |
| + Vector<const char> chars(string_->GetChars() + from_, length_); |
| + return HEAP->AllocateAsciiSymbol(chars, hash_field_); |
| + } |
| + |
| + private: |
| + Handle<SeqAsciiString> string_; |
| + int from_; |
| + int length_; |
| + uint32_t hash_field_; |
| +}; |
| + |
| + |
| class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
| public: |
| explicit TwoByteSymbolKey(Vector<const uc16> str) |
| @@ -9490,6 +9563,15 @@ |
| } |
| +MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, |
| + int from, |
| + int length, |
| + Object** s) { |
| + SubStringAsciiSymbolKey key(str, from, length); |
| + return LookupKey(&key, s); |
| +} |
| + |
| + |
| MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
| Object** s) { |
| TwoByteSymbolKey key(str); |