Bug 887016 - Part 15: Use RegExpSearcher in RegExp.prototype[@@replace] optimized path. r=till
☠☠ backed out by 9cb8165a2a66 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Thu, 28 Jan 2016 18:56:09 +0900
changeset 290633 817e8aab2348ecd7a16df359e054ef8fb14491de
parent 290632 7db6a99ec5462372a107b3e346aa8c1ecffaa4ae
child 290634 58946916593bf635aad899497442fcfd884e97c0
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs887016
milestone48.0a1
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.