Bug 1097283: Fix count/byte mismatches in NS_ABORT_OOM calls. r=froydnj
authorDavid Major <dmajor@mozilla.com>
Wed, 12 Nov 2014 21:13:44 +1300
changeset 239507 2cedc0acd40b6e12de9ce0c10cce10db48c80855
parent 239506 f96fe425680e30cefeed2919cc6adb750d75ff47
child 239508 53e23b1b36424ede6967be5d23148cebddac5752
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1097283
milestone36.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 1097283: Fix count/byte mismatches in NS_ABORT_OOM calls. r=froydnj
dom/base/nsTextFragment.h
xpcom/glue/nsDeque.h
xpcom/string/nsReadableUtils.cpp
xpcom/string/nsStringObsolete.cpp
xpcom/string/nsTStringObsolete.cpp
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
--- a/dom/base/nsTextFragment.h
+++ b/dom/base/nsTextFragment.h
@@ -121,17 +121,17 @@ public:
    */
   bool Append(const char16_t* aBuffer, uint32_t aLength, bool aUpdateBidi);
 
   /**
    * Append the contents of this string fragment to aString
    */
   void AppendTo(nsAString& aString) const {
     if (!AppendTo(aString, mozilla::fallible_t())) {
-      NS_ABORT_OOM(GetLength());
+      aString.AllocFailed(aString.Length() + GetLength());
     }
   }
 
   /**
    * Append the contents of this string fragment to aString
    * @return false if an out of memory condition is detected, true otherwise
    */
   bool AppendTo(nsAString& aString,
@@ -151,17 +151,17 @@ public:
 
   /**
    * Append a substring of the contents of this string fragment to aString.
    * @param aOffset where to start the substring in this text fragment
    * @param aLength the length of the substring
    */
   void AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength) const {
     if (!AppendTo(aString, aOffset, aLength, mozilla::fallible_t())) {
-      NS_ABORT_OOM(aLength);
+      aString.AllocFailed(aString.Length() + aLength);
     }
   }
 
   /**
    * Append a substring of the contents of this string fragment to aString.
    * @param aString the string in which to append
    * @param aOffset where to start the substring in this text fragment
    * @param aLength the length of the substring
--- a/xpcom/glue/nsDeque.h
+++ b/xpcom/glue/nsDeque.h
@@ -80,31 +80,31 @@ public:
   /**
    * Appends new member at the end of the deque.
    *
    * @param   item to store in deque
    */
   void Push(void* aItem)
   {
     if (!Push(aItem, fallible_t())) {
-      NS_ABORT_OOM(mSize);
+      NS_ABORT_OOM(mSize * sizeof(void*));
     }
   }
 
   NS_WARN_UNUSED_RESULT bool Push(void* aItem, const fallible_t&);
 
   /**
    * Inserts new member at the front of the deque.
    *
    * @param   item to store in deque
    */
   void PushFront(void* aItem)
   {
     if (!PushFront(aItem, fallible_t())) {
-      NS_ABORT_OOM(mSize);
+      NS_ABORT_OOM(mSize * sizeof(void*));
     }
   }
 
   NS_WARN_UNUSED_RESULT bool PushFront(void* aItem, const fallible_t&);
 
   /**
    * Remove and return the last item in the container.
    *
--- a/xpcom/string/nsReadableUtils.cpp
+++ b/xpcom/string/nsReadableUtils.cpp
@@ -90,17 +90,17 @@ LossyAppendUTF16toASCII(const nsAString&
   copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd),
               converter);
 }
 
 void
 AppendASCIItoUTF16(const nsACString& aSource, nsAString& aDest)
 {
   if (!AppendASCIItoUTF16(aSource, aDest, mozilla::fallible_t())) {
-    NS_ABORT_OOM(aDest.Length() + aSource.Length());
+    aDest.AllocFailed(aDest.Length() + aSource.Length());
   }
 }
 
 bool
 AppendASCIItoUTF16(const nsACString& aSource, nsAString& aDest,
                    const mozilla::fallible_t&)
 {
   uint32_t old_dest_length = aDest.Length();
@@ -139,17 +139,17 @@ AppendASCIItoUTF16(const char* aSource, 
     AppendASCIItoUTF16(nsDependentCString(aSource), aDest);
   }
 }
 
 void
 AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest)
 {
   if (!AppendUTF16toUTF8(aSource, aDest, mozilla::fallible_t())) {
-    NS_ABORT_OOM(aDest.Length() + aSource.Length());
+    aDest.AllocFailed(aDest.Length() + aSource.Length());
   }
 }
 
 bool
 AppendUTF16toUTF8(const nsAString& aSource, nsACString& aDest,
                   const mozilla::fallible_t&)
 {
   nsAString::const_iterator source_start, source_end;
@@ -180,17 +180,17 @@ AppendUTF16toUTF8(const nsAString& aSour
 
   return true;
 }
 
 void
 AppendUTF8toUTF16(const nsACString& aSource, nsAString& aDest)
 {
   if (!AppendUTF8toUTF16(aSource, aDest, mozilla::fallible_t())) {
-    NS_ABORT_OOM(aDest.Length() + aSource.Length());
+    aDest.AllocFailed(aDest.Length() + aSource.Length());
   }
 }
 
 bool
 AppendUTF8toUTF16(const nsACString& aSource, nsAString& aDest,
                   const mozilla::fallible_t&)
 {
   nsACString::const_iterator source_start, source_end;
--- a/xpcom/string/nsStringObsolete.cpp
+++ b/xpcom/string/nsStringObsolete.cpp
@@ -914,17 +914,17 @@ nsString::FindCharInSet( const char16_t*
     result += aOffset;
   return result;
 }
 
 void
 nsString::ReplaceChar( const char16_t* aSet, char16_t aNewChar )
 {
   if (!EnsureMutable()) // XXX do this lazily?
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
 
   char16_t* data = mData;
   uint32_t lenRemaining = mLength;
 
   while (lenRemaining)
   {
     int32_t i = ::FindCharInSet(data, lenRemaining, aSet);
     if (i == kNotFound)
--- a/xpcom/string/nsTStringObsolete.cpp
+++ b/xpcom/string/nsTStringObsolete.cpp
@@ -381,32 +381,32 @@ nsTString_CharT::Mid( self_type& aResult
 
 bool
 nsTString_CharT::SetCharAt( char16_t aChar, uint32_t aIndex )
 {
   if (aIndex >= mLength)
     return false;
 
   if (!EnsureMutable())
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
 
   mData[aIndex] = CharT(aChar);
   return true;
 }
 
 
 /**
  * nsTString::StripChars,StripChar,StripWhitespace
  */
 
 void
 nsTString_CharT::StripChars( const char* aSet )
 {
   if (!EnsureMutable())
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
 
   mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
 }
 
 void
 nsTString_CharT::StripWhitespace()
 {
   StripChars(kWhitespace);
@@ -416,30 +416,30 @@ nsTString_CharT::StripWhitespace()
 /**
  * nsTString::ReplaceChar,ReplaceSubstring
  */
 
 void
 nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
 {
   if (!EnsureMutable()) // XXX do this lazily?
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
 
   for (uint32_t i=0; i<mLength; ++i)
   {
     if (mData[i] == aOldChar)
       mData[i] = aNewChar;
   }
 }
 
 void
 nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
 {
   if (!EnsureMutable()) // XXX do this lazily?
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
 
   char_type* data = mData;
   uint32_t lenRemaining = mLength;
 
   while (lenRemaining)
   {
     int32_t i = ::FindCharInSet(data, lenRemaining, aSet);
     if (i == kNotFound)
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -258,17 +258,17 @@ nsTSubstring_CharT::EnsureMutable(size_t
 
 // ---------------------------------------------------------------------------
 
 // This version of Assign is optimized for single-character assignment.
 void
 nsTSubstring_CharT::Assign(char_type aChar)
 {
   if (!ReplacePrep(0, mLength, 1)) {
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
   }
 
   *mData = aChar;
 }
 
 bool
 nsTSubstring_CharT::Assign(char_type aChar, const fallible_t&)
 {
@@ -279,26 +279,26 @@ nsTSubstring_CharT::Assign(char_type aCh
   *mData = aChar;
   return true;
 }
 
 void
 nsTSubstring_CharT::Assign(const char_type* aData)
 {
   if (!Assign(aData, size_type(-1), fallible_t())) {
-    NS_ABORT_OOM(char_traits::length(aData));
+    AllocFailed(char_traits::length(aData));
   }
 }
 
 void
 nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength)
 {
   if (!Assign(aData, aLength, fallible_t())) {
-    NS_ABORT_OOM(aLength == size_type(-1) ? char_traits::length(aData)
-                                          : aLength);
+    AllocFailed(aLength == size_type(-1) ? char_traits::length(aData)
+                                         : aLength);
   }
 }
 
 bool
 nsTSubstring_CharT::Assign(const char_type* aData, size_type aLength,
                            const fallible_t&)
 {
   if (!aData || aLength == 0) {
@@ -321,17 +321,17 @@ nsTSubstring_CharT::Assign(const char_ty
   char_traits::copy(mData, aData, aLength);
   return true;
 }
 
 void
 nsTSubstring_CharT::AssignASCII(const char* aData, size_type aLength)
 {
   if (!AssignASCII(aData, aLength, fallible_t())) {
-    NS_ABORT_OOM(aLength);
+    AllocFailed(aLength);
   }
 }
 
 bool
 nsTSubstring_CharT::AssignASCII(const char* aData, size_type aLength,
                                 const fallible_t&)
 {
   // A Unicode string can't depend on an ASCII string buffer,
@@ -358,17 +358,17 @@ nsTSubstring_CharT::AssignLiteral(const 
   mLength = aLength;
   SetDataFlags(F_TERMINATED | F_LITERAL);
 }
 
 void
 nsTSubstring_CharT::Assign(const self_type& aStr)
 {
   if (!Assign(aStr, fallible_t())) {
-    NS_ABORT_OOM(aStr.Length());
+    AllocFailed(aStr.Length());
   }
 }
 
 bool
 nsTSubstring_CharT::Assign(const self_type& aStr, const fallible_t&)
 {
   // |aStr| could be sharable. We need to check its flags to know how to
   // deal with it.
@@ -408,17 +408,17 @@ nsTSubstring_CharT::Assign(const self_ty
   // else, treat this like an ordinary assignment.
   return Assign(aStr.Data(), aStr.Length(), fallible_t());
 }
 
 void
 nsTSubstring_CharT::Assign(const substring_tuple_type& aTuple)
 {
   if (!Assign(aTuple, fallible_t())) {
-    NS_ABORT_OOM(aTuple.Length());
+    AllocFailed(aTuple.Length());
   }
 }
 
 bool
 nsTSubstring_CharT::Assign(const substring_tuple_type& aTuple,
                            const fallible_t&)
 {
   if (aTuple.IsDependentOn(mData, mData + mLength)) {
@@ -500,17 +500,17 @@ nsTSubstring_CharT::Replace(index_type a
 }
 
 void
 nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength,
                             const char_type* aData, size_type aLength)
 {
   if (!Replace(aCutStart, aCutLength, aData, aLength,
                mozilla::fallible_t())) {
-    NS_ABORT_OOM(Length() - aCutLength + 1);
+    AllocFailed(Length() - aCutLength + 1);
   }
 }
 
 bool
 nsTSubstring_CharT::Replace(index_type aCutStart, size_type aCutLength,
                             const char_type* aData, size_type aLength,
                             const mozilla::fallible_t&)
 {
@@ -598,17 +598,17 @@ nsTSubstring_CharT::ReplaceLiteral(index
     char_traits::copy(mData + aCutStart, aData, aLength);
   }
 }
 
 void
 nsTSubstring_CharT::SetCapacity(size_type aCapacity)
 {
   if (!SetCapacity(aCapacity, fallible_t())) {
-    NS_ABORT_OOM(aCapacity);
+    AllocFailed(aCapacity);
   }
 }
 
 bool
 nsTSubstring_CharT::SetCapacity(size_type aCapacity, const fallible_t&)
 {
   // capacity does not include room for the terminating null char
 
@@ -779,17 +779,17 @@ nsTSubstring_CharT::FindChar(char_type a
 void
 nsTSubstring_CharT::StripChar(char_type aChar, int32_t aOffset)
 {
   if (mLength == 0 || aOffset >= int32_t(mLength)) {
     return;
   }
 
   if (!EnsureMutable()) { // XXX do this lazily?
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
   }
 
   // XXX(darin): this code should defer writing until necessary.
 
   char_type* to   = mData + aOffset;
   char_type* from = mData + aOffset;
   char_type* end  = mData + mLength;
 
@@ -806,17 +806,17 @@ nsTSubstring_CharT::StripChar(char_type 
 void
 nsTSubstring_CharT::StripChars(const char_type* aChars, uint32_t aOffset)
 {
   if (aOffset >= uint32_t(mLength)) {
     return;
   }
 
   if (!EnsureMutable()) { // XXX do this lazily?
-    NS_ABORT_OOM(mLength);
+    AllocFailed(mLength);
   }
 
   // XXX(darin): this code should defer writing until necessary.
 
   char_type* to   = mData + aOffset;
   char_type* from = mData + aOffset;
   char_type* end  = mData + mLength;
 
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -141,31 +141,31 @@ public:
 
   /**
    * writing iterators
    */
 
   char_iterator BeginWriting()
   {
     if (!EnsureMutable()) {
-      NS_ABORT_OOM(mLength);
+      AllocFailed(mLength);
     }
 
     return mData;
   }
 
   char_iterator BeginWriting(const fallible_t&)
   {
     return EnsureMutable() ? mData : char_iterator(0);
   }
 
   char_iterator EndWriting()
   {
     if (!EnsureMutable()) {
-      NS_ABORT_OOM(mLength);
+      AllocFailed(mLength);
     }
 
     return mData + mLength;
   }
 
   char_iterator EndWriting(const fallible_t&)
   {
     return EnsureMutable() ? (mData + mLength) : char_iterator(0);
@@ -737,17 +737,17 @@ public:
    * length of the string).
    *
    * @returns The length of the buffer in characters or 0 if unable to
    * satisfy the request due to low-memory conditions.
    */
   size_type GetMutableData(char_type** aData, size_type aNewLen = size_type(-1))
   {
     if (!EnsureMutable(aNewLen)) {
-      NS_ABORT_OOM(aNewLen == size_type(-1) ? mLength : aNewLen);
+      AllocFailed(aNewLen == size_type(-1) ? mLength : aNewLen);
     }
 
     *aData = mData;
     return mLength;
   }
 
   size_type GetMutableData(char_type** aData, size_type aNewLen, const fallible_t&)
   {
@@ -864,16 +864,30 @@ public:
    * you do use them, please explain clearly in a comment why it's safe
    * and won't lead to double-counting.
    */
   size_t SizeOfExcludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
   const;
   size_t SizeOfIncludingThisEvenIfShared(mozilla::MallocSizeOf aMallocSizeOf)
   const;
 
+  template<class T>
+  void NS_ABORT_OOM(T)
+  {
+    struct never {};
+    static_assert(mozilla::IsSame<T, never>::value,
+      "In string classes, use AllocFailed to account for sizeof(char_type). "
+      "Use the global ::NS_ABORT_OOM if you really have a count of bytes.");
+  }
+
+  MOZ_ALWAYS_INLINE void AllocFailed(size_t aLength)
+  {
+    ::NS_ABORT_OOM(aLength * sizeof(char_type));
+  }
+
 protected:
 
   friend class nsTObsoleteAStringThunk_CharT;
   friend class nsTSubstringTuple_CharT;
 
   // XXX GCC 3.4 needs this :-(
   friend class nsTPromiseFlatString_CharT;