Bug 1386381 - nsTextFragment::SetTo() could be faster by allocating less often, p=makoto,smaug, r=makoto,smaug
authorm_kato@ga2.so-net.ne.jp
Tue, 09 Jan 2018 15:36:01 +0200
changeset 452669 a0cf29a08c3d44b62d740cea24f524a9c8fd450b
parent 452668 469468b7a0706f5c14c3eef902e09ab693832a35
child 452670 9bcdad9d7f4372f12125a42b6f4a413566e0fe8e
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmakoto, smaug
bugs1386381
milestone59.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 1386381 - nsTextFragment::SetTo() could be faster by allocating less often, p=makoto,smaug, r=makoto,smaug
dom/base/nsTextFragment.cpp
--- a/dom/base/nsTextFragment.cpp
+++ b/dom/base/nsTextFragment.cpp
@@ -197,16 +197,45 @@ FirstNon8Bit(const char16_t *str, const 
 
   return FirstNon8BitUnvectorized(str, end);
 }
 
 bool
 nsTextFragment::SetTo(const char16_t* aBuffer, int32_t aLength,
                       bool aUpdateBidi, bool aForce2b)
 {
+  if (aForce2b && mState.mIs2b && !m2b->IsReadonly()) {
+    uint32_t storageSize = m2b->StorageSize();
+    uint32_t neededSize = aLength * sizeof(char16_t);
+    if (!neededSize) {
+      if (storageSize < AutoStringDefaultStorageSize) {
+        // If we're storing small enough nsStringBuffer, let's preserve it.
+
+        static_cast<char16_t*>(m2b->Data())[0] = char16_t(0);
+        mState.mLength = 0;
+        mState.mIsBidi = false;
+        return true;
+      }
+    } else if ((neededSize < storageSize) &&
+               ((storageSize / 2) <
+                (neededSize + AutoStringDefaultStorageSize))) {
+      // Don't try to reuse the existing nsStringBuffer, if it would have
+      // lots of unused space.
+
+      memcpy(m2b->Data(), aBuffer, neededSize);
+      static_cast<char16_t*>(m2b->Data())[aLength] = char16_t(0);
+      mState.mLength = aLength;
+      mState.mIsBidi = false;
+      if (aUpdateBidi) {
+        UpdateBidiFlag(aBuffer, aLength);
+      }
+      return true;
+    }
+  }
+
   ReleaseText();
 
   if (aLength == 0) {
     return true;
   }
 
   char16_t firstChar = *aBuffer;
   if (!aForce2b && aLength == 1 && firstChar < 256) {