Bug 456165 part 2. Trace Date.now. r=gal
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 26 Sep 2008 14:37:50 -0400
changeset 19990 b8dcfe8b5efba925ad209faeebc7b49a941ea76a
parent 19989 3a02053b2cffd0c06000bcebf3e12ba35be1ac26
child 19992 7b29d221e3564ab124c7104437c56b9e56fe1a3f
push id2577
push userbrendan@mozilla.com
push dateWed, 01 Oct 2008 04:35:27 +0000
treeherdermozilla-central@a613924403d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs456165
milestone1.9.1b1pre
Bug 456165 part 2. Trace Date.now. r=gal
js/src/builtins.tbl
js/src/jsbuiltins.cpp
js/src/jsdate.cpp
js/src/jsdate.h
js/src/jstracer.cpp
js/src/trace-test.js
--- a/js/src/builtins.tbl
+++ b/js/src/builtins.tbl
@@ -134,16 +134,19 @@ BUILTIN3(Object_p_propertyIsEnumerable,
 BUILTIN2(BooleanToNumber,       LO, LO, F,      jsdouble,  JSContext*, jsint, 1, 1)
 BUILTIN2(ObjectToString,        LO,     LO, P,  JSString*, JSContext*, JSObject*, 0, 0)
 BUILTIN3(Array_1int,            LO, LO, LO, P,  JSObject*, JSContext*, JSObject*, jsint, 0, 0)
 BUILTIN3(Array_1str,            LO, LO, LO, P,  JSObject*, JSContext*, JSObject*, JSString*, 0, 0)
 BUILTIN4(Array_2obj,            LO, LO, LO, LO, P, JSObject*, JSContext*, JSObject*, JSObject*, JSObject**, 0, 0)
 BUILTIN5(Array_3num,            LO, LO, F, F, F, P, JSObject*, JSContext*, JSObject*, jsdouble, jsdouble, jsdouble, 0, 0)
 BUILTIN1(Arguments,             LO,     P,      JSObject*, JSContext*, 0, 0)
 
+// Don't really need an argument here, but we don't support arg-less builtins
+BUILTIN1(Date_now,              LO,     F,      jsdouble, JSContext*, 0, 0)
+
 // soft float
 BUILTIN1(fneg,   F,       F,  jsdouble, jsdouble, 1, 1)
 BUILTIN1(i2f,    LO,      F,  jsdouble, jsint,    1, 1)
 BUILTIN1(u2f,    LO,      F,  jsdouble, jsuint,   1, 1)
 BUILTIN2(fcmpeq, F,   F,  LO, jsint,    jsdouble, jsdouble, 1, 1)
 BUILTIN2(fcmplt, F,   F,  LO, jsint,    jsdouble, jsdouble, 1, 1)
 BUILTIN2(fcmple, F,   F,  LO, jsint,    jsdouble, jsdouble, 1, 1)
 BUILTIN2(fcmpgt, F,   F,  LO, jsint,    jsdouble, jsdouble, 1, 1)
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -46,16 +46,17 @@
 #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 "prmjtime.h"
 #include "jsscope.h"
 #include "jsstr.h"
 #include "jstracer.h"
 
 #include "nanojit/avmplus.h"
 #include "nanojit/nanojit.h"
 
 using namespace avmplus;
@@ -857,16 +858,22 @@ js_Array_3num(JSContext* cx, JSObject* p
 }
 
 JSObject* FASTCALL
 js_Arguments(JSContext* cx)
 {
     return NULL;
 }
 
+jsdouble FASTCALL
+js_Date_now(JSContext*)
+{
+    return PRMJ_Now() / PRMJ_USEC_PER_MSEC;
+}
+
 /* soft float */
 
 jsdouble FASTCALL
 js_fneg(jsdouble x)
 {
     return -x;
 }
 
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -907,18 +907,18 @@ date_parse(JSContext *cx, uintN argc, js
         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
         return JS_TRUE;
     }
 
     result = TIMECLIP(result);
     return js_NewNumberInRootedValue(cx, result, vp);
 }
 
-static JSBool
-date_now(JSContext *cx, uintN argc, jsval *vp)
+JSBool
+js_date_now(JSContext *cx, uintN argc, jsval *vp)
 {
     return js_NewDoubleInRootedValue(cx, PRMJ_Now() / PRMJ_USEC_PER_MSEC, vp);
 }
 
 /*
  * Get UTC time from the date object. Returns false if the object is not
  * Date type.
  */
@@ -1953,17 +1953,17 @@ date_valueOf(JSContext *cx, uintN argc, 
 
 /*
  * creation and destruction
  */
 
 static JSFunctionSpec date_static_methods[] = {
     JS_FN("UTC",                 date_UTC,                MAXARGS,0),
     JS_FN("parse",               date_parse,              1,0),
-    JS_FN("now",                 date_now,                0,0),
+    JS_FN("now",                 js_date_now,             0,0),
     JS_FS_END
 };
 
 static JSFunctionSpec date_methods[] = {
     JS_FN("getTime",             date_getTime,            0,0),
     JS_FN("getTimezoneOffset",   date_getTimezoneOffset,  0,0),
     JS_FN("getYear",             date_getYear,            0,0),
     JS_FN("getFullYear",         date_getFullYear,        0,0),
--- a/js/src/jsdate.h
+++ b/js/src/jsdate.h
@@ -46,16 +46,19 @@
 
 JS_BEGIN_EXTERN_C
 
 extern JSClass js_DateClass;
 
 extern JSObject *
 js_InitDateClass(JSContext *cx, JSObject *obj);
 
+extern JSBool
+js_date_now(JSContext *cx, uintN argc, jsval *vp);
+
 /*
  * These functions provide a C interface to the date/time object
  */
 
 /*
  * Construct a new Date Object from a time value given in milliseconds UTC
  * since the epoch.
  */
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -61,16 +61,17 @@
 #include "jsfun.h"
 #include "jsinterp.h"
 #include "jsiter.h"
 #include "jsobj.h"
 #include "jsopcode.h"
 #include "jsregexp.h"
 #include "jsscope.h"
 #include "jsscript.h"
+#include "jsdate.h"
 #include "jstracer.h"
 
 #include "jsautooplen.h"        // generated headers last
 
 /* Number of iterations of a loop where we start tracing.  That is, we don't
    start tracing until the beginning of the HOTLOOP-th iteration. */
 #define HOTLOOP 2
 
@@ -5029,16 +5030,17 @@ TraceRecorder::record_JSOP_CALL()
         { js_str_replace,              F_String_p_replace_str, "SC",  "sr",   FAIL_NULL },
         { js_str_replace,              F_String_p_replace_str2,"SC",  "ss",   FAIL_NULL },
         { js_str_replace,              F_String_p_replace_str3,"SC",  "sss",  FAIL_NULL },
         { js_str_split,                F_String_p_split,       "SC",  "s",    FAIL_NULL },
         { js_str_substring,            F_String_p_substring,   "SC",  "ii",   FAIL_NULL },
         { js_str_substring,            F_String_p_substring_1, "SC",  "i",    FAIL_NULL },
         { js_str_toLowerCase,          F_toLowerCase,          "SC",   "",    FAIL_NULL },
         { js_str_toUpperCase,          F_toUpperCase,          "SC",   "",    FAIL_NULL },
+        { js_date_now,                 F_Date_now,             "C",    "",    INFALLIBLE },
     };
 
     uintN i = 0;
     LIns* arg1_ins = NULL;
     jsval arg1 = JSVAL_VOID;
     jsval thisval = tval;
     if ((JSFastNative)fun->u.n.native == js_fun_apply) {
         if (argc != 2)
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -1670,11 +1670,30 @@ testRUNLOOPCorrectness.jitstats = {
     recorderStarted: 1,
     recorderAborted: 0,
     traceTriggered: 1
 };
 // Change the global shape right before doing the test
 this.testRUNLOOPCorrectnessVar = 1;
 test(testRUNLOOPCorrectness);
 
+function testDateNow()
+{
+    // Accessing global.Date for the first time will change the global shape,
+    // so do it before the loop starts; otherwise we have to loop an extra time
+    // to pick things up.
+    var time = Date.now();
+    for (var j = 0; j < RUNLOOP; ++j) {
+	time = Date.now();
+    }
+    return "ok";
+}
+testDateNow.expected = "ok";
+testDateNow.jitstats = {
+    recorderStarted: 1,
+    recorderAborted: 0,
+    traceTriggered: 1
+};
+test(testDateNow);
+
 /* 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(","));