Bug 887016 - Part 15: Use RegExpSearcher in RegExp.prototype[@@replace] optimized path. r=till
authorTooru Fujisawa <arai_a@mac.com>
Thu, 28 Jan 2016 18:56:09 +0900
changeset 292181 e6d08e4b452331d9d8d7fd4b827217bb95fc9331
parent 292180 b4e25cbe3dcbcf4018b59505816de535a0c29a07
child 292182 829fee28b3ea0dc0b2d81b60e693e510811253dd
push id74764
push userarai_a@mac.com
push dateThu, 07 Apr 2016 10:49:15 +0000
treeherdermozilla-inbound@4d0f975a2311 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs887016
milestone48.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 887016 - Part 15: Use RegExpSearcher in RegExp.prototype[@@replace] optimized path. r=till
js/src/builtin/RegExp.js
--- a/js/src/builtin/RegExp.js
+++ b/js/src/builtin/RegExp.js
@@ -182,18 +182,21 @@ function RegExpReplace(string, replaceVa
         firstDollarIndex = callFunction(std_String_indexOf, replaceValue, "$");
     }
 
     // Step 7.
     var global = !!rx.global;
 
     // Optimized paths for simple cases.
     if (!functionalReplace && firstDollarIndex === -1 && IsRegExpReplaceOptimizable(rx)) {
-        if (global)
+        if (global) {
+            if (lengthS < 0x7fff)
+                return RegExpGlobalReplaceShortOpt(rx, S, lengthS, replaceValue);
             return RegExpGlobalReplaceOpt(rx, S, lengthS, replaceValue);
+        }
         return RegExpLocalReplaceOpt(rx, S, lengthS, replaceValue);
     }
 
     // Step 8.
     var fullUnicode = false;
     if (global) {
         // Step 8.a.
         fullUnicode = !!rx.unicode;
@@ -342,16 +345,71 @@ function RegExpReplace(string, replaceVa
     // Step 15.
     if (nextSourcePosition >= lengthS)
         return accumulatedResult;
 
     // Step 16.
     return accumulatedResult + Substring(S, nextSourcePosition, lengthS - nextSourcePosition);
 }
 
+// ES 2016 draft Mar 25, 2016 21.2.5.8 steps 8.a-16.
+// Optimized path for @@replace with global flag, short string.
+function RegExpGlobalReplaceShortOpt(rx, S, lengthS, replaceValue)
+{
+   // Step 8.a.
+    var fullUnicode = !!rx.unicode;
+
+    // Step 8.b.
+    var lastIndex = 0;
+    rx.lastIndex = 0;
+
+    // Step 12 (reordered).
+    var accumulatedResult = "";
+
+    // Step 13 (reordered).
+    var nextSourcePosition = 0;
+
+    var sticky = !!rx.sticky;
+
+    // Step 11.
+    while (true) {
+        // Step 11.a.
+        var result = RegExpSearcher(rx, S, lastIndex, sticky);
+
+        // Step 11.b.
+        if (result === -1)
+            break;
+
+        var position = result & 0x7fff;
+        lastIndex = (result >> 15) & 0x7fff;
+
+        // Step 14.l.ii.
+        accumulatedResult += Substring(S, nextSourcePosition,
+                                       position - nextSourcePosition) + replaceValue;
+
+        // Step 14.l.iii.
+        nextSourcePosition = lastIndex;
+
+        // Step 11.c.iii.2.
+        if (lastIndex === position) {
+            lastIndex = fullUnicode ? AdvanceStringIndex(S, lastIndex) : lastIndex + 1;
+            if (lastIndex > lengthS)
+                break;
+        }
+    }
+
+    // Step 15.
+    if (nextSourcePosition >= lengthS)
+        return accumulatedResult;
+
+    // Step 16.
+    return accumulatedResult + Substring(S, nextSourcePosition, lengthS - nextSourcePosition);
+}
+
+// ES 2016 draft Mar 25, 2016 21.2.5.8 steps 8.a-16.
 // Optimized path for @@replace with global flag.
 function RegExpGlobalReplaceOpt(rx, S, lengthS, replaceValue)
 {
    // Step 8.a.
     var fullUnicode = !!rx.unicode;
 
     // Step 8.b.
     var lastIndex = 0;
@@ -405,16 +463,17 @@ function RegExpGlobalReplaceOpt(rx, S, l
     // Step 15.
     if (nextSourcePosition >= lengthS)
         return accumulatedResult;
 
     // Step 16.
     return accumulatedResult + Substring(S, nextSourcePosition, lengthS - nextSourcePosition);
 }
 
+// ES 2016 draft Mar 25, 2016 21.2.5.8 steps 11.a-16.
 // Optimized path for @@replace without global flag.
 function RegExpLocalReplaceOpt(rx, S, lengthS, replaceValue)
 {
     var sticky = !!rx.sticky;
 
     var lastIndex = sticky ? rx.lastIndex : 0;
 
     // Step 11.a.