Bug 1236801: Don't check for simulated OOM in a way that invalidates AddPtrs for no discernable reason. (Revised to fix uninitialized var, r=sfink) r=jonco
authorJim Blandy <jimb@mozilla.com>
Tue, 12 Jan 2016 16:49:45 -0800
changeset 279718 f46824dc517a6b73d1eda31640b18d93e7020a35
parent 279717 7df7cf796d9ac7de39162e92fdf081f6a69e8746
child 279719 60e81558a5e8a46a75b204314b157fa12ee40075
push id29885
push usercbook@mozilla.com
push dateWed, 13 Jan 2016 10:57:28 +0000
treeherdermozilla-central@531d1f6d1cde [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink, jonco
bugs1236801
milestone46.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1236801: Don't check for simulated OOM in a way that invalidates AddPtrs for no discernable reason. (Revised to fix uninitialized var, r=sfink) r=jonco
js/public/HashTable.h
js/src/jsapi-tests/testHashTable.cpp
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -1652,17 +1652,17 @@ class HashTable : private AllocPolicy
             METER(stats.addOverRemoved++);
             removedCount--;
             p.keyHash |= sCollisionBit;
         } else {
             // Preserve the validity of |p.entry_|.
             RebuildStatus status = checkOverloaded();
             if (status == RehashFailed)
                 return false;
-            if (!this->checkSimulatedOOM())
+            if (status == NotOverloaded && !this->checkSimulatedOOM())
                 return false;
             if (status == Rehashed)
                 p.entry_ = &findFreeEntry(p.keyHash);
         }
 
         p.entry_->setLive(p.keyHash, mozilla::Forward<Args>(args)...);
         entryCount++;
 #ifdef JS_DEBUG
--- a/js/src/jsapi-tests/testHashTable.cpp
+++ b/js/src/jsapi-tests/testHashTable.cpp
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 "js/HashTable.h"
+#include "js/Utility.h"
 #include "jsapi-tests/tests.h"
 
 //#define FUZZ
 
 typedef js::HashMap<uint32_t, uint32_t, js::DefaultHasher<uint32_t>, js::SystemAllocPolicy> IntMap;
 typedef js::HashSet<uint32_t, js::DefaultHasher<uint32_t>, js::SystemAllocPolicy> IntSet;
 
 /*
@@ -338,8 +339,56 @@ BEGIN_TEST(testHashSetOfMoveOnlyType)
 
     MoveOnlyType a(1);
 
     CHECK(set.put(mozilla::Move(a))); // This shouldn't generate a compiler error.
 
     return true;
 }
 END_TEST(testHashSetOfMoveOnlyType)
+
+#if defined(DEBUG)
+
+// Add entries to a HashMap using lookupWithDefault until either we get an OOM,
+// or the table has been resized a few times.
+static bool
+LookupWithDefaultUntilResize() {
+    IntMap m;
+
+    if (!m.init())
+        return false;
+
+    // Add entries until we've resized the table four times.
+    size_t lastCapacity = m.capacity();
+    size_t resizes = 0;
+    uint32_t key = 0;
+    while (resizes < 4) {
+        if (!m.lookupWithDefault(key++, 0))
+            return false;
+
+        size_t capacity = m.capacity();
+        if (capacity != lastCapacity) {
+            resizes++;
+            lastCapacity = capacity;
+        }
+    }
+
+    return true;
+}
+
+BEGIN_TEST(testHashMapLookupWithDefaultOOM)
+{
+    js::oom::targetThread = js::oom::THREAD_TYPE_MAIN;
+    uint32_t timeToFail;
+    for (timeToFail = 1; timeToFail < 1000; timeToFail++) {
+        OOM_maxAllocations = OOM_counter + timeToFail;
+        OOM_failAlways = false;
+
+        LookupWithDefaultUntilResize();
+    }
+
+    js::oom::targetThread = js::oom::THREAD_TYPE_NONE;
+
+    return true;
+}
+
+END_TEST(testHashMapLookupWithDefaultOOM)
+#endif // defined(DEBUG)