Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: webkit/port/bindings/v8/npruntime.cpp

Issue 100069: Replace std::map, std::set by WTF::HashMap and WTF::HashSet.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2007-2009 Google, Inc. All rights reserved. 3 * Copyright (C) 2007-2009 Google, Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 28
29 #include <map>
30 #include <set>
31 #include <string>
32 #include <v8.h>
33
34 #include "bindings/npruntime.h"
35 #include "NPV8Object.h" 29 #include "NPV8Object.h"
36 #include "npruntime_priv.h" 30 #include "npruntime_priv.h"
37 #include "V8NPObject.h" 31 #include "V8NPObject.h"
38 32
33 #include <wtf/HashMap.h>
34 #include <wtf/HashSet.h>
39 #include <wtf/Assertions.h> 35 #include <wtf/Assertions.h>
40 36
41 using namespace v8;
42
43
44 // FIXME: Consider removing locks if we're singlethreaded already. 37 // FIXME: Consider removing locks if we're singlethreaded already.
45 // The static initializer here should work okay, but we want to avoid 38 // The static initializer here should work okay, but we want to avoid
46 // static initialization in general. 39 // static initialization in general.
47 // 40 //
48 // Commenting out the locks to avoid dependencies on chrome for now. 41 // Commenting out the locks to avoid dependencies on chrome for now.
49 // Need a platform abstraction which we can use. 42 // Need a platform abstraction which we can use.
50 // static Lock StringIdentifierMapLock; 43 // static Lock StringIdentifierMapLock;
51 44
52 namespace { 45 namespace {
53 46
54 // We use StringKey here as the key-type to avoid a string copy to 47 // We use StringKey here as the key-type to avoid a string copy to
55 // construct the map key and for faster comparisons than strcmp. 48 // construct the map key and for faster comparisons than strcmp.
56 struct StringKey { 49 class StringKey {
57 StringKey(const char* str) : string(str), length(strlen(str)) {} 50 public:
58 const char* string; 51 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?
59 const size_t length; 52 StringKey() : _string(0), _length(0) {}
53 StringKey(WTF::HashTableDeletedValueType)
54 : _string(hashTableDeletedValue()), _length(0) { }
55
56 StringKey& operator=(const StringKey& other) {
57 this->_string = other._string;
58 this->_length = other._length;
59 return *this;
60 }
61
62 bool isHashTableDeletedValue() const {
63 return _string == hashTableDeletedValue();
64 }
65
66 const char* _string;
67 size_t _length;
68 private:
69 const char* hashTableDeletedValue() const {
70 return reinterpret_cast<const char*>(-1);
71 }
60 }; 72 };
61 73
62 inline bool operator<(const StringKey& x, const StringKey& y) { 74 inline bool operator==(const StringKey& x, const StringKey& y) {
63 // Shorter strings are less than longer strings, memcmp breaks ties. 75 if (x._length != y._length) {
64 if (x.length < y.length) 76 return false;
77 } else if (x._string == y._string) {
65 return true; 78 return true;
66 else if (x.length > y.length) 79 } else {
67 return false; 80 ASSERT(!x.isHashTableDeletedValue() && !y.isHashTableDeletedValue());
68 else 81 return memcmp(x._string, y._string, y._length) == 0;
69 return memcmp(x.string, y.string, y.length) < 0; 82 }
70 } 83 }
71 84
85 // Implement WTF::DefaultHash<StringKey>::Hash interface.
86 struct StringKeyHash {
87 static unsigned hash(const StringKey& key) {
88 // 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
89 unsigned hash = 0;
90 size_t len = key._length;
91 const char* str = key._string;
92 for (size_t i = 0; i < len; i++) {
93 char c = str[i];
94 hash += c;
95 hash += (hash << 10);
96 hash ^= (hash >> 6);
97 }
98 hash += (hash << 3);
99 hash ^= (hash >> 11);
100 hash += (hash << 15);
101 if (hash == 0) {
102 hash = 27;
103 }
104 return hash;
105 }
106
107 static bool equal(const StringKey& x, const StringKey& y) {
108 return x == y;
109 }
110
111 static const bool safeToCompareToEmptyOrDeleted = true;
112 };
113
72 } // namespace 114 } // namespace
73 115
74 typedef std::map<const StringKey, PrivateIdentifier*> StringIdentifierMap; 116 // Implement HashTraits<StringKey>
117 struct StringKeyHashTraits : WTF::GenericHashTraits<StringKey> {
118 static void constructDeletedValue(StringKey& slot) {
119 new (&slot) StringKey(WTF::HashTableDeletedValue);
120 }
121 static bool isDeletedValue(const StringKey& value) {
122 return value.isHashTableDeletedValue();
123 }
124 };
125
126 typedef WTF::HashMap<StringKey, PrivateIdentifier*, \
127 StringKeyHash, StringKeyHashTraits> StringIdentifierMap;
75 128
76 static StringIdentifierMap* getStringIdentifierMap() { 129 static StringIdentifierMap* getStringIdentifierMap() {
77 static StringIdentifierMap* stringIdentifierMap = 0; 130 static StringIdentifierMap* stringIdentifierMap = 0;
78 if (!stringIdentifierMap) 131 if (!stringIdentifierMap)
79 stringIdentifierMap = new StringIdentifierMap(); 132 stringIdentifierMap = new StringIdentifierMap();
80 return stringIdentifierMap; 133 return stringIdentifierMap;
81 } 134 }
82 135
83 // FIXME: Consider removing locks if we're singlethreaded already. 136 // FIXME: Consider removing locks if we're singlethreaded already.
84 // static Lock IntIdentifierMapLock; 137 // static Lock IntIdentifierMapLock;
85 138
86 typedef std::map<int, PrivateIdentifier*> IntIdentifierMap; 139 typedef WTF::HashMap<int, PrivateIdentifier*> IntIdentifierMap;
87 140
88 static IntIdentifierMap* getIntIdentifierMap() { 141 static IntIdentifierMap* getIntIdentifierMap() {
89 static IntIdentifierMap* intIdentifierMap = 0; 142 static IntIdentifierMap* intIdentifierMap = 0;
90 if (!intIdentifierMap) 143 if (!intIdentifierMap)
91 intIdentifierMap = new IntIdentifierMap(); 144 intIdentifierMap = new IntIdentifierMap();
92 return intIdentifierMap; 145 return intIdentifierMap;
93 } 146 }
94 147
95 extern "C" { 148 extern "C" {
96 149
97 NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name) { 150 NPIdentifier NPN_GetStringIdentifier(const NPUTF8* name) {
98 ASSERT(name); 151 ASSERT(name);
99 152
100 if (name) { 153 if (name) {
101 // AutoLock safeLock(StringIdentifierMapLock); 154 // AutoLock safeLock(StringIdentifierMapLock);
102 155
103 StringKey key(name); 156 StringKey key(name);
104 StringIdentifierMap* identMap = getStringIdentifierMap(); 157 StringIdentifierMap* identMap = getStringIdentifierMap();
105 StringIdentifierMap::iterator iter = identMap->find(key); 158 StringIdentifierMap::iterator iter = identMap->find(key);
106 if (iter != identMap->end()) 159 if (iter != identMap->end())
107 return static_cast<NPIdentifier>(iter->second); 160 return static_cast<NPIdentifier>(iter->second);
108 161
109 size_t nameLen = key.length; 162 size_t nameLen = key._length;
110 163
111 // We never release identifiers, so this dictionary will grow. 164 // We never release identifiers, so this dictionary will grow.
112 PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>( 165 PrivateIdentifier* identifier = static_cast<PrivateIdentifier*>(
113 malloc(sizeof(PrivateIdentifier) + nameLen + 1)); 166 malloc(sizeof(PrivateIdentifier) + nameLen + 1));
114 char* nameStorage = reinterpret_cast<char*>(identifier + 1); 167 char* nameStorage = reinterpret_cast<char*>(identifier + 1);
115 memcpy(nameStorage, name, nameLen + 1); 168 memcpy(nameStorage, name, nameLen + 1);
116 identifier->isString = true; 169 identifier->isString = true;
117 identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage); 170 identifier->value.string = reinterpret_cast<NPUTF8*>(nameStorage);
118 key.string = nameStorage; 171 key._string = nameStorage;
119 (*identMap)[key] = identifier; 172 identMap->set(key, identifier);
120 return (NPIdentifier)identifier; 173 return (NPIdentifier)identifier;
121 } 174 }
122 175
123 return 0; 176 return 0;
124 } 177 }
125 178
126 void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, 179 void NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount,
127 NPIdentifier* identifiers) { 180 NPIdentifier* identifiers) {
128 ASSERT(names); 181 ASSERT(names);
129 ASSERT(identifiers); 182 ASSERT(identifiers);
130 183
131 if (names && identifiers) 184 if (names && identifiers)
132 for (int i = 0; i < nameCount; i++) 185 for (int i = 0; i < nameCount; i++)
133 identifiers[i] = NPN_GetStringIdentifier(names[i]); 186 identifiers[i] = NPN_GetStringIdentifier(names[i]);
134 } 187 }
135 188
136 NPIdentifier NPN_GetIntIdentifier(int32_t intid) { 189 NPIdentifier NPN_GetIntIdentifier(int32_t intid) {
137 // AutoLock safeLock(IntIdentifierMapLock); 190 // AutoLock safeLock(IntIdentifierMapLock);
138 191
139 IntIdentifierMap* identMap = getIntIdentifierMap(); 192 IntIdentifierMap* identMap = getIntIdentifierMap();
140 IntIdentifierMap::iterator iter = identMap->find(intid); 193 IntIdentifierMap::iterator iter = identMap->find(intid);
141 if (iter != identMap->end()) 194 if (iter != identMap->end())
142 return static_cast<NPIdentifier>(iter->second); 195 return static_cast<NPIdentifier>(iter->second);
143 196
144 // We never release identifiers, so this dictionary will grow. 197 // We never release identifiers, so this dictionary will grow.
145 PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>( 198 PrivateIdentifier* identifier = reinterpret_cast<PrivateIdentifier*>(
146 malloc(sizeof(PrivateIdentifier))); 199 malloc(sizeof(PrivateIdentifier)));
147 identifier->isString = false; 200 identifier->isString = false;
148 identifier->value.number = intid; 201 identifier->value.number = intid;
149 (*identMap)[intid] = identifier; 202 identMap->set(intid, identifier);
150 return (NPIdentifier)identifier; 203 return (NPIdentifier)identifier;
151 } 204 }
152 205
153 bool NPN_IdentifierIsString(NPIdentifier identifier) { 206 bool NPN_IdentifierIsString(NPIdentifier identifier) {
154 PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier); 207 PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier);
155 return i->isString; 208 return i->isString;
156 } 209 }
157 210
158 NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) { 211 NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) {
159 PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier); 212 PrivateIdentifier* i = reinterpret_cast<PrivateIdentifier*>(identifier);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 // The g_live_objects is a hash table of all live objects to their owner 322 // The g_live_objects is a hash table of all live objects to their owner
270 // objects. Presence in this table is used primarily to determine if 323 // objects. Presence in this table is used primarily to determine if
271 // objects are live or not. 324 // objects are live or not.
272 // 325 //
273 // The g_root_objects is a hash table of root objects to a set of 326 // The g_root_objects is a hash table of root objects to a set of
274 // objects that should be deactivated in sync with the root. A 327 // objects that should be deactivated in sync with the root. A
275 // root is defined as a top-level owner object. This is used on 328 // root is defined as a top-level owner object. This is used on
276 // Frame teardown to deactivate all objects associated 329 // Frame teardown to deactivate all objects associated
277 // with a particular plugin. 330 // with a particular plugin.
278 331
279 typedef std::set<NPObject*> NPObjectSet; 332 typedef WTF::HashSet<NPObject*> NPObjectSet;
280 typedef std::map<NPObject*, NPObject*> NPObjectMap; 333 typedef WTF::HashMap<NPObject*, NPObject*> NPObjectMap;
281 typedef std::map<NPObject*, NPObjectSet*> NPRootObjectMap; 334 typedef WTF::HashMap<NPObject*, NPObjectSet*> NPRootObjectMap;
282 335
283 // A map of live NPObjects with pointers to their Roots. 336 // A map of live NPObjects with pointers to their Roots.
284 NPObjectMap g_live_objects; 337 NPObjectMap g_live_objects;
285 338
286 // A map of the root objects and the list of NPObjects 339 // A map of the root objects and the list of NPObjects
287 // associated with that object. 340 // associated with that object.
288 NPRootObjectMap g_root_objects; 341 NPRootObjectMap g_root_objects;
289 342
290 void _NPN_RegisterObject(NPObject* obj, NPObject* owner) { 343 void _NPN_RegisterObject(NPObject* obj, NPObject* owner) {
291 ASSERT(obj); 344 ASSERT(obj);
292 345
293 // Check if already registered. 346 // Check if already registered.
294 if (g_live_objects.find(obj) != g_live_objects.end()) { 347 if (g_live_objects.find(obj) != g_live_objects.end()) {
295 return; 348 return;
296 } 349 }
297 350
298 if (!owner) { 351 if (!owner) {
299 // Registering a new owner object. 352 // Registering a new owner object.
300 ASSERT(g_root_objects.find(obj) == g_root_objects.end()); 353 ASSERT(g_root_objects.find(obj) == g_root_objects.end());
301 g_root_objects[obj] = new NPObjectSet(); 354 g_root_objects.set(obj, new NPObjectSet());
302 } else { 355 } else {
303 // Always associate this object with it's top-most parent. 356 // Always associate this object with it's top-most parent.
304 // Since we always flatten, we only have to look up one level. 357 // Since we always flatten, we only have to look up one level.
305 NPObjectMap::iterator owner_entry = g_live_objects.find(owner); 358 NPObjectMap::iterator owner_entry = g_live_objects.find(owner);
306 NPObject* parent = NULL; 359 NPObject* parent = NULL;
307 if (g_live_objects.end() != owner_entry) 360 if (g_live_objects.end() != owner_entry)
308 parent = owner_entry->second; 361 parent = owner_entry->second;
309 362
310 if (parent) { 363 if (parent) {
311 owner = parent; 364 owner = parent;
312 } 365 }
313 ASSERT(g_root_objects.find(obj) == g_root_objects.end()); 366 ASSERT(g_root_objects.find(obj) == g_root_objects.end());
314 if (g_root_objects.find(owner) != g_root_objects.end()) 367 if (g_root_objects.find(owner) != g_root_objects.end())
315 (g_root_objects[owner])->insert(obj); 368 g_root_objects.get(owner)->add(obj);
316 } 369 }
317 370
318 ASSERT(g_live_objects.find(obj) == g_live_objects.end()); 371 ASSERT(g_live_objects.find(obj) == g_live_objects.end());
319 g_live_objects[obj] = owner; 372 g_live_objects.set(obj, owner);
320 } 373 }
321 374
322 void _NPN_UnregisterObject(NPObject* obj) { 375 void _NPN_UnregisterObject(NPObject* obj) {
323 ASSERT(obj); 376 ASSERT(obj);
324 ASSERT(g_live_objects.find(obj) != g_live_objects.end()); 377 ASSERT(g_live_objects.find(obj) != g_live_objects.end());
325 378
326 NPObject* owner = NULL; 379 NPObject* owner = NULL;
327 if (g_live_objects.find(obj) != g_live_objects.end()) 380 if (g_live_objects.find(obj) != g_live_objects.end())
328 owner = g_live_objects.find(obj)->second; 381 owner = g_live_objects.find(obj)->second;
329 382
330 if (owner == NULL) { 383 if (owner == NULL) {
331 // Unregistering a owner object; also unregister it's descendants. 384 // Unregistering a owner object; also unregister it's descendants.
332 ASSERT(g_root_objects.find(obj) != g_root_objects.end()); 385 ASSERT(g_root_objects.find(obj) != g_root_objects.end());
333 NPObjectSet* set = g_root_objects[obj]; 386 NPObjectSet* set = g_root_objects.get(obj);
334 while (set->size() > 0) { 387 while (set->size() > 0) {
335 #ifndef NDEBUG 388 #ifndef NDEBUG
336 size_t size = set->size(); 389 int size = set->size();
337 #endif 390 #endif
338 NPObject* sub_object = *(set->begin()); 391 NPObject* sub_object = *(set->begin());
339 // The sub-object should not be a owner! 392 // The sub-object should not be a owner!
340 ASSERT(g_root_objects.find(sub_object) == g_root_objects.end()); 393 ASSERT(g_root_objects.find(sub_object) == g_root_objects.end());
341 394
342 // First, unregister the object. 395 // First, unregister the object.
343 set->erase(sub_object); 396 set->remove(sub_object);
344 g_live_objects.erase(sub_object); 397 g_live_objects.remove(sub_object);
345 398
346 // Remove the JS references to the object. 399 // Remove the JS references to the object.
347 ForgetV8ObjectForNPObject(sub_object); 400 ForgetV8ObjectForNPObject(sub_object);
348 401
349 ASSERT(set->size() < size); 402 ASSERT(set->size() < size);
350 } 403 }
351 delete set; 404 delete set;
352 g_root_objects.erase(obj); 405 g_root_objects.remove(obj);
353 } else { 406 } else {
354 NPRootObjectMap::iterator owner_entry = g_root_objects.find(owner); 407 NPRootObjectMap::iterator owner_entry = g_root_objects.find(owner);
355 if (owner_entry != g_root_objects.end()) { 408 if (owner_entry != g_root_objects.end()) {
356 NPObjectSet* list = owner_entry->second; 409 NPObjectSet* list = owner_entry->second;
357 ASSERT(list->find(obj) != list->end()); 410 ASSERT(list->find(obj) != list->end());
358 list->erase(obj); 411 list->remove(obj);
359 } 412 }
360 } 413 }
361 ForgetV8ObjectForNPObject(obj); 414 ForgetV8ObjectForNPObject(obj);
362 415
363 g_live_objects.erase(obj); 416 g_live_objects.remove(obj);
364 } 417 }
365 418
366 bool _NPN_IsAlive(NPObject* obj) { 419 bool _NPN_IsAlive(NPObject* obj) {
367 return g_live_objects.find(obj) != g_live_objects.end(); 420 return g_live_objects.find(obj) != g_live_objects.end();
368 } 421 }
369 422
370 } // extern "C" 423 } // extern "C"
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698