Bug 1012632 - IonMonkey: Recover Mod instructions. r=nbp
authorAmol Mundayoor <amol.com@gmail.com>
Tue, 03 Jun 2014 07:10:26 -0700
changeset 205573 2bd26c86bbd0a4528b5b756d30e05d581f4dd79e
parent 205572 59a10383f36121abe88531a3ac651e9e417c2773
child 205574 516ad717d7f4bdae076c5c45ae13ccee1ec93c75
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1012632
milestone32.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 1012632 - IonMonkey: Recover Mod instructions. 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
@@ -187,16 +187,35 @@ function rsub_object(i) {
     var o = { valueOf: function () { return t; } };
     var x = o - i; /* computed with t == i, not 1000 */
     t = 1000;
     if (uceFault_sub_object(i) || uceFault_sub_object(i))
         assertEq(x, 0);
     return i;
 }
 
+var uceFault_mod_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_mod_number'));
+function rmod_number(i) {
+    var x = i % 98;
+    if (uceFault_mod_number(i) || uceFault_mod_number(i))
+        assertEq(x, 1); /* 99 % 98 = 1 */
+    return i;
+}
+
+var uceFault_mod_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_mod_object'));
+function rmod_object(i) {
+    var t = i;
+    var o = { valueOf: function() { return t; } };
+    var x = o % 98; /* computed with t == i, not 1000 */
+    t = 1000;
+    if(uceFault_mod_object(i) || uceFault_mod_object(i))
+        assertEq(x, 1); /* 99 % 98 = 1 */
+    return i;
+}
+
 for (i = 0; i < 100; i++) {
     rbitnot_number(i);
     rbitnot_object(i);
     rbitor_number(i);
     rbitor_object(i);
     rbitxor_number(i);
     rbitxor_object(i);
     rlsh_number(i);
@@ -207,16 +226,18 @@ for (i = 0; i < 100; i++) {
     rursh_object(i);
     radd_number(i);
     radd_float(i);
     radd_string(i);
     radd_object(i);
     rsub_number(i);
     rsub_float(i);
     rsub_object(i);
+    rmod_number(i);
+    rmod_object(i);
 }
 
 // Test that we can refer multiple time to the same recover instruction, as well
 // as chaining recover instructions.
 
 function alignedAlloc($size, $alignment) {
     var $1 = $size + 4 | 0;
     var $2 = $alignment - 1 | 0;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4544,16 +4544,21 @@ class MMod : public MBinaryArithInstruct
     }
     bool canBeDivideByZero() const;
     bool canBePowerOfTwoDivisor() const;
 
     bool isUnsigned() const {
         return unsigned_;
     }
 
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return specialization_ < MIRType_Object;
+    }
+
     bool fallible() const;
 
     void computeRange(TempAllocator &alloc);
     bool truncate(TruncateKind kind);
     void collectRangeInfoPreTrunc();
     TruncateKind operandTruncateKind(size_t index) const;
 };
 
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -359,16 +359,43 @@ RSub::recover(JSContext *cx, SnapshotIte
     // rounded to a Float32.
     if (isFloatOperation_ && !RoundFloat32(cx, result, &result))
         return false;
 
     iter.storeInstructionResult(result);
     return true;
 }
 
+
+bool
+MMod::writeRecoverData(CompactBufferWriter &writer) const
+{
+	MOZ_ASSERT(canRecoverOnBailout());
+	writer.writeUnsigned(uint32_t(RInstruction::Recover_Mod));
+	return true;
+}
+
+RMod::RMod(CompactBufferReader &reader)
+{ }
+
+bool
+RMod::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+	RootedValue lhs(cx, iter.read());
+	RootedValue rhs(cx, iter.read());
+	RootedValue result(cx);
+
+	MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
+	if (!js::ModValues(cx, &lhs, &rhs, &result))
+		return false;
+
+	iter.storeInstructionResult(result);
+	return true;
+}
+
 bool
 MNewObject::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_NewObject));
     writer.writeByte(templateObjectIsClassPrototype_);
     return true;
 }
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -21,16 +21,17 @@ namespace jit {
     _(BitNot)                                   \
     _(BitOr)                                    \
     _(BitXor)                                   \
     _(Lsh)                                      \
     _(Rsh)                                      \
     _(Ursh)                                     \
     _(Add)                                      \
     _(Sub)                                      \
+    _(Mod)                                      \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
 class RInstruction
 {
@@ -192,16 +193,28 @@ class RSub MOZ_FINAL : public RInstructi
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RMod MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(Mod)
+
+    virtual uint32_t numOperands() const {
+        return 2;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RNewObject MOZ_FINAL : public RInstruction
 {
   private:
     bool templateObjectIsClassPrototype_;
 
   public:
     RINSTRUCTION_HEADER_(NewObject)