Bug 1425462 Jitter performance.now()
MozReview-Commit-ID: F7oaiKjt2AI
--- 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;