Bug 1009967 - Add recover functionality for BitXor; r=nbp
authorInanc Seylan <acimilan@yahoo.com>
Thu, 15 May 2014 23:40:44 -0700
changeset 183435 22298ae9c687db3f2de683887758866d4f2185c5
parent 183434 677d12a5d608f6313c84de0f86f651a98e669c74
child 183436 2d50053fec04526614967cc7149723f7b4b56966
push idunknown
push userunknown
push dateunknown
reviewersnbp
bugs1009967
milestone32.0a1
Bug 1009967 - Add recover functionality for BitXor; 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
@@ -45,16 +45,35 @@ function rbitor_object(i) {
     var o = { valueOf: function() { return t; } };
     var x = o | -100;
     t = 1000;
     if (uceFault_bitor_object(i) || uceFault_bitor_object(i))
         assertEq(x, -1);
     return i;
 }
 
+var uceFault_bitxor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_bitxor_number'));
+function rbitxor_number(i) {
+    var x = 1 ^ i;
+    if (uceFault_bitxor_number(i) || uceFault_bitxor_number(i))
+        assertEq(x, 98  /* = 1 XOR 99 */);
+    return i;
+}
+
+var uceFault_bitxor_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_bitxor_object'));
+function rbitxor_object(i) {
+    var t = 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_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;
 }
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3531,16 +3531,21 @@ class MBitXor : public MBinaryBitwiseIns
     }
     MDefinition *foldIfNegOne(size_t operand) {
         return this;
     }
     MDefinition *foldIfEqual() {
         return this;
     }
     void computeRange(TempAllocator &alloc);
+
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return specialization_ < MIRType_Object;
+    }
 };
 
 class MShiftInstruction
   : public MBinaryBitwiseInstruction
 {
   protected:
     MShiftInstruction(MDefinition *left, MDefinition *right)
       : MBinaryBitwiseInstruction(left, right)
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -193,16 +193,42 @@ RBitNot::recover(JSContext *cx, Snapshot
         return false;
 
     RootedValue rootedResult(cx, js::Int32Value(result));
     iter.storeInstructionResult(rootedResult);
     return true;
 }
 
 bool
+MBitXor::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_BitXor));
+    return true;
+}
+
+RBitXor::RBitXor(CompactBufferReader &reader)
+{ }
+
+bool
+RBitXor::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue lhs(cx, iter.read());
+    RootedValue rhs(cx, iter.read());
+
+    int32_t result;
+    if (!js::BitXor(cx, lhs, rhs, &result))
+        return false;
+
+    RootedValue rootedResult(cx, js::Int32Value(result));
+    iter.storeInstructionResult(rootedResult);
+    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
@@ -15,16 +15,17 @@ class JSContext;
 
 namespace js {
 namespace jit {
 
 #define RECOVER_OPCODE_LIST(_)                  \
     _(ResumePoint)                              \
     _(BitNot)                                   \
     _(BitOr)                                    \
+    _(BitXor)                                   \
     _(Add)                                      \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
 class RInstruction
@@ -97,16 +98,28 @@ class RBitNot MOZ_FINAL : public RInstru
 
     virtual uint32_t numOperands() const {
         return 1;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RBitXor MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(BitXor)
+
+    virtual uint32_t numOperands() const {
+        return 2;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RAdd MOZ_FINAL : public RInstruction
 {
   private:
     bool isFloatOperation_;
 
   public:
     RINSTRUCTION_HEADER_(Add)