diff options
Diffstat (limited to 'dom/performance')
-rwxr-xr-x[-rw-r--r--] | dom/performance/Performance.cpp | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | dom/performance/PerformanceTiming.cpp | 22 | ||||
-rwxr-xr-x[-rw-r--r--] | dom/performance/PerformanceTiming.h | 25 | ||||
-rw-r--r-- | dom/performance/tests/test_worker_performance_now.js | 48 |
4 files changed, 28 insertions, 72 deletions
diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp index 17273c55d..8dc239b05 100644..100755 --- a/dom/performance/Performance.cpp +++ b/dom/performance/Performance.cpp @@ -21,6 +21,7 @@ #include "mozilla/dom/PerformanceObserverBinding.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Preferences.h" +#include "mozilla/TimerClamping.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" @@ -228,9 +229,9 @@ Performance::ClearResourceTimings() DOMHighResTimeStamp Performance::RoundTime(double aTime) const { - // Round down to the nearest 20us, because if the timer is too accurate people + // Round down to the nearest 2ms, because if the timer is too accurate people // can do nasty timing attacks with it. - const double maxResolutionMs = 0.020; + const double maxResolutionMs = 2; return floor(aTime / maxResolutionMs) * maxResolutionMs; } diff --git a/dom/performance/PerformanceTiming.cpp b/dom/performance/PerformanceTiming.cpp index 4070b6a0f..97bbcb0ca 100644..100755 --- a/dom/performance/PerformanceTiming.cpp +++ b/dom/performance/PerformanceTiming.cpp @@ -21,7 +21,7 @@ PerformanceTiming::PerformanceTiming(Performance* aPerformance, DOMHighResTimeStamp aZeroTime) : mPerformance(aPerformance), mFetchStart(0.0), - mZeroTime(aZeroTime), + mZeroTime(TimerClamping::ReduceMsTimeValue(aZeroTime)), mRedirectCount(0), mTimingAllowed(true), mAllRedirectsSameOrigin(true), @@ -117,7 +117,7 @@ PerformanceTiming::FetchStartHighRes() ? TimeStampToDOMHighRes(mAsyncOpen) : 0.0; } - return mFetchStart; + return TimerClamping::ReduceMsTimeValue(mFetchStart); } DOMTimeMilliSec @@ -203,7 +203,7 @@ PerformanceTiming::RedirectStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRedirectStart); + return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart); } DOMTimeMilliSec @@ -236,7 +236,7 @@ PerformanceTiming::RedirectEndHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRedirectEnd); + return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd); } DOMTimeMilliSec @@ -259,7 +259,7 @@ PerformanceTiming::DomainLookupStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart); + return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart); } DOMTimeMilliSec @@ -276,7 +276,7 @@ PerformanceTiming::DomainLookupEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes() - : TimeStampToDOMHighRes(mDomainLookupEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mDomainLookupEnd)); } DOMTimeMilliSec @@ -292,7 +292,7 @@ PerformanceTiming::ConnectStartHighRes() return mZeroTime; } return mConnectStart.IsNull() ? DomainLookupEndHighRes() - : TimeStampToDOMHighRes(mConnectStart); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectStart)); } DOMTimeMilliSec @@ -329,7 +329,7 @@ PerformanceTiming::ConnectEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null return mConnectEnd.IsNull() ? ConnectStartHighRes() - : TimeStampToDOMHighRes(mConnectEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectEnd)); } DOMTimeMilliSec @@ -344,7 +344,7 @@ PerformanceTiming::RequestStartHighRes() if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) { return mZeroTime; } - return TimeStampToDOMHighResOrFetchStart(mRequestStart); + return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart); } DOMTimeMilliSec @@ -363,7 +363,7 @@ PerformanceTiming::ResponseStartHighRes() (!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) { mResponseStart = mCacheReadStart; } - return TimeStampToDOMHighResOrFetchStart(mResponseStart); + return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart); } DOMTimeMilliSec @@ -384,7 +384,7 @@ PerformanceTiming::ResponseEndHighRes() } // Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null return mResponseEnd.IsNull() ? ResponseStartHighRes() - : TimeStampToDOMHighRes(mResponseEnd); + : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mResponseEnd)); } DOMTimeMilliSec diff --git a/dom/performance/PerformanceTiming.h b/dom/performance/PerformanceTiming.h index 0bc73fd3f..edfac8d02 100644..100755 --- a/dom/performance/PerformanceTiming.h +++ b/dom/performance/PerformanceTiming.h @@ -10,6 +10,7 @@ #include "mozilla/Attributes.h" #include "nsContentUtils.h" #include "nsDOMNavigationTiming.h" +#include "mozilla/TimerClamping.h" #include "nsWrapperCache.h" #include "Performance.h" @@ -68,10 +69,10 @@ public: * page), if the given TimeStamp is valid. Otherwise, it will return * the FetchStart timing value. */ - inline DOMHighResTimeStamp TimeStampToDOMHighResOrFetchStart(TimeStamp aStamp) + inline DOMHighResTimeStamp TimeStampToReducedDOMHighResOrFetchStart(TimeStamp aStamp) { return (!aStamp.IsNull()) - ? TimeStampToDOMHighRes(aStamp) + ? TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(aStamp)) : FetchStartHighRes(); } @@ -119,7 +120,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetNavigationStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetNavigationStart()); } DOMTimeMilliSec UnloadEventStart() @@ -127,7 +128,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetUnloadEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventStart()); } DOMTimeMilliSec UnloadEventEnd() @@ -135,7 +136,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetUnloadEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventEnd()); } uint16_t GetRedirectCount() const; @@ -185,7 +186,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomLoading(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomLoading()); } DOMTimeMilliSec DomInteractive() const @@ -193,7 +194,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomInteractive(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomInteractive()); } DOMTimeMilliSec DomContentLoadedEventStart() const @@ -201,7 +202,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomContentLoadedEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventStart()); } DOMTimeMilliSec DomContentLoadedEventEnd() const @@ -209,7 +210,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomContentLoadedEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventEnd()); } DOMTimeMilliSec DomComplete() const @@ -217,7 +218,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetDomComplete(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomComplete()); } DOMTimeMilliSec LoadEventStart() const @@ -225,7 +226,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetLoadEventStart(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventStart()); } DOMTimeMilliSec LoadEventEnd() const @@ -233,7 +234,7 @@ public: if (!nsContentUtils::IsPerformanceTimingEnabled()) { return 0; } - return GetDOMTiming()->GetLoadEventEnd(); + return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventEnd()); } private: diff --git a/dom/performance/tests/test_worker_performance_now.js b/dom/performance/tests/test_worker_performance_now.js index c2a905031..dee4efce6 100644 --- a/dom/performance/tests/test_worker_performance_now.js +++ b/dom/performance/tests/test_worker_performance_now.js @@ -26,51 +26,5 @@ var n = self.performance.now(), d = Date.now(); ok(n >= 0, "The value of now() should be equal to or greater than 0."); ok(self.performance.now() >= n, "The value of now() should monotonically increase."); -// The spec says performance.now() should have micro-second resolution, but allows 1ms if the platform doesn't support it. -// Our implementation does provide micro-second resolution, except for windows XP combined with some HW properties -// where we can't use QueryPerformanceCounters (see comments at mozilla-central/xpcom/ds/TimeStamp_windows.cpp). -// This XP-low-res case results in about 15ms resolutions, and can be identified when perf.now() returns only integers. -// -// Since setTimeout might return too early/late, our goal is that perf.now() changed within 2ms -// (or 25ms for XP-low-res), rather than specific number of setTimeout(N) invocations. -// See bug 749894 (intermittent failures of this test) -var platformPossiblyLowRes; -workerTestGetOSCPU(function(oscpu) { - platformPossiblyLowRes = oscpu.indexOf("Windows NT 5.1") == 0; // XP only - setTimeout(checkAfterTimeout, 1); -}); -var allInts = (n % 1) == 0; // Indicator of limited HW resolution. -var checks = 0; +workerTestDone(); -function checkAfterTimeout() { - checks++; - var d2 = Date.now(); - var n2 = self.performance.now(); - - allInts = allInts && (n2 % 1) == 0; - var lowResCounter = platformPossiblyLowRes && allInts; - - if ( n2 == n && checks < 50 && // 50 is just a failsafe. Our real goals are 2ms or 25ms. - ( (d2 - d) < 2 // The spec allows 1ms resolution. We allow up to measured 2ms to ellapse. - || - lowResCounter && - (d2 - d) < 25 - ) - ) { - setTimeout(checkAfterTimeout, 1); - return; - } - - // Loose spec: 1ms resolution, or 15ms resolution for the XP-low-res case. - // We shouldn't test that dt is actually within 2/25ms since the iterations break if it isn't, and timeout could be late. - ok(n2 > n, "Loose - the value of now() should increase within 2ms (or 25ms if low-res counter) (delta now(): " + (n2 - n) + " ms)."); - - // Strict spec: if it's not the XP-low-res case, while the spec allows 1ms resolution, it prefers microseconds, which we provide. - // Since the fastest setTimeout return which I observed was ~500 microseconds, a microseconds counter should change in 1 iteretion. - ok(n2 > n && (lowResCounter || checks == 1), - "Strict - [if high-res counter] the value of now() should increase after one setTimeout (hi-res: " + (!lowResCounter) + - ", iters: " + checks + - ", dt: " + (d2 - d) + - ", now(): " + n2 + ")."); - workerTestDone(); -}; |