Bug 1004814 - console.time/timeEnd work in workers. r=bz, a=sledru
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 06 May 2014 10:50:12 +0100
changeset 192277 aa9bc2b880a1
parent 192276 ff4da156e917
child 192278 a713e6bd540d
push id3557
push userryanvm@gmail.com
push date2014-05-14 16:23 +0000
Treeherderresults
reviewersbz, sledru
bugs1004814
milestone30.0
Bug 1004814 - console.time/timeEnd work in workers. r=bz, a=sledru
dom/base/Console.cpp
dom/tests/browser/browser.ini
dom/tests/browser/browser_bug1004814.js
dom/tests/browser/test_bug1004814.html
dom/tests/browser/worker_bug1004814.js
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -837,27 +837,37 @@ Console::Method(JSContext* aCx, MethodNa
     if (NS_FAILED(rv)) {
       return;
     }
 
     stack.swap(caller);
   } while (stack);
 
   // Monotonic timer for 'time' and 'timeEnd'
-  if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd) && mWindow) {
-    nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
-    MOZ_ASSERT(win);
+  if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd)) {
+    if (mWindow) {
+      nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
+      MOZ_ASSERT(win);
 
-    ErrorResult rv;
-    nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
-    if (rv.Failed()) {
-      return;
+      ErrorResult rv;
+      nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
+      if (rv.Failed()) {
+        return;
+      }
+
+      callData->mMonotonicTimer = performance->Now();
+    } else {
+      WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+      MOZ_ASSERT(workerPrivate);
+
+      TimeDuration duration =
+        mozilla::TimeStamp::Now() - workerPrivate->CreationTimeStamp();
+
+      callData->mMonotonicTimer = duration.ToMilliseconds();
     }
-
-    callData->mMonotonicTimer = performance->Now();
   }
 
   // The operation is completed. RAII class has to be disabled.
   raii.Finished();
 
   if (!NS_IsMainThread()) {
     // Here we are in a worker thread. The ConsoleCallData has to been removed
     // from the list and it will be deleted by the ConsoleCallDataRunnable or
--- a/dom/tests/browser/browser.ini
+++ b/dom/tests/browser/browser.ini
@@ -1,15 +1,17 @@
 [DEFAULT]
 support-files =
   browser_frame_elements.html
   browser_geolocation_privatebrowsing_page.html
   network_geolocation.sjs
   page_privatestorageevent.html
   test-console-api.html
+  test_bug1004814.html
+  worker_bug1004814.js
 
 [browser_test__content.js]
 [browser_ConsoleAPITests.js]
 [browser_ConsoleStorageAPITests.js]
 [browser_ConsoleStoragePBTest_perwindowpb.js]
 [browser_autofocus_background.js]
 [browser_autofocus_preference.js]
 [browser_bug396843.js]
@@ -24,8 +26,9 @@ skip-if = buildapp != "b2g"
 support-files =
   test-webapp.webapp
   test-webapp-reinstall.webapp
   test-webapp-original.webapp
   test-webapps-permissions.html
 [browser_webapps_perms_reinstall.js]
 disabled = re-enable when bug 794920 is fixed
 [browser_xhr_sandbox.js]
+[browser_bug1004814.js]
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/browser_bug1004814.js
@@ -0,0 +1,46 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const TEST_URI = "http://example.com/browser/dom/tests/browser/test_bug1004814.html";
+
+function test() {
+  waitForExplicitFinish();
+
+  ConsoleObserver.init();
+
+  var tab = gBrowser.addTab(TEST_URI);
+  gBrowser.selectedTab = tab;
+
+  registerCleanupFunction(function () {
+    gBrowser.removeTab(tab);
+  });
+}
+
+var ConsoleObserver = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+
+  init: function() {
+    Services.obs.addObserver(this, "console-api-log-event", false);
+  },
+
+  destroy: function() {
+    Services.obs.removeObserver(this, "console-api-log-event");
+  },
+
+  observe: function(aSubject, aTopic, aData) {
+    var obj = aSubject.wrappedJSObject;
+    if (obj.arguments.length != 1 || obj.arguments[0] != 'bug1004814' ||
+        obj.level != 'timeEnd') {
+      return;
+    }
+
+    ok("timer" in obj, "ConsoleEvent contains 'timer' property");
+    ok("duration" in obj.timer, "ConsoleEvent.timer contains 'duration' property");
+    ok(obj.timer.duration > 0, "ConsoleEvent.timer.duration > 0: " + obj.timer.duration + " ~ 200ms");
+
+    this.destroy();
+    finish();
+  }
+};
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/test_bug1004814.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <title>Console API test bug 1004814</title>
+  </head>
+  <body>
+    <script>
+
+var w = new Worker('worker_bug1004814.js');
+w.postMessage(true);
+
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/browser/worker_bug1004814.js
@@ -0,0 +1,6 @@
+onmessage = function(evt) {
+  console.time('bug1004814');
+  setTimeout(function() {
+    console.timeEnd('bug1004814');
+  }, 200);
+}
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2099,17 +2099,18 @@ WorkerPrivateParent<Derived>::WorkerPriv
                                            LoadInfo& aLoadInfo)
 : mMutex("WorkerPrivateParent Mutex"),
   mCondVar(mMutex, "WorkerPrivateParent CondVar"),
   mMemoryReportCondVar(mMutex, "WorkerPrivateParent Memory Report CondVar"),
   mParent(aParent), mScriptURL(aScriptURL),
   mSharedWorkerName(aSharedWorkerName), mBusyCount(0), mMessagePortSerial(0),
   mParentStatus(Pending), mParentSuspended(false),
   mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false),
-  mWorkerType(aWorkerType)
+  mWorkerType(aWorkerType),
+  mCreationTimeStamp(TimeStamp::Now())
 {
   SetIsDOMBinding();
 
   MOZ_ASSERT_IF(IsSharedWorker(), !aSharedWorkerName.IsVoid() &&
                                   NS_IsMainThread());
   MOZ_ASSERT_IF(!IsSharedWorker(), aSharedWorkerName.IsEmpty());
 
   if (aLoadInfo.mWindow) {
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -236,16 +236,17 @@ private:
 
   uint64_t mBusyCount;
   uint64_t mMessagePortSerial;
   Status mParentStatus;
   bool mParentSuspended;
   bool mIsChromeWorker;
   bool mMainThreadObjectsForgotten;
   WorkerType mWorkerType;
+  TimeStamp mCreationTimeStamp;
 
 protected:
   // The worker is owned by its thread, which is represented here.  This is set
   // in Construct() and emptied by WorkerFinishedRunnable, and conditionally
   // traversed by the cycle collector if the busy count is zero.
   nsRefPtr<WorkerPrivate> mSelfRef;
 
   WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
@@ -503,16 +504,21 @@ public:
 
   nsIURI*
   GetResolvedScriptURI() const
   {
     AssertIsOnMainThread();
     return mLoadInfo.mResolvedScriptURI;
   }
 
+  TimeStamp CreationTimeStamp() const
+  {
+    return mCreationTimeStamp;
+  }
+
   nsIPrincipal*
   GetPrincipal() const
   {
     AssertIsOnMainThread();
     return mLoadInfo.mPrincipal;
   }
 
   // This method allows the principal to be retrieved off the main thread.