Commit 030b783f authored by Jeff Walden's avatar Jeff Walden
Browse files

Bug 1595260 - Allow OrderedHash{Map,Set} to be safely destroyed in cases where...

Bug 1595260 - Allow OrderedHash{Map,Set} to be safely destroyed in cases where it was never successfully initialized.  r=sfink

Differential Revision: https://phabricator.services.mozilla.com/D52713

--HG--
extra : moz-landing-system : lando
parent b09cf1a6
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -144,7 +144,10 @@ class OrderedHashTable {

  ~OrderedHashTable() {
    forEachRange<Range::onTableDestroyed>();
    if (hashTable) {
      // |hashBuckets()| isn't valid when |hashTable| hasn't been created.
      alloc.free_(hashTable, hashBuckets());
    }
    freeData(data, dataLength, dataCapacity);
  }

+29 −0
Original line number Diff line number Diff line
@@ -2,8 +2,10 @@
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/HashFunctions.h"
#include "mozilla/Move.h"

#include "ds/OrderedHashTable.h"
#include "js/HashTable.h"
#include "js/Utility.h"

@@ -533,3 +535,30 @@ BEGIN_TEST(testHashLazyStorage) {
  return true;
}
END_TEST(testHashLazyStorage)

BEGIN_TEST(testOrderedHashSetWithoutInit) {
  {
    struct NonzeroUint32HashPolicy {
      using Lookup = uint32_t;
      static js::HashNumber hash(const Lookup& v,
                                 const mozilla::HashCodeScrambler& hcs) {
        return mozilla::HashGeneric(v);
      }
      static bool match(const uint32_t& k, const Lookup& l) { return k == l; }
      static bool isEmpty(const uint32_t& v) { return v == 0; }
      static void makeEmpty(uint32_t* v) { *v = 0; }
    };

    using OHS = js::OrderedHashSet<uint32_t, NonzeroUint32HashPolicy,
                                   js::SystemAllocPolicy>;

    OHS set(js::SystemAllocPolicy(), mozilla::HashCodeScrambler(17, 42));
    CHECK(set.count() == 0);

    // This test passes if the set is safely destructible even when |init()| is
    // never called.
  }

  return true;
}
END_TEST(testOrderedHashSetWithoutInit)