Trace Math.max. r=brendan
authorBlake Kaplan <mrbkap@gmail.com>
Mon, 08 Sep 2008 20:06:58 -0700
changeset 19083 fb6919347a3c7dfe0f7d11afb6c4a8e30d132305
parent 19082 c89b79a10734bde6a91839fbaa6ac16322507660
child 19086 dba82b744d758163ea346691beb7c909436f030b
push id1930
push usermrbkap@mozilla.com
push dateWed, 10 Sep 2008 06:40:47 +0000
treeherderautoland@ee61af1469cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
milestone1.9.1b1pre
Trace Math.max. r=brendan
js/src/builtins.tbl
js/src/jsbuiltins.cpp
js/src/jsmath.cpp
js/src/jstracer.cpp
js/src/trace-test.js
--- a/js/src/builtins.tbl
+++ b/js/src/builtins.tbl
@@ -50,16 +50,17 @@ BUILTIN1(DoubleToInt32,         F,      
 BUILTIN1(DoubleToUint32,        F,      LO,     int32,     jsdouble, 1, 1)
 BUILTIN1(Math_sin,              F,      F,      jsdouble,  jsdouble, 1, 1)
 BUILTIN1(Math_cos,              F,      F,      jsdouble,  jsdouble, 1, 1)
 BUILTIN2(Math_pow,              F,  F,  F,      jsdouble,  jsdouble, jsdouble, 1, 1)
 BUILTIN1(Math_sqrt,             F,      F,      jsdouble,  jsdouble, 1, 1)
 BUILTIN1(Math_floor,            F,      F,      jsdouble,  jsdouble, 1, 1)
 BUILTIN1(Math_ceil,             F,      F,      jsdouble,  jsdouble, 1, 1)
 BUILTIN1(Math_log,              F,      F,      jsdouble,  jsdouble, 1, 1)
+BUILTIN2(Math_max,              F,  F,  F,      jsdouble,  jsdouble, jsdouble, 1, 1)
 BUILTIN4(Array_dense_setelem,   LO, LO, LO, LO, LO, bool,  JSContext*, JSObject*, jsint, jsval, 0, 0)
 BUILTIN3(Array_p_join,          LO, LO, LO, P,  JSString*, JSContext*, JSObject*, JSString*, 0, 0)
 BUILTIN4(String_p_substring,    LO, LO, LO, LO, P,  JSString*, JSContext*, JSString*, jsint, jsint, 1, 1)
 BUILTIN3(String_p_substring_1,  LO, LO, LO, P,  JSString*, JSContext*, JSString*, jsint, 1, 1)
 BUILTIN3(ConcatStrings,         LO, LO, LO, P,  JSString*, JSContext*, JSString*, JSString*, 1, 1)
 BUILTIN3(String_getelem,        LO, LO, LO, P,  JSString*, JSContext*, JSString*, jsint, 1, 1)
 BUILTIN2(String_fromCharCode,   LO, LO, P,      JSString*, JSContext*, jsint, 1, 1)
 BUILTIN2(String_p_charCodeAt,   LO,     LO, LO, jsint,     JSString*, jsint, 1, 1)
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -43,16 +43,17 @@
 #include <math.h>
 
 #include "jsapi.h"
 #include "jsarray.h"
 #include "jsbool.h"
 #include "jscntxt.h"
 #include "jsgc.h"
 #include "jsiter.h"
+#include "jslibmath.h"
 #include "jsmath.h"
 #include "jsnum.h"
 #include "jsscope.h"
 #include "jsstr.h"
 #include "jstracer.h"
 
 #include "nanojit/avmplus.h"
 #include "nanojit/nanojit.h"
@@ -190,16 +191,27 @@ js_Math_log(jsdouble d)
 {
 #if !JS_USE_FDLIBM_MATH && defined(SOLARIS) && defined(__GNUC__)
     if (d < 0)
         return js_NaN;
 #endif
     return log(d);
 }
 
+jsdouble FASTCALL
+js_Math_max(jsdouble d, jsdouble p)
+{
+    if (JSDOUBLE_IS_NaN(d) || JSDOUBLE_IS_NaN(p))
+        return js_NaN;
+
+    if (p == 0 && p == d && fd_copysign(1.0, d) == -1)
+        return p;
+    return (d > p) ? d : p;
+}
+
 JSBool FASTCALL
 js_Array_dense_setelem(JSContext* cx, JSObject* obj, jsint i, jsval v)
 {
     JS_ASSERT(OBJ_IS_DENSE_ARRAY(cx, obj));
 
     jsuint length = ARRAY_DENSE_LENGTH(obj);
     if ((jsuint)i < length) {
         if (obj->dslots[i] == JSVAL_HOLE) {
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -316,18 +316,18 @@ js_math_log(JSContext *cx, uintN argc, j
         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
         return JS_TRUE;
     }
 #endif
     z = fd_log(x);
     return js_NewNumberInRootedValue(cx, z, vp);
 }
 
-static JSBool
-math_max(JSContext *cx, uintN argc, jsval *vp)
+JSBool
+js_math_max(JSContext *cx, uintN argc, jsval *vp)
 {
     jsdouble x, z = *cx->runtime->jsNegativeInfinity;
     jsval *argv;
     uintN i;
 
     if (argc == 0) {
         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
         return JS_TRUE;
@@ -593,17 +593,17 @@ static JSFunctionSpec math_static_method
     JS_FN("asin",           math_asin,          1, 0),
     JS_FN("atan",           math_atan,          1, 0),
     JS_FN("atan2",          math_atan2,         2, 0),
     JS_FN("ceil",           js_math_ceil,       1, 0),
     JS_FN("cos",            js_math_cos,        1, 0),
     JS_FN("exp",            math_exp,           1, 0),
     JS_FN("floor",          js_math_floor,      1, 0),
     JS_FN("log",            js_math_log,        1, 0),
-    JS_FN("max",            math_max,           2, 0),
+    JS_FN("max",            js_math_max,        2, 0),
     JS_FN("min",            math_min,           2, 0),
     JS_FN("pow",            js_math_pow,        2, 0),
     JS_FN("random",         js_math_random,     0, 0),
     JS_FN("round",          math_round,         1, 0),
     JS_FN("sin",            js_math_sin,        1, 0),
     JS_FN("sqrt",           js_math_sqrt,       1, 0),
     JS_FN("tan",            math_tan,           1, 0),
     JS_FS_END
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -4619,16 +4619,17 @@ TraceRecorder::interpretedFunctionCall(j
 
 #define KNOWN_NATIVE_DECL(name) JSBool name(JSContext* cx, uintN argc, jsval* vp);
 
 KNOWN_NATIVE_DECL(js_fun_apply)
 KNOWN_NATIVE_DECL(js_math_ceil)
 KNOWN_NATIVE_DECL(js_math_cos)
 KNOWN_NATIVE_DECL(js_math_floor)
 KNOWN_NATIVE_DECL(js_math_log)
+KNOWN_NATIVE_DECL(js_math_max)
 KNOWN_NATIVE_DECL(js_math_pow)
 KNOWN_NATIVE_DECL(js_math_random)
 KNOWN_NATIVE_DECL(js_math_sin)
 KNOWN_NATIVE_DECL(js_math_sqrt)
 KNOWN_NATIVE_DECL(js_num_toString)
 KNOWN_NATIVE_DECL(js_str_charAt)
 KNOWN_NATIVE_DECL(js_str_charCodeAt)
 KNOWN_NATIVE_DECL(js_str_concat)
@@ -4674,16 +4675,17 @@ TraceRecorder::record_JSOP_CALL()
         { js_math_sin,                 F_Math_sin,             "",    "d",    INFALLIBLE },
         { js_math_cos,                 F_Math_cos,             "",    "d",    INFALLIBLE },
         { js_math_pow,                 F_Math_pow,             "",    "dd",   INFALLIBLE },
         { js_math_sqrt,                F_Math_sqrt,            "",    "d",    INFALLIBLE },
         { js_math_floor,               F_Math_floor,           "",    "d",    INFALLIBLE },
         { js_math_ceil,                F_Math_ceil,            "",    "d",    INFALLIBLE },
         { js_math_random,              F_Math_random,          "R",    "",    INFALLIBLE },
         { js_math_log,                 F_Math_log,             "",    "d",    INFALLIBLE },
+        { js_math_max,                 F_Math_max,             "",    "dd",   INFALLIBLE },
         { js_num_parseInt,             F_ParseInt,             "C",   "s",    INFALLIBLE },
         { js_num_parseInt,             F_ParseIntDouble,       "",    "d",    INFALLIBLE },
         { js_num_parseFloat,           F_ParseFloat,           "C",   "s",    INFALLIBLE },
         { js_num_toString,             F_NumberToString,       "TC",   "",    FAIL_NULL },
         { js_obj_hasOwnProperty,       F_Object_p_hasOwnProperty,
                                                                "TC",  "s",    FAIL_VOID },
         { js_obj_propertyIsEnumerable, F_Object_p_propertyIsEnumerable,
                                                                "TC",  "s",    FAIL_VOID },
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -1201,17 +1201,17 @@ function testConstIf() {
 testConstIf.expected = 2;
 test(testConstIf);
 
 function testTypeofHole() {
   var a = new Array(6);
   a[5] = 3;
   for (var i = 0; i < 6; ++i)
     a[i] = typeof a[i];
-  return a.toString();
+  return a.join(",");
 }
 testTypeofHole.expected = "undefined,undefined,undefined,undefined,undefined,number"
 test(testTypeofHole);
 
 function testNativeLog() {
   var a = new Array(5);
   for (var i = 0; i < 5; i++) {
     a[i] = Math.log(Math.pow(Math.E, 10));
@@ -1274,11 +1274,33 @@ function test_JSOP_ARGCNT() {
         a[8] = f8('a','b','c','d','e','f','g','h','i');
         a[9] = f9('a','b','c','d','e','f','g','h','i','j');
     }
     return a.join(",");
 }
 test_JSOP_ARGCNT.expected = "1,2,3,4,5,6,7,8,9,10";
 test(test_JSOP_ARGCNT);
 
+function testNativeMax() {
+    var out = [], k;
+    for (var i = 0; i < 5; ++i) {
+        k = Math.max(k, i);
+    }
+    out.push(k);
+
+    k = 0;
+    for (var i = 0; i < 5; ++i) {
+        k = Math.max(k, i);
+    }
+    out.push(k);
+
+    for (var i = 0; i < 5; ++i) {
+        k = Math.max(0, -0);
+    }
+    out.push((1 / k) < 0);
+    return out.join(",");
+}
+testNativeMax.expected = "NaN,4,false";
+test(testNativeMax);
+
 /* Keep these at the end so that we can see the summary after the trace-debug spew. */
 print("\npassed:", passes.length && passes.join(","));
 print("\nFAILED:", fails.length && fails.join(","));