Bug 1017275 - Make Number.isNaN and Number.isFinite inlinable. r=jwalden
authorNathan Braswell <miloignis@gmail.com>
Thu, 05 Jun 2014 15:40:20 -0700
changeset 206221 e6905f611ad6bc6c08f8feaca144791ba3cb2afe
parent 206220 4db799c3cee9b520d1b99d7175924ddfce9c3674
child 206222 34f371b1024bb9392a29a31280ebf6db534bea38
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1017275
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 1017275 - Make Number.isNaN and Number.isFinite inlinable. r=jwalden
CLOBBER
js/src/builtin/Number.js
js/src/jit-test/tests/ion/inlining/isFiniteInline.js
js/src/jit-test/tests/ion/inlining/isNaNInline.js
js/src/jsnum.cpp
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 965870 sadly requires configure to re-run
+Bug 1017275 needs clobber because of new self-hosted functions.
--- a/js/src/builtin/Number.js
+++ b/js/src/builtin/Number.js
@@ -34,16 +34,30 @@ function Number_toLocaleString() {
     } else {
         numberFormat = intl_NumberFormat(locales, options);
     }
 
     // Step 5.
     return intl_FormatNumber(numberFormat, x);
 }
 
+// ES6 draft ES6 20.1.2.4
+function Number_isFinite(num) {
+    if (typeof num !== "number")
+        return false;
+    return num - num === 0;
+}
+
+// ES6 draft ES6 20.1.2.2
+function Number_isNaN(num) {
+    if (typeof num !== "number")
+        return false;
+    return num !== num;
+}
+
 // ES6 draft ES6 20.1.2.5
 function Number_isSafeInteger(number) {
     // Step 1.
     if (typeof number !== 'number')
         return false;
 
     // Step 2.
     if (!std_isFinite(number))
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/inlining/isFiniteInline.js
@@ -0,0 +1,15 @@
+/* Test inlining of Number.isFinite() */
+
+for (var i = 0; i < 200000; i++) {
+    assertEq(Number.isFinite(NaN), false);
+    assertEq(Number.isFinite(-NaN), false);
+    assertEq(Number.isFinite(+Infinity), false);
+    assertEq(Number.isFinite(-Infinity), false);
+    assertEq(Number.isFinite(3), true);
+    assertEq(Number.isFinite(3.141592654), true);
+    assertEq(Number.isFinite(+0), true);
+    assertEq(Number.isFinite(-0), true);
+    assertEq(Number.isFinite(-3), true);
+    assertEq(Number.isFinite(-3.141592654), true);
+    assertEq(Number.isFinite({}), false);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/inlining/isNaNInline.js
@@ -0,0 +1,15 @@
+/* Test inlining of Number.isNaN() */
+
+for (var i = 0; i < 200000; i++) {
+    assertEq(Number.isNaN(NaN), true);
+    assertEq(Number.isNaN(-NaN), true);
+    assertEq(Number.isNaN(+Infinity), false);
+    assertEq(Number.isNaN(-Infinity), false);
+    assertEq(Number.isNaN(3.14159), false);
+    assertEq(Number.isNaN(-3.14159), false);
+    assertEq(Number.isNaN(3), false);
+    assertEq(Number.isNaN(-3), false);
+    assertEq(Number.isNaN(+0), false);
+    assertEq(Number.isNaN(-0), false);
+    assertEq(Number.isNaN({}), false);
+}
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -995,44 +995,16 @@ static const JSFunctionSpec number_metho
 #endif
     JS_FN(js_valueOf_str,        js_num_valueOf,        0, 0),
     JS_FN("toFixed",             num_toFixed,           1, 0),
     JS_FN("toExponential",       num_toExponential,     1, 0),
     JS_FN("toPrecision",         num_toPrecision,       1, 0),
     JS_FS_END
 };
 
-
-// ES6 draft ES6 15.7.3.10
-static bool
-Number_isNaN(JSContext *cx, unsigned argc, Value *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 1 || !args[0].isDouble()) {
-        args.rval().setBoolean(false);
-        return true;
-    }
-    args.rval().setBoolean(mozilla::IsNaN(args[0].toDouble()));
-    return true;
-}
-
-// ES6 draft ES6 15.7.3.11
-static bool
-Number_isFinite(JSContext *cx, unsigned argc, Value *vp)
-{
-    CallArgs args = CallArgsFromVp(argc, vp);
-    if (args.length() < 1 || !args[0].isNumber()) {
-        args.rval().setBoolean(false);
-        return true;
-    }
-    args.rval().setBoolean(args[0].isInt32() ||
-                           mozilla::IsFinite(args[0].toDouble()));
-    return true;
-}
-
 // ES6 draft ES6 15.7.3.12
 static bool
 Number_isInteger(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() < 1 || !args[0].isNumber()) {
         args.rval().setBoolean(false);
         return true;
@@ -1057,24 +1029,23 @@ Number_toInteger(JSContext *cx, unsigned
     if (!ToInteger(cx, args[0], &asint))
         return false;
     args.rval().setNumber(asint);
     return true;
 }
 
 
 static const JSFunctionSpec number_static_methods[] = {
-    JS_FN("isFinite", Number_isFinite, 1, 0),
+    JS_SELF_HOSTED_FN("isFinite", "Number_isFinite", 1,0),
     JS_FN("isInteger", Number_isInteger, 1, 0),
-    JS_FN("isNaN", Number_isNaN, 1, 0),
-    JS_FN("toInteger", Number_toInteger, 1, 0),
-    /* ES6 additions. */
+    JS_SELF_HOSTED_FN("isNaN", "Number_isNaN", 1,0),
+    JS_SELF_HOSTED_FN("isSafeInteger", "Number_isSafeInteger", 1,0),
     JS_FN("parseFloat", num_parseFloat, 1, 0),
     JS_FN("parseInt", num_parseInt, 2, 0),
-    JS_SELF_HOSTED_FN("isSafeInteger", "Number_isSafeInteger", 1,0),
+    JS_FN("toInteger", Number_toInteger, 1, 0),
     JS_FS_END
 };
 
 
 /* NB: Keep this in synch with number_constants[]. */
 enum nc_slot {
     NC_NaN,
     NC_POSITIVE_INFINITY,