Bug 887016 - Part 16: Use RegExpSearcher in RegExp.prototype[@@search] optimized path. r=till
☠☠ backed out by 7596439fda73 ☠ ☠
authorTooru Fujisawa <arai_a@mac.com>
Thu, 28 Jan 2016 18:56:12 +0900
changeset 290634 58946916593bf635aad899497442fcfd884e97c0
parent 290633 817e8aab2348ecd7a16df359e054ef8fb14491de
child 290635 b903c18bbb32c68c210a45da69ee3cbbe2ebeb41
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 16: Use RegExpSearcher in RegExp.prototype[@@search] optimized path. r=till
js/src/builtin/RegExp.js
--- a/js/src/builtin/RegExp.js
+++ b/js/src/builtin/RegExp.js
@@ -142,17 +142,23 @@ function RegExpMatch(string) {
             rx.lastIndex = fullUnicode ? AdvanceStringIndex(S, lastIndex) : lastIndex + 1;
         }
 
         // Step 6.e.iii.5.
         n++;
     }
 }
 
-function IsRegExpReplaceOptimizable(rx) {
+// Checks if following properties and getters are not modified, and accessing
+// them not observed by content script:
+//   * global
+//   * sticky
+//   * exec
+//   * lastIndex
+function IsRegExpMethodOptimizable(rx) {
     var RegExpProto = GetBuiltinPrototype("RegExp");
     // If RegExpPrototypeOptimizable and RegExpInstanceOptimizable succeed,
     // `RegExpProto.exec` is guaranteed to be data properties.
     return RegExpPrototypeOptimizable(RegExpProto) &&
            RegExpInstanceOptimizable(rx, RegExpProto) &&
            RegExpProto.exec === RegExp_prototype_Exec;
 }
 
@@ -181,17 +187,17 @@ function RegExpReplace(string, replaceVa
         replaceValue = ToString(replaceValue);
         firstDollarIndex = callFunction(std_String_indexOf, replaceValue, "$");
     }
 
     // Step 7.
     var global = !!rx.global;
 
     // Optimized paths for simple cases.
-    if (!functionalReplace && firstDollarIndex === -1 && IsRegExpReplaceOptimizable(rx)) {
+    if (!functionalReplace && firstDollarIndex === -1 && IsRegExpMethodOptimizable(rx)) {
         if (global) {
             if (lengthS < 0x7fff)
                 return RegExpGlobalReplaceShortOpt(rx, S, lengthS, replaceValue);
             return RegExpGlobalReplaceOpt(rx, S, lengthS, replaceValue);
         }
         return RegExpLocalReplaceOpt(rx, S, lengthS, replaceValue);
     }
 
@@ -520,24 +526,39 @@ function RegExpSearch(string) {
 
     // Step 2.
     if (!IsObject(rx))
         ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, rx === null ? "null" : typeof rx);
 
     // Step 3.
     var S = ToString(string);
 
+    var result;
+    if (IsRegExpMethodOptimizable(rx) && S.length < 0x7fff) {
+        var sticky = !!rx.sticky;
+
+        // Step 6.
+        result = RegExpSearcher(rx, S, 0, sticky);
+
+        // Step 8.
+        if (result === -1)
+            return -1;
+
+        // Step 9.
+        return result & 0x7fff;
+    }
+
     // Step 4.
     var previousLastIndex = rx.lastIndex;
 
     // Step 5.
     rx.lastIndex = 0;
 
     // Step 6.
-    var result = RegExpExec(rx, S, false);
+    result = RegExpExec(rx, S, false);
 
     // Step 7.
     rx.lastIndex = previousLastIndex;
 
     // Step 8.
     if (result === null)
         return -1;