From 931bf1d63d7dc7ddea89ccd86fad3885df18152f Mon Sep 17 00:00:00 2001 From: "serya@chromium.org" Date: Fri, 16 Jul 2010 10:07:57 +0000 Subject: [PATCH] StringDictionary::FindEntry optimized for symbol strings. Review URL: http://codereview.chromium.org/3020003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5086 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/objects.h | 6 +++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/objects.cc b/src/objects.cc index d9efe6cea7..8f668fb3b1 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -7338,6 +7338,46 @@ int HashTable::FindEntry(Key key) { } +// Find entry for key otherwise return kNotFound. +int StringDictionary::FindEntry(String* key) { + if (!key->IsSymbol()) { + return HashTable::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 Object* HashTable::EnsureCapacity(int n, Key key) { int capacity = Capacity(); diff --git a/src/objects.h b/src/objects.h index b90aced5f7..2b646113a0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2012,7 +2012,7 @@ class HashTable: public FixedArray { static const int kMaxCapacity = (FixedArray::kMaxLength - kElementsStartOffset) / kEntrySize; - // Find entry for key otherwise return -1. + // Find entry for key otherwise return kNotFound. int FindEntry(Key key); protected: @@ -2294,6 +2294,10 @@ class StringDictionary: public Dictionary { // For transforming properties of a JSObject. Object* TransformPropertiesToFastFor(JSObject* obj, int unused_property_fields); + + // Find entry for key otherwise return kNotFound. Optimzed version of + // HashTable::FindEntry. + int FindEntry(String* key); };