Bug 1430173 Reduce the precision of all explicit clocks to 2ms r?baku
Backport to ESR where we don't have the ResistFingerprinting component.
MozReview-Commit-ID: 9bjycHjR3SF
old mode 100644
new mode 100755
--- a/dom/base/File.cpp
+++ b/dom/base/File.cpp
@@ -24,16 +24,17 @@
#include "nsIRemoteBlob.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsIUUIDGenerator.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsStringStream.h"
#include "nsJSUtils.h"
#include "nsPrintfCString.h"
+#include "mozilla/TimerClamping.h"
#include "mozilla/SHA1.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Preferences.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/FileSystemUtils.h"
@@ -722,17 +723,17 @@ BlobImplBase::GetType(nsAString& aType)
int64_t
BlobImplBase::GetLastModified(ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
if (IsDateUnknown()) {
mLastModificationDate = PR_Now();
}
- return mLastModificationDate / PR_USEC_PER_MSEC;
+ return TimerClamping::ReduceUsTimeValue(mLastModificationDate) / PR_USEC_PER_MSEC;
}
void
BlobImplBase::SetLastModified(int64_t aLastModified)
{
mLastModificationDate = aLastModified * PR_USEC_PER_MSEC;
}
old mode 100644
new mode 100755
--- a/dom/base/MultipartBlobImpl.cpp
+++ b/dom/base/MultipartBlobImpl.cpp
@@ -12,16 +12,17 @@
#include "nsDOMClassInfoID.h"
#include "nsIMultiplexInputStream.h"
#include "nsStringStream.h"
#include "nsTArray.h"
#include "nsJSUtils.h"
#include "nsContentUtils.h"
#include "nsIScriptError.h"
#include "nsIXPConnect.h"
+#include "mozilla/TimerClamping.h"
#include <algorithm>
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS_INHERITED0(MultipartBlobImpl, BlobImpl)
/* static */ already_AddRefed<MultipartBlobImpl>
@@ -265,18 +266,17 @@ MultipartBlobImpl::SetLengthAndModifiedD
mLength = totalLength;
if (mIsFile) {
// We cannot use PR_Now() because bug 493756 and, for this reason:
// var x = new Date(); var f = new File(...);
// x.getTime() < f.dateModified.getTime()
// could fail.
- mLastModificationDate =
- lastModifiedSet ? lastModified * PR_USEC_PER_MSEC : JS_Now();
+ mLastModificationDate = TimerClamping::ReduceUsTimeValue(lastModifiedSet ? lastModified * PR_USEC_PER_MSEC : JS_Now());
}
}
void
MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv) const
{
if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
new file mode 100755
--- /dev/null
+++ b/dom/base/TimerClamping.cpp
@@ -0,0 +1,35 @@
+/* -*- 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 "TimerClamping.h"
+
+namespace mozilla {
+
+/* static */
+double
+TimerClamping::ReduceSTimeValue(double aTime)
+{
+ static const double maxResolutionS = .002;
+ return floor(aTime / maxResolutionS) * maxResolutionS;
+}
+
+/* static */
+double
+TimerClamping::ReduceMsTimeValue(double aTime)
+{
+ static const double maxResolutionMs = 2;
+ return floor(aTime / maxResolutionMs) * maxResolutionMs;
+}
+
+/* static */
+double
+TimerClamping::ReduceUsTimeValue(double aTime)
+{
+ static const double maxResolutionUs = 2000;
+ return floor(aTime / maxResolutionUs) * maxResolutionUs;
+}
+
+}
\ No newline at end of file
new file mode 100755
--- /dev/null
+++ b/dom/base/TimerClamping.h
@@ -0,0 +1,22 @@
+/* -*- 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 TimerClamping_h___
+#define TimerClamping_h___
+
+namespace mozilla {
+
+class TimerClamping
+{
+public:
+ static double ReduceSTimeValue(double aTime);
+ static double ReduceMsTimeValue(double aTime);
+ static double ReduceUsTimeValue(double aTime);
+};
+
+}
+
+#endif /* TimerClamping_h___ */
\ No newline at end of file
old mode 100644
new mode 100755
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -138,16 +138,17 @@ if CONFIG['MOZ_WEBRTC']:
'nsDOMDataChannel.h',
'nsDOMDataChannelDeclarations.h',
]
EXPORTS.mozilla += [
'CORSMode.h',
'FeedWriterEnabled.h',
'TextInputProcessor.h',
+ 'TimerClamping.h',
'UseCounter.h',
]
EXPORTS.mozilla.dom += [
'!UseCounterList.h',
'AnonymousContent.h',
'Attr.h',
'BarProps.h',
@@ -358,16 +359,17 @@ UNIFIED_SOURCES += [
'StructuredCloneHolder.cpp',
'StyleSheetList.cpp',
'SubtleCrypto.cpp',
'TabGroup.cpp',
'Text.cpp',
'TextInputProcessor.cpp',
'ThirdPartyUtil.cpp',
'Timeout.cpp',
+ 'TimerClamping.cpp',
'TreeWalker.cpp',
'WebKitCSSMatrix.cpp',
'WebSocket.cpp',
'WindowNamedPropertiesHandler.cpp',
'WindowOrientationObserver.cpp',
]
if CONFIG['MOZ_WEBRTC']:
old mode 100644
new mode 100755
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -25,16 +25,17 @@
#include "ScriptSettings.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "WorkerScope.h"
#include "xpcpublic.h"
#include "nsContentUtils.h"
#include "nsDocShell.h"
#include "nsProxyRelease.h"
+#include "mozilla/TimerClamping.h"
#include "mozilla/ConsoleTimelineMarker.h"
#include "mozilla/TimestampTimelineMarker.h"
#include "nsIConsoleAPIStorage.h"
#include "nsIDOMWindowUtils.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadContext.h"
#include "nsIProgrammingLanguage.h"
@@ -1333,17 +1334,17 @@ Console::MethodInternal(JSContext* aCx,
}
} else {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
TimeDuration duration =
mozilla::TimeStamp::Now() - workerPrivate->NowBaseTimeStamp();
- monotonicTimer = duration.ToMilliseconds();
+ monotonicTimer = TimerClamping::ReduceMsTimeValue(duration.ToMilliseconds());
}
}
if (aMethodName == MethodTime && !aData.IsEmpty()) {
callData->mStartTimerStatus = StartTimer(aCx, aData[0],
monotonicTimer,
callData->mStartTimerLabel,
&callData->mStartTimerValue);
old mode 100644
new mode 100755
--- a/dom/events/Event.cpp
+++ b/dom/events/Event.cpp
@@ -27,16 +27,17 @@
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIScrollableFrame.h"
#include "nsJSEnvironment.h"
#include "nsLayoutUtils.h"
#include "nsPIWindowRoot.h"
+#include "mozilla/TimerClamping.h"
#include "WorkerPrivate.h"
namespace mozilla {
namespace dom {
namespace workers {
extern bool IsCurrentThreadRunningChromeWorker();
} // namespace workers
@@ -1080,16 +1081,22 @@ Event::DefaultPrevented(JSContext* aCx)
// i.e., preventDefault() has been called by chrome, return true only when
// this is called by chrome.
return mEvent->DefaultPreventedByContent() || IsChrome(aCx);
}
double
Event::TimeStamp() const
{
+ return TimerClamping::ReduceMsTimeValue(TimeStampImpl());
+}
+
+double
+Event::TimeStampImpl() const
+{
if (!sReturnHighResTimeStamp) {
return static_cast<double>(mEvent->mTime);
}
if (mEvent->mTimeStamp.IsNull()) {
return 0.0;
}
old mode 100644
new mode 100755
--- a/dom/events/Event.h
+++ b/dom/events/Event.h
@@ -57,16 +57,17 @@ public:
protected:
virtual ~Event();
private:
void ConstructorInit(EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent);
+ double TimeStampImpl() const;
public:
static Event* FromSupports(nsISupports* aSupports)
{
nsIDOMEvent* event =
static_cast<nsIDOMEvent*>(aSupports);
#ifdef DEBUG
{
old mode 100644
new mode 100755
--- a/dom/media/DOMMediaStream.cpp
+++ b/dom/media/DOMMediaStream.cpp
@@ -4,16 +4,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DOMMediaStream.h"
#include "nsContentUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIScriptError.h"
#include "nsIUUIDGenerator.h"
#include "nsPIDOMWindow.h"
+#include "mozilla/TimerClamping.h"
#include "mozilla/dom/MediaStreamBinding.h"
#include "mozilla/dom/MediaStreamTrackEvent.h"
#include "mozilla/dom/LocalMediaStreamBinding.h"
#include "mozilla/dom/AudioNode.h"
#include "AudioChannelAgent.h"
#include "mozilla/dom/AudioTrack.h"
#include "mozilla/dom/AudioTrackList.h"
#include "mozilla/dom/VideoTrack.h"
@@ -539,18 +540,18 @@ DOMMediaStream::Constructor(const Global
}
double
DOMMediaStream::CurrentTime()
{
if (!mPlaybackStream) {
return 0.0;
}
- return mPlaybackStream->
- StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime);
+ return TimerClamping::ReduceSTimeValue(mPlaybackStream->
+ StreamTimeToSeconds(mPlaybackStream->GetCurrentTime() - mLogicalStreamStartTime));
}
void
DOMMediaStream::GetId(nsAString& aID) const
{
aID = mID;
}
old mode 100644
new mode 100755
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -36,16 +36,17 @@
#include "MediaStreamAudioDestinationNode.h"
#include "MediaStreamAudioSourceNode.h"
#include "MediaStreamGraph.h"
#include "nsContentUtils.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsPIDOMWindow.h"
#include "nsPrintfCString.h"
+#include "mozilla/TimerClamping.h"
#include "OscillatorNode.h"
#include "PannerNode.h"
#include "PeriodicWave.h"
#include "ScriptProcessorNode.h"
#include "StereoPannerNode.h"
#include "WaveShaperNode.h"
namespace mozilla {
@@ -739,17 +740,17 @@ AudioContext::DestinationStream() const
}
return nullptr;
}
double
AudioContext::CurrentTime() const
{
MediaStream* stream = Destination()->Stream();
- return stream->StreamTimeToSeconds(stream->GetCurrentTime());
+ return TimerClamping::ReduceSTimeValue(stream->StreamTimeToSeconds(stream->GetCurrentTime()));
}
void
AudioContext::Shutdown()
{
mIsShutDown = true;
if (!mIsOffline) {
old mode 100644
new mode 100755
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -16,16 +16,17 @@
#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"
+#include "mozilla/TimerClamping.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#ifdef MOZ_WIDGET_GONK
#define PERFLOG(msg, ...) __android_log_print(ANDROID_LOG_INFO, "PerformanceTiming", msg, ##__VA_ARGS__)
#else
#define PERFLOG(msg, ...) printf_stderr(msg, ##__VA_ARGS__)
#endif
@@ -223,19 +224,19 @@ Performance::ClearResourceTimings()
{
MOZ_ASSERT(NS_IsMainThread());
mResourceEntries.Clear();
}
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;
}
void
Performance::Mark(const nsAString& aName, ErrorResult& aRv)
{
// Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
old mode 100644
new mode 100755
--- a/dom/performance/PerformanceTiming.cpp
+++ b/dom/performance/PerformanceTiming.cpp
@@ -16,17 +16,17 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Per
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
PerformanceTiming::PerformanceTiming(Performance* aPerformance,
nsITimedChannel* aChannel,
nsIHttpChannel* aHttpChannel,
DOMHighResTimeStamp aZeroTime)
: mPerformance(aPerformance),
mFetchStart(0.0),
- mZeroTime(aZeroTime),
+ mZeroTime(TimerClamping::ReduceMsTimeValue(aZeroTime)),
mRedirectCount(0),
mTimingAllowed(true),
mAllRedirectsSameOrigin(true),
mInitialized(!!aChannel),
mReportCrossOriginRedirect(true)
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");
@@ -84,17 +84,17 @@ PerformanceTiming::FetchStartHighRes()
return mZeroTime;
}
MOZ_ASSERT(!mAsyncOpen.IsNull(), "The fetch start time stamp should always be "
"valid if the performance timing is enabled");
mFetchStart = (!mAsyncOpen.IsNull())
? TimeStampToDOMHighRes(mAsyncOpen)
: 0.0;
}
- return mFetchStart;
+ return TimerClamping::ReduceMsTimeValue(mFetchStart);
}
DOMTimeMilliSec
PerformanceTiming::FetchStart()
{
return static_cast<int64_t>(FetchStartHighRes());
}
@@ -170,17 +170,17 @@ PerformanceTiming::ShouldReportCrossOrig
* @return a valid timing if the Performance Timing is enabled
*/
DOMHighResTimeStamp
PerformanceTiming::RedirectStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mRedirectStart);
+ return TimeStampToReducedDOMHighResOrFetchStart(mRedirectStart);
}
DOMTimeMilliSec
PerformanceTiming::RedirectStart()
{
if (!IsInitialized()) {
return 0;
}
@@ -203,17 +203,17 @@ PerformanceTiming::RedirectStart()
* @return a valid timing if the Performance Timing is enabled
*/
DOMHighResTimeStamp
PerformanceTiming::RedirectEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mRedirectEnd);
+ return TimeStampToReducedDOMHighResOrFetchStart(mRedirectEnd);
}
DOMTimeMilliSec
PerformanceTiming::RedirectEnd()
{
if (!IsInitialized()) {
return 0;
}
@@ -226,82 +226,82 @@ PerformanceTiming::RedirectEnd()
}
DOMHighResTimeStamp
PerformanceTiming::DomainLookupStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mDomainLookupStart);
+ return TimeStampToReducedDOMHighResOrFetchStart(mDomainLookupStart);
}
DOMTimeMilliSec
PerformanceTiming::DomainLookupStart()
{
return static_cast<int64_t>(DomainLookupStartHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::DomainLookupEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
// Bug 1155008 - nsHttpTransaction is racy. Return DomainLookupStart when null
return mDomainLookupEnd.IsNull() ? DomainLookupStartHighRes()
- : TimeStampToDOMHighRes(mDomainLookupEnd);
+ : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mDomainLookupEnd));
}
DOMTimeMilliSec
PerformanceTiming::DomainLookupEnd()
{
return static_cast<int64_t>(DomainLookupEndHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::ConnectStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
return mConnectStart.IsNull() ? DomainLookupEndHighRes()
- : TimeStampToDOMHighRes(mConnectStart);
+ : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectStart));
}
DOMTimeMilliSec
PerformanceTiming::ConnectStart()
{
return static_cast<int64_t>(ConnectStartHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::ConnectEndHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
// Bug 1155008 - nsHttpTransaction is racy. Return ConnectStart when null
return mConnectEnd.IsNull() ? ConnectStartHighRes()
- : TimeStampToDOMHighRes(mConnectEnd);
+ : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mConnectEnd));
}
DOMTimeMilliSec
PerformanceTiming::ConnectEnd()
{
return static_cast<int64_t>(ConnectEndHighRes());
}
DOMHighResTimeStamp
PerformanceTiming::RequestStartHighRes()
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
- return TimeStampToDOMHighResOrFetchStart(mRequestStart);
+ return TimeStampToReducedDOMHighResOrFetchStart(mRequestStart);
}
DOMTimeMilliSec
PerformanceTiming::RequestStart()
{
return static_cast<int64_t>(RequestStartHighRes());
}
@@ -310,17 +310,17 @@ PerformanceTiming::ResponseStartHighRes(
{
if (!nsContentUtils::IsPerformanceTimingEnabled() || !IsInitialized()) {
return mZeroTime;
}
if (mResponseStart.IsNull() ||
(!mCacheReadStart.IsNull() && mCacheReadStart < mResponseStart)) {
mResponseStart = mCacheReadStart;
}
- return TimeStampToDOMHighResOrFetchStart(mResponseStart);
+ return TimeStampToReducedDOMHighResOrFetchStart(mResponseStart);
}
DOMTimeMilliSec
PerformanceTiming::ResponseStart()
{
return static_cast<int64_t>(ResponseStartHighRes());
}
@@ -331,17 +331,17 @@ PerformanceTiming::ResponseEndHighRes()
return mZeroTime;
}
if (mResponseEnd.IsNull() ||
(!mCacheReadEnd.IsNull() && mCacheReadEnd < mResponseEnd)) {
mResponseEnd = mCacheReadEnd;
}
// Bug 1155008 - nsHttpTransaction is racy. Return ResponseStart when null
return mResponseEnd.IsNull() ? ResponseStartHighRes()
- : TimeStampToDOMHighRes(mResponseEnd);
+ : TimerClamping::ReduceMsTimeValue(TimeStampToDOMHighRes(mResponseEnd));
}
DOMTimeMilliSec
PerformanceTiming::ResponseEnd()
{
return static_cast<int64_t>(ResponseEndHighRes());
}
old mode 100644
new mode 100755
--- a/dom/performance/PerformanceTiming.h
+++ b/dom/performance/PerformanceTiming.h
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PerformanceTiming_h
#define mozilla_dom_PerformanceTiming_h
#include "mozilla/Attributes.h"
#include "nsContentUtils.h"
#include "nsDOMNavigationTiming.h"
+#include "mozilla/TimerClamping.h"
#include "nsWrapperCache.h"
#include "Performance.h"
class nsIHttpChannel;
class nsITimedChannel;
namespace mozilla {
namespace dom {
@@ -63,20 +64,20 @@ public:
* @param aStamp
* The TimeStamp recorded for a specific event. This TimeStamp can
* be null.
* @return the duration of an event with a given TimeStamp, relative to the
* navigationStart TimeStamp (the moment the user landed on the
* 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();
}
/**
* The nsITimedChannel records an absolute timestamp for each event.
* The nsDOMNavigationTiming will record the moment when the user landed on
* the page. This is a window.performance unique timestamp, so it can be used
* for all the events (navigation timing and resource timing events).
@@ -114,33 +115,33 @@ public:
JS::Handle<JSObject*> aGivenProto) override;
// PerformanceNavigation WebIDL methods
DOMTimeMilliSec NavigationStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetNavigationStart();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetNavigationStart());
}
DOMTimeMilliSec UnloadEventStart()
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetUnloadEventStart();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventStart());
}
DOMTimeMilliSec UnloadEventEnd()
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetUnloadEventEnd();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetUnloadEventEnd());
}
uint16_t GetRedirectCount() const;
// Checks if the resource is either same origin as the page that started
// the load, or if the response contains the Timing-Allow-Origin header
// with a value of * or matching the domain of the loading Principal
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
@@ -178,65 +179,65 @@ public:
DOMTimeMilliSec ResponseStart();
DOMTimeMilliSec ResponseEnd();
DOMTimeMilliSec DomLoading()
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetDomLoading();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomLoading());
}
DOMTimeMilliSec DomInteractive() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetDomInteractive();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomInteractive());
}
DOMTimeMilliSec DomContentLoadedEventStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetDomContentLoadedEventStart();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventStart());
}
DOMTimeMilliSec DomContentLoadedEventEnd() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetDomContentLoadedEventEnd();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomContentLoadedEventEnd());
}
DOMTimeMilliSec DomComplete() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetDomComplete();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetDomComplete());
}
DOMTimeMilliSec LoadEventStart() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetLoadEventStart();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventStart());
}
DOMTimeMilliSec LoadEventEnd() const
{
if (!nsContentUtils::IsPerformanceTimingEnabled()) {
return 0;
}
- return GetDOMTiming()->GetLoadEventEnd();
+ return TimerClamping::ReduceMsTimeValue(GetDOMTiming()->GetLoadEventEnd());
}
private:
~PerformanceTiming();
bool IsInitialized() const;
void InitializeTimingInfo(nsITimedChannel* aChannel);
old mode 100644
new mode 100755
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -1227,17 +1227,20 @@ date_parse(JSContext* cx, unsigned argc,
args.rval().set(TimeValue(result));
return true;
}
static ClippedTime
NowAsMillis()
{
- return TimeClip(static_cast<double>(PRMJ_Now()) / PRMJ_USEC_PER_MSEC);
+ const double maxResolutionMs = 2;
+ double timestamp = static_cast<double>(PRMJ_Now()) / PRMJ_USEC_PER_MSEC;
+ timestamp = floor(timestamp / maxResolutionMs) * maxResolutionMs;
+ return TimeClip(timestamp);
}
bool
js::date_now(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
args.rval().set(TimeValue(NowAsMillis()));
return true;