Bug 1383646 - Optimize x.indexOf(x) for AngularJS. r=anba
authorTom Schuster <evilpies@gmail.com>
Fri, 28 Jul 2017 11:25:38 +0200
changeset 422808 5f8790aae878be61fcb64ff03fcdf51ae2689166
parent 422807 e781433714c456eb678826fb00725a630e88c736
child 422809 75902ad4c97a19b048160e3ef2470ad56ddfdcee
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1383646
milestone56.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 1383646 - Optimize x.indexOf(x) for AngularJS. r=anba
js/src/jit-test/tests/basic/indexof-equal.js
js/src/jsstr.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/indexof-equal.js
@@ -0,0 +1,10 @@
+var x = "abc";
+assertEq(x.indexOf(x), 0);
+assertEq(x.indexOf(x, -1), 0);
+assertEq(x.indexOf(x, 1), -1);
+assertEq(x.indexOf(x, 100), -1);
+
+assertEq(x.lastIndexOf(x), 0);
+assertEq(x.lastIndexOf(x, -1), 0);
+assertEq(x.lastIndexOf(x, 1), 0);
+assertEq(x.lastIndexOf(x, 100), 0);
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -2159,16 +2159,23 @@ js::str_indexOf(JSContext* cx, unsigned 
     }
 
    // Step 8
     uint32_t textLen = str->length();
 
     // Step 9
     uint32_t start = Min(Max(pos, 0U), textLen);
 
+    if (str == searchStr) {
+        // AngularJS often invokes "false".indexOf("false"). This check should
+        // be cheap enough to not hurt anything else.
+        args.rval().setInt32(start == 0 ? 0 : -1);
+        return true;
+    }
+
     // Steps 10 and 11
     JSLinearString* text = str->ensureLinear(cx);
     if (!text)
         return false;
 
     args.rval().setInt32(StringMatch(text, searchStr, start));
     return true;
 }
@@ -2243,16 +2250,21 @@ js::str_lastIndexOf(JSContext* cx, unsig
                 if (d <= 0)
                     start = 0;
                 else if (d < start)
                     start = int(d);
             }
         }
     }
 
+    if (str == searchStr) {
+        args.rval().setInt32(0);
+        return true;
+    }
+
     if (searchLen > len) {
         args.rval().setInt32(-1);
         return true;
     }
 
     if (searchLen == 0) {
         args.rval().setInt32(start);
         return true;