Bug 1009968 - IonMonkey: Implement RLsh recover operation. r=nbp
authorJulien Levesy <jlevesy@gmail.com>
Mon, 26 May 2014 06:38:27 -0700
changeset 184965 ca15242af3a36d880642fb4e13d5c8a7536fa584
parent 184964 76f83b6745f1bad697d06a0eeaff0509d590f30e
child 184966 a903e95a20180d05c6a639f0c41938af01a5f80b
push id43972
push usernpierron@mozilla.com
push dateMon, 26 May 2014 13:39:02 +0000
treeherdermozilla-inbound@ca15242af3a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1009968
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 1009968 - IonMonkey: Implement RLsh recover operation. 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
@@ -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_lsh_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_lsh_number'));
+function rlsh_number(i) {
+    var x = i << 1;
+    if (uceFault_lsh_number(i) || uceFault_lsh_number(i))
+        assertEq(x, 198); /* 99 << 1 == 198 */
+    return i;
+}
+
+var uceFault_lsh_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_lsh_object'));
+function rlsh_object(i) {
+    var t = i;
+    var o = { valueOf: function() { return t; } };
+    var x = o << 1;
+    t = 1000;
+    if (uceFault_lsh_object(i) || uceFault_lsh_object(i))
+        assertEq(x, 198);
+    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;
 }
 
@@ -127,16 +146,18 @@ function radd_object(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);
+    rlsh_object(i);
     rursh_number(i);
     rursh_object(i);
     radd_number(i);
     radd_float(i);
     radd_string(i);
     radd_object(i);
 }
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3657,16 +3657,20 @@ class MLsh : public MShiftInstruction
 
     MDefinition *foldIfZero(size_t operand) {
         // 0 << x => 0
         // x << 0 => x
         return getOperand(0);
     }
 
     void computeRange(TempAllocator &alloc);
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return specialization_ != MIRType_None;
+    }
 };
 
 class MRsh : public MShiftInstruction
 {
     MRsh(MDefinition *left, MDefinition *right)
       : MShiftInstruction(left, right)
     { }
 
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -212,16 +212,43 @@ RBitXor::recover(JSContext *cx, Snapshot
         return false;
 
     RootedValue rootedResult(cx, js::Int32Value(result));
     iter.storeInstructionResult(rootedResult);
     return true;
 }
 
 bool
+MLsh::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_Lsh));
+    return true;
+}
+
+RLsh::RLsh(CompactBufferReader &reader)
+{}
+
+bool
+RLsh::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue lhs(cx, iter.read());
+    RootedValue rhs(cx, iter.read());
+    int32_t result;
+    MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
+
+    if (!js::BitLsh(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)
--- 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)                                   \
+    _(Lsh)                                      \
     _(Ursh)                                     \
     _(Add)                                      \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
@@ -123,16 +124,28 @@ class RBitXor MOZ_FINAL : public RInstru
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RLsh MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(Lsh)
+
+    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;
     }