Bug 1440195 Support internal callers of performance.now() from receiving clamped/jittered timestamps
The primary motivation of this change, and the reason it is landing ahead of
Bug 1443943, is that it will delay the initialization of NSS in marionette tests
until after we have a profile directory.
MozReview-Commit-ID: ITvivf6vM3r
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -2491,17 +2491,19 @@ Console::MonotonicTimer(JSContext* aCx,
nsGlobalWindowInner *win = nsGlobalWindowInner::Cast(mWindow);
MOZ_ASSERT(win);
RefPtr<Performance> performance = win->GetPerformance();
if (!performance) {
return false;
}
- *aTimeStamp = performance->Now();
+ // We do not need to clamp/jitter timestamps sent to the console, as
+ // they are inaccessible to Web Content.
+ *aTimeStamp = performance->Now(false);
nsDocShell* docShell = static_cast<nsDocShell*>(mWindow->GetDocShell());
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
bool isTimelineRecording = timelines && timelines->HasConsumer(docShell);
// The 'timeStamp' recordings do not need an argument; use empty string
// if no arguments passed in.
if (isTimelineRecording && aMethodName == MethodTimeStamp) {
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -87,20 +87,23 @@ Performance::Performance(nsPIDOMWindowIn
{
MOZ_ASSERT(NS_IsMainThread());
}
Performance::~Performance()
{}
DOMHighResTimeStamp
-Performance::Now()
+Performance::Now(bool clampAndJitter /* = true */)
{
TimeDuration duration = TimeStamp::Now() - CreationTimeStamp();
- return RoundTime(duration.ToMilliseconds());
+ DOMHighResTimeStamp minimallyClamped = RoundTime(duration.ToMilliseconds());
+ if (!clampAndJitter)
+ return minimallyClamped;
+ return nsRFPService::ReduceTimePrecisionAsMSecs(minimallyClamped, GetRandomSeed());
}
DOMHighResTimeStamp
Performance::TimeOrigin()
{
if (!mPerformanceService) {
mPerformanceService = PerformanceService::GetOrCreate();
}
@@ -212,19 +215,17 @@ Performance::ClearResourceTimings()
}
DOMHighResTimeStamp
Performance::RoundTime(double aTime)
{
// 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,
- GetRandomSeed());
+ return floor(aTime / maxResolutionMs) * maxResolutionMs;
}
void
Performance::Mark(const nsAString& aName, ErrorResult& aRv)
{
// We add nothing when 'privacy.resistFingerprinting' is on.
if (nsContentUtils::ShouldResistFingerprinting()) {
--- a/dom/performance/Performance.h
+++ b/dom/performance/Performance.h
@@ -58,17 +58,17 @@ public:
virtual void GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval);
virtual PerformanceStorage* AsPerformanceStorage() = 0;
void ClearResourceTimings();
- DOMHighResTimeStamp Now();
+ DOMHighResTimeStamp Now(bool clampAndJitter = true);
DOMHighResTimeStamp TimeOrigin();
void Mark(const nsAString& aName, ErrorResult& aRv);
void ClearMarks(const Optional<nsAString>& aName);
void Measure(const nsAString& aName,
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -8781,17 +8781,20 @@ DOMHighResTimeStamp
PresShell::GetPerformanceNow()
{
DOMHighResTimeStamp now = 0;
if (nsPIDOMWindowInner* window = mDocument->GetInnerWindow()) {
Performance* perf = window->GetPerformance();
if (perf) {
- now = perf->Now();
+ // This is used for tracking time spent doing reflows; and is
+ // not exposed to Web Content, so we ask for un-clamped and
+ // un-jittered timestamps.
+ now = perf->Now(false);
}
}
return now;
}
void
PresShell::sReflowContinueCallback(nsITimer* aTimer, void* aPresShell)