Bug 1349719 - Share max capacity logic in nsTString. r=froydnj
authorEric Rahm <erahm@mozilla.com>
Thu, 23 Mar 2017 12:32:53 -0700
changeset 349390 ac2f80412724b28f3a89cf2d8262bc92d400dbf5
parent 349389 c8379919d781f0aeb8eadf124f47ed89541731ed
child 349391 ebcd681132b2c2aeea106a49f037da7428bb19c5
push id31551
push usercbook@mozilla.com
push dateFri, 24 Mar 2017 13:24:56 +0000
treeherdermozilla-central@4c987b7ed54a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1349719
milestone55.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 1349719 - Share max capacity logic in nsTString. r=froydnj This refactors the max capacity logic so that both |MutatePrep| and |Adopt| can share it. MozReview-Commit-ID: CMn4kiAoWub
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -6,16 +6,21 @@
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/double-conversion.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Printf.h"
 
 using double_conversion::DoubleToStringConverter;
 
+const nsTSubstring_CharT::size_type nsTSubstring_CharT::kMaxCapacity =
+    (nsTSubstring_CharT::size_type(-1) /
+        2 - sizeof(nsStringBuffer)) /
+    sizeof(nsTSubstring_CharT::char_type) - 2;
+
 #ifdef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
 nsTSubstring_CharT::nsTSubstring_CharT(char_type* aData, size_type aLength,
                                        uint32_t aFlags)
   : nsTStringRepr_CharT(aData, aLength, aFlags)
 {
   if (aFlags & F_OWNED) {
     STRING_STAT_INCREMENT(Adopt);
     MOZ_LOG_CTOR(mData, "StringAdopt", 1);
@@ -49,23 +54,18 @@ nsTSubstring_CharT::MutatePrep(size_type
 
   size_type curCapacity = Capacity();
 
   // If |aCapacity > kMaxCapacity|, then our doubling algorithm may not be
   // able to allocate it.  Just bail out in cases like that.  We don't want
   // to be allocating 2GB+ strings anyway.
   static_assert((sizeof(nsStringBuffer) & 0x1) == 0,
                 "bad size for nsStringBuffer");
-  const size_type kMaxCapacity =
-    (size_type(-1) / 2 - sizeof(nsStringBuffer)) / sizeof(char_type) - 2;
-  if (aCapacity > kMaxCapacity) {
-    // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
-    // use that value to flag immutability.
-    NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
-    return false;
+  if (!CheckCapacity(aCapacity)) {
+      return false;
   }
 
   // |curCapacity == 0| means that the buffer is immutable or 0-sized, so we
   // need to allocate a new buffer. We cannot use the existing buffer even
   // though it might be large enough.
 
   if (curCapacity != 0) {
     if (aCapacity <= curCapacity) {
@@ -503,16 +503,18 @@ nsTSubstring_CharT::Adopt(char_type* aDa
 {
   if (aData) {
     ::ReleaseData(mData, mFlags);
 
     if (aLength == size_type(-1)) {
       aLength = char_traits::length(aData);
     }
 
+    MOZ_RELEASE_ASSERT(CheckCapacity(aLength), "adopting a too-long string");
+
     mData = aData;
     mLength = aLength;
     SetDataFlags(F_TERMINATED | F_OWNED);
 
     STRING_STAT_INCREMENT(Adopt);
     // Treat this as construction of a "StringAdopt" object for leak
     // tracking purposes.
     MOZ_LOG_CTOR(mData, "StringAdopt", 1);
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -1106,27 +1106,42 @@ protected:
   /**
    * this helper function can be called prior to directly manipulating
    * the contents of mData.  see, for example, BeginWriting.
    */
   MOZ_MUST_USE bool NS_FASTCALL EnsureMutable(
     size_type aNewLen = size_type(-1));
 
   /**
+   * Checks if the given capacity is valid for this string type.
+   */
+  static MOZ_MUST_USE bool CheckCapacity(size_type aCapacity) {
+    if (aCapacity > kMaxCapacity) {
+      // Also assert for |aCapacity| equal to |size_type(-1)|, since we used to
+      // use that value to flag immutability.
+      NS_ASSERTION(aCapacity != size_type(-1), "Bogus capacity");
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
    * this helper function stores the specified dataFlags in mFlags
    */
   void SetDataFlags(uint32_t aDataFlags)
   {
     NS_ASSERTION((aDataFlags & 0xFFFF0000) == 0, "bad flags");
     mFlags = aDataFlags | (mFlags & 0xFFFF0000);
   }
 
   void NS_FASTCALL ReplaceLiteral(index_type aCutStart, size_type aCutLength,
                                   const char_type* aData, size_type aLength);
 
+  static const size_type kMaxCapacity;
 public:
 
   // NOTE: this method is declared public _only_ for convenience for
   // callers who don't have access to the original nsLiteralString_CharT.
   void NS_FASTCALL AssignLiteral(const char_type* aData, size_type aLength);
 };
 
 static_assert(sizeof(nsTSubstring_CharT) ==