Bug 1028662 - IonMonkey: Implement PowHalf Recover Instruction. r=nbp
authorGuillaume Maudoux <layus.on@gmail.com>
Mon, 23 Jun 2014 04:41:39 -0700
changeset 190112 7d12d632c7a3873207c0b4f2fbb880246bab1921
parent 190111 bc1c4ff7de9ee31fb830fc473f721e1c697fcace
child 190113 b9fac1fab6ca9ba4b839667ce8c795b863adeeea
push id27001
push userkwierso@gmail.com
push dateTue, 24 Jun 2014 00:35:42 +0000
treeherdermozilla-central@984cd22ec8c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1028662
milestone33.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 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)