Bug 1092547 - IonMonkey: Implement MathFunction(Log) recover instruction. r=nbp
☠☠ backed out by dd0c846feacd ☠ ☠
authorAbhishek Bhattacharya <babhishek21@yahoo.co.in>
Tue, 20 Jan 2015 19:05:04 +0100
changeset 224732 973ede87dcdd56cc6419863269971422cfb43a72
parent 224731 373b1a2edd6af2667a4ffa694dc429f1f6b6d686
child 224733 ba0a19bda7d57c8075ccf3ccb1e8894fd72a67f2
push id28143
push userryanvm@gmail.com
push dateWed, 21 Jan 2015 03:14:12 +0000
treeherdermozilla-central@540077a30866 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1092547
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 1092547 - IonMonkey: Implement MathFunction(Log) 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/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
@@ -1072,16 +1072,35 @@ function rsin_object(i) {
     var o = { valueOf: function() { return t; } };
     var x = Math.sin(o);
     t = 777;
     if (uceFault_sin_object(i) || uceFault_sin_object(i))
         assertEq(x, Math.sin(i));
     return i;
 }
 
+var uceFault_log_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_log_number'));
+function rlog_number(i) {
+    var x = Math.log(i);
+    if (uceFault_log_number(i) || uceFault_log_number(i))
+        assertEq(x, Math.log(99) /* log(99) */);
+    return i;
+}
+
+var uceFault_log_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_log_object'));
+function rlog_object(i) {
+    var t = i;
+    var o = { valueOf: function() { return t; } };
+    var x = Math.log(o); /* Evaluated with t == i, not t == 1000 */
+    t = 1000;
+    if (uceFault_log_object(i) || uceFault_log_object(i))
+        assertEq(x, Math.log(99) /* log(99) */);
+    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);
@@ -1175,16 +1194,18 @@ for (i = 0; i < 100; i++) {
     rtodouble_value(i);
     rtodouble_number(i);
     rtofloat32_number(i);
     rtofloat32_object(i);
     rhypot_number(i);
     rhypot_object(i);
     rsin_number(i);
     rsin_object(i);
+    rlog_number(i);
+    rlog_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
@@ -5711,16 +5711,17 @@ class MMathFunction
         return function_ == Floor || function_ == Ceil || function_ == Round;
     }
     void trySpecializeFloat32(TempAllocator &alloc) MOZ_OVERRIDE;
     void computeRange(TempAllocator &alloc) MOZ_OVERRIDE;
     bool writeRecoverData(CompactBufferWriter &writer) const MOZ_OVERRIDE;
     bool canRecoverOnBailout() const MOZ_OVERRIDE {
         switch(function_) {
           case Sin:
+          case Log:
           case Round:
             return true;
           default:
             return false;
         }
     }
 
     ALLOW_CLONE(MMathFunction)
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -905,16 +905,17 @@ bool
 MMathFunction::writeRecoverData(CompactBufferWriter &writer) const
 {
     MOZ_ASSERT(canRecoverOnBailout());
     switch (function_) {
       case Round:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
         return true;
       case Sin:
+      case Log:
         writer.writeUnsigned(uint32_t(RInstruction::Recover_MathFunction));
         writer.writeByte(function_);
         return true;
       default:
         MOZ_CRASH("Unknown math function.");
     }
 }
 
@@ -932,16 +933,26 @@ RMathFunction::recover(JSContext *cx, Sn
         RootedValue result(cx);
 
         if (!js::math_sin_handle(cx, arg, &result))
             return false;
 
         iter.storeInstructionResult(result);
         return true;
       }
+      case MMathFunction::Log: {
+        RootedValue arg(cx, iter.read());
+        RootedValue result(cx);
+
+        if (!js::math_log_handle(cx, arg, &result))
+            return false;
+
+        iter.storeInstructionResult(result);
+        return true;
+      }
       default:
         MOZ_CRASH("Unknown math function.");
     }
 }
 
 bool
 MStringSplit::writeRecoverData(CompactBufferWriter &writer) const
 {
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -528,49 +528,55 @@ js::math_fround(JSContext *cx, unsigned 
 #else
 #define LOG_IF_OUT_OF_RANGE(x)
 #endif
 
 double
 js::math_log_impl(MathCache *cache, double x)
 {
     LOG_IF_OUT_OF_RANGE(x);
-    return cache->lookup(log, x, MathCache::Log);
+    return cache->lookup(math_log_uncached, x, MathCache::Log);
 }
 
 double
 js::math_log_uncached(double x)
 {
     LOG_IF_OUT_OF_RANGE(x);
     return log(x);
 }
 
 #undef LOG_IF_OUT_OF_RANGE
 
 bool
+js::math_log_handle(JSContext *cx, HandleValue val, MutableHandleValue res)
+{
+    double in;
+    if (!ToNumber(cx, val, &in))
+        return false;
+
+    MathCache *mathCache = cx->runtime()->getMathCache(cx);
+    if (!mathCache)
+        return false;
+
+    double out = math_log_impl(mathCache, in);
+    res.setNumber(out);
+    return true;
+}
+
+bool
 js::math_log(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;
-
-    MathCache *mathCache = cx->runtime()->getMathCache(cx);
-    if (!mathCache)
-        return false;
-
-    double z = math_log_impl(mathCache, x);
-    args.rval().setNumber(z);
-    return true;
+    return math_log_handle(cx, args[0], args.rval());
 }
 
 double
 js::math_max_impl(double x, double y)
 {
     // Math.max(num, NaN) => NaN, Math.max(-0, +0) => +0
     if (x > y || IsNaN(x) || (x == y && IsNegative(y)))
         return x;
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -166,16 +166,19 @@ math_log(JSContext *cx, unsigned argc, j
 
 extern double
 math_log_impl(MathCache *cache, double x);
 
 extern double
 math_log_uncached(double x);
 
 extern bool
+math_log_handle(JSContext *cx, HandleValue val, MutableHandleValue res);
+
+extern bool
 math_sin(JSContext *cx, unsigned argc, js::Value *vp);
 
 extern double
 math_sin_impl(MathCache *cache, double x);
 
 extern double
 math_sin_uncached(double x);