Bug 1096129 - IonMonkey: Implement Ceil Recover Instruction. r=nbp
authorNicolas Devillers <devillers.nicolas+moz@gmail.com>
Mon, 19 Jan 2015 11:16:32 +0100
changeset 224478 9ccd38ce999f6442a8ce73d0b07d64539fb6deb5
parent 224477 37ec2038576eebcc2f4013e6ec3b133a1cc74ad7
child 224479 1d32c46f21434e7501d12a1067c4c1cfc962176d
push id54245
push usernpierron@mozilla.com
push dateMon, 19 Jan 2015 10:31:03 +0000
treeherdermozilla-inbound@9ccd38ce999f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1096129
milestone38.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 1096129 - IonMonkey: Implement Ceil 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
js/src/jsmath.cpp
js/src/jsmath.h
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -369,16 +369,24 @@ function rfloor_object(i) {
     var o = { valueOf: function () { return t; } };
     var x = Math.floor(o);
     t = 1000.1111;
     if (uceFault_floor_object(i) || uceFault_floor_object(i))
         assertEq(x, i);
     return i;
 }
 
+var uceFault_ceil_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_ceil_number'));
+function rceil_number(i){
+    var x = Math.ceil(-i - 0.12010799100);
+    if (uceFault_ceil_number(i) ||uceFault_ceil_number(i))
+        assertEq(x, - i);
+    return i;
+}
+
 var uceFault_round_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_round'));
 function rround_number(i) {
     var x = Math.round(i + 1.4);
     if (uceFault_round_number(i) || uceFault_round_number(i))
         assertEq(x, 100); /* = i + 1*/
     return i;
 }
 
@@ -1104,16 +1112,17 @@ for (i = 0; i < 100; i++) {
     rconcat_number(i);
     rstring_length(i);
     rarguments_length_1(i);
     rarguments_length_3(i, 0, 1);
     rinline_arguments_length_1(i);
     rinline_arguments_length_3(i, 0, 1);
     rfloor_number(i);
     rfloor_object(i);
+    rceil_number(i);
     rround_number(i);
     rround_double(i);
     rcharCodeAt(i);
     rfrom_char_code(i);
     rfrom_char_code_non_ascii(i);
     rpow_number(i);
     rpow_object(i);
     rpowhalf_number(i);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -10734,16 +10734,20 @@ class MCeil
     bool isConsistentFloat32Use(MUse *use) const MOZ_OVERRIDE {
         return true;
     }
 #endif
     bool congruentTo(const MDefinition *ins) const MOZ_OVERRIDE {
         return congruentIfOperandsEqual(ins);
     }
     void computeRange(TempAllocator &alloc) MOZ_OVERRIDE;
+    bool writeRecoverData(CompactBufferWriter &writer) const MOZ_OVERRIDE;
+    bool canRecoverOnBailout() const MOZ_OVERRIDE {
+        return true;
+    }
 
     ALLOW_CLONE(MCeil)
 };
 
 // Inlined version of Math.round().
 class MRound
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>::Data
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -602,16 +602,41 @@ bool RFloor::recover(JSContext *cx, Snap
     if (!js::math_floor_handle(cx, v, &result))
         return false;
 
     iter.storeInstructionResult(result);
     return true;
 }
 
 bool
+MCeil::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_Ceil));
+    return true;
+}
+
+RCeil::RCeil(CompactBufferReader &reader)
+{ }
+
+
+bool
+RCeil::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    RootedValue v(cx, iter.read());
+    RootedValue result(cx);
+
+    if (!js::math_ceil_handle(cx, v, &result))
+        return false;
+
+    iter.storeInstructionResult(result);
+    return true;
+}
+
+bool
 MRound::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
     return true;
 }
 
 RRound::RRound(CompactBufferReader &reader)
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -32,16 +32,17 @@ namespace jit {
     _(Mul)                                      \
     _(Div)                                      \
     _(Mod)                                      \
     _(Not)                                      \
     _(Concat)                                   \
     _(StringLength)                             \
     _(ArgumentsLength)                          \
     _(Floor)                                    \
+    _(Ceil)                                     \
     _(Round)                                    \
     _(CharCodeAt)                               \
     _(FromCharCode)                             \
     _(Pow)                                      \
     _(PowHalf)                                  \
     _(MinMax)                                   \
     _(Abs)                                      \
     _(Sqrt)                                     \
@@ -342,16 +343,28 @@ class RFloor MOZ_FINAL : public RInstruc
 
     virtual uint32_t numOperands() const {
         return 1;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RCeil MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(Ceil)
+
+    virtual uint32_t numOperands() const {
+        return 1;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 class RRound MOZ_FINAL : public RInstruction
 {
   public:
     RINSTRUCTION_HEADER_(Round)
 
     virtual uint32_t numOperands() const {
         return 1;
     }
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -293,32 +293,41 @@ js::math_ceil_impl(double x)
 #ifdef __APPLE__
     if (x < 0 && x > -1.0)
         return js_copysign(0, -1);
 #endif
     return ceil(x);
 }
 
 bool
+js::math_ceil_handle(JSContext *cx, HandleValue v, MutableHandleValue res)
+{
+    double d;
+    if(!ToNumber(cx, v, &d))
+        return false;
+
+    double result = math_ceil_impl(d);
+    res.setDouble(result);
+    return true;
+}
+
+bool
 js::math_ceil(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() == 0) {
         args.rval().setNaN();
         return true;
     }
 
     double x;
     if (!ToNumber(cx, args[0], &x))
         return false;
-
-    double z = math_ceil_impl(x);
-    args.rval().setNumber(z);
-    return true;
+    return math_ceil_handle(cx, args[0], args.rval());
 }
 
 bool
 js::math_clz32(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     if (args.length() == 0) {
@@ -430,17 +439,17 @@ js::math_floor_impl(double x)
 {
     return floor(x);
 }
 
 bool
 js::math_floor_handle(JSContext *cx, HandleValue v, MutableHandleValue r)
 {
     double d;
-    if(!ToNumber(cx, v, &d))
+    if (!ToNumber(cx, v, &d))
         return false;
 
     double z = math_floor_impl(d);
     r.setNumber(z);
 
     return true;
 }
 
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -298,16 +298,19 @@ math_acos_impl(MathCache *cache, double 
 
 extern double
 math_acos_uncached(double x);
 
 extern bool
 math_acos(JSContext *cx, unsigned argc, js::Value *vp);
 
 extern bool
+math_ceil_handle(JSContext *cx, HandleValue value, MutableHandleValue res);
+
+extern bool
 math_ceil(JSContext *cx, unsigned argc, Value *vp);
 
 extern double
 math_ceil_impl(double x);
 
 extern bool
 math_clz32(JSContext *cx, unsigned argc, Value *vp);