Chromium Code Reviews| Index: webkit/port/bindings/v8/npruntime.cpp |
| =================================================================== |
| --- webkit/port/bindings/v8/npruntime.cpp (revision 14928) |
| +++ webkit/port/bindings/v8/npruntime.cpp (working copy) |
| @@ -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,26 +46,86 @@ |
| // 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: |
| + StringKey(const char* str) : _string(str), _length(strlen(str)) {} |
|
Mike Belshe
2009/04/30 21:37:52
style wise, these should be m_string and m_length?
|
| + StringKey() : _string(0), _length(0) {} |
| + 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) |
| +inline bool operator==(const StringKey& x, const StringKey& y) { |
| + if (x._length != y._length) { |
| + return false; |
| + } else if (x._string == y._string) { |
| return true; |
| - else if (x.length > y.length) |
| - return false; |
| - else |
| - return memcmp(x.string, y.string, y.length) < 0; |
| + } 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. |
|
Mike Belshe
2009/04/30 21:37:52
This comment might make the reader think this need
|
| + 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; |
| if (!stringIdentifierMap) |
| @@ -83,7 +136,7 @@ |
| // 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 @@ |
| 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 @@ |
| 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 @@ |
| malloc(sizeof(PrivateIdentifier))); |
| identifier->isString = false; |
| identifier->value.number = intid; |
| - (*identMap)[intid] = identifier; |
| + identMap->set(intid, identifier); |
| return (NPIdentifier)identifier; |
| } |
| @@ -276,9 +329,9 @@ |
| // 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 @@ |
| 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 @@ |
| 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 @@ |
| 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 @@ |
| 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) { |