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; |
+ } |
} |
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); |