Bug 1358297: Part 4. Optimize Strip/CompressWhitespace as a special case using ASCIIMask. r=froydnj
☠☠ backed out by b820c2281605 ☠ ☠
authorMilan Sreckovic <milan@mozilla.com>
Fri, 05 May 2017 13:40:31 -0400
changeset 356830 95211a49619145612d3e55e95b9f596bd649f0cb
parent 356829 3c1b426a5cce74b34841fc608842518c8746f8f3
child 356831 92ec85d184950fe93974716b8cac3c9273e4e3aa
push id31775
push userihsiao@mozilla.com
push dateMon, 08 May 2017 03:10:38 +0000
treeherdermozilla-central@22aaf8bad4df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1358297
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 1358297: Part 4. Optimize Strip/CompressWhitespace as a special case using ASCIIMask. r=froydnj MozReview-Commit-ID: H43rS5WN5Ly
xpcom/string/nsStringObsolete.cpp
xpcom/string/nsTStringObsolete.cpp
--- a/xpcom/string/nsStringObsolete.cpp
+++ b/xpcom/string/nsStringObsolete.cpp
@@ -535,18 +535,16 @@ StripChars2(char16_t* aString,uint32_t a
     }
     *to = 0;
   }
   return to - (char16_t*)aString;
 }
 
 /* ***** END RICKG BLOCK ***** */
 
-static const char* kWhitespace="\f\t\r\n ";
-
 // This function is used to implement FindCharInSet and friends
 template <class CharT>
 #ifndef __SUNPRO_CC
 static
 #endif /* !__SUNPRO_CC */
 CharT
 GetFindInSetFilter( const CharT* set)
 {
--- a/xpcom/string/nsTStringObsolete.cpp
+++ b/xpcom/string/nsTStringObsolete.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsTArray.h"
+#include "nsASCIIMask.h"
 #include "mozilla/CheckedInt.h"
 
 /**
  * nsTString::Find
  *
  * aOffset specifies starting index
  * aCount specifies number of string compares (iterations)
  */
@@ -396,43 +397,49 @@ nsTString_CharT::SetCharAt( char16_t aCh
 
 /**
  * nsTString::StripChars,StripChar,StripWhitespace
  */
 
 void
 nsTString_CharT::StripChars( const char* aSet )
 {
-  if (!EnsureMutable())
+  if (!StripChars(aSet, mozilla::fallible)) {
     AllocFailed(mLength);
-
-  mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
+  }
 }
 
 bool
 nsTString_CharT::StripChars( const char* aSet, const fallible_t& )
 {
   if (!EnsureMutable()) {
     return false;
   }
 
   mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
   return true;
 }
 
 void
 nsTString_CharT::StripWhitespace()
 {
-  StripChars(kWhitespace);
+  if (!StripWhitespace(mozilla::fallible)) {
+    AllocFailed(mLength);
+  }
 }
 
 bool
-nsTString_CharT::StripWhitespace(const fallible_t& aFallible)
+nsTString_CharT::StripWhitespace( const fallible_t& )
 {
-  return StripChars(kWhitespace, aFallible);
+  if (!EnsureMutable()) {
+    return false;
+  }
+
+  StripTaggedASCII(mozilla::ASCIIMask::MaskWhitespace());
+  return true;
 }
 
 /**
  * nsTString::ReplaceChar,ReplaceSubstring
  */
 
 void
 nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
@@ -661,29 +668,60 @@ nsTString_CharT::Trim( const char* aSet,
 
     if (cutLength)
       Cut(cutEnd - cutLength, cutLength);
   }
 }
 
 
 /**
- * nsTString::CompressWhitespace
+ * nsTString::CompressWhitespace.
  */
 
 void
 nsTString_CharT::CompressWhitespace( bool aTrimLeading, bool aTrimTrailing )
 {
-  const char* set = kWhitespace;
+  // Quick exit
+  if (mLength == 0) {
+    return;
+  }
+
+  if (!EnsureMutable())
+    AllocFailed(mLength);
+
+  const ASCIIMaskArray& mask = mozilla::ASCIIMask::MaskWhitespace();
+
+  char_type* to   = mData;
+  char_type* from = mData;
+  char_type* end  = mData + mLength;
 
-  ReplaceChar(set, ' ');
-  Trim(set, aTrimLeading, aTrimTrailing);
+  // Compresses runs of whitespace down to a normal space ' ' and convert
+  // any whitespace to a normal space.  This assumes that whitespace is
+  // all standard 7-bit ASCII.
+  bool skipWS = aTrimLeading;
+  while (from < end) {
+    uint32_t theChar = *from++;
+    if (mozilla::ASCIIMask::IsMasked(mask, theChar)) {
+      if (!skipWS) {
+        *to++ = ' ';
+        skipWS = true;
+      }
+    } else {
+      *to++ = theChar;
+      skipWS = false;
+    }
+  }
 
-  // this one does some questionable fu... just copying the old code!
-  mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
+  // If we need to trim the trailing whitespace, back up one character.
+  if (aTrimTrailing && skipWS && to > mData) {
+    to--;
+  }
+
+  *to = char_type(0); // add the null
+  mLength = to - mData;
 }
 
 
 /**
  * nsTString::AssignWithConversion
  */
 
 void