Bug 1028662 - IonMonkey: Implement PowHalf Recover Instruction. r=nbp
authorGuillaume Maudoux <layus.on@gmail.com>
Mon, 23 Jun 2014 04:41:39 -0700
changeset 190133 7d12d632c7a3873207c0b4f2fbb880246bab1921
parent 190132 bc1c4ff7de9ee31fb830fc473f721e1c697fcace
child 190134 b9fac1fab6ca9ba4b839667ce8c795b863adeeea
push id7411
push userkwierso@gmail.com
push dateTue, 24 Jun 2014 02:07:45 +0000
treeherderfx-team@cc4602e0c1d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1028662
milestone33.0a1
Bug 1028662 - IonMonkey: Implement PowHalf Recover Instruction. 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
@@ -345,16 +345,35 @@ function rpow_object(i) {
     var o = { valueOf: function () { return t; } };
     var x = Math.pow(o, 3.14159); /* computed with t == i, not 1.5 */
     t = 1.5;
     if (uceFault_bitnot_object(i) || uceFault_bitnot_object(i))
         assertEq(x, Math.pow(99, 3.14159));
     return i;
 }
 
+var uceFault_powhalf_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_powhalf_number'));
+function rpowhalf_number(i) {
+    var x = Math.pow(i, 0.5);
+    if (uceFault_powhalf_number(i) || uceFault_powhalf_number(i))
+        assertEq(x, Math.pow(99, 0.5));
+    return i;
+}
+
+var uceFault_powhalf_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_powhalf_object'));
+function rpowhalf_object(i) {
+    var t = i;
+    var o = { valueOf: function () { return t; } };
+    var x = Math.pow(o, 0.5); /* computed with t == i, not 1.5 */
+    t = 1.5;
+    if (uceFault_powhalf_object(i) || uceFault_powhalf_object(i))
+        assertEq(x, Math.pow(99, 0.5));
+    return i;
+}
+
 for (i = 0; i < 100; i++) {
     rbitnot_number(i);
     rbitnot_object(i);
     rbitand_number(i);
     rbitand_object(i);
     rbitor_number(i);
     rbitor_object(i);
     rbitxor_number(i);
@@ -382,16 +401,18 @@ for (i = 0; i < 100; i++) {
     rconcat_string(i);
     rconcat_number(i);
     rfloor_number(i);
     rfloor_object(i);
     rround_number(i);
     rround_double(i);
     rpow_number(i);
     rpow_object(i);
+    rpowhalf_number(i);
+    rpowhalf_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
@@ -4202,16 +4202,20 @@ class MPowHalf
     }
     TypePolicy *typePolicy() {
         return this;
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void collectRangeInfoPreTrunc();
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return true;
+    }
 };
 
 // Inline implementation of Math.random().
 class MRandom : public MNullaryInstruction
 {
     MRandom()
     {
         setResultType(MIRType_Double);
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -579,16 +579,43 @@ RPow::recover(JSContext *cx, SnapshotIte
     if (!js_math_pow_handle(cx, base, power, &result))
         return false;
 
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
+MPowHalf::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_PowHalf));
+    return true;
+}
+
+RPowHalf::RPowHalf(CompactBufferReader &reader)
+{ }
+
+bool
+RPowHalf::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue base(cx, iter.read());
+    RootedValue power(cx);
+    RootedValue result(cx);
+    power.setNumber(0.5);
+
+    MOZ_ASSERT(base.isNumber());
+    if (!js_math_pow_handle(cx, base, power, &result))
+        return false;
+
+    iter.storeInstructionResult(result);
+    return true;
+}
+
+bool
 MMathFunction::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     switch (function_) {
       case Round:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
         return true;
       default:
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -29,16 +29,17 @@ namespace jit {
     _(Sub)                                      \
     _(Mul)                                      \
     _(Div)                                      \
     _(Mod)                                      \
     _(Concat)                                   \
     _(Floor)                                    \
     _(Round)                                    \
     _(Pow)                                      \
+    _(PowHalf)                                  \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
 class RInstruction
 {
@@ -302,16 +303,28 @@ class RPow MOZ_FINAL : public RInstructi
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RPowHalf MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(PowHalf)
+
+    virtual uint32_t numOperands() const {
+        return 1;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RNewObject MOZ_FINAL : public RInstruction
 {
   private:
     bool templateObjectIsClassPrototype_;
 
   public:
     RINSTRUCTION_HEADER_(NewObject)