Bug 1231224 part 10 - Make various Vector calls check for OOM. r=terrence
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 06 Jan 2016 21:06:25 +0100
changeset 315842 80a318392bb0b16cf7b0f5cccfd94839bcfbe133
parent 315841 dc55c41b6331765915feca8e0569951ede13220b
child 315843 a1c2db363fa9f8b0c2c36c7d21b5483f52b08d7a
push id1079
push userjlund@mozilla.com
push dateFri, 15 Apr 2016 21:02:33 +0000
treeherdermozilla-release@575fbf6786d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1231224
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 1231224 part 10 - Make various Vector calls check for OOM. r=terrence
js/src/gc/Nursery.cpp
js/src/jit/RegisterAllocator.cpp
js/src/jsgc.cpp
js/src/jsobj.cpp
mfbt/Vector.h
mfbt/tests/TestBinarySearch.cpp
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -534,17 +534,17 @@ js::Nursery::collect(JSRuntime* rt, JS::
     // pointers to nursery things, which will force a collection well before
     // the nursery is full, look for object groups that are getting promoted
     // excessively and try to pretenure them.
     TIME_START(pretenure);
     if (pretenureGroups && (promotionRate > 0.8 || reason == JS::gcreason::FULL_STORE_BUFFER)) {
         for (size_t i = 0; i < ArrayLength(tenureCounts.entries); i++) {
             const TenureCount& entry = tenureCounts.entries[i];
             if (entry.count >= 3000)
-                pretenureGroups->append(entry.group); // ignore alloc failure
+                (void)pretenureGroups->append(entry.group); // ignore alloc failure
         }
     }
     TIME_END(pretenure);
 
     TIME_START(logPromotionsToTenured);
     for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
         zone->logPromotionsToTenured();
     }
--- a/js/src/jit/RegisterAllocator.cpp
+++ b/js/src/jit/RegisterAllocator.cpp
@@ -441,17 +441,20 @@ AllocationIntegrityState::dump()
             fprintf(stderr, "\n");
         }
     }
 
     // Print discovered allocations at the ends of blocks, in the order they
     // were discovered.
 
     Vector<IntegrityItem, 20, SystemAllocPolicy> seenOrdered;
-    seenOrdered.appendN(IntegrityItem(), seen.count());
+    if (!seenOrdered.appendN(IntegrityItem(), seen.count())) {
+        fprintf(stderr, "OOM while dumping allocations\n");
+        return;
+    }
 
     for (IntegrityItemSet::Enum iter(seen); !iter.empty(); iter.popFront()) {
         IntegrityItem item = iter.front();
         seenOrdered[item.index] = item;
     }
 
     if (!seenOrdered.empty()) {
         fprintf(stderr, "Intermediate Allocations:\n");
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -3735,17 +3735,17 @@ Zone::sweepCompartments(FreeOp* fop, boo
             if (comp->principals())
                 JS_DropPrincipals(rt, comp->principals());
             js_delete(comp);
         } else {
             *write++ = comp;
             foundOne = true;
         }
     }
-    compartments.resize(write - compartments.begin());
+    compartments.shrinkTo(write - compartments.begin());
     MOZ_ASSERT_IF(keepAtleastOne, !compartments.empty());
 }
 
 void
 GCRuntime::sweepZones(FreeOp* fop, bool destroyingRuntime)
 {
     MOZ_ASSERT_IF(destroyingRuntime, rt->gc.numActiveZoneIters == 0);
     if (rt->gc.numActiveZoneIters)
@@ -3779,17 +3779,17 @@ GCRuntime::sweepZones(FreeOp* fop, bool 
                 MOZ_ASSERT(zone->compartments.empty());
                 fop->delete_(zone);
                 continue;
             }
             zone->sweepCompartments(fop, true, destroyingRuntime);
         }
         *write++ = zone;
     }
-    zones.resize(write - zones.begin());
+    zones.shrinkTo(write - zones.begin());
 }
 
 void
 GCRuntime::purgeRuntime()
 {
     for (GCCompartmentsIter comp(rt); !comp.done(); comp.next())
         comp->purge();
 
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3532,18 +3532,22 @@ JSObject::dump()
         fprintf(stderr, "= ");
         dumpValue(obj->as<NativeObject>().getSlot(i));
         fputc('\n', stderr);
     }
 
     if (obj->isNative()) {
         fprintf(stderr, "properties:\n");
         Vector<Shape*, 8, SystemAllocPolicy> props;
-        for (Shape::Range<NoGC> r(obj->as<NativeObject>().lastProperty()); !r.empty(); r.popFront())
-            props.append(&r.front());
+        for (Shape::Range<NoGC> r(obj->as<NativeObject>().lastProperty()); !r.empty(); r.popFront()) {
+            if (!props.append(&r.front())) {
+                fprintf(stderr, "(OOM while appending properties)\n");
+                break;
+            }
+        }
         for (size_t i = props.length(); i-- != 0;)
             DumpProperty(&obj->as<NativeObject>(), *props[i]);
     }
     fputc('\n', stderr);
 }
 
 static void
 MaybeDumpObject(const char* name, JSObject* obj)
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -535,16 +535,22 @@ public:
   bool reserve(size_t aRequest);
 
   /**
    * Destroy elements in the range [end() - aIncr, end()). Does not deallocate
    * or unreserve storage for those elements.
    */
   void shrinkBy(size_t aIncr);
 
+  /**
+   * Destroy elements in the range [aNewLength, end()). Does not deallocate
+   * or unreserve storage for those elements.
+   */
+  void shrinkTo(size_t aNewLength);
+
   /** Grow the vector by aIncr elements. */
   bool growBy(size_t aIncr);
 
   /** Call shrinkBy or growBy based on whether newSize > length(). */
   bool resize(size_t aNewLength);
 
   /**
    * Increase the length of the vector, but don't initialize the new elements
@@ -944,16 +950,24 @@ Vector<T, N, AP>::shrinkBy(size_t aIncr)
 {
   MOZ_REENTRANCY_GUARD_ET_AL;
   MOZ_ASSERT(aIncr <= mLength);
   Impl::destroy(endNoCheck() - aIncr, endNoCheck());
   mLength -= aIncr;
 }
 
 template<typename T, size_t N, class AP>
+MOZ_ALWAYS_INLINE void
+Vector<T, N, AP>::shrinkTo(size_t aNewLength)
+{
+  MOZ_ASSERT(aNewLength <= mLength);
+  shrinkBy(mLength - aNewLength);
+}
+
+template<typename T, size_t N, class AP>
 MOZ_ALWAYS_INLINE bool
 Vector<T, N, AP>::growBy(size_t aIncr)
 {
   MOZ_REENTRANCY_GUARD_ET_AL;
   if (aIncr > mCapacity - mLength) {
     if (MOZ_UNLIKELY(!growStorageBy(aIncr))) {
       return false;
     }
--- a/mfbt/tests/TestBinarySearch.cpp
+++ b/mfbt/tests/TestBinarySearch.cpp
@@ -40,20 +40,20 @@ struct RangeFinder {
 };
 
 static void
 TestBinarySearch()
 {
   size_t m;
 
   Vector<int> v1;
-  v1.append(2);
-  v1.append(4);
-  v1.append(6);
-  v1.append(8);
+  MOZ_RELEASE_ASSERT(v1.append(2));
+  MOZ_RELEASE_ASSERT(v1.append(4));
+  MOZ_RELEASE_ASSERT(v1.append(6));
+  MOZ_RELEASE_ASSERT(v1.append(8));
 
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, v1.length(), 1, &m) && m == 0);
   MOZ_RELEASE_ASSERT( BinarySearch(v1, 0, v1.length(), 2, &m) && m == 0);
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, v1.length(), 3, &m) && m == 1);
   MOZ_RELEASE_ASSERT( BinarySearch(v1, 0, v1.length(), 4, &m) && m == 1);
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, v1.length(), 5, &m) && m == 2);
   MOZ_RELEASE_ASSERT( BinarySearch(v1, 0, v1.length(), 6, &m) && m == 2);
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, v1.length(), 7, &m) && m == 3);
@@ -73,19 +73,19 @@ TestBinarySearch()
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, 0, 0, &m) && m == 0);
   MOZ_RELEASE_ASSERT(!BinarySearch(v1, 0, 0, 9, &m) && m == 0);
 
   Vector<int> v2;
   MOZ_RELEASE_ASSERT(!BinarySearch(v2, 0, 0, 0, &m) && m == 0);
   MOZ_RELEASE_ASSERT(!BinarySearch(v2, 0, 0, 9, &m) && m == 0);
 
   Vector<Person> v3;
-  v3.append(Person(2, 42));
-  v3.append(Person(4, 13));
-  v3.append(Person(6, 360));
+  MOZ_RELEASE_ASSERT(v3.append(Person(2, 42)));
+  MOZ_RELEASE_ASSERT(v3.append(Person(4, 13)));
+  MOZ_RELEASE_ASSERT(v3.append(Person(6, 360)));
 
   A(!BinarySearch(GetAge(v3), 0, v3.length(), 1, &m) && m == 0);
   A( BinarySearch(GetAge(v3), 0, v3.length(), 2, &m) && m == 0);
   A(!BinarySearch(GetAge(v3), 0, v3.length(), 3, &m) && m == 1);
   A( BinarySearch(GetAge(v3), 0, v3.length(), 4, &m) && m == 1);
   A(!BinarySearch(GetAge(v3), 0, v3.length(), 5, &m) && m == 2);
   A( BinarySearch(GetAge(v3), 0, v3.length(), 6, &m) && m == 2);
   A(!BinarySearch(GetAge(v3), 0, v3.length(), 7, &m) && m == 3);