Bug 1425462 Jitter performance.now() draft
authorTom Ritter <tom@mozilla.com>
Fri, 26 Jan 2018 15:28:51 -0600
changeset 747820 9202092b1ebbd575a1c6d34334546a88ed8dcaf5
parent 747819 e1941f8cd39a62a6c8d9bae6e6763b9c0a607795
push id97017
push userbmo:tom@mozilla.com
push dateFri, 26 Jan 2018 22:16:13 +0000
bugs1425462
milestone60.0a1
Bug 1425462 Jitter performance.now() MozReview-Commit-ID: F7oaiKjt2AI
dom/performance/Performance.cpp
dom/performance/Performance.h
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -117,20 +117,32 @@ Performance::Performance(nsPIDOMWindowIn
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 Performance::~Performance()
 {}
 
 DOMHighResTimeStamp
-Performance::Now() const
+Performance::Now()
 {
+  if (!mPerformanceService) {
+    mPerformanceService = PerformanceService::GetOrCreate();
+  }
+
   TimeDuration duration = TimeStamp::Now() - CreationTimeStamp();
-  return RoundTime(duration.ToMilliseconds());
+  // Be certain to round down to the nearest 20us, because if the
+  // timer is too accurate people can do nasty timing attacks with it.
+  const double maxResolutionMs = 0.020;
+  double minimumRounding = floor(
+    (duration.ToMilliseconds() / maxResolutionMs)) * maxResolutionMs;
+
+  // Additionally apply any (optional) reduction of precision and jitter
+  return nsRFPService::ReduceTimePrecisionAsMSecs(minimumRounding,
+    true, mPerformanceService->TimeOrigin(CreationTimeStamp()));
 }
 
 DOMHighResTimeStamp
 Performance::TimeOrigin()
 {
   if (!mPerformanceService) {
     mPerformanceService = PerformanceService::GetOrCreate();
   }
@@ -235,27 +247,16 @@ Performance::ClearUserEntries(const Opti
 }
 
 void
 Performance::ClearResourceTimings()
 {
   mResourceEntries.Clear();
 }
 
-DOMHighResTimeStamp
-Performance::RoundTime(double aTime) const
-{
-  // Round down to the nearest 20us, because if the timer is too accurate people
-  // can do nasty timing attacks with it.
-  const double maxResolutionMs = 0.020;
-  return nsRFPService::ReduceTimePrecisionAsMSecs(
-    floor(aTime / maxResolutionMs) * maxResolutionMs);
-}
-
-
 void
 Performance::Mark(const nsAString& aName, ErrorResult& aRv)
 {
   // We add nothing when 'privacy.resistFingerprinting' is on.
   if (nsContentUtils::ShouldResistFingerprinting()) {
     return;
   }
 
--- a/dom/performance/Performance.h
+++ b/dom/performance/Performance.h
@@ -60,17 +60,17 @@ public:
   virtual void GetEntriesByName(const nsAString& aName,
                                 const Optional<nsAString>& aEntryType,
                                 nsTArray<RefPtr<PerformanceEntry>>& aRetval);
 
   virtual PerformanceStorage* AsPerformanceStorage() = 0;
 
   void ClearResourceTimings();
 
-  DOMHighResTimeStamp Now() const;
+  DOMHighResTimeStamp Now();
 
   DOMHighResTimeStamp TimeOrigin();
 
   void Mark(const nsAString& aName, ErrorResult& aRv);
 
   void ClearMarks(const Optional<nsAString>& aName);
 
   void Measure(const nsAString& aName,
@@ -140,18 +140,16 @@ protected:
 
   void LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const;
   void TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner,
                           uint64_t epoch);
 
   void RunNotificationObserversTask();
   void QueueEntry(PerformanceEntry* aEntry);
 
-  DOMHighResTimeStamp RoundTime(double aTime) const;
-
   nsTObserverArray<PerformanceObserver*> mObservers;
 
 protected:
   static const uint64_t kDefaultResourceTimingBufferSize = 150;
 
   // When kDefaultResourceTimingBufferSize is increased or removed, these should
   // be changed to use SegmentedVector
   AutoTArray<RefPtr<PerformanceEntry>, kDefaultResourceTimingBufferSize> mUserEntries;