xpcom/glue/nsTHashtable.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsTHashtable_h__
michael@0 7 #define nsTHashtable_h__
michael@0 8
michael@0 9 #include "nscore.h"
michael@0 10 #include "pldhash.h"
michael@0 11 #include "nsDebug.h"
michael@0 12 #include "mozilla/MemoryChecking.h"
michael@0 13 #include "mozilla/MemoryReporting.h"
michael@0 14 #include "mozilla/Move.h"
michael@0 15 #include "mozilla/fallible.h"
michael@0 16 #include "mozilla/PodOperations.h"
michael@0 17
michael@0 18 #include <new>
michael@0 19
michael@0 20 // helper function for nsTHashtable::Clear()
michael@0 21 NS_COM_GLUE PLDHashOperator
michael@0 22 PL_DHashStubEnumRemove(PLDHashTable *table,
michael@0 23 PLDHashEntryHdr *entry,
michael@0 24 uint32_t ordinal,
michael@0 25 void *userArg);
michael@0 26
michael@0 27
michael@0 28 /**
michael@0 29 * a base class for templated hashtables.
michael@0 30 *
michael@0 31 * Clients will rarely need to use this class directly. Check the derived
michael@0 32 * classes first, to see if they will meet your needs.
michael@0 33 *
michael@0 34 * @param EntryType the templated entry-type class that is managed by the
michael@0 35 * hashtable. <code>EntryType</code> must extend the following declaration,
michael@0 36 * and <strong>must not declare any virtual functions or derive from classes
michael@0 37 * with virtual functions.</strong> Any vtable pointer would break the
michael@0 38 * PLDHashTable code.
michael@0 39 *<pre> class EntryType : public PLDHashEntryHdr
michael@0 40 * {
michael@0 41 * public: or friend nsTHashtable<EntryType>;
michael@0 42 * // KeyType is what we use when Get()ing or Put()ing this entry
michael@0 43 * // this should either be a simple datatype (uint32_t, nsISupports*) or
michael@0 44 * // a const reference (const nsAString&)
michael@0 45 * typedef something KeyType;
michael@0 46 * // KeyTypePointer is the pointer-version of KeyType, because pldhash.h
michael@0 47 * // requires keys to cast to <code>const void*</code>
michael@0 48 * typedef const something* KeyTypePointer;
michael@0 49 *
michael@0 50 * EntryType(KeyTypePointer aKey);
michael@0 51 *
michael@0 52 * // A copy or C++11 Move constructor must be defined, even if
michael@0 53 * // AllowMemMove() == true, otherwise you will cause link errors.
michael@0 54 * EntryType(const EntryType& aEnt); // Either this...
michael@0 55 * EntryType(EntryType&& aEnt); // ...or this
michael@0 56 *
michael@0 57 * // the destructor must be defined... or you will cause link errors!
michael@0 58 * ~EntryType();
michael@0 59 *
michael@0 60 * // KeyEquals(): does this entry match this key?
michael@0 61 * bool KeyEquals(KeyTypePointer aKey) const;
michael@0 62 *
michael@0 63 * // KeyToPointer(): Convert KeyType to KeyTypePointer
michael@0 64 * static KeyTypePointer KeyToPointer(KeyType aKey);
michael@0 65 *
michael@0 66 * // HashKey(): calculate the hash number
michael@0 67 * static PLDHashNumber HashKey(KeyTypePointer aKey);
michael@0 68 *
michael@0 69 * // ALLOW_MEMMOVE can we move this class with memmove(), or do we have
michael@0 70 * // to use the copy constructor?
michael@0 71 * enum { ALLOW_MEMMOVE = true/false };
michael@0 72 * }</pre>
michael@0 73 *
michael@0 74 * @see nsInterfaceHashtable
michael@0 75 * @see nsDataHashtable
michael@0 76 * @see nsClassHashtable
michael@0 77 * @author "Benjamin Smedberg <bsmedberg@covad.net>"
michael@0 78 */
michael@0 79
michael@0 80 template<class EntryType>
michael@0 81 class nsTHashtable
michael@0 82 {
michael@0 83 typedef mozilla::fallible_t fallible_t;
michael@0 84
michael@0 85 public:
michael@0 86 // Separate constructors instead of default aInitSize parameter since
michael@0 87 // otherwise the default no-arg constructor isn't found.
michael@0 88 nsTHashtable()
michael@0 89 {
michael@0 90 Init(PL_DHASH_MIN_SIZE);
michael@0 91 }
michael@0 92 explicit nsTHashtable(uint32_t aInitSize)
michael@0 93 {
michael@0 94 Init(aInitSize);
michael@0 95 }
michael@0 96
michael@0 97 /**
michael@0 98 * destructor, cleans up and deallocates
michael@0 99 */
michael@0 100 ~nsTHashtable();
michael@0 101
michael@0 102 nsTHashtable(nsTHashtable<EntryType>&& aOther);
michael@0 103
michael@0 104 /**
michael@0 105 * Return the generation number for the table. This increments whenever
michael@0 106 * the table data items are moved.
michael@0 107 */
michael@0 108 uint32_t GetGeneration() const { return mTable.generation; }
michael@0 109
michael@0 110 /**
michael@0 111 * KeyType is typedef'ed for ease of use.
michael@0 112 */
michael@0 113 typedef typename EntryType::KeyType KeyType;
michael@0 114
michael@0 115 /**
michael@0 116 * KeyTypePointer is typedef'ed for ease of use.
michael@0 117 */
michael@0 118 typedef typename EntryType::KeyTypePointer KeyTypePointer;
michael@0 119
michael@0 120 /**
michael@0 121 * Return the number of entries in the table.
michael@0 122 * @return number of entries
michael@0 123 */
michael@0 124 uint32_t Count() const { return mTable.entryCount; }
michael@0 125
michael@0 126 /**
michael@0 127 * Get the entry associated with a key.
michael@0 128 * @param aKey the key to retrieve
michael@0 129 * @return pointer to the entry class, if the key exists; nullptr if the
michael@0 130 * key doesn't exist
michael@0 131 */
michael@0 132 EntryType* GetEntry(KeyType aKey) const
michael@0 133 {
michael@0 134 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 135
michael@0 136 EntryType* entry =
michael@0 137 reinterpret_cast<EntryType*>
michael@0 138 (PL_DHashTableOperate(
michael@0 139 const_cast<PLDHashTable*>(&mTable),
michael@0 140 EntryType::KeyToPointer(aKey),
michael@0 141 PL_DHASH_LOOKUP));
michael@0 142 return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nullptr;
michael@0 143 }
michael@0 144
michael@0 145 /**
michael@0 146 * Return true if an entry for the given key exists, false otherwise.
michael@0 147 * @param aKey the key to retrieve
michael@0 148 * @return true if the key exists, false if the key doesn't exist
michael@0 149 */
michael@0 150 bool Contains(KeyType aKey) const
michael@0 151 {
michael@0 152 return !!GetEntry(aKey);
michael@0 153 }
michael@0 154
michael@0 155 /**
michael@0 156 * Get the entry associated with a key, or create a new entry,
michael@0 157 * @param aKey the key to retrieve
michael@0 158 * @return pointer to the entry class retreived; nullptr only if memory
michael@0 159 can't be allocated
michael@0 160 */
michael@0 161 EntryType* PutEntry(KeyType aKey)
michael@0 162 {
michael@0 163 EntryType* e = PutEntry(aKey, fallible_t());
michael@0 164 if (!e)
michael@0 165 NS_ABORT_OOM(mTable.entrySize * mTable.entryCount);
michael@0 166 return e;
michael@0 167 }
michael@0 168
michael@0 169 EntryType* PutEntry(KeyType aKey, const fallible_t&) NS_WARN_UNUSED_RESULT
michael@0 170 {
michael@0 171 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 172
michael@0 173 return static_cast<EntryType*>
michael@0 174 (PL_DHashTableOperate(
michael@0 175 &mTable,
michael@0 176 EntryType::KeyToPointer(aKey),
michael@0 177 PL_DHASH_ADD));
michael@0 178 }
michael@0 179
michael@0 180 /**
michael@0 181 * Remove the entry associated with a key.
michael@0 182 * @param aKey of the entry to remove
michael@0 183 */
michael@0 184 void RemoveEntry(KeyType aKey)
michael@0 185 {
michael@0 186 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 187
michael@0 188 PL_DHashTableOperate(&mTable,
michael@0 189 EntryType::KeyToPointer(aKey),
michael@0 190 PL_DHASH_REMOVE);
michael@0 191 }
michael@0 192
michael@0 193 /**
michael@0 194 * Remove the entry associated with a key, but don't resize the hashtable.
michael@0 195 * This is a low-level method, and is not recommended unless you know what
michael@0 196 * you're doing and you need the extra performance. This method can be used
michael@0 197 * during enumeration, while RemoveEntry() cannot.
michael@0 198 * @param aEntry the entry-pointer to remove (obtained from GetEntry or
michael@0 199 * the enumerator
michael@0 200 */
michael@0 201 void RawRemoveEntry(EntryType* aEntry)
michael@0 202 {
michael@0 203 PL_DHashTableRawRemove(&mTable, aEntry);
michael@0 204 }
michael@0 205
michael@0 206 /**
michael@0 207 * client must provide an <code>Enumerator</code> function for
michael@0 208 * EnumerateEntries
michael@0 209 * @param aEntry the entry being enumerated
michael@0 210 * @param userArg passed unchanged from <code>EnumerateEntries</code>
michael@0 211 * @return combination of flags
michael@0 212 * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink ,
michael@0 213 * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink ,
michael@0 214 * @link PLDHashOperator::PL_DHASH_REMOVE PL_DHASH_REMOVE @endlink
michael@0 215 */
michael@0 216 typedef PLDHashOperator (* Enumerator)(EntryType* aEntry, void* userArg);
michael@0 217
michael@0 218 /**
michael@0 219 * Enumerate all the entries of the function.
michael@0 220 * @param enumFunc the <code>Enumerator</code> function to call
michael@0 221 * @param userArg a pointer to pass to the
michael@0 222 * <code>Enumerator</code> function
michael@0 223 * @return the number of entries actually enumerated
michael@0 224 */
michael@0 225 uint32_t EnumerateEntries(Enumerator enumFunc, void* userArg)
michael@0 226 {
michael@0 227 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 228
michael@0 229 s_EnumArgs args = { enumFunc, userArg };
michael@0 230 return PL_DHashTableEnumerate(&mTable, s_EnumStub, &args);
michael@0 231 }
michael@0 232
michael@0 233 /**
michael@0 234 * remove all entries, return hashtable to "pristine" state ;)
michael@0 235 */
michael@0 236 void Clear()
michael@0 237 {
michael@0 238 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 239
michael@0 240 PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nullptr);
michael@0 241 }
michael@0 242
michael@0 243 /**
michael@0 244 * client must provide a <code>SizeOfEntryExcludingThisFun</code> function for
michael@0 245 * SizeOfExcludingThis.
michael@0 246 * @param aEntry the entry being enumerated
michael@0 247 * @param mallocSizeOf the function used to measure heap-allocated blocks
michael@0 248 * @param arg passed unchanged from <code>SizeOf{In,Ex}cludingThis</code>
michael@0 249 * @return summed size of the things pointed to by the entries
michael@0 250 */
michael@0 251 typedef size_t (* SizeOfEntryExcludingThisFun)(EntryType* aEntry,
michael@0 252 mozilla::MallocSizeOf mallocSizeOf,
michael@0 253 void *arg);
michael@0 254
michael@0 255 /**
michael@0 256 * Measure the size of the table's entry storage, and if
michael@0 257 * |sizeOfEntryExcludingThis| is non-nullptr, measure the size of things
michael@0 258 * pointed to by entries.
michael@0 259 *
michael@0 260 * @param sizeOfEntryExcludingThis the
michael@0 261 * <code>SizeOfEntryExcludingThisFun</code> function to call
michael@0 262 * @param mallocSizeOf the function used to measure heap-allocated blocks
michael@0 263 * @param userArg a pointer to pass to the
michael@0 264 * <code>SizeOfEntryExcludingThisFun</code> function
michael@0 265 * @return the summed size of all the entries
michael@0 266 */
michael@0 267 size_t SizeOfExcludingThis(SizeOfEntryExcludingThisFun sizeOfEntryExcludingThis,
michael@0 268 mozilla::MallocSizeOf mallocSizeOf,
michael@0 269 void *userArg = nullptr) const
michael@0 270 {
michael@0 271 if (sizeOfEntryExcludingThis) {
michael@0 272 s_SizeOfArgs args = { sizeOfEntryExcludingThis, userArg };
michael@0 273 return PL_DHashTableSizeOfExcludingThis(&mTable, s_SizeOfStub, mallocSizeOf, &args);
michael@0 274 }
michael@0 275 return PL_DHashTableSizeOfExcludingThis(&mTable, nullptr, mallocSizeOf);
michael@0 276 }
michael@0 277
michael@0 278 #ifdef DEBUG
michael@0 279 /**
michael@0 280 * Mark the table as constant after initialization.
michael@0 281 *
michael@0 282 * This will prevent assertions when a read-only hash is accessed on multiple
michael@0 283 * threads without synchronization.
michael@0 284 */
michael@0 285 void MarkImmutable()
michael@0 286 {
michael@0 287 NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
michael@0 288
michael@0 289 PL_DHashMarkTableImmutable(&mTable);
michael@0 290 }
michael@0 291 #endif
michael@0 292
michael@0 293 protected:
michael@0 294 PLDHashTable mTable;
michael@0 295
michael@0 296 static const void* s_GetKey(PLDHashTable *table,
michael@0 297 PLDHashEntryHdr *entry);
michael@0 298
michael@0 299 static PLDHashNumber s_HashKey(PLDHashTable *table,
michael@0 300 const void *key);
michael@0 301
michael@0 302 static bool s_MatchEntry(PLDHashTable *table,
michael@0 303 const PLDHashEntryHdr *entry,
michael@0 304 const void *key);
michael@0 305
michael@0 306 static void s_CopyEntry(PLDHashTable *table,
michael@0 307 const PLDHashEntryHdr *from,
michael@0 308 PLDHashEntryHdr *to);
michael@0 309
michael@0 310 static void s_ClearEntry(PLDHashTable *table,
michael@0 311 PLDHashEntryHdr *entry);
michael@0 312
michael@0 313 static bool s_InitEntry(PLDHashTable *table,
michael@0 314 PLDHashEntryHdr *entry,
michael@0 315 const void *key);
michael@0 316
michael@0 317 /**
michael@0 318 * passed internally during enumeration. Allocated on the stack.
michael@0 319 *
michael@0 320 * @param userFunc the Enumerator function passed to
michael@0 321 * EnumerateEntries by the client
michael@0 322 * @param userArg the userArg passed unaltered
michael@0 323 */
michael@0 324 struct s_EnumArgs
michael@0 325 {
michael@0 326 Enumerator userFunc;
michael@0 327 void* userArg;
michael@0 328 };
michael@0 329
michael@0 330 static PLDHashOperator s_EnumStub(PLDHashTable *table,
michael@0 331 PLDHashEntryHdr *entry,
michael@0 332 uint32_t number,
michael@0 333 void *arg);
michael@0 334
michael@0 335 /**
michael@0 336 * passed internally during sizeOf counting. Allocated on the stack.
michael@0 337 *
michael@0 338 * @param userFunc the SizeOfEntryExcludingThisFun passed to
michael@0 339 * SizeOf{In,Ex}cludingThis by the client
michael@0 340 * @param userArg the userArg passed unaltered
michael@0 341 */
michael@0 342 struct s_SizeOfArgs
michael@0 343 {
michael@0 344 SizeOfEntryExcludingThisFun userFunc;
michael@0 345 void* userArg;
michael@0 346 };
michael@0 347
michael@0 348 static size_t s_SizeOfStub(PLDHashEntryHdr *entry,
michael@0 349 mozilla::MallocSizeOf mallocSizeOf,
michael@0 350 void *arg);
michael@0 351
michael@0 352 private:
michael@0 353 // copy constructor, not implemented
michael@0 354 nsTHashtable(nsTHashtable<EntryType>& toCopy) MOZ_DELETE;
michael@0 355
michael@0 356 /**
michael@0 357 * Initialize the table.
michael@0 358 * @param initSize the initial number of buckets in the hashtable
michael@0 359 */
michael@0 360 void Init(uint32_t aInitSize);
michael@0 361
michael@0 362 // assignment operator, not implemented
michael@0 363 nsTHashtable<EntryType>& operator= (nsTHashtable<EntryType>& toEqual) MOZ_DELETE;
michael@0 364 };
michael@0 365
michael@0 366 //
michael@0 367 // template definitions
michael@0 368 //
michael@0 369
michael@0 370 template<class EntryType>
michael@0 371 nsTHashtable<EntryType>::nsTHashtable(
michael@0 372 nsTHashtable<EntryType>&& aOther)
michael@0 373 : mTable(mozilla::Move(aOther.mTable))
michael@0 374 {
michael@0 375 // aOther shouldn't touch mTable after this, because we've stolen the table's
michael@0 376 // pointers but not overwitten them.
michael@0 377 MOZ_MAKE_MEM_UNDEFINED(&aOther.mTable, sizeof(aOther.mTable));
michael@0 378
michael@0 379 // Indicate that aOther is not initialized. This will make its destructor a
michael@0 380 // nop, which is what we want.
michael@0 381 aOther.mTable.entrySize = 0;
michael@0 382 }
michael@0 383
michael@0 384 template<class EntryType>
michael@0 385 nsTHashtable<EntryType>::~nsTHashtable()
michael@0 386 {
michael@0 387 if (mTable.entrySize)
michael@0 388 PL_DHashTableFinish(&mTable);
michael@0 389 }
michael@0 390
michael@0 391 template<class EntryType>
michael@0 392 void
michael@0 393 nsTHashtable<EntryType>::Init(uint32_t aInitSize)
michael@0 394 {
michael@0 395 static const PLDHashTableOps sOps =
michael@0 396 {
michael@0 397 ::PL_DHashAllocTable,
michael@0 398 ::PL_DHashFreeTable,
michael@0 399 s_HashKey,
michael@0 400 s_MatchEntry,
michael@0 401 EntryType::ALLOW_MEMMOVE ? ::PL_DHashMoveEntryStub : s_CopyEntry,
michael@0 402 s_ClearEntry,
michael@0 403 ::PL_DHashFinalizeStub,
michael@0 404 s_InitEntry
michael@0 405 };
michael@0 406
michael@0 407 PL_DHashTableInit(&mTable, &sOps, nullptr, sizeof(EntryType), aInitSize);
michael@0 408 }
michael@0 409
michael@0 410 // static definitions
michael@0 411
michael@0 412 template<class EntryType>
michael@0 413 PLDHashNumber
michael@0 414 nsTHashtable<EntryType>::s_HashKey(PLDHashTable *table,
michael@0 415 const void *key)
michael@0 416 {
michael@0 417 return EntryType::HashKey(reinterpret_cast<const KeyTypePointer>(key));
michael@0 418 }
michael@0 419
michael@0 420 template<class EntryType>
michael@0 421 bool
michael@0 422 nsTHashtable<EntryType>::s_MatchEntry(PLDHashTable *table,
michael@0 423 const PLDHashEntryHdr *entry,
michael@0 424 const void *key)
michael@0 425 {
michael@0 426 return ((const EntryType*) entry)->KeyEquals(
michael@0 427 reinterpret_cast<const KeyTypePointer>(key));
michael@0 428 }
michael@0 429
michael@0 430 template<class EntryType>
michael@0 431 void
michael@0 432 nsTHashtable<EntryType>::s_CopyEntry(PLDHashTable *table,
michael@0 433 const PLDHashEntryHdr *from,
michael@0 434 PLDHashEntryHdr *to)
michael@0 435 {
michael@0 436 EntryType* fromEntry =
michael@0 437 const_cast<EntryType*>(reinterpret_cast<const EntryType*>(from));
michael@0 438
michael@0 439 new(to) EntryType(mozilla::Move(*fromEntry));
michael@0 440
michael@0 441 fromEntry->~EntryType();
michael@0 442 }
michael@0 443
michael@0 444 template<class EntryType>
michael@0 445 void
michael@0 446 nsTHashtable<EntryType>::s_ClearEntry(PLDHashTable *table,
michael@0 447 PLDHashEntryHdr *entry)
michael@0 448 {
michael@0 449 reinterpret_cast<EntryType*>(entry)->~EntryType();
michael@0 450 }
michael@0 451
michael@0 452 template<class EntryType>
michael@0 453 bool
michael@0 454 nsTHashtable<EntryType>::s_InitEntry(PLDHashTable *table,
michael@0 455 PLDHashEntryHdr *entry,
michael@0 456 const void *key)
michael@0 457 {
michael@0 458 new(entry) EntryType(reinterpret_cast<KeyTypePointer>(key));
michael@0 459 return true;
michael@0 460 }
michael@0 461
michael@0 462 template<class EntryType>
michael@0 463 PLDHashOperator
michael@0 464 nsTHashtable<EntryType>::s_EnumStub(PLDHashTable *table,
michael@0 465 PLDHashEntryHdr *entry,
michael@0 466 uint32_t number,
michael@0 467 void *arg)
michael@0 468 {
michael@0 469 // dereferences the function-pointer to the user's enumeration function
michael@0 470 return (* reinterpret_cast<s_EnumArgs*>(arg)->userFunc)(
michael@0 471 reinterpret_cast<EntryType*>(entry),
michael@0 472 reinterpret_cast<s_EnumArgs*>(arg)->userArg);
michael@0 473 }
michael@0 474
michael@0 475 template<class EntryType>
michael@0 476 size_t
michael@0 477 nsTHashtable<EntryType>::s_SizeOfStub(PLDHashEntryHdr *entry,
michael@0 478 mozilla::MallocSizeOf mallocSizeOf,
michael@0 479 void *arg)
michael@0 480 {
michael@0 481 // dereferences the function-pointer to the user's enumeration function
michael@0 482 return (* reinterpret_cast<s_SizeOfArgs*>(arg)->userFunc)(
michael@0 483 reinterpret_cast<EntryType*>(entry),
michael@0 484 mallocSizeOf,
michael@0 485 reinterpret_cast<s_SizeOfArgs*>(arg)->userArg);
michael@0 486 }
michael@0 487
michael@0 488 class nsCycleCollectionTraversalCallback;
michael@0 489
michael@0 490 struct MOZ_STACK_CLASS nsTHashtableCCTraversalData
michael@0 491 {
michael@0 492 nsTHashtableCCTraversalData(nsCycleCollectionTraversalCallback& aCallback,
michael@0 493 const char* aName,
michael@0 494 uint32_t aFlags)
michael@0 495 : mCallback(aCallback),
michael@0 496 mName(aName),
michael@0 497 mFlags(aFlags)
michael@0 498 {
michael@0 499 }
michael@0 500
michael@0 501 nsCycleCollectionTraversalCallback& mCallback;
michael@0 502 const char* mName;
michael@0 503 uint32_t mFlags;
michael@0 504 };
michael@0 505
michael@0 506 template <class EntryType>
michael@0 507 PLDHashOperator
michael@0 508 ImplCycleCollectionTraverse_EnumFunc(EntryType *aEntry,
michael@0 509 void* aUserData)
michael@0 510 {
michael@0 511 auto userData = static_cast<nsTHashtableCCTraversalData*>(aUserData);
michael@0 512
michael@0 513 ImplCycleCollectionTraverse(userData->mCallback,
michael@0 514 *aEntry,
michael@0 515 userData->mName,
michael@0 516 userData->mFlags);
michael@0 517 return PL_DHASH_NEXT;
michael@0 518 }
michael@0 519
michael@0 520 template <class EntryType>
michael@0 521 inline void
michael@0 522 ImplCycleCollectionUnlink(nsTHashtable<EntryType>& aField)
michael@0 523 {
michael@0 524 aField.Clear();
michael@0 525 }
michael@0 526
michael@0 527 template <class EntryType>
michael@0 528 inline void
michael@0 529 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
michael@0 530 nsTHashtable<EntryType>& aField,
michael@0 531 const char* aName,
michael@0 532 uint32_t aFlags = 0)
michael@0 533 {
michael@0 534 nsTHashtableCCTraversalData userData(aCallback, aName, aFlags);
michael@0 535
michael@0 536 aField.EnumerateEntries(ImplCycleCollectionTraverse_EnumFunc<EntryType>,
michael@0 537 &userData);
michael@0 538 }
michael@0 539
michael@0 540 #endif // nsTHashtable_h__

mercurial