Bug 1462486 - Optimize copyCharsInternal for left-leaning ropes, r=jonco
authorSteve Fink <sfink@mozilla.com>
Thu, 17 May 2018 15:12:01 -0700
changeset 419181 da8925b18399d3740ae0207b01c59d9e2ef0ab1e
parent 419180 2698e931d8b863e5ab9d2bd5267768f3e9736a7d
child 419182 51f2535c797495f1f4e864072c2449b7c28669de
child 419248 a2dfc3fd6c0c4ea947e16ec9bfbc3712d2c7a626
push id34029
push usershindli@mozilla.com
push dateMon, 21 May 2018 21:30:22 +0000
treeherdermozilla-central@51f2535c7974 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1462486
milestone62.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 1462486 - Optimize copyCharsInternal for left-leaning ropes, r=jonco
js/src/vm/StringType.cpp
--- a/js/src/vm/StringType.cpp
+++ b/js/src/vm/StringType.cpp
@@ -302,48 +302,47 @@ JSRope::copyTwoByteChars(JSContext* cx, 
     return copyCharsInternal<char16_t>(cx, out, false);
 }
 
 template <typename CharT>
 bool
 JSRope::copyCharsInternal(JSContext* cx, ScopedJSFreePtr<CharT>& out,
                           bool nullTerminate) const
 {
-    /*
-     * Perform non-destructive post-order traversal of the rope, splatting
-     * each node's characters into a contiguous buffer.
-     */
+    // Left-leaning ropes are far more common than right-leaning ropes, so
+    // perform a non-destructive traversal of the rope, right node first,
+    // splatting each node's characters into a contiguous buffer.
 
     size_t n = length();
     if (cx)
         out.reset(cx->pod_malloc<CharT>(n + 1));
     else
         out.reset(js_pod_malloc<CharT>(n + 1));
 
     if (!out)
         return false;
 
     Vector<const JSString*, 8, SystemAllocPolicy> nodeStack;
     const JSString* str = this;
-    CharT* pos = out;
+    CharT* end = out + str->length();
     while (true) {
         if (str->isRope()) {
-            if (!nodeStack.append(str->asRope().rightChild()))
+            if (!nodeStack.append(str->asRope().leftChild()))
                 return false;
-            str = str->asRope().leftChild();
+            str = str->asRope().rightChild();
         } else {
-            CopyChars(pos, str->asLinear());
-            pos += str->length();
+            end -= str->length();
+            CopyChars(end, str->asLinear());
             if (nodeStack.empty())
                 break;
             str = nodeStack.popCopy();
         }
     }
 
-    MOZ_ASSERT(pos == out + n);
+    MOZ_ASSERT(end == out);
 
     if (nullTerminate)
         out[n] = 0;
 
     return true;
 }
 
 #ifdef DEBUG