Bug 1038593 - IonMonkey: Implement RRegExpExec. r=nbp
authorLawrence Abadier <LawrenceAbadier@hotmail.com>
Tue, 19 Aug 2014 18:16:31 +0200
changeset 200395 8b1bfc63995e758c17bea8f5bc1a2ec254ae05b1
parent 200394 b7aa62ee02a563a59007330c19bf727124780391
child 200396 bf759fde3847030e10651818e2e4ffdcc09d6359
push id27342
push userryanvm@gmail.com
push dateTue, 19 Aug 2014 20:23:11 +0000
treeherdermozilla-central@149d3ce6e020 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1038593
milestone34.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 1038593 - IonMonkey: Implement RRegExpExec. r=nbp
js/src/jit-test/tests/ion/dce-with-rinstructions.js
js/src/jit/MIR.h
js/src/jit/Recover.cpp
js/src/jit/Recover.h
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -560,16 +560,123 @@ var uceFault_str_split = eval(uneval(uce
 function rstr_split(i) {
     var x = "str01234567899876543210rts".split("" + i);
     if (uceFault_str_split(i) || uceFault_str_split(i)) {
         assertEq(x[0], "str012345678");
     }
     return i;
 }
 
+var uceFault_regexp_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_exec'))
+function rregexp_exec(i) {
+    var re = new RegExp("(str)\\d+" + i + "\\d+rts");
+    var res = re.exec("str01234567899876543210rts");
+    if (uceFault_regexp_exec(i) || uceFault_regexp_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    return i;
+}
+var uceFault_regexp_y_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_y_exec'))
+function rregexp_y_exec(i) {
+    var re = new RegExp("(str)\\d+" + (i % 10), "y");
+    var res = re.exec("str00123456789");
+    if (uceFault_regexp_y_exec(i) || uceFault_regexp_y_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, false);
+    return i;
+}
+
+var uceFault_regexp_y_literal_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_y_literal_exec'))
+function rregexp_y_literal_exec(i) {
+    var re = /(str)\d*0/y;
+    var res = re.exec("str00123456789");
+    if (uceFault_regexp_y_literal_exec(i) || uceFault_regexp_y_literal_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, false);
+    return i;
+}
+
+var uceFault_regexp_g_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_g_exec'))
+function rregexp_g_exec(i) {
+    var re = new RegExp("(str)\\d+" + (i % 10), "g");
+    var res = re.exec("str00123456789str00123456789");
+    if (uceFault_regexp_g_exec(i) || uceFault_regexp_g_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, false);
+    return i;
+}
+
+var uceFault_regexp_g_literal_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_g_literal_exec'))
+function rregexp_g_literal_exec(i) {
+    var re = /(str)\d*0/g;
+    var res = re.exec("str00123456789str00123456789");
+    if (uceFault_regexp_g_literal_exec(i) || uceFault_regexp_g_literal_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, false);
+    return i;
+}
+
+var uceFault_regexp_i_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_i_exec'))
+function rregexp_i_exec(i) {
+    var re = new RegExp("(str)\\d+" + (i % 10), "i");
+    var res = re.exec("STR00123456789");
+    if (uceFault_regexp_i_exec(i) || uceFault_regexp_i_exec(i)) {
+        assertEq(res[1], "STR");
+    }
+
+    assertEq(re.lastIndex == 0, true);
+    return i;
+}
+
+var uceFault_regexp_i_literal_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_i_literal_exec'))
+function rregexp_i_literal_exec(i) {
+    var re = /(str)\d*0/i;
+    var res = re.exec("STR00123456789");
+    if (uceFault_regexp_i_literal_exec(i) || uceFault_regexp_i_literal_exec(i)) {
+        assertEq(res[1], "STR");
+    }
+
+    assertEq(re.lastIndex == 0, true);
+    return i;
+}
+
+
+var uceFault_regexp_m_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_m_exec'))
+function rregexp_m_exec(i) {
+    var re = new RegExp("^(str)\\d+" + (i % 10), "m");
+    var res = re.exec("abc\nstr00123456789");
+    if (uceFault_regexp_m_exec(i) || uceFault_regexp_m_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, true);
+    return i;
+}
+
+var uceFault_regexp_m_literal_exec = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_m_literal_exec'))
+function rregexp_m_literal_exec(i) {
+    var re = /^(str)\d*0/m;
+    var res = re.exec("abc\nstr00123456789");
+    if (uceFault_regexp_m_literal_exec(i) || uceFault_regexp_m_literal_exec(i)) {
+        assertEq(res[1], "str");
+    }
+
+    assertEq(re.lastIndex == 0, true);
+    return i;
+}
+
 var uceFault_regexp_test = eval(uneval(uceFault).replace('uceFault', 'uceFault_regexp_test'))
 function rregexp_test(i) {
     var re = new RegExp("str\\d+" + i + "\\d+rts");
     var res = re.test("str01234567899876543210rts");
     if (uceFault_regexp_test(i) || uceFault_regexp_test(i)) {
         assertEq(res, true);
     }
     return i;
@@ -727,16 +834,25 @@ for (i = 0; i < 100; i++) {
     rabs_number(i);
     rabs_object(i);
     rsqrt_number(i);
     rsqrt_float(i);
     rsqrt_object(i);
     ratan2_number(i);
     ratan2_object(i);
     rstr_split(i);
+    rregexp_exec(i);
+    rregexp_y_exec(i);
+    rregexp_y_literal_exec(i);
+    rregexp_g_exec(i);
+    rregexp_g_literal_exec(i);
+    rregexp_i_exec(i);
+    rregexp_i_literal_exec(i);
+    rregexp_m_exec(i);
+    rregexp_m_literal_exec(i);
     rregexp_test(i);
     rregexp_y_test(i);
     rregexp_y_literal_test(i);
     rregexp_g_test(i);
     rregexp_g_literal_test(i);
     rregexp_i_test(i);
     rregexp_i_literal_test(i);
     rregexp_m_test(i);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -5981,16 +5981,24 @@ class MRegExpExec
     MDefinition *regexp() const {
         return getOperand(1);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+
+    bool canRecoverOnBailout() const {
+        if (regexp()->isRegExp())
+            return !regexp()->toRegExp()->source()->needUpdateLastIndex();
+        return false;
+    }
+
     bool possiblyCalls() const {
         return true;
     }
 };
 
 class MRegExpTest
   : public MBinaryInstruction,
     public MixPolicy<ObjectPolicy<1>, ConvertToStringPolicy<0> >
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -6,16 +6,17 @@
 
 #include "jit/Recover.h"
 
 #include "jscntxt.h"
 #include "jsmath.h"
 #include "jsobj.h"
 #include "jsstr.h"
 
+#include "builtin/RegExp.h"
 #include "builtin/TypedObject.h"
 
 #include "jit/IonSpewer.h"
 #include "jit/JitFrameIterator.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 #include "jit/VMFunctions.h"
 
@@ -880,16 +881,39 @@ RStringSplit::recover(JSContext *cx, Sna
     if (!res)
         return false;
 
     result.setObject(*res);
     iter.storeInstructionResult(result);
     return true;
 }
 
+bool MRegExpExec::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_RegExpExec));
+    return true;
+}
+
+RRegExpExec::RRegExpExec(CompactBufferReader &reader)
+{}
+
+bool RRegExpExec::recover(JSContext *cx, SnapshotIterator &iter) const{
+    RootedObject regexp(cx, &iter.read().toObject());
+    RootedString input(cx, iter.read().toString());
+
+    RootedValue result(cx);
+
+    if(!regexp_exec_raw(cx, regexp, input, &result))
+        return false;
+
+    iter.storeInstructionResult(result);
+    return true;
+}
+
 bool
 MRegExpTest::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_RegExpTest));
     return true;
 }
 
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -40,16 +40,17 @@ namespace jit {
     _(FromCharCode)                             \
     _(Pow)                                      \
     _(PowHalf)                                  \
     _(MinMax)                                   \
     _(Abs)                                      \
     _(Sqrt)                                     \
     _(Atan2)                                    \
     _(StringSplit)                              \
+    _(RegExpExec)                               \
     _(RegExpTest)                               \
     _(NewObject)                                \
     _(NewArray)                                 \
     _(NewDerivedTypedObject)                    \
     _(ObjectState)                              \
     _(ArrayState)
 
 class RResumePoint;
@@ -456,16 +457,28 @@ class RStringSplit MOZ_FINAL : public RI
 
     virtual uint32_t numOperands() const {
         return 3;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RRegExpExec MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(RegExpExec)
+
+    virtual uint32_t numOperands() const {
+        return 2;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RRegExpTest MOZ_FINAL : public RInstruction
 {
   public:
     RINSTRUCTION_HEADER_(RegExpTest)
 
     virtual uint32_t numOperands() const {
         return 2;
     }