Bug 1010339 - Add recover functionality for Ursh; r=bbouvier
authorInanc Seylan <inanc.seylan@gmail.com>
Mon, 19 May 2014 13:56:23 +0200
changeset 183751 0a298fb5be4ee3fc68999c54c5db482398f0aceb
parent 183750 e89a9d2621cb8890d613ccc9ef0143a38f11ea63
child 183752 d67479bdf3428a59da8aa91b8a1f7d422fe4bbdd
push id26801
push userkwierso@gmail.com
push dateMon, 19 May 2014 19:35:37 +0000
treeherdermozilla-central@6b52f777d2ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1010339
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 1010339 - Add recover functionality for Ursh; r=bbouvier
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
@@ -64,16 +64,35 @@ function rbitxor_object(i) {
     var o = { valueOf: function () { return t; } };
     var x = 1 ^ o; /* computed with t == i, not 1000 */
     t = 1000;
     if (uceFault_bitxor_object(i) || uceFault_bitxor_object(i))
         assertEq(x, 98  /* = 1 XOR 99 */);
     return i;
 }
 
+var uceFault_ursh_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_ursh_number'));
+function rursh_number(i) {
+    var x = i >>> 1;
+    if (uceFault_ursh_number(i) || uceFault_ursh_number(i))
+        assertEq(x, 49  /* = 99 >>> 1 */);
+    return i;
+}
+
+var uceFault_ursh_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_ursh_object'));
+function rursh_object(i) {
+    var t = i;
+    var o = { valueOf: function () { return t; } };
+    var x = o >>> 1; /* computed with t == i, not 1000 */
+    t = 1000;
+    if (uceFault_ursh_object(i) || uceFault_ursh_object(i))
+        assertEq(x, 49  /* = 99 >>> 1 */);
+    return i;
+}
+
 var uceFault_add_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_add_number'));
 function radd_number(i) {
     var x = 1 + i;
     if (uceFault_add_number(i) || uceFault_add_number(i))
         assertEq(x, 100  /* = 1 + 99 */);
     return i;
 }
 
@@ -106,16 +125,18 @@ function radd_object(i) {
     return i;
 }
 
 for (i = 0; i < 100; i++) {
     rbitnot_number(i);
     rbitnot_object(i);
     rbitor_number(i);
     rbitor_object(i);
+    rursh_number(i);
+    rursh_object(i);
     radd_number(i);
     radd_float(i);
     radd_string(i);
     radd_object(i);
 }
 
 // Test that we can refer multiple time to the same recover instruction, as well
 // as chaining recover instructions.
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3627,16 +3627,21 @@ class MUrsh : public MShiftInstruction
     bool bailoutsDisabled() const {
         return bailoutsDisabled_;
     }
 
     bool fallible() const;
 
     void computeRange(TempAllocator &alloc);
     void collectRangeInfoPreTrunc();
+
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return specialization_ < MIRType_Object;
+    }
 };
 
 class MBinaryArithInstruction
   : public MBinaryInstruction,
     public ArithPolicy
 {
     // Implicit truncate flag is set by the truncate backward range analysis
     // optimization phase, and by asm.js pre-processing. It is used in
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -306,8 +306,34 @@ RBitOr::recover(JSContext *cx, SnapshotI
 
     if (!js::BitOr(cx, lhs, rhs, &result))
         return false;
 
     RootedValue asValue(cx, js::Int32Value(result));
     iter.storeInstructionResult(asValue);
     return true;
 }
+
+bool
+MUrsh::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_Ursh));
+    return true;
+}
+
+RUrsh::RUrsh(CompactBufferReader &reader)
+{ }
+
+bool
+RUrsh::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue lhs(cx, iter.read());
+    RootedValue rhs(cx, iter.read());
+    MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
+
+    RootedValue result(cx);
+    if (!js::UrshOperation(cx, lhs, rhs, &result))
+        return false;
+
+    iter.storeInstructionResult(result);
+    return true;
+}
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -16,16 +16,17 @@ class JSContext;
 namespace js {
 namespace jit {
 
 #define RECOVER_OPCODE_LIST(_)                  \
     _(ResumePoint)                              \
     _(BitNot)                                   \
     _(BitOr)                                    \
     _(BitXor)                                   \
+    _(Ursh)                                     \
     _(Add)                                      \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
 class RInstruction
@@ -164,16 +165,28 @@ class RBitOr MOZ_FINAL : public RInstruc
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RUrsh MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(Ursh)
+
+    virtual uint32_t numOperands() const {
+        return 2;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 #undef RINSTRUCTION_HEADER_
 
 const RResumePoint *
 RInstruction::toResumePoint() const
 {
     MOZ_ASSERT(isResumePoint());
     return static_cast<const RResumePoint *>(this);
 }