Bug 1313420 - Implement Performance.timeOrigin - part 1, r=bz
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 17 Nov 2016 10:00:05 +0100
changeset 323039 cf0f72f0b0be8817389893a625c12c4bbc04922b
parent 322962 0e069443912292d0f98b82a425eeb0a60582c2f1
child 323040 c22f17e0db9d41cd15cd22fd4fb38730f4927d8a
push id30967
push userphilringnalda@gmail.com
push dateFri, 18 Nov 2016 03:21:38 +0000
treeherdermozilla-central@8e476f8bd52d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1313420
milestone53.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 1313420 - Implement Performance.timeOrigin - part 1, r=bz
dom/performance/Performance.cpp
dom/performance/Performance.h
dom/performance/PerformanceService.cpp
dom/performance/PerformanceService.h
dom/performance/moz.build
dom/webidl/Performance.webidl
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -8,16 +8,17 @@
 
 #include "GeckoProfiler.h"
 #include "PerformanceEntry.h"
 #include "PerformanceMainThread.h"
 #include "PerformanceMark.h"
 #include "PerformanceMeasure.h"
 #include "PerformanceObserver.h"
 #include "PerformanceResourceTiming.h"
+#include "PerformanceService.h"
 #include "PerformanceWorker.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/PerformanceBinding.h"
 #include "mozilla/dom/PerformanceEntryEvent.h"
 #include "mozilla/dom/PerformanceNavigationBinding.h"
 #include "mozilla/dom/PerformanceObserverBinding.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/Preferences.h"
@@ -136,16 +137,27 @@ Performance::Performance(nsPIDOMWindowIn
   , mPendingNotificationObserversTask(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 Performance::~Performance()
 {}
 
+DOMHighResTimeStamp
+Performance::TimeOrigin()
+{
+  if (!mPerformanceService) {
+    mPerformanceService = PerformanceService::GetOrCreate();
+  }
+
+  MOZ_ASSERT(mPerformanceService);
+  return mPerformanceService->TimeOrigin(CreationTimeStamp());
+}
+
 JSObject*
 Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return PerformanceBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 Performance::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
@@ -261,17 +273,17 @@ Performance::Mark(const nsAString& aName
 void
 Performance::ClearMarks(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
 }
 
 DOMHighResTimeStamp
 Performance::ResolveTimestampFromName(const nsAString& aName,
-                                          ErrorResult& aRv)
+                                      ErrorResult& aRv)
 {
   AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
   DOMHighResTimeStamp ts;
   Optional<nsAString> typeParam;
   nsAutoString str;
   str.AssignLiteral("mark");
   typeParam = &str;
   GetEntriesByName(aName, typeParam, arr);
--- a/dom/performance/Performance.h
+++ b/dom/performance/Performance.h
@@ -19,16 +19,17 @@ namespace mozilla {
 
 class ErrorResult;
 
 namespace dom {
 
 class PerformanceEntry;
 class PerformanceNavigation;
 class PerformanceObserver;
+class PerformanceService;
 class PerformanceTiming;
 
 namespace workers {
 class WorkerPrivate;
 }
 
 // Base class for main-thread and worker Performance API
 class Performance : public DOMEventTargetHelper
@@ -65,16 +66,18 @@ public:
 
   virtual void AddEntry(nsIHttpChannel* channel,
                         nsITimedChannel* timedChannel) = 0;
 
   void ClearResourceTimings();
 
   virtual DOMHighResTimeStamp Now() const = 0;
 
+  DOMHighResTimeStamp TimeOrigin();
+
   void Mark(const nsAString& aName, ErrorResult& aRv);
 
   void ClearMarks(const Optional<nsAString>& aName);
 
   void Measure(const nsAString& aName,
                const Optional<nsAString>& aStartMark,
                const Optional<nsAString>& aEndMark,
                ErrorResult& aRv);
@@ -149,14 +152,16 @@ protected:
 
 private:
   nsTArray<RefPtr<PerformanceEntry>> mUserEntries;
   nsTArray<RefPtr<PerformanceEntry>> mResourceEntries;
 
   uint64_t mResourceTimingBufferSize;
   static const uint64_t kDefaultResourceTimingBufferSize = 150;
   bool mPendingNotificationObserversTask;
+
+  RefPtr<PerformanceService> mPerformanceService;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_Performance_h
new file mode 100644
--- /dev/null
+++ b/dom/performance/PerformanceService.cpp
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "PerformanceService.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPtr.h"
+
+namespace mozilla {
+namespace dom {
+
+static StaticRefPtr<PerformanceService> gPerformanceService;
+static StaticMutex gPerformanceServiceMutex;
+
+/* static */ PerformanceService*
+PerformanceService::GetOrCreate()
+{
+  StaticMutexAutoLock al(gPerformanceServiceMutex);
+
+  if (!gPerformanceService) {
+    gPerformanceService = new PerformanceService();
+    ClearOnShutdown(&gPerformanceService);
+  }
+
+  return gPerformanceService;
+}
+
+DOMHighResTimeStamp
+PerformanceService::TimeOrigin(const TimeStamp& aCreationTimeStamp) const
+{
+  return (aCreationTimeStamp - mCreationTimeStamp).ToMilliseconds() +
+           (mCreationEpochTime / PR_USEC_PER_MSEC);
+}
+
+PerformanceService::PerformanceService()
+{
+  mCreationTimeStamp = TimeStamp::Now();
+  mCreationEpochTime = PR_Now();
+}
+
+} // dom namespace
+} // mozilla namespace
new file mode 100644
--- /dev/null
+++ b/dom/performance/PerformanceService.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef dom_performance_PerformanceService_h
+#define dom_performance_PerformanceService_h
+
+#include "mozilla/TimeStamp.h"
+#include "nsCOMPtr.h"
+#include "nsDOMNavigationTiming.h"
+
+namespace mozilla {
+namespace dom {
+
+// This class is thread-safe.
+
+// We use this singleton for having the correct value of performance.timeOrigin.
+// This value must be calculated on top of the pair:
+// - mCreationTimeStamp (monotonic clock)
+// - mCreationEpochTime (unix epoch time)
+// These 2 values must be taken "at the same time" in order to be used
+// correctly.
+
+class PerformanceService
+{
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PerformanceService)
+
+  static PerformanceService*
+  GetOrCreate();
+
+  DOMHighResTimeStamp
+  TimeOrigin(const TimeStamp& aCreationTimeStamp) const;
+
+private:
+  PerformanceService();
+  ~PerformanceService() = default;
+
+  TimeStamp mCreationTimeStamp;
+  PRTime mCreationEpochTime;
+};
+
+} // dom namespace
+} // mozilla namespace
+
+#endif // dom_performance_PerformanceService_h
--- a/dom/performance/moz.build
+++ b/dom/performance/moz.build
@@ -8,29 +8,31 @@ EXPORTS.mozilla.dom += [
     'Performance.h',
     'PerformanceEntry.h',
     'PerformanceMark.h',
     'PerformanceMeasure.h',
     'PerformanceNavigation.h',
     'PerformanceObserver.h',
     'PerformanceObserverEntryList.h',
     'PerformanceResourceTiming.h',
+    'PerformanceService.h',
     'PerformanceTiming.h',
 ]
 
 UNIFIED_SOURCES += [
     'Performance.cpp',
     'PerformanceEntry.cpp',
     'PerformanceMainThread.cpp',
     'PerformanceMark.cpp',
     'PerformanceMeasure.cpp',
     'PerformanceNavigation.cpp',
     'PerformanceObserver.cpp',
     'PerformanceObserverEntryList.cpp',
     'PerformanceResourceTiming.cpp',
+    'PerformanceService.cpp',
     'PerformanceTiming.cpp',
     'PerformanceWorker.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/workers',
 ]
 
--- a/dom/webidl/Performance.webidl
+++ b/dom/webidl/Performance.webidl
@@ -12,16 +12,19 @@
 
 typedef double DOMHighResTimeStamp;
 typedef sequence <PerformanceEntry> PerformanceEntryList;
 
 [Exposed=(Window,Worker)]
 interface Performance {
   [DependsOn=DeviceState, Affects=Nothing]
   DOMHighResTimeStamp now();
+
+  [Constant]
+  readonly attribute DOMHighResTimeStamp timeOrigin;
 };
 
 [Exposed=Window]
 partial interface Performance {
   [Constant]
   readonly attribute PerformanceTiming timing;
   [Constant]
   readonly attribute PerformanceNavigation navigation;