diff options
author | fqian@google.com <fqian@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 21:16:06 +0000 |
---|---|---|
committer | fqian@google.com <fqian@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-30 21:16:06 +0000 |
commit | b57d5cc9dd98fc4fb284878ecc73e2eb95f6d1bd (patch) | |
tree | 1a01cf3c55bcb330c44c5dd2bba0061ed5d78ac2 | |
parent | 00b3428f078942747bd62c45b82b733f61e436b2 (diff) | |
download | chromium_src-b57d5cc9dd98fc4fb284878ecc73e2eb95f6d1bd.zip chromium_src-b57d5cc9dd98fc4fb284878ecc73e2eb95f6d1bd.tar.gz chromium_src-b57d5cc9dd98fc4fb284878ecc73e2eb95f6d1bd.tar.bz2 |
Replace std::map, std::set by WTF::HashMap and WTF::HashSet.
WebKit gurus, please review the change carefully, WTF::HashMap interface is not well documented, so I have implement
customized hash functions and HashTraits in order to use StringKey as the hash key.
Review URL: http://codereview.chromium.org/100069
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14995 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/port/bindings/v8/npruntime.cpp | 133 |
1 files changed, 93 insertions, 40 deletions
diff --git a/webkit/port/bindings/v8/npruntime.cpp b/webkit/port/bindings/v8/npruntime.cpp index 1ecb68c..427ea0c 100644 --- a/webkit/port/bindings/v8/npruntime.cpp +++ b/webkit/port/bindings/v8/npruntime.cpp @@ -26,21 +26,14 @@ #include "config.h" -#include <map> -#include <set> -#include <string> -#include <v8.h> - -#include "bindings/npruntime.h" #include "NPV8Object.h" #include "npruntime_priv.h" #include "V8NPObject.h" +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> #include <wtf/Assertions.h> -using namespace v8; - - // FIXME: Consider removing locks if we're singlethreaded already. // The static initializer here should work okay, but we want to avoid // static initialization in general. @@ -53,25 +46,85 @@ namespace { // We use StringKey here as the key-type to avoid a string copy to // construct the map key and for faster comparisons than strcmp. -struct StringKey { - StringKey(const char* str) : string(str), length(strlen(str)) {} - const char* string; - const size_t length; +class StringKey { + public: + explicit StringKey(const char* str) : _string(str), _length(strlen(str)) {} + StringKey() : _string(0), _length(0) {} + explicit StringKey(WTF::HashTableDeletedValueType) + : _string(hashTableDeletedValue()), _length(0) { } + + StringKey& operator=(const StringKey& other) { + this->_string = other._string; + this->_length = other._length; + return *this; + } + + bool isHashTableDeletedValue() const { + return _string == hashTableDeletedValue(); + } + + const char* _string; + size_t _length; + private: + const char* hashTableDeletedValue() const { + return reinterpret_cast<const char*>(-1); + } }; -inline bool operator<(const StringKey& x, const StringKey& y) { - // Shorter strings are less than longer strings, memcmp breaks ties. - if (x.length < y.length) - return true; - else if (x.length > y.length) +inline bool operator==(const StringKey& x, const StringKey& y) { + if (x._length != y._length) { return false; - else - return memcmp(x.string, y.string, y.length) < 0; + } else if (x._string == y._string) { + return true; + } else { + ASSERT(!x.isHashTableDeletedValue() && !y.isHashTableDeletedValue()); + return memcmp(x._string, y._string, y._length) == 0; + } } +// Implement WTF::DefaultHash<StringKey>::Hash interface. +struct StringKeyHash { + static unsigned hash(const StringKey& key) { + // Use the same string hash function as in V8. + unsigned hash = 0; + size_t len = key._length; + const char* str = key._string; + for (size_t i = 0; i < len; i++) { + char c = str[i]; + hash += c; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + if (hash == 0) { + hash = 27; + } + return hash; + } + + static bool equal(const StringKey& x, const StringKey& y) { + return x == y; + } + + static const bool safeToCompareToEmptyOrDeleted = true; +}; + } // namespace -typedef std::map<const StringKey, PrivateIdentifier*> StringIdentifierMap; +// Implement HashTraits<StringKey> +struct StringKeyHashTraits : WTF::GenericHashTraits<StringKey> { + static void constructDeletedValue(StringKey& slot) { + new (&slot) StringKey(WTF::HashTableDeletedValue); + } + static bool isDeletedValue(const StringKey& value) { + return value.isHashTableDeletedValue(); + } +}; + +typedef WTF::HashMap<StringKey, PrivateIdentifier*, \ + StringKeyHash, StringKeyHashTraits> StringIdentifierMap; static StringIdentifierMap* getStringIdentifierMap() { static StringIdentifierMap* stringIdentifierMap = 0; @@ -83,7 +136,7 @@ static StringIdentifierMap* getStringIdentifierMap() { // FIXME: Consider removing locks if we're singlethreaded already. // static Lock IntIdentifierMapLock; -typedef std::map<int, PrivateIdentifier*> IntIdentifierMap; +typedef WTF::HashMap<int, PrivateIdentifier*> IntIdentifierMap; static IntIdentifierMap* getIntIdentifierMap() { static IntIdentifierMap* intIdentifierMap = 0; @@ -106,7 +159,7 @@ NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name) { if (iter != identMap->end()) return static_cast<NPIdentifier>(iter->second); - size_t nameLen = key.length; + size_t nameLen = key._length; // We never release identifiers, so this dictionary will grow. PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>( @@ -115,8 +168,8 @@ NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name) { memcpy(nameStorage, name, nameLen + 1); identifier->isString = true; identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage); - key.string = nameStorage; - (*identMap)[key] = identifier; + key._string = nameStorage; + identMap->set(key, identifier); return (NPIdentifier)identifier; } @@ -146,7 +199,7 @@ NPIdentifier NPN_GetIntIdentifier(int32_t intid) { malloc(sizeof(PrivateIdentifier))); identifier->isString = false; identifier->value.number = intid; - (*identMap)[intid] = identifier; + identMap->set(intid, identifier); return (NPIdentifier)identifier; } @@ -276,9 +329,9 @@ void _NPN_InitializeVariantWithStringCopy(NPVariant* variant, // Frame teardown to deactivate all objects associated // with a particular plugin. -typedef std::set<NPObject*> NPObjectSet; -typedef std::map<NPObject*, NPObject*> NPObjectMap; -typedef std::map<NPObject*, NPObjectSet*> NPRootObjectMap; +typedef WTF::HashSet<NPObject*> NPObjectSet; +typedef WTF::HashMap<NPObject*, NPObject*> NPObjectMap; +typedef WTF::HashMap<NPObject*, NPObjectSet*> NPRootObjectMap; // A map of live NPObjects with pointers to their Roots. NPObjectMap g_live_objects; @@ -298,7 +351,7 @@ void _NPN_RegisterObject(NPObject* obj, NPObject* owner) { if (!owner) { // Registering a new owner object. ASSERT(g_root_objects.find(obj) == g_root_objects.end()); - g_root_objects[obj] = new NPObjectSet(); + g_root_objects.set(obj, new NPObjectSet()); } else { // Always associate this object with it's top-most parent. // Since we always flatten, we only have to look up one level. @@ -308,15 +361,15 @@ void _NPN_RegisterObject(NPObject* obj, NPObject* owner) { parent = owner_entry->second; if (parent) { - owner = parent; + owner = parent; } ASSERT(g_root_objects.find(obj) == g_root_objects.end()); if (g_root_objects.find(owner) != g_root_objects.end()) - (g_root_objects[owner])->insert(obj); + g_root_objects.get(owner)->add(obj); } ASSERT(g_live_objects.find(obj) == g_live_objects.end()); - g_live_objects[obj] = owner; + g_live_objects.set(obj, owner); } void _NPN_UnregisterObject(NPObject* obj) { @@ -330,18 +383,18 @@ void _NPN_UnregisterObject(NPObject* obj) { if (owner == NULL) { // Unregistering a owner object; also unregister it's descendants. ASSERT(g_root_objects.find(obj) != g_root_objects.end()); - NPObjectSet* set = g_root_objects[obj]; + NPObjectSet* set = g_root_objects.get(obj); while (set->size() > 0) { #ifndef NDEBUG - size_t size = set->size(); + int size = set->size(); #endif NPObject* sub_object = *(set->begin()); // The sub-object should not be a owner! ASSERT(g_root_objects.find(sub_object) == g_root_objects.end()); // First, unregister the object. - set->erase(sub_object); - g_live_objects.erase(sub_object); + set->remove(sub_object); + g_live_objects.remove(sub_object); // Remove the JS references to the object. ForgetV8ObjectForNPObject(sub_object); @@ -349,18 +402,18 @@ void _NPN_UnregisterObject(NPObject* obj) { ASSERT(set->size() < size); } delete set; - g_root_objects.erase(obj); + g_root_objects.remove(obj); } else { NPRootObjectMap::iterator owner_entry = g_root_objects.find(owner); if (owner_entry != g_root_objects.end()) { NPObjectSet* list = owner_entry->second; ASSERT(list->find(obj) != list->end()); - list->erase(obj); + list->remove(obj); } } ForgetV8ObjectForNPObject(obj); - g_live_objects.erase(obj); + g_live_objects.remove(obj); } bool _NPN_IsAlive(NPObject* obj) { |