1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/src/XPCMaps.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,643 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* Private maps (hashtables). */ 1.11 + 1.12 +#include "mozilla/MathAlgorithms.h" 1.13 +#include "mozilla/MemoryReporting.h" 1.14 +#include "xpcprivate.h" 1.15 + 1.16 +#include "js/HashTable.h" 1.17 + 1.18 +using namespace mozilla; 1.19 + 1.20 +/***************************************************************************/ 1.21 +// static shared... 1.22 + 1.23 +// Note this is returning the bit pattern of the first part of the nsID, not 1.24 +// the pointer to the nsID. 1.25 + 1.26 +static PLDHashNumber 1.27 +HashIIDPtrKey(PLDHashTable *table, const void *key) 1.28 +{ 1.29 + return *((js::HashNumber*)key); 1.30 +} 1.31 + 1.32 +static bool 1.33 +MatchIIDPtrKey(PLDHashTable *table, 1.34 + const PLDHashEntryHdr *entry, 1.35 + const void *key) 1.36 +{ 1.37 + return ((const nsID*)key)-> 1.38 + Equals(*((const nsID*)((PLDHashEntryStub*)entry)->key)); 1.39 +} 1.40 + 1.41 +static PLDHashNumber 1.42 +HashNativeKey(PLDHashTable *table, const void *key) 1.43 +{ 1.44 + XPCNativeSetKey* Key = (XPCNativeSetKey*) key; 1.45 + 1.46 + PLDHashNumber h = 0; 1.47 + 1.48 + XPCNativeSet* Set; 1.49 + XPCNativeInterface* Addition; 1.50 + uint16_t Position; 1.51 + 1.52 + if (Key->IsAKey()) { 1.53 + Set = Key->GetBaseSet(); 1.54 + Addition = Key->GetAddition(); 1.55 + Position = Key->GetPosition(); 1.56 + } else { 1.57 + Set = (XPCNativeSet*) Key; 1.58 + Addition = nullptr; 1.59 + Position = 0; 1.60 + } 1.61 + 1.62 + if (!Set) { 1.63 + MOZ_ASSERT(Addition, "bad key"); 1.64 + // This would be an XOR like below. 1.65 + // But "0 ^ x == x". So it does not matter. 1.66 + h = (js::HashNumber) NS_PTR_TO_INT32(Addition) >> 2; 1.67 + } else { 1.68 + XPCNativeInterface** Current = Set->GetInterfaceArray(); 1.69 + uint16_t count = Set->GetInterfaceCount(); 1.70 + if (Addition) { 1.71 + count++; 1.72 + for (uint16_t i = 0; i < count; i++) { 1.73 + if (i == Position) 1.74 + h ^= (js::HashNumber) NS_PTR_TO_INT32(Addition) >> 2; 1.75 + else 1.76 + h ^= (js::HashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2; 1.77 + } 1.78 + } else { 1.79 + for (uint16_t i = 0; i < count; i++) 1.80 + h ^= (js::HashNumber) NS_PTR_TO_INT32(*(Current++)) >> 2; 1.81 + } 1.82 + } 1.83 + 1.84 + return h; 1.85 +} 1.86 + 1.87 +/***************************************************************************/ 1.88 +// implement JSObject2WrappedJSMap... 1.89 + 1.90 +void 1.91 +JSObject2WrappedJSMap::FindDyingJSObjects(nsTArray<nsXPCWrappedJS*>* dying) 1.92 +{ 1.93 + for (Map::Range r = mTable.all(); !r.empty(); r.popFront()) { 1.94 + nsXPCWrappedJS* wrapper = r.front().value(); 1.95 + MOZ_ASSERT(wrapper, "found a null JS wrapper!"); 1.96 + 1.97 + // walk the wrapper chain and find any whose JSObject is to be finalized 1.98 + while (wrapper) { 1.99 + if (wrapper->IsSubjectToFinalization() && wrapper->IsObjectAboutToBeFinalized()) 1.100 + dying->AppendElement(wrapper); 1.101 + wrapper = wrapper->GetNextWrapper(); 1.102 + } 1.103 + } 1.104 +} 1.105 + 1.106 +void 1.107 +JSObject2WrappedJSMap::ShutdownMarker() 1.108 +{ 1.109 + for (Map::Range r = mTable.all(); !r.empty(); r.popFront()) { 1.110 + nsXPCWrappedJS* wrapper = r.front().value(); 1.111 + MOZ_ASSERT(wrapper, "found a null JS wrapper!"); 1.112 + MOZ_ASSERT(wrapper->IsValid(), "found an invalid JS wrapper!"); 1.113 + wrapper->SystemIsBeingShutDown(); 1.114 + } 1.115 +} 1.116 + 1.117 +/***************************************************************************/ 1.118 +// implement Native2WrappedNativeMap... 1.119 + 1.120 +// static 1.121 +Native2WrappedNativeMap* 1.122 +Native2WrappedNativeMap::newMap(int size) 1.123 +{ 1.124 + Native2WrappedNativeMap* map = new Native2WrappedNativeMap(size); 1.125 + if (map && map->mTable) 1.126 + return map; 1.127 + // Allocation of the map or the creation of its hash table has 1.128 + // failed. This will cause a nullptr deref later when we attempt 1.129 + // to use the map, so we abort immediately to provide a more 1.130 + // useful crash stack. 1.131 + NS_RUNTIMEABORT("Ran out of memory."); 1.132 + return nullptr; 1.133 +} 1.134 + 1.135 +Native2WrappedNativeMap::Native2WrappedNativeMap(int size) 1.136 +{ 1.137 + mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, 1.138 + sizeof(Entry), size); 1.139 +} 1.140 + 1.141 +Native2WrappedNativeMap::~Native2WrappedNativeMap() 1.142 +{ 1.143 + if (mTable) 1.144 + PL_DHashTableDestroy(mTable); 1.145 +} 1.146 + 1.147 +size_t 1.148 +Native2WrappedNativeMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) 1.149 +{ 1.150 + size_t n = 0; 1.151 + n += mallocSizeOf(this); 1.152 + n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; 1.153 + return n; 1.154 +} 1.155 + 1.156 +/* static */ size_t 1.157 +Native2WrappedNativeMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, 1.158 + mozilla::MallocSizeOf mallocSizeOf, void *) 1.159 +{ 1.160 + return mallocSizeOf(((Native2WrappedNativeMap::Entry*)hdr)->value); 1.161 +} 1.162 + 1.163 +/***************************************************************************/ 1.164 +// implement IID2WrappedJSClassMap... 1.165 + 1.166 +const struct PLDHashTableOps IID2WrappedJSClassMap::Entry::sOps = 1.167 +{ 1.168 + PL_DHashAllocTable, 1.169 + PL_DHashFreeTable, 1.170 + HashIIDPtrKey, 1.171 + MatchIIDPtrKey, 1.172 + PL_DHashMoveEntryStub, 1.173 + PL_DHashClearEntryStub, 1.174 + PL_DHashFinalizeStub 1.175 +}; 1.176 + 1.177 +// static 1.178 +IID2WrappedJSClassMap* 1.179 +IID2WrappedJSClassMap::newMap(int size) 1.180 +{ 1.181 + IID2WrappedJSClassMap* map = new IID2WrappedJSClassMap(size); 1.182 + if (map && map->mTable) 1.183 + return map; 1.184 + delete map; 1.185 + return nullptr; 1.186 +} 1.187 + 1.188 +IID2WrappedJSClassMap::IID2WrappedJSClassMap(int size) 1.189 +{ 1.190 + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); 1.191 +} 1.192 + 1.193 +IID2WrappedJSClassMap::~IID2WrappedJSClassMap() 1.194 +{ 1.195 + if (mTable) 1.196 + PL_DHashTableDestroy(mTable); 1.197 +} 1.198 + 1.199 + 1.200 +/***************************************************************************/ 1.201 +// implement IID2NativeInterfaceMap... 1.202 + 1.203 +const struct PLDHashTableOps IID2NativeInterfaceMap::Entry::sOps = 1.204 +{ 1.205 + PL_DHashAllocTable, 1.206 + PL_DHashFreeTable, 1.207 + HashIIDPtrKey, 1.208 + MatchIIDPtrKey, 1.209 + PL_DHashMoveEntryStub, 1.210 + PL_DHashClearEntryStub, 1.211 + PL_DHashFinalizeStub 1.212 +}; 1.213 + 1.214 +// static 1.215 +IID2NativeInterfaceMap* 1.216 +IID2NativeInterfaceMap::newMap(int size) 1.217 +{ 1.218 + IID2NativeInterfaceMap* map = new IID2NativeInterfaceMap(size); 1.219 + if (map && map->mTable) 1.220 + return map; 1.221 + delete map; 1.222 + return nullptr; 1.223 +} 1.224 + 1.225 +IID2NativeInterfaceMap::IID2NativeInterfaceMap(int size) 1.226 +{ 1.227 + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); 1.228 +} 1.229 + 1.230 +IID2NativeInterfaceMap::~IID2NativeInterfaceMap() 1.231 +{ 1.232 + if (mTable) 1.233 + PL_DHashTableDestroy(mTable); 1.234 +} 1.235 + 1.236 +size_t 1.237 +IID2NativeInterfaceMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) 1.238 +{ 1.239 + size_t n = 0; 1.240 + n += mallocSizeOf(this); 1.241 + n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; 1.242 + return n; 1.243 +} 1.244 + 1.245 +/* static */ size_t 1.246 +IID2NativeInterfaceMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, 1.247 + mozilla::MallocSizeOf mallocSizeOf, void *) 1.248 +{ 1.249 + XPCNativeInterface *iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value; 1.250 + return iface->SizeOfIncludingThis(mallocSizeOf); 1.251 +} 1.252 + 1.253 +/***************************************************************************/ 1.254 +// implement ClassInfo2NativeSetMap... 1.255 + 1.256 +// static 1.257 +ClassInfo2NativeSetMap* 1.258 +ClassInfo2NativeSetMap::newMap(int size) 1.259 +{ 1.260 + ClassInfo2NativeSetMap* map = new ClassInfo2NativeSetMap(size); 1.261 + if (map && map->mTable) 1.262 + return map; 1.263 + delete map; 1.264 + return nullptr; 1.265 +} 1.266 + 1.267 +ClassInfo2NativeSetMap::ClassInfo2NativeSetMap(int size) 1.268 +{ 1.269 + mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, 1.270 + sizeof(Entry), size); 1.271 +} 1.272 + 1.273 +ClassInfo2NativeSetMap::~ClassInfo2NativeSetMap() 1.274 +{ 1.275 + if (mTable) 1.276 + PL_DHashTableDestroy(mTable); 1.277 +} 1.278 + 1.279 +size_t 1.280 +ClassInfo2NativeSetMap::ShallowSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) 1.281 +{ 1.282 + size_t n = 0; 1.283 + n += mallocSizeOf(this); 1.284 + // The second arg is nullptr because this is a "shallow" measurement of the map. 1.285 + n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, nullptr, mallocSizeOf) : 0; 1.286 + return n; 1.287 +} 1.288 + 1.289 +/***************************************************************************/ 1.290 +// implement ClassInfo2WrappedNativeProtoMap... 1.291 + 1.292 +// static 1.293 +ClassInfo2WrappedNativeProtoMap* 1.294 +ClassInfo2WrappedNativeProtoMap::newMap(int size) 1.295 +{ 1.296 + ClassInfo2WrappedNativeProtoMap* map = new ClassInfo2WrappedNativeProtoMap(size); 1.297 + if (map && map->mTable) 1.298 + return map; 1.299 + // Allocation of the map or the creation of its hash table has 1.300 + // failed. This will cause a nullptr deref later when we attempt 1.301 + // to use the map, so we abort immediately to provide a more 1.302 + // useful crash stack. 1.303 + NS_RUNTIMEABORT("Ran out of memory."); 1.304 + return nullptr; 1.305 +} 1.306 + 1.307 +ClassInfo2WrappedNativeProtoMap::ClassInfo2WrappedNativeProtoMap(int size) 1.308 +{ 1.309 + mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, 1.310 + sizeof(Entry), size); 1.311 +} 1.312 + 1.313 +ClassInfo2WrappedNativeProtoMap::~ClassInfo2WrappedNativeProtoMap() 1.314 +{ 1.315 + if (mTable) 1.316 + PL_DHashTableDestroy(mTable); 1.317 +} 1.318 + 1.319 +size_t 1.320 +ClassInfo2WrappedNativeProtoMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) 1.321 +{ 1.322 + size_t n = 0; 1.323 + n += mallocSizeOf(this); 1.324 + n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; 1.325 + return n; 1.326 +} 1.327 + 1.328 +/* static */ size_t 1.329 +ClassInfo2WrappedNativeProtoMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, 1.330 + mozilla::MallocSizeOf mallocSizeOf, void *) 1.331 +{ 1.332 + return mallocSizeOf(((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value); 1.333 +} 1.334 + 1.335 +/***************************************************************************/ 1.336 +// implement NativeSetMap... 1.337 + 1.338 +bool 1.339 +NativeSetMap::Entry::Match(PLDHashTable *table, 1.340 + const PLDHashEntryHdr *entry, 1.341 + const void *key) 1.342 +{ 1.343 + XPCNativeSetKey* Key = (XPCNativeSetKey*) key; 1.344 + 1.345 + // See the comment in the XPCNativeSetKey declaration in xpcprivate.h. 1.346 + if (!Key->IsAKey()) { 1.347 + XPCNativeSet* Set1 = (XPCNativeSet*) key; 1.348 + XPCNativeSet* Set2 = ((Entry*)entry)->key_value; 1.349 + 1.350 + if (Set1 == Set2) 1.351 + return true; 1.352 + 1.353 + uint16_t count = Set1->GetInterfaceCount(); 1.354 + if (count != Set2->GetInterfaceCount()) 1.355 + return false; 1.356 + 1.357 + XPCNativeInterface** Current1 = Set1->GetInterfaceArray(); 1.358 + XPCNativeInterface** Current2 = Set2->GetInterfaceArray(); 1.359 + for (uint16_t i = 0; i < count; i++) { 1.360 + if (*(Current1++) != *(Current2++)) 1.361 + return false; 1.362 + } 1.363 + 1.364 + return true; 1.365 + } 1.366 + 1.367 + XPCNativeSet* SetInTable = ((Entry*)entry)->key_value; 1.368 + XPCNativeSet* Set = Key->GetBaseSet(); 1.369 + XPCNativeInterface* Addition = Key->GetAddition(); 1.370 + 1.371 + if (!Set) { 1.372 + // This is a special case to deal with the invariant that says: 1.373 + // "All sets have exactly one nsISupports interface and it comes first." 1.374 + // See XPCNativeSet::NewInstance for details. 1.375 + // 1.376 + // Though we might have a key that represents only one interface, we 1.377 + // know that if that one interface were contructed into a set then 1.378 + // it would end up really being a set with two interfaces (except for 1.379 + // the case where the one interface happened to be nsISupports). 1.380 + 1.381 + return ((SetInTable->GetInterfaceCount() == 1 && 1.382 + SetInTable->GetInterfaceAt(0) == Addition) || 1.383 + (SetInTable->GetInterfaceCount() == 2 && 1.384 + SetInTable->GetInterfaceAt(1) == Addition)); 1.385 + } 1.386 + 1.387 + if (!Addition && Set == SetInTable) 1.388 + return true; 1.389 + 1.390 + uint16_t count = Set->GetInterfaceCount() + (Addition ? 1 : 0); 1.391 + if (count != SetInTable->GetInterfaceCount()) 1.392 + return false; 1.393 + 1.394 + uint16_t Position = Key->GetPosition(); 1.395 + XPCNativeInterface** CurrentInTable = SetInTable->GetInterfaceArray(); 1.396 + XPCNativeInterface** Current = Set->GetInterfaceArray(); 1.397 + for (uint16_t i = 0; i < count; i++) { 1.398 + if (Addition && i == Position) { 1.399 + if (Addition != *(CurrentInTable++)) 1.400 + return false; 1.401 + } else { 1.402 + if (*(Current++) != *(CurrentInTable++)) 1.403 + return false; 1.404 + } 1.405 + } 1.406 + 1.407 + return true; 1.408 +} 1.409 + 1.410 +const struct PLDHashTableOps NativeSetMap::Entry::sOps = 1.411 +{ 1.412 + PL_DHashAllocTable, 1.413 + PL_DHashFreeTable, 1.414 + HashNativeKey, 1.415 + Match, 1.416 + PL_DHashMoveEntryStub, 1.417 + PL_DHashClearEntryStub, 1.418 + PL_DHashFinalizeStub 1.419 +}; 1.420 + 1.421 +// static 1.422 +NativeSetMap* 1.423 +NativeSetMap::newMap(int size) 1.424 +{ 1.425 + NativeSetMap* map = new NativeSetMap(size); 1.426 + if (map && map->mTable) 1.427 + return map; 1.428 + delete map; 1.429 + return nullptr; 1.430 +} 1.431 + 1.432 +NativeSetMap::NativeSetMap(int size) 1.433 +{ 1.434 + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); 1.435 +} 1.436 + 1.437 +NativeSetMap::~NativeSetMap() 1.438 +{ 1.439 + if (mTable) 1.440 + PL_DHashTableDestroy(mTable); 1.441 +} 1.442 + 1.443 +size_t 1.444 +NativeSetMap::SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) 1.445 +{ 1.446 + size_t n = 0; 1.447 + n += mallocSizeOf(this); 1.448 + n += mTable ? PL_DHashTableSizeOfIncludingThis(mTable, SizeOfEntryExcludingThis, mallocSizeOf) : 0; 1.449 + return n; 1.450 +} 1.451 + 1.452 +/* static */ size_t 1.453 +NativeSetMap::SizeOfEntryExcludingThis(PLDHashEntryHdr *hdr, mozilla::MallocSizeOf mallocSizeOf, void *) 1.454 +{ 1.455 + XPCNativeSet *set = ((NativeSetMap::Entry*)hdr)->key_value; 1.456 + return set->SizeOfIncludingThis(mallocSizeOf); 1.457 +} 1.458 + 1.459 +/***************************************************************************/ 1.460 +// implement IID2ThisTranslatorMap... 1.461 + 1.462 +bool 1.463 +IID2ThisTranslatorMap::Entry::Match(PLDHashTable *table, 1.464 + const PLDHashEntryHdr *entry, 1.465 + const void *key) 1.466 +{ 1.467 + return ((const nsID*)key)->Equals(((Entry*)entry)->key); 1.468 +} 1.469 + 1.470 +void 1.471 +IID2ThisTranslatorMap::Entry::Clear(PLDHashTable *table, PLDHashEntryHdr *entry) 1.472 +{ 1.473 + static_cast<Entry*>(entry)->value = nullptr; 1.474 + memset(entry, 0, table->entrySize); 1.475 +} 1.476 + 1.477 +const struct PLDHashTableOps IID2ThisTranslatorMap::Entry::sOps = 1.478 +{ 1.479 + PL_DHashAllocTable, 1.480 + PL_DHashFreeTable, 1.481 + HashIIDPtrKey, 1.482 + Match, 1.483 + PL_DHashMoveEntryStub, 1.484 + Clear, 1.485 + PL_DHashFinalizeStub 1.486 +}; 1.487 + 1.488 +// static 1.489 +IID2ThisTranslatorMap* 1.490 +IID2ThisTranslatorMap::newMap(int size) 1.491 +{ 1.492 + IID2ThisTranslatorMap* map = new IID2ThisTranslatorMap(size); 1.493 + if (map && map->mTable) 1.494 + return map; 1.495 + delete map; 1.496 + return nullptr; 1.497 +} 1.498 + 1.499 +IID2ThisTranslatorMap::IID2ThisTranslatorMap(int size) 1.500 +{ 1.501 + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); 1.502 +} 1.503 + 1.504 +IID2ThisTranslatorMap::~IID2ThisTranslatorMap() 1.505 +{ 1.506 + if (mTable) 1.507 + PL_DHashTableDestroy(mTable); 1.508 +} 1.509 + 1.510 +/***************************************************************************/ 1.511 + 1.512 +PLDHashNumber 1.513 +XPCNativeScriptableSharedMap::Entry::Hash(PLDHashTable *table, const void *key) 1.514 +{ 1.515 + PLDHashNumber h; 1.516 + const unsigned char *s; 1.517 + 1.518 + XPCNativeScriptableShared* obj = 1.519 + (XPCNativeScriptableShared*) key; 1.520 + 1.521 + // hash together the flags and the classname string, ignore the interfaces 1.522 + // bitmap since it's very rare that it's different when flags and classname 1.523 + // are the same. 1.524 + 1.525 + h = (PLDHashNumber) obj->GetFlags(); 1.526 + for (s = (const unsigned char*) obj->GetJSClass()->name; *s != '\0'; s++) 1.527 + h = RotateLeft(h, 4) ^ *s; 1.528 + return h; 1.529 +} 1.530 + 1.531 +bool 1.532 +XPCNativeScriptableSharedMap::Entry::Match(PLDHashTable *table, 1.533 + const PLDHashEntryHdr *entry, 1.534 + const void *key) 1.535 +{ 1.536 + XPCNativeScriptableShared* obj1 = 1.537 + ((XPCNativeScriptableSharedMap::Entry*) entry)->key; 1.538 + 1.539 + XPCNativeScriptableShared* obj2 = 1.540 + (XPCNativeScriptableShared*) key; 1.541 + 1.542 + // match the flags, the classname string and the interfaces bitmap 1.543 + 1.544 + if (obj1->GetFlags() != obj2->GetFlags() || 1.545 + obj1->GetInterfacesBitmap() != obj2->GetInterfacesBitmap()) 1.546 + return false; 1.547 + 1.548 + const char* name1 = obj1->GetJSClass()->name; 1.549 + const char* name2 = obj2->GetJSClass()->name; 1.550 + 1.551 + if (!name1 || !name2) 1.552 + return name1 == name2; 1.553 + 1.554 + return 0 == strcmp(name1, name2); 1.555 +} 1.556 + 1.557 +const struct PLDHashTableOps XPCNativeScriptableSharedMap::Entry::sOps = 1.558 +{ 1.559 + PL_DHashAllocTable, 1.560 + PL_DHashFreeTable, 1.561 + Hash, 1.562 + Match, 1.563 + PL_DHashMoveEntryStub, 1.564 + PL_DHashClearEntryStub, 1.565 + PL_DHashFinalizeStub 1.566 +}; 1.567 + 1.568 +// static 1.569 +XPCNativeScriptableSharedMap* 1.570 +XPCNativeScriptableSharedMap::newMap(int size) 1.571 +{ 1.572 + XPCNativeScriptableSharedMap* map = 1.573 + new XPCNativeScriptableSharedMap(size); 1.574 + if (map && map->mTable) 1.575 + return map; 1.576 + delete map; 1.577 + return nullptr; 1.578 +} 1.579 + 1.580 +XPCNativeScriptableSharedMap::XPCNativeScriptableSharedMap(int size) 1.581 +{ 1.582 + mTable = PL_NewDHashTable(&Entry::sOps, nullptr, sizeof(Entry), size); 1.583 +} 1.584 + 1.585 +XPCNativeScriptableSharedMap::~XPCNativeScriptableSharedMap() 1.586 +{ 1.587 + if (mTable) 1.588 + PL_DHashTableDestroy(mTable); 1.589 +} 1.590 + 1.591 +bool 1.592 +XPCNativeScriptableSharedMap::GetNewOrUsed(uint32_t flags, 1.593 + char* name, 1.594 + uint32_t interfacesBitmap, 1.595 + XPCNativeScriptableInfo* si) 1.596 +{ 1.597 + NS_PRECONDITION(name,"bad param"); 1.598 + NS_PRECONDITION(si,"bad param"); 1.599 + 1.600 + XPCNativeScriptableShared key(flags, name, interfacesBitmap); 1.601 + Entry* entry = (Entry*) 1.602 + PL_DHashTableOperate(mTable, &key, PL_DHASH_ADD); 1.603 + if (!entry) 1.604 + return false; 1.605 + 1.606 + XPCNativeScriptableShared* shared = entry->key; 1.607 + 1.608 + if (!shared) { 1.609 + entry->key = shared = 1.610 + new XPCNativeScriptableShared(flags, key.TransferNameOwnership(), 1.611 + interfacesBitmap); 1.612 + if (!shared) 1.613 + return false; 1.614 + shared->PopulateJSClass(); 1.615 + } 1.616 + si->SetScriptableShared(shared); 1.617 + return true; 1.618 +} 1.619 + 1.620 +/***************************************************************************/ 1.621 +// implement XPCWrappedNativeProtoMap... 1.622 + 1.623 +// static 1.624 +XPCWrappedNativeProtoMap* 1.625 +XPCWrappedNativeProtoMap::newMap(int size) 1.626 +{ 1.627 + XPCWrappedNativeProtoMap* map = new XPCWrappedNativeProtoMap(size); 1.628 + if (map && map->mTable) 1.629 + return map; 1.630 + delete map; 1.631 + return nullptr; 1.632 +} 1.633 + 1.634 +XPCWrappedNativeProtoMap::XPCWrappedNativeProtoMap(int size) 1.635 +{ 1.636 + mTable = PL_NewDHashTable(PL_DHashGetStubOps(), nullptr, 1.637 + sizeof(PLDHashEntryStub), size); 1.638 +} 1.639 + 1.640 +XPCWrappedNativeProtoMap::~XPCWrappedNativeProtoMap() 1.641 +{ 1.642 + if (mTable) 1.643 + PL_DHashTableDestroy(mTable); 1.644 +} 1.645 + 1.646 +/***************************************************************************/