Index: src/objects.cc |
=================================================================== |
--- src/objects.cc (revision 5077) |
+++ src/objects.cc (working copy) |
@@ -7338,6 +7338,46 @@ |
} |
+// Find entry for key otherwise return kNotFound. |
+int StringDictionary::FindEntry(String* key) { |
+ if (!key->IsSymbol()) { |
+ return HashTable<StringDictionaryShape, String*>::FindEntry(key); |
+ } |
+ |
+ // Optimized for symbol key. Knowledge of the key type allows: |
+ // 1. Move the check if the key is a symbol out of the loop. |
+ // 2. Avoid comparing hash codes in symbol to symbol comparision. |
+ // 3. Detect a case when a dictionary key is not a symbol but the key is. |
+ // In case of positive result the dictionary key may be replaced by |
+ // the symbol with minimal performance penalty. It gives a chance to |
+ // perform further lookups in code stubs (and significant performance boost |
+ // a certain style of code). |
+ |
+ // EnsureCapacity will guarantee the hash table is never full. |
+ uint32_t capacity = Capacity(); |
+ uint32_t entry = FirstProbe(key->Hash(), capacity); |
+ uint32_t count = 1; |
+ |
+ while (true) { |
+ int index = EntryToIndex(entry); |
+ Object* element = get(index); |
+ if (element->IsUndefined()) break; // Empty entry. |
+ if (key == element) return entry; |
+ if (!element->IsSymbol() && |
+ !element->IsNull() && |
+ String::cast(element)->Equals(key)) { |
+ // Replace a non-symbol key by the equivalent symbol for faster further |
+ // lookups. |
+ set(index, key); |
+ return entry; |
+ } |
+ ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
+ entry = NextProbe(entry, count++, capacity); |
+ } |
+ return kNotFound; |
+} |
+ |
+ |
template<typename Shape, typename Key> |
Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
int capacity = Capacity(); |