Bug 1278838 - Remove separate worker binding for Performance API, r=smaug

--HG--
rename : dom/performance/nsPerformance.cpp => dom/performance/Performance.cpp
rename : dom/performance/nsPerformance.h => dom/performance/Performance.h
rename : dom/workers/Performance.cpp => dom/performance/PerformanceWorker.cpp
rename : dom/workers/Performance.h => dom/performance/PerformanceWorker.h
This commit is contained in:
Andrea Marchesini 2016-06-09 19:04:42 +02:00
parent a8e509a525
commit 64734bf74c
43 changed files with 1320 additions and 1231 deletions

View File

@ -15,10 +15,10 @@
#include "nsContentSecurityManager.h"
#include "nsScreen.h"
#include "nsHistory.h"
#include "nsPerformance.h"
#include "nsDOMNavigationTiming.h"
#include "nsIDOMStorageManager.h"
#include "mozilla/dom/DOMStorage.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/StorageEvent.h"
#include "mozilla/dom/StorageEventBinding.h"
#include "mozilla/IntegerPrintfMacros.h"
@ -2811,10 +2811,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
currentInner->AsInner()->CreatePerformanceObjectIfNeeded();
if (currentInner->mPerformance) {
newInnerWindow->mPerformance =
new nsPerformance(newInnerWindow->AsInner(),
currentInner->mPerformance->GetDOMTiming(),
currentInner->mPerformance->GetChannel(),
currentInner->mPerformance->GetParentPerformance());
Performance::CreateForMainThread(newInnerWindow->AsInner(),
currentInner->mPerformance->GetDOMTiming(),
currentInner->mPerformance->GetChannel(),
currentInner->mPerformance->GetParentPerformance());
}
}
@ -3832,7 +3832,7 @@ nsGlobalWindow::GetHistory(ErrorResult& aError)
return mHistory;
}
nsPerformance*
Performance*
nsPIDOMWindowInner::GetPerformance()
{
MOZ_ASSERT(IsInnerWindow());
@ -3840,7 +3840,7 @@ nsPIDOMWindowInner::GetPerformance()
return mPerformance;
}
nsPerformance*
Performance*
nsGlobalWindow::GetPerformance()
{
return AsInner()->GetPerformance();
@ -3865,7 +3865,7 @@ nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
if (timing) {
// If we are dealing with an iframe, we will need the parent's performance
// object (so we can add the iframe as a resource of that page).
nsPerformance* parentPerformance = nullptr;
Performance* parentPerformance = nullptr;
nsCOMPtr<nsPIDOMWindowOuter> parentWindow = GetScriptableParentOrNull();
if (parentWindow) {
nsPIDOMWindowInner* parentInnerWindow = nullptr;
@ -3877,7 +3877,8 @@ nsPIDOMWindowInner::CreatePerformanceObjectIfNeeded()
}
}
mPerformance =
new nsPerformance(this, timing, timedChannel, parentPerformance);
Performance::CreateForMainThread(this, timing, timedChannel,
parentPerformance);
}
}

View File

@ -1257,7 +1257,8 @@ public:
already_AddRefed<nsWindowRoot> GetWindowRootOuter();
already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
nsPerformance* GetPerformance();
mozilla::dom::Performance* GetPerformance();
protected:
// Web IDL helpers

View File

@ -31,7 +31,6 @@ class nsIDocument;
class nsIIdleObserver;
class nsIScriptTimeoutHandler;
class nsIURI;
class nsPerformance;
class nsPIDOMWindowInner;
class nsPIDOMWindowOuter;
class nsPIWindowRoot;
@ -44,6 +43,7 @@ namespace mozilla {
namespace dom {
class AudioContext;
class Element;
class Performance;
class ServiceWorkerRegistrationMainThread;
} // namespace dom
namespace gfx {
@ -611,7 +611,7 @@ protected:
nsIDocShell* MOZ_NON_OWNING_REF mDocShell; // Weak Reference
// mPerformance is only used on inner windows.
RefPtr<nsPerformance> mPerformance;
RefPtr<mozilla::dom::Performance> mPerformance;
typedef nsRefPtrHashtable<nsStringHashKey,
mozilla::dom::ServiceWorkerRegistrationMainThread>
@ -741,7 +741,7 @@ public:
GetServiceWorkerRegistration(const nsAString& aScope);
void InvalidateServiceWorkerRegistration(const nsAString& aScope);
nsPerformance* GetPerformance();
mozilla::dom::Performance* GetPerformance();
bool HasMutationListeners(uint32_t aMutationEventType) const
{

View File

@ -885,15 +885,6 @@ DOMInterfaces = {
'wrapperCache': False
},
'Performance': [{
'nativeType': 'nsPerformance',
},
{
'nativeType': 'mozilla::dom::workers::Performance',
'headerFile': 'mozilla/dom/workers/bindings/Performance.h',
'workers': True,
}],
'Plugin': {
'headerFile' : 'nsPluginArray.h',
'nativeType': 'nsPluginElement',

View File

@ -11,6 +11,7 @@
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FunctionBinding.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Maybe.h"
@ -20,7 +21,6 @@
#include "nsGlobalWindow.h"
#include "nsJSUtils.h"
#include "nsNetUtil.h"
#include "nsPerformance.h"
#include "ScriptSettings.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
@ -1355,7 +1355,7 @@ Console::MethodInternal(JSContext* aCx, MethodName aMethodName,
nsGlobalWindow *win = nsGlobalWindow::Cast(mWindow);
MOZ_ASSERT(win);
RefPtr<nsPerformance> performance = win->GetPerformance();
RefPtr<Performance> performance = win->GetPerformance();
if (!performance) {
return;
}

View File

@ -13,6 +13,7 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/InternalMutationEvent.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Preferences.h"
@ -30,7 +31,6 @@
#include "nsIScrollableFrame.h"
#include "nsJSEnvironment.h"
#include "nsLayoutUtils.h"
#include "nsPerformance.h"
#include "nsPIWindowRoot.h"
#include "WorkerPrivate.h"
@ -1096,7 +1096,8 @@ Event::TimeStamp() const
if (NS_WARN_IF(!win)) {
return 0.0;
}
nsPerformance* perf = win->GetPerformance();
Performance* perf = win->GetPerformance();
if (NS_WARN_IF(!perf)) {
return 0.0;
}

View File

@ -29,7 +29,7 @@ Gamepad::UpdateTimestamp()
{
nsCOMPtr<nsPIDOMWindowInner> newWindow(do_QueryInterface(mParent));
if(newWindow) {
nsPerformance* perf = newWindow->GetPerformance();
Performance* perf = newWindow->GetPerformance();
if (perf) {
mTimestamp = perf->Now();
}

View File

@ -10,12 +10,12 @@
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/GamepadBinding.h"
#include "mozilla/dom/GamepadButton.h"
#include "mozilla/dom/Performance.h"
#include <stdint.h>
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsWrapperCache.h"
#include "nsPerformance.h"
namespace mozilla {
namespace dom {

View File

@ -28,7 +28,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "nsPerformance.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/VideoPlaybackQuality.h"
NS_IMPL_NS_NEW_HTML_ELEMENT(Video)
@ -235,7 +235,7 @@ HTMLVideoElement::GetVideoPlaybackQuality()
if (sVideoStatsEnabled) {
if (nsPIDOMWindowInner* window = OwnerDoc()->GetInnerWindow()) {
nsPerformance* perf = window->GetPerformance();
Performance* perf = window->GetPerformance();
if (perf) {
creationTime = perf->Now();
}

View File

@ -0,0 +1,537 @@
/* -*- 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 "Performance.h"
#include "GeckoProfiler.h"
#include "PerformanceEntry.h"
#include "PerformanceMainThread.h"
#include "PerformanceMark.h"
#include "PerformanceMeasure.h"
#include "PerformanceObserver.h"
#include "PerformanceResourceTiming.h"
#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 "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
namespace mozilla {
namespace dom {
using namespace workers;
namespace {
// Helper classes
class MOZ_STACK_CLASS PerformanceEntryComparator final
{
public:
bool Equals(const PerformanceEntry* aElem1,
const PerformanceEntry* aElem2) const
{
MOZ_ASSERT(aElem1 && aElem2,
"Trying to compare null performance entries");
return aElem1->StartTime() == aElem2->StartTime();
}
bool LessThan(const PerformanceEntry* aElem1,
const PerformanceEntry* aElem2) const
{
MOZ_ASSERT(aElem1 && aElem2,
"Trying to compare null performance entries");
return aElem1->StartTime() < aElem2->StartTime();
}
};
class PrefEnabledRunnable final
: public WorkerCheckAPIExposureOnMainThreadRunnable
{
public:
PrefEnabledRunnable(WorkerPrivate* aWorkerPrivate,
const nsCString& aPrefName)
: WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
, mEnabled(false)
, mPrefName(aPrefName)
{ }
bool MainThreadRun() override
{
MOZ_ASSERT(NS_IsMainThread());
mEnabled = Preferences::GetBool(mPrefName.get(), false);
return true;
}
bool IsEnabled() const
{
return mEnabled;
}
private:
bool mEnabled;
nsCString mPrefName;
};
} // anonymous namespace
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Performance)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(Performance,
DOMEventTargetHelper,
mUserEntries,
mResourceEntries);
NS_IMPL_ADDREF_INHERITED(Performance, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(Performance, DOMEventTargetHelper)
/* static */ already_AddRefed<Performance>
Performance::CreateForMainThread(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
Performance* aParentPerformance)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<Performance> performance =
new PerformanceMainThread(aWindow, aDOMTiming, aChannel,
aParentPerformance);
return performance.forget();
}
/* static */ already_AddRefed<Performance>
Performance::CreateForWorker(workers::WorkerPrivate* aWorkerPrivate)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
RefPtr<Performance> performance = new PerformanceWorker(aWorkerPrivate);
return performance.forget();
}
Performance::Performance()
: mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(!NS_IsMainThread());
}
Performance::Performance(nsPIDOMWindowInner* aWindow)
: DOMEventTargetHelper(aWindow)
, mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
Performance::~Performance()
{}
JSObject*
Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PerformanceBinding::Wrap(aCx, this, aGivenProto);
}
void
Performance::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
aRetval = mResourceEntries;
aRetval.AppendElements(mUserEntries);
aRetval.Sort(PerformanceEntryComparator());
}
void
Performance::GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
if (aEntryType.EqualsLiteral("resource")) {
aRetval = mResourceEntries;
return;
}
aRetval.Clear();
if (aEntryType.EqualsLiteral("mark") ||
aEntryType.EqualsLiteral("measure")) {
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetEntryType().Equals(aEntryType)) {
aRetval.AppendElement(entry);
}
}
}
}
void
Performance::GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
aRetval.Clear();
for (PerformanceEntry* entry : mResourceEntries) {
if (entry->GetName().Equals(aName) &&
(!aEntryType.WasPassed() ||
entry->GetEntryType().Equals(aEntryType.Value()))) {
aRetval.AppendElement(entry);
}
}
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetName().Equals(aName) &&
(!aEntryType.WasPassed() ||
entry->GetEntryType().Equals(aEntryType.Value()))) {
aRetval.AppendElement(entry);
}
}
aRetval.Sort(PerformanceEntryComparator());
}
void
Performance::ClearUserEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType)
{
for (uint32_t i = 0; i < mUserEntries.Length();) {
if ((!aEntryName.WasPassed() ||
mUserEntries[i]->GetName().Equals(aEntryName.Value())) &&
(aEntryType.IsEmpty() ||
mUserEntries[i]->GetEntryType().Equals(aEntryType))) {
mUserEntries.RemoveElementAt(i);
} else {
++i;
}
}
}
void
Performance::ClearResourceTimings()
{
MOZ_ASSERT(NS_IsMainThread());
mResourceEntries.Clear();
}
DOMHighResTimeStamp
Performance::RoundTime(double aTime) const
{
// Round down to the nearest 5us, because if the timer is too accurate people
// can do nasty timing attacks with it. See similar code in the worker
// Performance implementation.
const double maxResolutionMs = 0.005;
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.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
if (IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
RefPtr<PerformanceMark> performanceMark =
new PerformanceMark(GetAsISupports(), aName, Now());
InsertUserEntry(performanceMark);
if (profiler_is_active()) {
PROFILER_MARKER(NS_ConvertUTF16toUTF8(aName).get());
}
}
void
Performance::ClearMarks(const Optional<nsAString>& aName)
{
ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
}
DOMHighResTimeStamp
Performance::ResolveTimestampFromName(const nsAString& aName,
ErrorResult& aRv)
{
AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
DOMHighResTimeStamp ts;
Optional<nsAString> typeParam;
nsAutoString str;
str.AssignLiteral("mark");
typeParam = &str;
GetEntriesByName(aName, typeParam, arr);
if (!arr.IsEmpty()) {
return arr.LastElement()->StartTime();
}
if (!IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return 0;
}
ts = GetPerformanceTimingFromString(aName);
if (!ts) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return 0;
}
return ts - CreationTime();
}
void
Performance::Measure(const nsAString& aName,
const Optional<nsAString>& aStartMark,
const Optional<nsAString>& aEndMark,
ErrorResult& aRv)
{
// Don't add the entry if the buffer is full. XXX should be removed by bug
// 1159003.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
DOMHighResTimeStamp startTime;
DOMHighResTimeStamp endTime;
if (IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (aStartMark.WasPassed()) {
startTime = ResolveTimestampFromName(aStartMark.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} else {
// Navigation start is used in this case, but since DOMHighResTimeStamp is
// in relation to navigation start, this will be zero if a name is not
// passed.
startTime = 0;
}
if (aEndMark.WasPassed()) {
endTime = ResolveTimestampFromName(aEndMark.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} else {
endTime = Now();
}
RefPtr<PerformanceMeasure> performanceMeasure =
new PerformanceMeasure(GetAsISupports(), aName, startTime, endTime);
InsertUserEntry(performanceMeasure);
}
void
Performance::ClearMeasures(const Optional<nsAString>& aName)
{
ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
}
void
Performance::LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const
{
PERFLOG("Performance Entry: %s|%s|%s|%f|%f|%" PRIu64 "\n",
aOwner.BeginReading(),
NS_ConvertUTF16toUTF8(aEntry->GetEntryType()).get(),
NS_ConvertUTF16toUTF8(aEntry->GetName()).get(),
aEntry->StartTime(),
aEntry->Duration(),
static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC));
}
void
Performance::TimingNotification(PerformanceEntry* aEntry,
const nsACString& aOwner, uint64_t aEpoch)
{
PerformanceEntryEventInit init;
init.mBubbles = false;
init.mCancelable = false;
init.mName = aEntry->GetName();
init.mEntryType = aEntry->GetEntryType();
init.mStartTime = aEntry->StartTime();
init.mDuration = aEntry->Duration();
init.mEpoch = aEpoch;
init.mOrigin = NS_ConvertUTF8toUTF16(aOwner.BeginReading());
RefPtr<PerformanceEntryEvent> perfEntryEvent =
PerformanceEntryEvent::Constructor(this, NS_LITERAL_STRING("performanceentry"), init);
nsCOMPtr<EventTarget> et = do_QueryInterface(GetOwner());
if (et) {
bool dummy = false;
et->DispatchEvent(perfEntryEvent, &dummy);
}
}
void
Performance::InsertUserEntry(PerformanceEntry* aEntry)
{
mUserEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
QueueEntry(aEntry);
}
void
Performance::SetResourceTimingBufferSize(uint64_t aMaxSize)
{
mResourceTimingBufferSize = aMaxSize;
}
void
Performance::InsertResourceEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(aEntry);
MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
return;
}
mResourceEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
if (mResourceEntries.Length() == mResourceTimingBufferSize) {
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
QueueEntry(aEntry);
}
void
Performance::AddObserver(PerformanceObserver* aObserver)
{
mObservers.AppendElementUnlessExists(aObserver);
}
void
Performance::RemoveObserver(PerformanceObserver* aObserver)
{
mObservers.RemoveElement(aObserver);
}
void
Performance::NotifyObservers()
{
mPendingNotificationObserversTask = false;
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
Notify, ());
}
void
Performance::CancelNotificationObservers()
{
mPendingNotificationObserversTask = false;
}
class NotifyObserversTask final : public CancelableRunnable
{
public:
explicit NotifyObserversTask(Performance* aPerformance)
: mPerformance(aPerformance)
{
MOZ_ASSERT(mPerformance);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(mPerformance);
mPerformance->NotifyObservers();
return NS_OK;
}
nsresult Cancel() override
{
mPerformance->CancelNotificationObservers();
mPerformance = nullptr;
return NS_OK;
}
private:
~NotifyObserversTask()
{
}
RefPtr<Performance> mPerformance;
};
void
Performance::RunNotificationObserversTask()
{
mPendingNotificationObserversTask = true;
nsCOMPtr<nsIRunnable> task = new NotifyObserversTask(this);
nsresult rv = NS_DispatchToCurrentThread(task);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPendingNotificationObserversTask = false;
}
}
void
Performance::QueueEntry(PerformanceEntry* aEntry)
{
if (mObservers.IsEmpty()) {
return;
}
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
QueueEntry, (aEntry));
if (!mPendingNotificationObserversTask) {
RunNotificationObserversTask();
}
}
/* static */ bool
Performance::IsEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.enable_user_timing", false);
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<PrefEnabledRunnable> runnable =
new PrefEnabledRunnable(workerPrivate,
NS_LITERAL_CSTRING("dom.enable_user_timing"));
return runnable->Dispatch() && runnable->IsEnabled();
}
/* static */ bool
Performance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.enable_performance_observer", false);
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<PrefEnabledRunnable> runnable =
new PrefEnabledRunnable(workerPrivate,
NS_LITERAL_CSTRING("dom.enable_performance_observer"));
return runnable->Dispatch() && runnable->IsEnabled();
}
} // dom namespace
} // mozilla namespace

View File

@ -0,0 +1,162 @@
/* -*- 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 mozilla_dom_Performance_h
#define mozilla_dom_Performance_h
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCOMPtr.h"
#include "nsDOMNavigationTiming.h"
class nsITimedChannel;
class nsIHttpChannel;
namespace mozilla {
class ErrorResult;
namespace dom {
class PerformanceEntry;
class PerformanceNavigation;
class PerformanceObserver;
class PerformanceTiming;
namespace workers {
class WorkerPrivate;
}
// Base class for main-thread and worker Performance API
class Performance : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Performance,
DOMEventTargetHelper)
static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<Performance>
CreateForMainThread(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
Performance* aParentPerformance);
static already_AddRefed<Performance>
CreateForWorker(workers::WorkerPrivate* aWorkerPrivate);
JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto) override;
void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval);
virtual void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel) = 0;
void ClearResourceTimings();
virtual DOMHighResTimeStamp Now() const = 0;
void Mark(const nsAString& aName, ErrorResult& aRv);
void ClearMarks(const Optional<nsAString>& aName);
void Measure(const nsAString& aName,
const Optional<nsAString>& aStartMark,
const Optional<nsAString>& aEndMark,
ErrorResult& aRv);
void ClearMeasures(const Optional<nsAString>& aName);
void SetResourceTimingBufferSize(uint64_t aMaxSize);
void AddObserver(PerformanceObserver* aObserver);
void RemoveObserver(PerformanceObserver* aObserver);
void NotifyObservers();
void CancelNotificationObservers();
virtual PerformanceTiming* Timing() = 0;
virtual PerformanceNavigation* Navigation() = 0;
IMPL_EVENT_HANDLER(resourcetimingbufferfull)
virtual void GetMozMemory(JSContext *aCx,
JS::MutableHandle<JSObject*> aObj) = 0;
virtual nsDOMNavigationTiming* GetDOMTiming() const = 0;
virtual nsITimedChannel* GetChannel() const = 0;
virtual Performance* GetParentPerformance() const = 0;
protected:
Performance();
explicit Performance(nsPIDOMWindowInner* aWindow);
virtual ~Performance();
virtual void InsertUserEntry(PerformanceEntry* aEntry);
void InsertResourceEntry(PerformanceEntry* aEntry);
void ClearUserEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType);
DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
ErrorResult& aRv);
virtual nsISupports* GetAsISupports() = 0;
virtual void DispatchBufferFullEvent() = 0;
virtual TimeStamp CreationTimeStamp() const = 0;
virtual DOMHighResTimeStamp CreationTime() const = 0;
virtual bool IsPerformanceTimingAttribute(const nsAString& aName) = 0;
virtual DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) = 0;
bool IsResourceEntryLimitReached() const
{
return mResourceEntries.Length() >= mResourceTimingBufferSize;
}
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;
private:
nsTArray<RefPtr<PerformanceEntry>> mUserEntries;
nsTArray<RefPtr<PerformanceEntry>> mResourceEntries;
uint64_t mResourceTimingBufferSize;
static const uint64_t kDefaultResourceTimingBufferSize = 150;
bool mPendingNotificationObserversTask;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_Performance_h

View File

@ -0,0 +1,336 @@
/* -*- 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 "PerformanceMainThread.h"
#include "PerformanceNavigation.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(PerformanceMainThread)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PerformanceMainThread,
Performance)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTiming,
mNavigation,
mParentPerformance)
tmp->mMozMemory = nullptr;
mozilla::DropJSObjects(this);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PerformanceMainThread,
Performance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming,
mNavigation,
mParentPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(PerformanceMainThread,
Performance)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMozMemory)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(PerformanceMainThread, Performance)
NS_IMPL_RELEASE_INHERITED(PerformanceMainThread, Performance)
// QueryInterface implementation for PerformanceMainThread
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PerformanceMainThread)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END_INHERITING(Performance)
PerformanceMainThread::PerformanceMainThread(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
Performance* aParentPerformance)
: Performance(aWindow)
, mDOMTiming(aDOMTiming)
, mChannel(aChannel)
, mParentPerformance(aParentPerformance)
{
MOZ_ASSERT(aWindow, "Parent window object should be provided");
}
PerformanceMainThread::~PerformanceMainThread()
{
mozilla::DropJSObjects(this);
}
void
PerformanceMainThread::GetMozMemory(JSContext *aCx,
JS::MutableHandle<JSObject*> aObj)
{
if (!mMozMemory) {
mMozMemory = js::gc::NewMemoryInfoObject(aCx);
if (mMozMemory) {
mozilla::HoldJSObjects(this);
}
}
aObj.set(mMozMemory);
}
PerformanceTiming*
PerformanceMainThread::Timing()
{
if (!mTiming) {
// For navigation timing, the third argument (an nsIHtttpChannel) is null
// since the cross-domain redirect were already checked. The last argument
// (zero time) for performance.timing is the navigation start value.
mTiming = new PerformanceTiming(this, mChannel, nullptr,
mDOMTiming->GetNavigationStart());
}
return mTiming;
}
void
PerformanceMainThread::DispatchBufferFullEvent()
{
RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
// it bubbles, and it isn't cancelable
event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"), true, false);
event->SetTrusted(true);
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
}
PerformanceNavigation*
PerformanceMainThread::Navigation()
{
if (!mNavigation) {
mNavigation = new PerformanceNavigation(this);
}
return mNavigation;
}
DOMHighResTimeStamp
PerformanceMainThread::Now() const
{
return RoundTime(GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now()));
}
/**
* An entry should be added only after the resource is loaded.
* This method is not thread safe and can only be called on the main thread.
*/
void
PerformanceMainThread::AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel)
{
MOZ_ASSERT(NS_IsMainThread());
// Check if resource timing is prefed off.
if (!nsContentUtils::IsResourceTimingEnabled()) {
return;
}
// Don't add the entry if the buffer is full
if (IsResourceEntryLimitReached()) {
return;
}
if (channel && timedChannel) {
nsAutoCString name;
nsAutoString initiatorType;
nsCOMPtr<nsIURI> originalURI;
timedChannel->GetInitiatorType(initiatorType);
// According to the spec, "The name attribute must return the resolved URL
// of the requested resource. This attribute must not change even if the
// fetch redirected to a different URL."
channel->GetOriginalURI(getter_AddRefs(originalURI));
originalURI->GetSpec(name);
NS_ConvertUTF8toUTF16 entryName(name);
// The nsITimedChannel argument will be used to gather all the timings.
// The nsIHttpChannel argument will be used to check if any cross-origin
// redirects occurred.
// The last argument is the "zero time" (offset). Since we don't want
// any offset for the resource timing, this will be set to "0" - the
// resource timing returns a relative timing (no offset).
RefPtr<PerformanceTiming> performanceTiming =
new PerformanceTiming(this, timedChannel, channel,
0);
// The PerformanceResourceTiming object will use the PerformanceTiming
// object to get all the required timings.
RefPtr<PerformanceResourceTiming> performanceEntry =
new PerformanceResourceTiming(performanceTiming, this, entryName);
nsAutoCString protocol;
channel->GetProtocolVersion(protocol);
performanceEntry->SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
uint64_t encodedBodySize = 0;
channel->GetEncodedBodySize(&encodedBodySize);
performanceEntry->SetEncodedBodySize(encodedBodySize);
uint64_t transferSize = 0;
channel->GetTransferSize(&transferSize);
performanceEntry->SetTransferSize(transferSize);
uint64_t decodedBodySize = 0;
channel->GetDecodedBodySize(&decodedBodySize);
if (decodedBodySize == 0) {
decodedBodySize = encodedBodySize;
}
performanceEntry->SetDecodedBodySize(decodedBodySize);
// If the initiator type had no valid value, then set it to the default
// ("other") value.
if (initiatorType.IsEmpty()) {
initiatorType = NS_LITERAL_STRING("other");
}
performanceEntry->SetInitiatorType(initiatorType);
InsertResourceEntry(performanceEntry);
}
}
// To be removed once bug 1124165 lands
bool
PerformanceMainThread::IsPerformanceTimingAttribute(const nsAString& aName)
{
// Note that toJSON is added to this list due to bug 1047848
static const char* attributes[] =
{"navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart",
"redirectEnd", "fetchStart", "domainLookupStart", "domainLookupEnd",
"connectStart", "connectEnd", "requestStart", "responseStart",
"responseEnd", "domLoading", "domInteractive",
"domContentLoadedEventStart", "domContentLoadedEventEnd", "domComplete",
"loadEventStart", "loadEventEnd", nullptr};
for (uint32_t i = 0; attributes[i]; ++i) {
if (aName.EqualsASCII(attributes[i])) {
return true;
}
}
return false;
}
DOMHighResTimeStamp
PerformanceMainThread::GetPerformanceTimingFromString(const nsAString& aProperty)
{
if (!IsPerformanceTimingAttribute(aProperty)) {
return 0;
}
if (aProperty.EqualsLiteral("navigationStart")) {
// DOMHighResTimeStamp is in relation to navigationStart, so this will be
// zero.
return GetDOMTiming()->GetNavigationStart();
}
if (aProperty.EqualsLiteral("unloadEventStart")) {
return GetDOMTiming()->GetUnloadEventStart();
}
if (aProperty.EqualsLiteral("unloadEventEnd")) {
return GetDOMTiming()->GetUnloadEventEnd();
}
if (aProperty.EqualsLiteral("redirectStart")) {
return Timing()->RedirectStart();
}
if (aProperty.EqualsLiteral("redirectEnd")) {
return Timing()->RedirectEnd();
}
if (aProperty.EqualsLiteral("fetchStart")) {
return Timing()->FetchStart();
}
if (aProperty.EqualsLiteral("domainLookupStart")) {
return Timing()->DomainLookupStart();
}
if (aProperty.EqualsLiteral("domainLookupEnd")) {
return Timing()->DomainLookupEnd();
}
if (aProperty.EqualsLiteral("connectStart")) {
return Timing()->ConnectStart();
}
if (aProperty.EqualsLiteral("connectEnd")) {
return Timing()->ConnectEnd();
}
if (aProperty.EqualsLiteral("requestStart")) {
return Timing()->RequestStart();
}
if (aProperty.EqualsLiteral("responseStart")) {
return Timing()->ResponseStart();
}
if (aProperty.EqualsLiteral("responseEnd")) {
return Timing()->ResponseEnd();
}
if (aProperty.EqualsLiteral("domLoading")) {
return GetDOMTiming()->GetDomLoading();
}
if (aProperty.EqualsLiteral("domInteractive")) {
return GetDOMTiming()->GetDomInteractive();
}
if (aProperty.EqualsLiteral("domContentLoadedEventStart")) {
return GetDOMTiming()->GetDomContentLoadedEventStart();
}
if (aProperty.EqualsLiteral("domContentLoadedEventEnd")) {
return GetDOMTiming()->GetDomContentLoadedEventEnd();
}
if (aProperty.EqualsLiteral("domComplete")) {
return GetDOMTiming()->GetDomComplete();
}
if (aProperty.EqualsLiteral("loadEventStart")) {
return GetDOMTiming()->GetLoadEventStart();
}
if (aProperty.EqualsLiteral("loadEventEnd")) {
return GetDOMTiming()->GetLoadEventEnd();
}
MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
return 0;
}
void
PerformanceMainThread::InsertUserEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(NS_IsMainThread());
nsAutoCString uri;
uint64_t markCreationEpoch = 0;
if (nsContentUtils::IsUserTimingLoggingEnabled() ||
nsContentUtils::SendPerformanceTimingNotifications()) {
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
if (owner && owner->GetDocumentURI()) {
rv = owner->GetDocumentURI()->GetHost(uri);
}
if(NS_FAILED(rv)) {
// If we have no URI, just put in "none".
uri.AssignLiteral("none");
}
markCreationEpoch = static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC);
if (nsContentUtils::IsUserTimingLoggingEnabled()) {
Performance::LogEntry(aEntry, uri);
}
}
if (nsContentUtils::SendPerformanceTimingNotifications()) {
TimingNotification(aEntry, uri, markCreationEpoch);
}
Performance::InsertUserEntry(aEntry);
}
TimeStamp
PerformanceMainThread::CreationTimeStamp() const
{
return GetDOMTiming()->GetNavigationStartTimeStamp();
}
DOMHighResTimeStamp
PerformanceMainThread::CreationTime() const
{
return GetDOMTiming()->GetNavigationStart();
}
} // dom namespace
} // mozilla namespace

View File

@ -0,0 +1,87 @@
/* -*- 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 mozilla_dom_PerformanceMainThread_h
#define mozilla_dom_PerformanceMainThread_h
#include "Performance.h"
namespace mozilla {
namespace dom {
class PerformanceMainThread final : public Performance
{
public:
PerformanceMainThread(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
Performance* aParentPerformance);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(PerformanceMainThread,
Performance)
// Performance WebIDL methods
DOMHighResTimeStamp Now() const override;
virtual PerformanceTiming* Timing() override;
virtual PerformanceNavigation* Navigation() override;
virtual void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel) override;
TimeStamp CreationTimeStamp() const override;
DOMHighResTimeStamp CreationTime() const override;
virtual void GetMozMemory(JSContext *aCx,
JS::MutableHandle<JSObject*> aObj) override;
virtual nsDOMNavigationTiming* GetDOMTiming() const override
{
return mDOMTiming;
}
virtual nsITimedChannel* GetChannel() const override
{
return mChannel;
}
virtual Performance* GetParentPerformance() const override
{
return mParentPerformance;
}
protected:
~PerformanceMainThread();
nsISupports* GetAsISupports() override
{
return this;
}
void InsertUserEntry(PerformanceEntry* aEntry) override;
bool IsPerformanceTimingAttribute(const nsAString& aName) override;
DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
void DispatchBufferFullEvent() override;
RefPtr<nsDOMNavigationTiming> mDOMTiming;
nsCOMPtr<nsITimedChannel> mChannel;
RefPtr<PerformanceTiming> mTiming;
RefPtr<PerformanceNavigation> mNavigation;
RefPtr<Performance> mParentPerformance;
JS::Heap<JSObject*> mMozMemory;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PerformanceMainThread_h

View File

@ -16,7 +16,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceNavigation, mPerformance)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceNavigation, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceNavigation, Release)
PerformanceNavigation::PerformanceNavigation(nsPerformance* aPerformance)
PerformanceNavigation::PerformanceNavigation(Performance* aPerformance)
: mPerformance(aPerformance)
{
MOZ_ASSERT(aPerformance, "Parent performance object should be provided");

View File

@ -8,8 +8,8 @@
#define mozilla_dom_PerformanceNavigation_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/Performance.h"
#include "nsDOMNavigationTiming.h"
#include "nsPerformance.h"
#include "nsWrapperCache.h"
namespace mozilla {
@ -26,7 +26,7 @@ public:
TYPE_RESERVED = 255,
};
explicit PerformanceNavigation(nsPerformance* aPerformance);
explicit PerformanceNavigation(Performance* aPerformance);
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PerformanceNavigation)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(PerformanceNavigation)
@ -41,7 +41,7 @@ public:
return mPerformance->Timing();
}
nsPerformance* GetParentObject() const
Performance* GetParentObject() const
{
return mPerformance;
}
@ -59,7 +59,7 @@ public:
private:
~PerformanceNavigation();
RefPtr<nsPerformance> mPerformance;
RefPtr<Performance> mPerformance;
};
} // namespace dom

View File

@ -6,11 +6,10 @@
#include "PerformanceObserver.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceBinding.h"
#include "mozilla/dom/PerformanceEntryBinding.h"
#include "mozilla/dom/PerformanceObserverBinding.h"
#include "mozilla/dom/workers/bindings/Performance.h"
#include "nsPerformance.h"
#include "nsPIDOMWindow.h"
#include "nsQueryObject.h"
#include "nsString.h"

View File

@ -15,7 +15,6 @@
#include "nsWrapperCache.h"
class nsPIDOMWindowInner;
class PerformanceBase;
namespace mozilla {
@ -24,6 +23,7 @@ class ErrorResult;
namespace dom {
class GlobalObject;
class Performance;
class PerformanceEntry;
class PerformanceObserverCallback;
struct PerformanceObserverInit;
@ -67,7 +67,7 @@ private:
nsCOMPtr<nsISupports> mOwner;
RefPtr<PerformanceObserverCallback> mCallback;
RefPtr<PerformanceBase> mPerformance;
RefPtr<Performance> mPerformance;
nsTArray<nsString> mEntryTypes;
bool mConnected;
nsTArray<RefPtr<PerformanceEntry>> mQueuedEntries;

View File

@ -6,8 +6,8 @@
#include "PerformanceObserverEntryList.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceObserverEntryListBinding.h"
#include "nsPerformance.h"
#include "nsString.h"
#include "PerformanceResourceTiming.h"

View File

@ -24,7 +24,7 @@ NS_IMPL_ADDREF_INHERITED(PerformanceResourceTiming, PerformanceEntry)
NS_IMPL_RELEASE_INHERITED(PerformanceResourceTiming, PerformanceEntry)
PerformanceResourceTiming::PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
nsPerformance* aPerformance,
Performance* aPerformance,
const nsAString& aName)
: PerformanceEntry(aPerformance, aName, NS_LITERAL_STRING("resource")),
mTiming(aPerformanceTiming),

View File

@ -8,10 +8,9 @@
#define mozilla_dom_PerformanceResourceTiming_h___
#include "nsCOMPtr.h"
#include "nsPerformance.h"
#include "nsIChannel.h"
#include "nsITimedChannel.h"
#include "nsDOMNavigationTiming.h"
#include "Performance.h"
#include "PerformanceEntry.h"
#include "PerformanceTiming.h"
@ -30,7 +29,7 @@ public:
PerformanceEntry)
PerformanceResourceTiming(PerformanceTiming* aPerformanceTiming,
nsPerformance* aPerformance,
Performance* aPerformance,
const nsAString& aName);
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;

View File

@ -15,7 +15,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PerformanceTiming, mPerformance)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(PerformanceTiming, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(PerformanceTiming, Release)
PerformanceTiming::PerformanceTiming(nsPerformance* aPerformance,
PerformanceTiming::PerformanceTiming(Performance* aPerformance,
nsITimedChannel* aChannel,
nsIHttpChannel* aHttpChannel,
DOMHighResTimeStamp aZeroTime)

View File

@ -10,8 +10,8 @@
#include "mozilla/Attributes.h"
#include "nsContentUtils.h"
#include "nsDOMNavigationTiming.h"
#include "nsPerformance.h"
#include "nsWrapperCache.h"
#include "Performance.h"
class nsIHttpChannel;
class nsITimedChannel;
@ -42,7 +42,7 @@ public:
* argument should be equal to performance.navigationStart for
* navigation timing and "0" for the resource timing.
*/
PerformanceTiming(nsPerformance* aPerformance,
PerformanceTiming(Performance* aPerformance,
nsITimedChannel* aChannel,
nsIHttpChannel* aHttpChannel,
DOMHighResTimeStamp aZeroTime);
@ -54,7 +54,7 @@ public:
return mPerformance->GetDOMTiming();
}
nsPerformance* GetParentObject() const
Performance* GetParentObject() const
{
return mPerformance;
}
@ -240,7 +240,7 @@ private:
bool IsInitialized() const;
void InitializeTimingInfo(nsITimedChannel* aChannel);
RefPtr<nsPerformance> mPerformance;
RefPtr<Performance> mPerformance;
DOMHighResTimeStamp mFetchStart;
// This is an offset that will be added to each timing ([ms] resolution).

View File

@ -4,32 +4,27 @@
* 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 "Performance.h"
#include "mozilla/dom/PerformanceBinding.h"
#include "PerformanceWorker.h"
#include "WorkerPrivate.h"
BEGIN_WORKERS_NAMESPACE
namespace mozilla {
namespace dom {
Performance::Performance(WorkerPrivate* aWorkerPrivate)
using namespace workers;
PerformanceWorker::PerformanceWorker(WorkerPrivate* aWorkerPrivate)
: mWorkerPrivate(aWorkerPrivate)
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
Performance::~Performance()
PerformanceWorker::~PerformanceWorker()
{
mWorkerPrivate->AssertIsOnWorkerThread();
}
JSObject*
Performance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return PerformanceBinding_workers::Wrap(aCx, this, aGivenProto);
}
DOMHighResTimeStamp
Performance::Now() const
PerformanceWorker::Now() const
{
TimeDuration duration =
TimeStamp::Now() - mWorkerPrivate->NowBaseTimeStamp();
@ -38,14 +33,14 @@ Performance::Now() const
// To be removed once bug 1124165 lands
bool
Performance::IsPerformanceTimingAttribute(const nsAString& aName)
PerformanceWorker::IsPerformanceTimingAttribute(const nsAString& aName)
{
// In workers we just support navigationStart.
return aName.EqualsASCII("navigationStart");
}
DOMHighResTimeStamp
Performance::GetPerformanceTimingFromString(const nsAString& aProperty)
PerformanceWorker::GetPerformanceTimingFromString(const nsAString& aProperty)
{
if (!IsPerformanceTimingAttribute(aProperty)) {
return 0;
@ -60,7 +55,7 @@ Performance::GetPerformanceTimingFromString(const nsAString& aProperty)
}
void
Performance::InsertUserEntry(PerformanceEntry* aEntry)
PerformanceWorker::InsertUserEntry(PerformanceEntry* aEntry)
{
if (mWorkerPrivate->PerformanceLoggingEnabled()) {
nsAutoCString uri;
@ -69,29 +64,22 @@ Performance::InsertUserEntry(PerformanceEntry* aEntry)
// If we have no URI, just put in "none".
uri.AssignLiteral("none");
}
PerformanceBase::LogEntry(aEntry, uri);
Performance::LogEntry(aEntry, uri);
}
PerformanceBase::InsertUserEntry(aEntry);
Performance::InsertUserEntry(aEntry);
}
TimeStamp
Performance::CreationTimeStamp() const
PerformanceWorker::CreationTimeStamp() const
{
return mWorkerPrivate->NowBaseTimeStamp();
}
DOMHighResTimeStamp
Performance::CreationTime() const
PerformanceWorker::CreationTime() const
{
return mWorkerPrivate->NowBaseTime();
}
void
Performance::DispatchBufferFullEvent()
{
// This method is needed just for InsertResourceEntry, but this method is not
// exposed to workers.
MOZ_CRASH("This should not be called.");
}
END_WORKERS_NAMESPACE
} // dom namespace
} // mozilla namespace

View File

@ -0,0 +1,100 @@
/* -*- 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 mozilla_dom_PerformanceWorker_h
#define mozilla_dom_PerformanceWorker_h
#include "Performance.h"
namespace mozilla {
namespace dom {
namespace workers {
class WorkerPrivate;
}
class PerformanceWorker final : public Performance
{
public:
PerformanceWorker(workers::WorkerPrivate* aWorkerPrivate);
// Performance WebIDL methods
DOMHighResTimeStamp Now() const override;
virtual PerformanceTiming* Timing() override
{
MOZ_CRASH("This should not be called on workers.");
return nullptr;
}
virtual PerformanceNavigation* Navigation() override
{
MOZ_CRASH("This should not be called on workers.");
return nullptr;
}
virtual void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel) override
{
MOZ_CRASH("This should not be called on workers.");
}
TimeStamp CreationTimeStamp() const override;
DOMHighResTimeStamp CreationTime() const override;
virtual void GetMozMemory(JSContext *aCx,
JS::MutableHandle<JSObject*> aObj) override
{
MOZ_CRASH("This should not be called on workers.");
}
virtual nsDOMNavigationTiming* GetDOMTiming() const override
{
MOZ_CRASH("This should not be called on workers.");
return nullptr;
}
virtual nsITimedChannel* GetChannel() const override
{
MOZ_CRASH("This should not be called on workers.");
return nullptr;
}
virtual Performance* GetParentPerformance() const override
{
MOZ_CRASH("This should not be called on workers.");
return nullptr;
}
protected:
~PerformanceWorker();
nsISupports* GetAsISupports() override
{
return nullptr;
}
void InsertUserEntry(PerformanceEntry* aEntry) override;
bool IsPerformanceTimingAttribute(const nsAString& aName) override;
DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
void DispatchBufferFullEvent() override
{
MOZ_CRASH("This should not be called on workers.");
}
private:
workers::WorkerPrivate* mWorkerPrivate;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PerformanceWorker_h

View File

@ -4,11 +4,8 @@
# 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/.
EXPORTS += [
'nsPerformance.h',
]
EXPORTS.mozilla.dom += [
'Performance.h',
'PerformanceEntry.h',
'PerformanceMark.h',
'PerformanceMeasure.h',
@ -20,8 +17,9 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'nsPerformance.cpp',
'Performance.cpp',
'PerformanceEntry.cpp',
'PerformanceMainThread.cpp',
'PerformanceMark.cpp',
'PerformanceMeasure.cpp',
'PerformanceNavigation.cpp',
@ -29,6 +27,7 @@ UNIFIED_SOURCES += [
'PerformanceObserverEntryList.cpp',
'PerformanceResourceTiming.cpp',
'PerformanceTiming.cpp',
'PerformanceWorker.cpp',
]
LOCAL_INCLUDES += [

View File

@ -1,833 +0,0 @@
/* -*- 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 "nsPerformance.h"
#include "nsCOMPtr.h"
#include "nsIHttpChannel.h"
#include "nsITimedChannel.h"
#include "nsDOMNavigationTiming.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDOMWindow.h"
#include "nsILoadInfo.h"
#include "nsIURI.h"
#include "nsThreadUtils.h"
#include "PerformanceEntry.h"
#include "PerformanceMark.h"
#include "PerformanceMeasure.h"
#include "PerformanceObserver.h"
#include "PerformanceResourceTiming.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/Preferences.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/TimeStamp.h"
#include "js/HeapAPI.h"
#include "GeckoProfiler.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
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPerformance)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsPerformance, PerformanceBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTiming,
mNavigation,
mParentPerformance)
tmp->mMozMemory = nullptr;
mozilla::DropJSObjects(this);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsPerformance, PerformanceBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTiming,
mNavigation,
mParentPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsPerformance, PerformanceBase)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMozMemory)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(nsPerformance, PerformanceBase)
NS_IMPL_RELEASE_INHERITED(nsPerformance, PerformanceBase)
nsPerformance::nsPerformance(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
nsPerformance* aParentPerformance)
: PerformanceBase(aWindow),
mDOMTiming(aDOMTiming),
mChannel(aChannel),
mParentPerformance(aParentPerformance)
{
MOZ_ASSERT(aWindow, "Parent window object should be provided");
}
nsPerformance::~nsPerformance()
{
mozilla::DropJSObjects(this);
}
// QueryInterface implementation for nsPerformance
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPerformance)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
void
nsPerformance::GetMozMemory(JSContext *aCx, JS::MutableHandle<JSObject*> aObj)
{
if (!mMozMemory) {
mMozMemory = js::gc::NewMemoryInfoObject(aCx);
if (mMozMemory) {
mozilla::HoldJSObjects(this);
}
}
aObj.set(mMozMemory);
}
PerformanceTiming*
nsPerformance::Timing()
{
if (!mTiming) {
// For navigation timing, the third argument (an nsIHtttpChannel) is null
// since the cross-domain redirect were already checked.
// The last argument (zero time) for performance.timing is the navigation
// start value.
mTiming = new PerformanceTiming(this, mChannel, nullptr,
mDOMTiming->GetNavigationStart());
}
return mTiming;
}
void
nsPerformance::DispatchBufferFullEvent()
{
RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr);
// it bubbles, and it isn't cancelable
event->InitEvent(NS_LITERAL_STRING("resourcetimingbufferfull"), true, false);
event->SetTrusted(true);
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
}
PerformanceNavigation*
nsPerformance::Navigation()
{
if (!mNavigation) {
mNavigation = new PerformanceNavigation(this);
}
return mNavigation;
}
DOMHighResTimeStamp
nsPerformance::Now() const
{
return RoundTime(GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now()));
}
JSObject*
nsPerformance::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
{
return PerformanceBinding::Wrap(cx, this, aGivenProto);
}
/**
* An entry should be added only after the resource is loaded.
* This method is not thread safe and can only be called on the main thread.
*/
void
nsPerformance::AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel)
{
MOZ_ASSERT(NS_IsMainThread());
// Check if resource timing is prefed off.
if (!nsContentUtils::IsResourceTimingEnabled()) {
return;
}
// Don't add the entry if the buffer is full
if (IsResourceEntryLimitReached()) {
return;
}
if (channel && timedChannel) {
nsAutoCString name;
nsAutoString initiatorType;
nsCOMPtr<nsIURI> originalURI;
timedChannel->GetInitiatorType(initiatorType);
// According to the spec, "The name attribute must return the resolved URL
// of the requested resource. This attribute must not change even if the
// fetch redirected to a different URL."
channel->GetOriginalURI(getter_AddRefs(originalURI));
originalURI->GetSpec(name);
NS_ConvertUTF8toUTF16 entryName(name);
// The nsITimedChannel argument will be used to gather all the timings.
// The nsIHttpChannel argument will be used to check if any cross-origin
// redirects occurred.
// The last argument is the "zero time" (offset). Since we don't want
// any offset for the resource timing, this will be set to "0" - the
// resource timing returns a relative timing (no offset).
RefPtr<PerformanceTiming> performanceTiming =
new PerformanceTiming(this, timedChannel, channel,
0);
// The PerformanceResourceTiming object will use the PerformanceTiming
// object to get all the required timings.
RefPtr<PerformanceResourceTiming> performanceEntry =
new PerformanceResourceTiming(performanceTiming, this, entryName);
nsAutoCString protocol;
channel->GetProtocolVersion(protocol);
performanceEntry->SetNextHopProtocol(NS_ConvertUTF8toUTF16(protocol));
uint64_t encodedBodySize = 0;
channel->GetEncodedBodySize(&encodedBodySize);
performanceEntry->SetEncodedBodySize(encodedBodySize);
uint64_t transferSize = 0;
channel->GetTransferSize(&transferSize);
performanceEntry->SetTransferSize(transferSize);
uint64_t decodedBodySize = 0;
channel->GetDecodedBodySize(&decodedBodySize);
if (decodedBodySize == 0) {
decodedBodySize = encodedBodySize;
}
performanceEntry->SetDecodedBodySize(decodedBodySize);
// If the initiator type had no valid value, then set it to the default
// ("other") value.
if (initiatorType.IsEmpty()) {
initiatorType = NS_LITERAL_STRING("other");
}
performanceEntry->SetInitiatorType(initiatorType);
InsertResourceEntry(performanceEntry);
}
}
// To be removed once bug 1124165 lands
bool
nsPerformance::IsPerformanceTimingAttribute(const nsAString& aName)
{
// Note that toJSON is added to this list due to bug 1047848
static const char* attributes[] =
{"navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart",
"redirectEnd", "fetchStart", "domainLookupStart", "domainLookupEnd",
"connectStart", "connectEnd", "requestStart", "responseStart",
"responseEnd", "domLoading", "domInteractive", "domContentLoadedEventStart",
"domContentLoadedEventEnd", "domComplete", "loadEventStart",
"loadEventEnd", nullptr};
for (uint32_t i = 0; attributes[i]; ++i) {
if (aName.EqualsASCII(attributes[i])) {
return true;
}
}
return false;
}
DOMHighResTimeStamp
nsPerformance::GetPerformanceTimingFromString(const nsAString& aProperty)
{
if (!IsPerformanceTimingAttribute(aProperty)) {
return 0;
}
if (aProperty.EqualsLiteral("navigationStart")) {
// DOMHighResTimeStamp is in relation to navigationStart, so this will be
// zero.
return GetDOMTiming()->GetNavigationStart();
}
if (aProperty.EqualsLiteral("unloadEventStart")) {
return GetDOMTiming()->GetUnloadEventStart();
}
if (aProperty.EqualsLiteral("unloadEventEnd")) {
return GetDOMTiming()->GetUnloadEventEnd();
}
if (aProperty.EqualsLiteral("redirectStart")) {
return Timing()->RedirectStart();
}
if (aProperty.EqualsLiteral("redirectEnd")) {
return Timing()->RedirectEnd();
}
if (aProperty.EqualsLiteral("fetchStart")) {
return Timing()->FetchStart();
}
if (aProperty.EqualsLiteral("domainLookupStart")) {
return Timing()->DomainLookupStart();
}
if (aProperty.EqualsLiteral("domainLookupEnd")) {
return Timing()->DomainLookupEnd();
}
if (aProperty.EqualsLiteral("connectStart")) {
return Timing()->ConnectStart();
}
if (aProperty.EqualsLiteral("connectEnd")) {
return Timing()->ConnectEnd();
}
if (aProperty.EqualsLiteral("requestStart")) {
return Timing()->RequestStart();
}
if (aProperty.EqualsLiteral("responseStart")) {
return Timing()->ResponseStart();
}
if (aProperty.EqualsLiteral("responseEnd")) {
return Timing()->ResponseEnd();
}
if (aProperty.EqualsLiteral("domLoading")) {
return GetDOMTiming()->GetDomLoading();
}
if (aProperty.EqualsLiteral("domInteractive")) {
return GetDOMTiming()->GetDomInteractive();
}
if (aProperty.EqualsLiteral("domContentLoadedEventStart")) {
return GetDOMTiming()->GetDomContentLoadedEventStart();
}
if (aProperty.EqualsLiteral("domContentLoadedEventEnd")) {
return GetDOMTiming()->GetDomContentLoadedEventEnd();
}
if (aProperty.EqualsLiteral("domComplete")) {
return GetDOMTiming()->GetDomComplete();
}
if (aProperty.EqualsLiteral("loadEventStart")) {
return GetDOMTiming()->GetLoadEventStart();
}
if (aProperty.EqualsLiteral("loadEventEnd")) {
return GetDOMTiming()->GetLoadEventEnd();
}
MOZ_CRASH("IsPerformanceTimingAttribute and GetPerformanceTimingFromString are out of sync");
return 0;
}
namespace {
// Helper classes
class MOZ_STACK_CLASS PerformanceEntryComparator final
{
public:
bool Equals(const PerformanceEntry* aElem1,
const PerformanceEntry* aElem2) const
{
MOZ_ASSERT(aElem1 && aElem2,
"Trying to compare null performance entries");
return aElem1->StartTime() == aElem2->StartTime();
}
bool LessThan(const PerformanceEntry* aElem1,
const PerformanceEntry* aElem2) const
{
MOZ_ASSERT(aElem1 && aElem2,
"Trying to compare null performance entries");
return aElem1->StartTime() < aElem2->StartTime();
}
};
class PrefEnabledRunnable final : public WorkerCheckAPIExposureOnMainThreadRunnable
{
public:
PrefEnabledRunnable(WorkerPrivate* aWorkerPrivate,
const nsCString& aPrefName)
: WorkerCheckAPIExposureOnMainThreadRunnable(aWorkerPrivate)
, mEnabled(false)
, mPrefName(aPrefName)
{ }
bool MainThreadRun() override
{
MOZ_ASSERT(NS_IsMainThread());
mEnabled = Preferences::GetBool(mPrefName.get(), false);
return true;
}
bool IsEnabled() const
{
return mEnabled;
}
private:
bool mEnabled;
nsCString mPrefName;
};
} // namespace
/* static */ bool
nsPerformance::IsEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.enable_user_timing", false);
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<PrefEnabledRunnable> runnable =
new PrefEnabledRunnable(workerPrivate,
NS_LITERAL_CSTRING("dom.enable_user_timing"));
return runnable->Dispatch() && runnable->IsEnabled();
}
/* static */ bool
nsPerformance::IsObserverEnabled(JSContext* aCx, JSObject* aGlobal)
{
if (NS_IsMainThread()) {
return Preferences::GetBool("dom.enable_performance_observer", false);
}
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
RefPtr<PrefEnabledRunnable> runnable =
new PrefEnabledRunnable(workerPrivate,
NS_LITERAL_CSTRING("dom.enable_performance_observer"));
return runnable->Dispatch() && runnable->IsEnabled();
}
void
nsPerformance::InsertUserEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(NS_IsMainThread());
nsAutoCString uri;
uint64_t markCreationEpoch = 0;
if (nsContentUtils::IsUserTimingLoggingEnabled() ||
nsContentUtils::SendPerformanceTimingNotifications()) {
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsPIDOMWindowInner> owner = GetOwner();
if (owner && owner->GetDocumentURI()) {
rv = owner->GetDocumentURI()->GetHost(uri);
}
if(NS_FAILED(rv)) {
// If we have no URI, just put in "none".
uri.AssignLiteral("none");
}
markCreationEpoch = static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC);
if (nsContentUtils::IsUserTimingLoggingEnabled()) {
PerformanceBase::LogEntry(aEntry, uri);
}
}
if (nsContentUtils::SendPerformanceTimingNotifications()) {
TimingNotification(aEntry, uri, markCreationEpoch);
}
PerformanceBase::InsertUserEntry(aEntry);
}
TimeStamp
nsPerformance::CreationTimeStamp() const
{
return GetDOMTiming()->GetNavigationStartTimeStamp();
}
DOMHighResTimeStamp
nsPerformance::CreationTime() const
{
return GetDOMTiming()->GetNavigationStart();
}
// PerformanceBase
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(PerformanceBase)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(PerformanceBase,
DOMEventTargetHelper,
mUserEntries,
mResourceEntries);
NS_IMPL_ADDREF_INHERITED(PerformanceBase, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(PerformanceBase, DOMEventTargetHelper)
PerformanceBase::PerformanceBase()
: mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(!NS_IsMainThread());
}
PerformanceBase::PerformanceBase(nsPIDOMWindowInner* aWindow)
: DOMEventTargetHelper(aWindow)
, mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
, mPendingNotificationObserversTask(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
PerformanceBase::~PerformanceBase()
{}
void
PerformanceBase::GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
aRetval = mResourceEntries;
aRetval.AppendElements(mUserEntries);
aRetval.Sort(PerformanceEntryComparator());
}
void
PerformanceBase::GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
if (aEntryType.EqualsLiteral("resource")) {
aRetval = mResourceEntries;
return;
}
aRetval.Clear();
if (aEntryType.EqualsLiteral("mark") ||
aEntryType.EqualsLiteral("measure")) {
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetEntryType().Equals(aEntryType)) {
aRetval.AppendElement(entry);
}
}
}
}
void
PerformanceBase::GetEntriesByName(const nsAString& aName,
const Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval)
{
aRetval.Clear();
for (PerformanceEntry* entry : mResourceEntries) {
if (entry->GetName().Equals(aName) &&
(!aEntryType.WasPassed() ||
entry->GetEntryType().Equals(aEntryType.Value()))) {
aRetval.AppendElement(entry);
}
}
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetName().Equals(aName) &&
(!aEntryType.WasPassed() ||
entry->GetEntryType().Equals(aEntryType.Value()))) {
aRetval.AppendElement(entry);
}
}
aRetval.Sort(PerformanceEntryComparator());
}
void
PerformanceBase::ClearUserEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType)
{
for (uint32_t i = 0; i < mUserEntries.Length();) {
if ((!aEntryName.WasPassed() ||
mUserEntries[i]->GetName().Equals(aEntryName.Value())) &&
(aEntryType.IsEmpty() ||
mUserEntries[i]->GetEntryType().Equals(aEntryType))) {
mUserEntries.RemoveElementAt(i);
} else {
++i;
}
}
}
void
PerformanceBase::ClearResourceTimings()
{
MOZ_ASSERT(NS_IsMainThread());
mResourceEntries.Clear();
}
DOMHighResTimeStamp
PerformanceBase::RoundTime(double aTime) const
{
// Round down to the nearest 5us, because if the timer is too accurate people
// can do nasty timing attacks with it. See similar code in the worker
// Performance implementation.
const double maxResolutionMs = 0.005;
return floor(aTime / maxResolutionMs) * maxResolutionMs;
}
void
PerformanceBase::Mark(const nsAString& aName, ErrorResult& aRv)
{
// Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
if (IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
RefPtr<PerformanceMark> performanceMark =
new PerformanceMark(GetAsISupports(), aName, Now());
InsertUserEntry(performanceMark);
if (profiler_is_active()) {
PROFILER_MARKER(NS_ConvertUTF16toUTF8(aName).get());
}
}
void
PerformanceBase::ClearMarks(const Optional<nsAString>& aName)
{
ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
}
DOMHighResTimeStamp
PerformanceBase::ResolveTimestampFromName(const nsAString& aName,
ErrorResult& aRv)
{
AutoTArray<RefPtr<PerformanceEntry>, 1> arr;
DOMHighResTimeStamp ts;
Optional<nsAString> typeParam;
nsAutoString str;
str.AssignLiteral("mark");
typeParam = &str;
GetEntriesByName(aName, typeParam, arr);
if (!arr.IsEmpty()) {
return arr.LastElement()->StartTime();
}
if (!IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return 0;
}
ts = GetPerformanceTimingFromString(aName);
if (!ts) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return 0;
}
return ts - CreationTime();
}
void
PerformanceBase::Measure(const nsAString& aName,
const Optional<nsAString>& aStartMark,
const Optional<nsAString>& aEndMark,
ErrorResult& aRv)
{
// Don't add the entry if the buffer is full. XXX should be removed by bug
// 1159003.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
DOMHighResTimeStamp startTime;
DOMHighResTimeStamp endTime;
if (IsPerformanceTimingAttribute(aName)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (aStartMark.WasPassed()) {
startTime = ResolveTimestampFromName(aStartMark.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} else {
// Navigation start is used in this case, but since DOMHighResTimeStamp is
// in relation to navigation start, this will be zero if a name is not
// passed.
startTime = 0;
}
if (aEndMark.WasPassed()) {
endTime = ResolveTimestampFromName(aEndMark.Value(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} else {
endTime = Now();
}
RefPtr<PerformanceMeasure> performanceMeasure =
new PerformanceMeasure(GetAsISupports(), aName, startTime, endTime);
InsertUserEntry(performanceMeasure);
}
void
PerformanceBase::ClearMeasures(const Optional<nsAString>& aName)
{
ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
}
void
PerformanceBase::LogEntry(PerformanceEntry* aEntry, const nsACString& aOwner) const
{
PERFLOG("Performance Entry: %s|%s|%s|%f|%f|%" PRIu64 "\n",
aOwner.BeginReading(),
NS_ConvertUTF16toUTF8(aEntry->GetEntryType()).get(),
NS_ConvertUTF16toUTF8(aEntry->GetName()).get(),
aEntry->StartTime(),
aEntry->Duration(),
static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC));
}
void
PerformanceBase::TimingNotification(PerformanceEntry* aEntry, const nsACString& aOwner, uint64_t aEpoch)
{
PerformanceEntryEventInit init;
init.mBubbles = false;
init.mCancelable = false;
init.mName = aEntry->GetName();
init.mEntryType = aEntry->GetEntryType();
init.mStartTime = aEntry->StartTime();
init.mDuration = aEntry->Duration();
init.mEpoch = aEpoch;
init.mOrigin = NS_ConvertUTF8toUTF16(aOwner.BeginReading());
RefPtr<PerformanceEntryEvent> perfEntryEvent =
PerformanceEntryEvent::Constructor(this, NS_LITERAL_STRING("performanceentry"), init);
nsCOMPtr<EventTarget> et = do_QueryInterface(GetOwner());
if (et) {
bool dummy = false;
et->DispatchEvent(perfEntryEvent, &dummy);
}
}
void
PerformanceBase::InsertUserEntry(PerformanceEntry* aEntry)
{
mUserEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
QueueEntry(aEntry);
}
void
PerformanceBase::SetResourceTimingBufferSize(uint64_t aMaxSize)
{
mResourceTimingBufferSize = aMaxSize;
}
void
PerformanceBase::InsertResourceEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(aEntry);
MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
return;
}
mResourceEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
if (mResourceEntries.Length() == mResourceTimingBufferSize) {
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
QueueEntry(aEntry);
}
void
PerformanceBase::AddObserver(PerformanceObserver* aObserver)
{
mObservers.AppendElementUnlessExists(aObserver);
}
void
PerformanceBase::RemoveObserver(PerformanceObserver* aObserver)
{
mObservers.RemoveElement(aObserver);
}
void
PerformanceBase::NotifyObservers()
{
mPendingNotificationObserversTask = false;
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
Notify, ());
}
void
PerformanceBase::CancelNotificationObservers()
{
mPendingNotificationObserversTask = false;
}
class NotifyObserversTask final : public CancelableRunnable
{
public:
explicit NotifyObserversTask(PerformanceBase* aPerformance)
: mPerformance(aPerformance)
{
MOZ_ASSERT(mPerformance);
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(mPerformance);
mPerformance->NotifyObservers();
return NS_OK;
}
nsresult Cancel() override
{
mPerformance->CancelNotificationObservers();
mPerformance = nullptr;
return NS_OK;
}
private:
~NotifyObserversTask()
{
}
RefPtr<PerformanceBase> mPerformance;
};
void
PerformanceBase::RunNotificationObserversTask()
{
mPendingNotificationObserversTask = true;
nsCOMPtr<nsIRunnable> task = new NotifyObserversTask(this);
nsresult rv = NS_DispatchToCurrentThread(task);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPendingNotificationObserversTask = false;
}
}
void
PerformanceBase::QueueEntry(PerformanceEntry* aEntry)
{
if (mObservers.IsEmpty()) {
return;
}
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers,
PerformanceObserver,
QueueEntry, (aEntry));
if (!mPendingNotificationObserversTask) {
RunNotificationObserversTask();
}
}

View File

@ -1,215 +0,0 @@
/* -*- 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 nsPerformance_h___
#define nsPerformance_h___
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "mozilla/Attributes.h"
#include "nsWrapperCache.h"
#include "nsDOMNavigationTiming.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
#include "js/TypeDecls.h"
#include "js/RootingAPI.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/DOMEventTargetHelper.h"
class nsITimedChannel;
class nsPerformance;
class nsIHttpChannel;
namespace mozilla {
class ErrorResult;
namespace dom {
class PerformanceEntry;
class PerformanceNavigation;
class PerformanceObserver;
class PerformanceTiming;
} // namespace dom
} // namespace mozilla
// Base class for main-thread and worker Performance API
class PerformanceBase : public mozilla::DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PerformanceBase,
DOMEventTargetHelper)
PerformanceBase();
explicit PerformanceBase(nsPIDOMWindowInner* aWindow);
typedef mozilla::dom::PerformanceEntry PerformanceEntry;
typedef mozilla::dom::PerformanceObserver PerformanceObserver;
void GetEntries(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByType(const nsAString& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void GetEntriesByName(const nsAString& aName,
const mozilla::dom::Optional<nsAString>& aEntryType,
nsTArray<RefPtr<PerformanceEntry>>& aRetval);
void ClearResourceTimings();
virtual DOMHighResTimeStamp Now() const = 0;
void Mark(const nsAString& aName, mozilla::ErrorResult& aRv);
void ClearMarks(const mozilla::dom::Optional<nsAString>& aName);
void Measure(const nsAString& aName,
const mozilla::dom::Optional<nsAString>& aStartMark,
const mozilla::dom::Optional<nsAString>& aEndMark,
mozilla::ErrorResult& aRv);
void ClearMeasures(const mozilla::dom::Optional<nsAString>& aName);
void SetResourceTimingBufferSize(uint64_t aMaxSize);
void AddObserver(PerformanceObserver* aObserver);
void RemoveObserver(PerformanceObserver* aObserver);
void NotifyObservers();
void CancelNotificationObservers();
protected:
virtual ~PerformanceBase();
virtual void InsertUserEntry(PerformanceEntry* aEntry);
void InsertResourceEntry(PerformanceEntry* aEntry);
void ClearUserEntries(const mozilla::dom::Optional<nsAString>& aEntryName,
const nsAString& aEntryType);
DOMHighResTimeStamp ResolveTimestampFromName(const nsAString& aName,
mozilla::ErrorResult& aRv);
virtual nsISupports* GetAsISupports() = 0;
virtual void DispatchBufferFullEvent() = 0;
virtual mozilla::TimeStamp CreationTimeStamp() const = 0;
virtual DOMHighResTimeStamp CreationTime() const = 0;
virtual bool IsPerformanceTimingAttribute(const nsAString& aName) = 0;
virtual DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) = 0;
bool IsResourceEntryLimitReached() const
{
return mResourceEntries.Length() >= mResourceTimingBufferSize;
}
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;
private:
nsTArray<RefPtr<PerformanceEntry>> mUserEntries;
nsTArray<RefPtr<PerformanceEntry>> mResourceEntries;
uint64_t mResourceTimingBufferSize;
static const uint64_t kDefaultResourceTimingBufferSize = 150;
bool mPendingNotificationObserversTask;
};
// Script "performance" object
class nsPerformance final : public PerformanceBase
{
public:
nsPerformance(nsPIDOMWindowInner* aWindow,
nsDOMNavigationTiming* aDOMTiming,
nsITimedChannel* aChannel,
nsPerformance* aParentPerformance);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsPerformance,
PerformanceBase)
static bool IsEnabled(JSContext* aCx, JSObject* aGlobal);
static bool IsObserverEnabled(JSContext* aCx, JSObject* aGlobal);
nsDOMNavigationTiming* GetDOMTiming() const
{
return mDOMTiming;
}
nsITimedChannel* GetChannel() const
{
return mChannel;
}
nsPerformance* GetParentPerformance() const
{
return mParentPerformance;
}
JSObject* WrapObject(JSContext *cx,
JS::Handle<JSObject*> aGivenProto) override;
// Performance WebIDL methods
DOMHighResTimeStamp Now() const override;
mozilla::dom::PerformanceTiming* Timing();
mozilla::dom::PerformanceNavigation* Navigation();
void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel);
using PerformanceBase::GetEntries;
using PerformanceBase::GetEntriesByType;
using PerformanceBase::GetEntriesByName;
using PerformanceBase::ClearResourceTimings;
using PerformanceBase::Mark;
using PerformanceBase::ClearMarks;
using PerformanceBase::Measure;
using PerformanceBase::ClearMeasures;
using PerformanceBase::SetResourceTimingBufferSize;
void GetMozMemory(JSContext *aCx, JS::MutableHandle<JSObject*> aObj);
IMPL_EVENT_HANDLER(resourcetimingbufferfull)
mozilla::TimeStamp CreationTimeStamp() const override;
DOMHighResTimeStamp CreationTime() const override;
protected:
~nsPerformance();
nsISupports* GetAsISupports() override
{
return this;
}
void InsertUserEntry(PerformanceEntry* aEntry) override;
bool IsPerformanceTimingAttribute(const nsAString& aName) override;
DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
void DispatchBufferFullEvent() override;
RefPtr<nsDOMNavigationTiming> mDOMTiming;
nsCOMPtr<nsITimedChannel> mChannel;
RefPtr<mozilla::dom::PerformanceTiming> mTiming;
RefPtr<mozilla::dom::PerformanceNavigation> mNavigation;
RefPtr<nsPerformance> mParentPerformance;
JS::Heap<JSObject*> mMozMemory;
};
#endif /* nsPerformance_h___ */

View File

@ -32,11 +32,11 @@ partial interface Performance {
// http://www.w3.org/TR/performance-timeline/#sec-window.performance-attribute
[Exposed=(Window,Worker)]
partial interface Performance {
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
PerformanceEntryList getEntries();
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
PerformanceEntryList getEntriesByType(DOMString entryType);
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
PerformanceEntryList getEntriesByName(DOMString name, optional DOMString
entryType);
};
@ -44,11 +44,11 @@ partial interface Performance {
// http://www.w3.org/TR/resource-timing/#extensions-performance-interface
[Exposed=Window]
partial interface Performance {
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
void clearResourceTimings();
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
void setResourceTimingBufferSize(unsigned long maxSize);
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
attribute EventHandler onresourcetimingbufferfull;
};
@ -62,13 +62,13 @@ partial interface Performance {
// http://www.w3.org/TR/user-timing/
[Exposed=(Window,Worker)]
partial interface Performance {
[Func="nsPerformance::IsEnabled", Throws]
[Func="Performance::IsEnabled", Throws]
void mark(DOMString markName);
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
void clearMarks(optional DOMString markName);
[Func="nsPerformance::IsEnabled", Throws]
[Func="Performance::IsEnabled", Throws]
void measure(DOMString measureName, optional DOMString startMark, optional DOMString endMark);
[Func="nsPerformance::IsEnabled"]
[Func="Performance::IsEnabled"]
void clearMeasures(optional DOMString measureName);
};

View File

@ -13,7 +13,7 @@ dictionary PerformanceObserverInit {
callback PerformanceObserverCallback = void (PerformanceObserverEntryList entries, PerformanceObserver observer);
[Func="nsPerformance::IsObserverEnabled",
[Func="Performance::IsObserverEnabled",
Constructor(PerformanceObserverCallback callback),
Exposed=(Window,Worker)]
interface PerformanceObserver {

View File

@ -14,7 +14,7 @@ dictionary PerformanceEntryFilterOptions {
DOMString initiatorType;
};
[Func="nsPerformance::IsObserverEnabled", Exposed=(Window,Worker)]
[Func="Performance::IsObserverEnabled", Exposed=(Window,Worker)]
interface PerformanceObserverEntryList {
PerformanceEntryList getEntries(optional PerformanceEntryFilterOptions filter);
PerformanceEntryList getEntriesByType(DOMString entryType);

View File

@ -1,65 +0,0 @@
/* -*- 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 mozilla_dom_workers_performance_h__
#define mozilla_dom_workers_performance_h__
#include "nsWrapperCache.h"
#include "js/TypeDecls.h"
#include "Workers.h"
#include "nsISupportsImpl.h"
#include "nsCycleCollectionParticipant.h"
#include "nsPerformance.h"
BEGIN_WORKERS_NAMESPACE
class WorkerPrivate;
class Performance final : public PerformanceBase
{
public:
explicit Performance(WorkerPrivate* aWorkerPrivate);
private:
~Performance();
void InsertUserEntry(PerformanceEntry* aEntry) override;
WorkerPrivate* mWorkerPrivate;
public:
JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// WebIDL (public APIs)
DOMHighResTimeStamp Now() const override;
using PerformanceBase::Mark;
using PerformanceBase::ClearMarks;
using PerformanceBase::Measure;
using PerformanceBase::ClearMeasures;
private:
nsISupports* GetAsISupports() override
{
return nullptr;
}
void DispatchBufferFullEvent() override;
bool IsPerformanceTimingAttribute(const nsAString& aName) override;
DOMHighResTimeStamp
GetPerformanceTimingFromString(const nsAString& aTimingName) override;
TimeStamp CreationTimeStamp() const override;
DOMHighResTimeStamp CreationTime() const override;
};
END_WORKERS_NAMESPACE
#endif // mozilla_dom_workers_performance_h__

View File

@ -30,7 +30,6 @@
#include "nsIWeakReferenceUtils.h"
#include "nsIWorkerDebugger.h"
#include "nsIXPConnect.h"
#include "nsPerformance.h"
#include "nsPIDOMWindow.h"
#include <algorithm>
@ -56,6 +55,7 @@
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/MessagePortBinding.h"
#include "mozilla/dom/MessagePortList.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PMessagePort.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseDebugging.h"

View File

@ -16,6 +16,7 @@
#include "mozilla/dom/IDBFactory.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/ImageBitmapBinding.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h"
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
@ -42,7 +43,6 @@
#include "ScriptLoader.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "Performance.h"
#include "ServiceWorkerClients.h"
#include "ServiceWorkerManager.h"
#include "ServiceWorkerRegistration.h"
@ -359,7 +359,7 @@ WorkerGlobalScope::GetPerformance()
mWorkerPrivate->AssertIsOnWorkerThread();
if (!mPerformance) {
mPerformance = new Performance(mWorkerPrivate);
mPerformance = Performance::CreateForWorker(mWorkerPrivate);
}
return mPerformance;

View File

@ -24,6 +24,7 @@ class Crypto;
class Function;
class IDBFactory;
enum class ImageBitmapFormat : uint32_t;
class Performance;
class Promise;
class RequestOrUSVString;
class ServiceWorkerRegistrationWorkerThread;
@ -42,7 +43,6 @@ BEGIN_WORKERS_NAMESPACE
class ServiceWorkerClients;
class WorkerPrivate;
class Performance;
class WorkerGlobalScope : public DOMEventTargetHelper,
public nsIGlobalObject,

View File

@ -32,7 +32,6 @@ EXPORTS.mozilla.dom.workers += [
# Stuff needed for the bindings, not really public though.
EXPORTS.mozilla.dom.workers.bindings += [
'Performance.h',
'ServiceWorker.h',
'ServiceWorkerClient.h',
'ServiceWorkerClients.h',
@ -54,7 +53,6 @@ XPIDL_SOURCES += [
UNIFIED_SOURCES += [
'ChromeWorkerScope.cpp',
'FileReaderSync.cpp',
'Performance.cpp',
'Principal.cpp',
'RegisterBindings.cpp',
'RuntimeService.cpp',

View File

@ -128,7 +128,7 @@
#include "nsArenaMemoryStats.h"
#include "nsFrameSelection.h"
#include "nsPerformance.h"
#include "mozilla/dom/Performance.h"
#include "nsRefreshDriver.h"
#include "nsDOMNavigationTiming.h"
@ -9417,7 +9417,7 @@ PresShell::GetPerformanceNow()
DOMHighResTimeStamp now = 0;
if (nsPIDOMWindowInner* window = mDocument->GetInnerWindow()) {
nsPerformance* perf = window->GetPerformance();
Performance* perf = window->GetPerformance();
if (perf) {
now = perf->Now();

View File

@ -44,7 +44,7 @@
#include "nsViewManager.h"
#include "GeckoProfiler.h"
#include "nsNPAPIPluginInstance.h"
#include "nsPerformance.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/WindowBinding.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/RestyleManagerHandle.h"
@ -1605,7 +1605,7 @@ nsRefreshDriver::RunFrameRequestCallbacks(TimeStamp aNowTime)
docCallbacks.mDocument->GetInnerWindow();
DOMHighResTimeStamp timeStamp = 0;
if (innerWindow && innerWindow->IsInnerWindow()) {
nsPerformance* perf = innerWindow->GetPerformance();
mozilla::dom::Performance* perf = innerWindow->GetPerformance();
if (perf) {
timeStamp = perf->GetDOMTiming()->TimeStampToDOMHighRes(aNowTime);
}

View File

@ -55,9 +55,9 @@
#endif // XP_WIN
#include "nsIDocument.h"
#include "nsPerformance.h"
#include "nsGlobalWindow.h"
#include "nsDOMDataChannel.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Telemetry.h"
#include "mozilla/Preferences.h"
@ -2093,7 +2093,7 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
nsresult
PeerConnectionImpl::GetTimeSinceEpoch(DOMHighResTimeStamp *result) {
MOZ_ASSERT(NS_IsMainThread());
nsPerformance *perf = mWindow->GetPerformance();
Performance *perf = mWindow->GetPerformance();
NS_ENSURE_TRUE(perf && perf->Timing(), NS_ERROR_UNEXPECTED);
*result = perf->Now() + perf->Timing()->NavigationStart();
return NS_OK;

View File

@ -38,8 +38,8 @@
#include "nsProxyRelease.h"
#include "nsPIDOMWindow.h"
#include "nsIDocShell.h"
#include "nsPerformance.h"
#include "nsINetworkInterceptController.h"
#include "mozilla/dom/Performance.h"
#include "mozIThirdPartyUtil.h"
#include "nsStreamUtils.h"
#include "nsContentSecurityManager.h"
@ -3340,10 +3340,10 @@ IMPL_TIMING_ATTR(RedirectEnd)
#undef IMPL_TIMING_ATTR
nsPerformance*
mozilla::dom::Performance*
HttpBaseChannel::GetPerformance()
{
// If performance timing is disabled, there is no need for the nsPerformance
// If performance timing is disabled, there is no need for the Performance
// object anymore.
if (!mTimingEnabled) {
return nullptr;
@ -3380,7 +3380,7 @@ HttpBaseChannel::GetPerformance()
return nullptr;
}
nsPerformance* docPerformance = innerWindow->GetPerformance();
mozilla::dom::Performance* docPerformance = innerWindow->GetPerformance();
if (!docPerformance) {
return nullptr;
}

View File

@ -44,12 +44,15 @@
#include "nsCOMArray.h"
#include "mozilla/net/ChannelEventQueue.h"
class nsPerformance;
class nsISecurityConsoleMessage;
class nsIPrincipal;
namespace mozilla {
namespace dom {
class Performance;
}
class LogCollector;
namespace net {
@ -321,7 +324,7 @@ protected:
// drop reference to listener, its callbacks, and the progress sink
void ReleaseListeners();
nsPerformance* GetPerformance();
mozilla::dom::Performance* GetPerformance();
nsIURI* GetReferringPage();
nsPIDOMWindowInner* GetInnerDOMWindow();

View File

@ -24,6 +24,7 @@
#include "nsNetUtil.h"
#include "nsSerializationHelper.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "mozilla/ipc/BackgroundUtils.h"
@ -32,7 +33,6 @@
#include "SerializedLoadContext.h"
#include "nsInputStreamPump.h"
#include "InterceptedChannel.h"
#include "nsPerformance.h"
#include "mozIThirdPartyUtil.h"
#include "nsContentSecurityManager.h"
#include "nsIDeprecationWarner.h"
@ -889,7 +889,7 @@ HttpChannelChild::OnStopRequest(const nsresult& channelStatus,
mCacheReadStart = timing.cacheReadStart;
mCacheReadEnd = timing.cacheReadEnd;
nsPerformance* documentPerformance = GetPerformance();
Performance* documentPerformance = GetPerformance();
if (documentPerformance) {
documentPerformance->AddEntry(this, this);
}

View File

@ -79,8 +79,8 @@
#include "nsISiteSecurityService.h"
#include "nsString.h"
#include "nsCRT.h"
#include "nsPerformance.h"
#include "CacheObserver.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/Telemetry.h"
#include "AlternateServices.h"
#include "InterceptedChannel.h"
@ -6393,7 +6393,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
}
// Register entry to the Performance resource timing
nsPerformance* documentPerformance = GetPerformance();
mozilla::dom::Performance* documentPerformance = GetPerformance();
if (documentPerformance) {
documentPerformance->AddEntry(this, this);
}

View File

@ -538,7 +538,7 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
// then the requestStart timestamp will be null, so we mark the timestamps
// for domainLookupStart/End and connectStart/End
// If we are using a persistent connection they will remain null,
// and the correct value will be returned in nsPerformance.
// and the correct value will be returned in Performance.
if (TimingEnabled() && GetRequestStart().IsNull()) {
if (status == NS_NET_STATUS_RESOLVING_HOST) {
SetDomainLookupStart(TimeStamp::Now(), true);