Bug 1271022 - add Vector::podResizeToFit (r=njn)
authorLuke Wagner <luke@mozilla.com>
Mon, 09 May 2016 08:59:10 -0500
changeset 321141 29e3f72069b43ba17c52cf36c8150da58e667462
parent 321140 7865878fa033018bc4ba8145a5417919505509e2
child 321142 6f2ac4c6db274d41a6e693010b249d043c6540f5
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1271022
milestone49.0a1
Bug 1271022 - add Vector::podResizeToFit (r=njn) MozReview-Commit-ID: 9HTY6O9GY4U
mfbt/Vector.h
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -224,16 +224,30 @@ struct VectorImpl<T, N, AP, true>
     if (MOZ_UNLIKELY(!newbuf)) {
       return false;
     }
     aV.mBegin = newbuf;
     /* aV.mLength is unchanged. */
     aV.mCapacity = aNewCap;
     return true;
   }
+
+  static inline void
+  podResizeToFit(Vector<T, N, AP>& aV)
+  {
+    if (aV.usingInlineStorage() || aV.mLength == aV.mCapacity) {
+      return;
+    }
+    T* newbuf = aV.template pod_realloc<T>(aV.mBegin, aV.mCapacity, aV.mLength);
+    if (MOZ_UNLIKELY(!newbuf)) {
+      return;
+    }
+    aV.mBegin = newbuf;
+    aV.mCapacity = aV.mLength;
+  }
 };
 
 // A struct for TestVector.cpp to access private internal fields.
 // DO NOT DEFINE IN YOUR OWN CODE.
 struct VectorTesting;
 
 } // namespace detail
 
@@ -555,16 +569,23 @@ public:
 
   /** Shorthand for shrinkBy(length()). */
   void clear();
 
   /** Clears and releases any heap-allocated storage. */
   void clearAndFree();
 
   /**
+   * Calls the AllocPolicy's pod_realloc to release excess capacity. Since
+   * realloc is only safe on PODs, this method fails to compile if IsPod<T>
+   * is false.
+   */
+  void podResizeToFit();
+
+  /**
    * If true, appending |aNeeded| elements won't reallocate elements storage.
    * This *doesn't* mean that infallibleAppend may be used!  You still must
    * reserve the extra space, even if this method indicates that appends won't
    * need to reallocate elements storage.
    */
   bool canAppendWithoutRealloc(size_t aNeeded) const;
 
   /** Potentially fallible append operations. */
@@ -1099,16 +1120,25 @@ Vector<T, N, AP>::clearAndFree()
   mBegin = static_cast<T*>(mStorage.addr());
   mCapacity = kInlineCapacity;
 #ifdef DEBUG
   mReserved = 0;
 #endif
 }
 
 template<typename T, size_t N, class AP>
+inline void
+Vector<T, N, AP>::podResizeToFit()
+{
+  // This function is only defined if IsPod is true and will fail to compile
+  // otherwise.
+  Impl::podResizeToFit(*this);
+}
+
+template<typename T, size_t N, class AP>
 inline bool
 Vector<T, N, AP>::canAppendWithoutRealloc(size_t aNeeded) const
 {
   return mLength + aNeeded <= mCapacity;
 }
 
 template<typename T, size_t N, class AP>
 template<typename U, size_t O, class BP>