diff options
Diffstat (limited to 'toolkit/components/perfmonitoring')
6 files changed, 676 insertions, 0 deletions
diff --git a/toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp b/toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp new file mode 100644 index 0000000000..593d2c89ef --- /dev/null +++ b/toolkit/components/perfmonitoring/PerformanceMetricsCollector.cpp @@ -0,0 +1,311 @@ +/* -*- 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 "nsContentUtils.h" +#include "nsThreadUtils.h" +#include "mozilla/AbstractThread.h" +#include "mozilla/Logging.h" +#include "mozilla/PerformanceUtils.h" +#include "mozilla/PerformanceMetricsCollector.h" +#include "mozilla/StaticPrefs_dom.h" +#include "mozilla/TaskQueue.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/WorkerDebugger.h" +#include "mozilla/dom/WorkerDebuggerManager.h" + +using namespace mozilla; +using namespace mozilla::dom; + +static mozilla::LazyLogModule sPerfLog("PerformanceMetricsCollector"); +#ifdef LOG +# undef LOG +#endif +#define LOG(args) MOZ_LOG(sPerfLog, mozilla::LogLevel::Debug, args) + +namespace mozilla { + +// +// class IPCTimeout +// +NS_IMPL_ISUPPORTS(IPCTimeout, nsIObserver) + +// static +IPCTimeout* IPCTimeout::CreateInstance(AggregatedResults* aResults) { + MOZ_ASSERT(aResults); + uint32_t delay = StaticPrefs::dom_performance_children_results_ipc_timeout(); + if (delay == 0) { + return nullptr; + } + return new IPCTimeout(aResults, delay); +} + +IPCTimeout::IPCTimeout(AggregatedResults* aResults, uint32_t aDelay) + : mResults(aResults) { + MOZ_ASSERT(aResults); + MOZ_ASSERT(aDelay > 0); + mozilla::DebugOnly<nsresult> rv = NS_NewTimerWithObserver( + getter_AddRefs(mTimer), this, aDelay, nsITimer::TYPE_ONE_SHOT); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + LOG(("IPCTimeout timer created")); +} + +IPCTimeout::~IPCTimeout() { Cancel(); } + +void IPCTimeout::Cancel() { + if (mTimer) { + LOG(("IPCTimeout timer canceled")); + mTimer->Cancel(); + mTimer = nullptr; + } +} + +NS_IMETHODIMP +IPCTimeout::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + MOZ_ASSERT(strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0); + LOG(("IPCTimeout timer triggered")); + mResults->ResolveNow(); + return NS_OK; +} + +// +// class AggregatedResults +// +AggregatedResults::AggregatedResults(nsID aUUID, + PerformanceMetricsCollector* aCollector) + : mPendingResults(0), mCollector(aCollector), mUUID(aUUID) { + MOZ_ASSERT(aCollector); + mIPCTimeout = IPCTimeout::CreateInstance(this); +} + +void AggregatedResults::Abort(nsresult aReason) { + MOZ_ASSERT(!mHolder.IsEmpty()); + MOZ_ASSERT(NS_FAILED(aReason)); + if (mIPCTimeout) { + mIPCTimeout->Cancel(); + mIPCTimeout = nullptr; + } + mHolder.Reject(aReason, __func__); + mPendingResults = 0; +} + +void AggregatedResults::ResolveNow() { + MOZ_ASSERT(!mHolder.IsEmpty()); + LOG(("[%s] Early resolve", nsIDToCString(mUUID).get())); + mHolder.Resolve(CopyableTArray(mData), __func__); + mIPCTimeout = nullptr; + mCollector->ForgetAggregatedResults(mUUID); +} + +void AggregatedResults::AppendResult( + const nsTArray<dom::PerformanceInfo>& aMetrics) { + if (mHolder.IsEmpty()) { + // A previous call failed and the promise was already rejected + return; + } + MOZ_ASSERT(mPendingResults > 0); + + // Each PerformanceInfo is converted into a PerformanceInfoDictionary + for (const PerformanceInfo& result : aMetrics) { + mozilla::dom::Sequence<mozilla::dom::CategoryDispatchDictionary> items; + + for (const CategoryDispatch& entry : result.items()) { + uint32_t count = entry.count(); + if (count == 0) { + continue; + } + CategoryDispatchDictionary* item = items.AppendElement(fallible); + if (NS_WARN_IF(!item)) { + Abort(NS_ERROR_OUT_OF_MEMORY); + return; + } + item->mCategory = entry.category(); + item->mCount = count; + } + + PerformanceInfoDictionary* data = mData.AppendElement(fallible); + if (NS_WARN_IF(!data)) { + Abort(NS_ERROR_OUT_OF_MEMORY); + return; + } + data->mPid = result.pid(); + data->mWindowId = result.windowId(); + data->mHost.Assign(result.host()); + data->mDuration = result.duration(); + data->mCounterId = result.counterId(); + data->mIsWorker = result.isWorker(); + data->mIsTopLevel = result.isTopLevel(); + data->mMemoryInfo.mDomDom = result.memory().domDom(); + data->mMemoryInfo.mDomStyle = result.memory().domStyle(); + data->mMemoryInfo.mDomOther = result.memory().domOther(); + data->mMemoryInfo.mGCHeapUsage = result.memory().GCHeapUsage(); + data->mMemoryInfo.mMedia.mAudioSize = result.memory().media().audioSize(); + data->mMemoryInfo.mMedia.mVideoSize = result.memory().media().videoSize(); + data->mMemoryInfo.mMedia.mResourcesSize = + result.memory().media().resourcesSize(); + data->mItems = items; + } + + mPendingResults--; + if (mPendingResults) { + return; + } + + LOG(("[%s] All data collected, resolving promise", + nsIDToCString(mUUID).get())); + if (mIPCTimeout) { + mIPCTimeout->Cancel(); + mIPCTimeout = nullptr; + } + nsTArray<dom::PerformanceInfoDictionary> data; + data.Assign(mData); + mHolder.Resolve(std::move(data), __func__); + mCollector->ForgetAggregatedResults(mUUID); +} + +void AggregatedResults::SetNumResultsRequired(uint32_t aNumResultsRequired) { + MOZ_ASSERT(!mPendingResults && aNumResultsRequired); + mPendingResults = aNumResultsRequired; +} + +RefPtr<RequestMetricsPromise> AggregatedResults::GetPromise() { + return mHolder.Ensure(__func__); +} + +// +// class PerformanceMetricsCollector (singleton) +// + +// raw pointer for the singleton +PerformanceMetricsCollector* gInstance = nullptr; + +PerformanceMetricsCollector::~PerformanceMetricsCollector() { + MOZ_ASSERT(gInstance == this); + gInstance = nullptr; +} + +void PerformanceMetricsCollector::ForgetAggregatedResults(const nsID& aUUID) { + MOZ_ASSERT(gInstance); + MOZ_ASSERT(XRE_IsParentProcess()); + // This Remove() call will trigger AggregatedResults DTOR and if its + // the last in the table, the DTOR of PerformanceMetricsCollector. + // That's why we need to make sure we hold a reference here before the call + RefPtr<PerformanceMetricsCollector> kungFuDeathGrip = this; + LOG(("[%s] Removing from the table", nsIDToCString(aUUID).get())); + mAggregatedResults.Remove(aUUID); +} + +// static +RefPtr<RequestMetricsPromise> PerformanceMetricsCollector::RequestMetrics() { + MOZ_ASSERT(XRE_IsParentProcess()); + RefPtr<PerformanceMetricsCollector> pmc = gInstance; + if (!pmc) { + pmc = new PerformanceMetricsCollector(); + gInstance = pmc; + } + return pmc->RequestMetricsInternal(); +} + +RefPtr<RequestMetricsPromise> +PerformanceMetricsCollector::RequestMetricsInternal() { + // each request has its own UUID + nsID uuid; + nsresult rv = nsContentUtils::GenerateUUIDInPlace(uuid); + if (NS_WARN_IF(NS_FAILED(rv))) { + return RequestMetricsPromise::CreateAndReject(rv, __func__); + } + + LOG(("[%s] Requesting Performance Metrics", nsIDToCString(uuid).get())); + + // Getting all content processes + nsTArray<ContentParent*> children; + ContentParent::GetAll(children); + uint32_t numChildren = children.Length(); + + // keep track of all results in an AggregatedResults instance + UniquePtr<AggregatedResults> results = + MakeUnique<AggregatedResults>(uuid, this); + RefPtr<RequestMetricsPromise> promise = results->GetPromise(); + + // We want to get back as many results as children + one parent if needed + uint32_t numResultsRequired = children.Length(); + nsTArray<RefPtr<PerformanceInfoPromise>> localPromises = + CollectPerformanceInfo(); + if (!localPromises.IsEmpty()) { + numResultsRequired++; + } + + LOG(("[%s] Expecting %d results back", nsIDToCString(uuid).get(), + numResultsRequired)); + results->SetNumResultsRequired(numResultsRequired); + mAggregatedResults.Put(uuid, std::move(results)); + + // calling all content processes via IPDL (async) + for (uint32_t i = 0; i < numChildren; i++) { + if (NS_WARN_IF(!children[i]->SendRequestPerformanceMetrics(uuid))) { + LOG(("[%s] Failed to send request to child %d", nsIDToCString(uuid).get(), + i)); + mAggregatedResults.GetValue(uuid)->get()->Abort(NS_ERROR_FAILURE); + return RequestMetricsPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); + } + LOG(("[%s] Request sent to child %d", nsIDToCString(uuid).get(), i)); + } + + nsTArray<RefPtr<PerformanceInfoPromise>> promises = CollectPerformanceInfo(); + if (promises.IsEmpty()) { + return promise; + } + + // collecting the current process PerformanceInfo + PerformanceInfoPromise::All(NS_GetCurrentThread(), localPromises) + ->Then( + NS_GetCurrentThread(), __func__, + [uuid](const nsTArray<mozilla::dom::PerformanceInfo> aResult) { + LOG(("[%s] Local CollectPerformanceInfo promise resolved", + nsIDToCString(uuid).get())); + DataReceived(uuid, aResult); + }, + [](const nsresult aResult) {}); + + return promise; +} + +// static +nsresult PerformanceMetricsCollector::DataReceived( + const nsID& aUUID, const nsTArray<PerformanceInfo>& aMetrics) { + // If some content process were unresponsive on shutdown, we may get called + // here with late data received from children - so instead of asserting + // that gInstance is available, we just return. + if (!gInstance) { + LOG(("[%s] gInstance is gone", nsIDToCString(aUUID).get())); + return NS_OK; + } + MOZ_ASSERT(XRE_IsParentProcess()); + return gInstance->DataReceivedInternal(aUUID, aMetrics); +} + +nsresult PerformanceMetricsCollector::DataReceivedInternal( + const nsID& aUUID, const nsTArray<PerformanceInfo>& aMetrics) { + MOZ_ASSERT(gInstance == this); + UniquePtr<AggregatedResults>* results = mAggregatedResults.GetValue(aUUID); + if (!results) { + LOG(("[%s] UUID is gone from mAggregatedResults", + nsIDToCString(aUUID).get())); + return NS_ERROR_FAILURE; + } + + LOG(("[%s] Received one PerformanceInfo array", nsIDToCString(aUUID).get())); + AggregatedResults* aggregatedResults = results->get(); + MOZ_ASSERT(aggregatedResults); + + // If this is the last result, AppendResult() will trigger the deletion + // of this collector, nothing should be done after this line. + aggregatedResults->AppendResult(aMetrics); + return NS_OK; +} + +} // namespace mozilla diff --git a/toolkit/components/perfmonitoring/PerformanceMetricsCollector.h b/toolkit/components/perfmonitoring/PerformanceMetricsCollector.h new file mode 100644 index 0000000000..76cf8e3a5e --- /dev/null +++ b/toolkit/components/perfmonitoring/PerformanceMetricsCollector.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 PerformanceMetricsCollector_h +#define PerformanceMetricsCollector_h + +#include "nsIObserver.h" +#include "nsITimer.h" +#include "nsID.h" +#include "mozilla/dom/ChromeUtilsBinding.h" // defines PerformanceInfoDictionary +#include "mozilla/dom/DOMTypes.h" // defines PerformanceInfo +#include "mozilla/PerformanceTypes.h" + +namespace mozilla { + +namespace dom { +class Promise; +} + +class PerformanceMetricsCollector; +class AggregatedResults; + +class IPCTimeout final : public nsIObserver { + public: + NS_DECL_NSIOBSERVER + NS_DECL_ISUPPORTS + static IPCTimeout* CreateInstance(AggregatedResults* aResults); + void Cancel(); + + private: + IPCTimeout(AggregatedResults* aResults, uint32_t aDelay); + ~IPCTimeout(); + + nsCOMPtr<nsITimer> mTimer; + AggregatedResults* mResults; +}; + +// AggregatedResults receives PerformanceInfo results that are collected +// asynchronously via IPDL from all content processes. +// They are converted into an array of +// PerformanceInfoDictionary dictionaries (webidl) +// +// Once every process have sent back its results, AggregatedResults will +// resolve the MozPromise returned by GetPromise() +// with all the collected data. +// +// See ChromeUtils::RequestPerformanceMetrics. +class AggregatedResults final { + public: + AggregatedResults(nsID aUUID, PerformanceMetricsCollector* aCollector); + ~AggregatedResults() = default; + void AppendResult(const nsTArray<dom::PerformanceInfo>& aMetrics); + void SetNumResultsRequired(uint32_t aNumResultsRequired); + void Abort(nsresult aReason); + void ResolveNow(); + RefPtr<RequestMetricsPromise> GetPromise(); + + private: + RefPtr<IPCTimeout> mIPCTimeout; + MozPromiseHolder<RequestMetricsPromise> mHolder; + uint32_t mPendingResults; + FallibleTArray<dom::PerformanceInfoDictionary> mData; + + // AggregatedResults keeps a reference on the collector + // so it gets destructed when all pending AggregatedResults + // are themselves destructed when removed from + // PerformanceMetricsCollector::mAggregatedResults. + // + // This lifecycle ensures that everything is released once + // all pending results are sent. + RefPtr<PerformanceMetricsCollector> mCollector; + nsID mUUID; +}; + +// +// PerformanceMetricsCollector is instanciated as a singleton, and creates +// one AggregatedResults instance everytime metrics are requested. +// +// Each AggregatedResults has a unique identifier (UUID) that is used +// to send metrics requests via IPDL. When metrics are back in an +// asynchronous fashion, the UUID is used to append the data to the +// right AggregatedResults instance and eventually let it resolve the +// linked promise. +// +class PerformanceMetricsCollector final { + public: + NS_INLINE_DECL_REFCOUNTING(PerformanceMetricsCollector) + static RefPtr<RequestMetricsPromise> RequestMetrics(); + static nsresult DataReceived(const nsID& aUUID, + const nsTArray<dom::PerformanceInfo>& aMetrics); + void ForgetAggregatedResults(const nsID& aUUID); + + private: + ~PerformanceMetricsCollector(); + RefPtr<RequestMetricsPromise> RequestMetricsInternal(); + nsresult DataReceivedInternal(const nsID& aUUID, + const nsTArray<dom::PerformanceInfo>& aMetrics); + nsDataHashtable<nsIDHashKey, UniquePtr<AggregatedResults>> mAggregatedResults; +}; + +} // namespace mozilla +#endif // PerformanceMetricsCollector_h diff --git a/toolkit/components/perfmonitoring/PerformanceTypes.h b/toolkit/components/perfmonitoring/PerformanceTypes.h new file mode 100644 index 0000000000..9ef53c1d13 --- /dev/null +++ b/toolkit/components/perfmonitoring/PerformanceTypes.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 PerformanceTypes_h +#define PerformanceTypes_h + +#include "mozilla/MozPromise.h" + +namespace mozilla { + +namespace dom { +class PerformanceInfo; +class PerformanceMemoryInfo; +struct PerformanceInfoDictionary; +} // namespace dom + +/** + * Promises definitions + */ +typedef MozPromise<dom::PerformanceInfo, nsresult, true> PerformanceInfoPromise; +typedef MozPromise<nsTArray<dom::PerformanceInfoDictionary>, nsresult, true> + RequestMetricsPromise; +typedef MozPromise<nsTArray<dom::PerformanceInfo>, nsresult, true> + PerformanceInfoArrayPromise; +typedef MozPromise<mozilla::dom::PerformanceMemoryInfo, nsresult, true> + MemoryPromise; + +} // namespace mozilla +#endif // PerformanceTypes_h diff --git a/toolkit/components/perfmonitoring/PerformanceUtils.cpp b/toolkit/components/perfmonitoring/PerformanceUtils.cpp new file mode 100644 index 0000000000..d119d4e7d0 --- /dev/null +++ b/toolkit/components/perfmonitoring/PerformanceUtils.cpp @@ -0,0 +1,171 @@ +/* -*- 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 "mozilla/PerformanceUtils.h" + +#include "mozilla/dom/DOMTypes.h" +#include "mozilla/dom/DocGroup.h" +#include "mozilla/dom/BrowsingContextGroup.h" +#include "mozilla/dom/Document.h" +#include "mozilla/dom/WorkerDebugger.h" +#include "mozilla/dom/WorkerDebuggerManager.h" + +#include "MediaDecoder.h" +#include "jsfriendapi.h" +#include "nsGlobalWindowOuter.h" +#include "nsWindowSizes.h" + +using namespace mozilla; +using namespace mozilla::dom; + +namespace mozilla { + +nsTArray<RefPtr<PerformanceInfoPromise>> CollectPerformanceInfo() { + nsTArray<RefPtr<PerformanceInfoPromise>> promises; + + // collecting ReportPerformanceInfo from all WorkerDebugger instances + RefPtr<mozilla::dom::WorkerDebuggerManager> wdm = + WorkerDebuggerManager::GetOrCreate(); + if (NS_WARN_IF(!wdm)) { + return promises; + } + + for (uint32_t i = 0; i < wdm->GetDebuggersLength(); i++) { + const RefPtr<WorkerDebugger> debugger = wdm->GetDebuggerAt(i); + promises.AppendElement(debugger->ReportPerformanceInfo()); + } + + nsTArray<RefPtr<BrowsingContextGroup>> groups; + BrowsingContextGroup::GetAllGroups(groups); + + nsTArray<DocGroup*> docGroups; + for (auto& browsingContextGroup : groups) { + browsingContextGroup->GetDocGroups(docGroups); + } + + for (DocGroup* docGroup : docGroups) { + promises.AppendElement(docGroup->ReportPerformanceInfo()); + } + + return promises; +} + +void AddWindowTabSizes(nsGlobalWindowOuter* aWindow, nsTabSizes* aSizes) { + Document* document = aWindow->GetDocument(); + if (document && document->GetCachedSizes(aSizes)) { + // We got a cached version + return; + } + // We measure the sizes on a fresh nsTabSizes instance + // because we want to cache the value and aSizes might + // already have some values from other windows. + nsTabSizes sizes; + + // Measure the window. + SizeOfState state(moz_malloc_size_of); + nsWindowSizes windowSizes(state); + aWindow->AddSizeOfIncludingThis(windowSizes); + // Measure the inner window, if there is one. + nsGlobalWindowInner* inner = aWindow->GetCurrentInnerWindowInternal(); + if (inner != nullptr) { + inner->AddSizeOfIncludingThis(windowSizes); + } + windowSizes.addToTabSizes(&sizes); + if (document) { + document->SetCachedSizes(&sizes); + } + aSizes->mDom += sizes.mDom; + aSizes->mStyle += sizes.mStyle; + aSizes->mOther += sizes.mOther; +} + +nsresult GetTabSizes(BrowsingContext* aContext, nsTabSizes* aSizes) { + if (!aContext) { + return NS_OK; + } + + // Add the window (and inner window) sizes. Might be cached. + nsGlobalWindowOuter* window = + nsGlobalWindowOuter::Cast(aContext->GetDOMWindow()); + if (window) { + AddWindowTabSizes(window, aSizes); + } + + // Measure this window's descendents. + for (const auto& child : aContext->Children()) { + MOZ_TRY(GetTabSizes(child, aSizes)); + } + return NS_OK; +} + +RefPtr<MemoryPromise> CollectMemoryInfo( + const RefPtr<DocGroup>& aDocGroup, + const RefPtr<AbstractThread>& aEventTarget) { + // Getting Dom sizes. -- XXX should we reimplement GetTabSizes to async here ? + nsTabSizes sizes; + + for (const auto& document : *aDocGroup) { + nsGlobalWindowOuter* window = + document ? nsGlobalWindowOuter::Cast(document->GetWindow()) : nullptr; + if (window) { + AddWindowTabSizes(window, &sizes); + } + } + + BrowsingContextGroup* group = aDocGroup->GetBrowsingContextGroup(); + // Getting GC Heap Usage + uint64_t GCHeapUsage = 0; + JSObject* object = group->GetWrapper(); + if (object != nullptr) { + GCHeapUsage = js::GetGCHeapUsageForObjectZone(object); + } + + // Getting Media sizes. + return GetMediaMemorySizes()->Then( + aEventTarget, __func__, + [GCHeapUsage, sizes](const MediaMemoryInfo& media) { + return MemoryPromise::CreateAndResolve( + PerformanceMemoryInfo(media, sizes.mDom, sizes.mStyle, sizes.mOther, + GCHeapUsage), + __func__); + }, + [](const nsresult rv) { + return MemoryPromise::CreateAndReject(rv, __func__); + }); +} + +RefPtr<MemoryPromise> CollectMemoryInfo( + const RefPtr<BrowsingContext>& aContext, + const RefPtr<AbstractThread>& aEventTarget) { + // Getting Dom sizes. -- XXX should we reimplement GetTabSizes to async here ? + nsTabSizes sizes; + nsresult rv = GetTabSizes(aContext, &sizes); + if (NS_FAILED(rv)) { + return MemoryPromise::CreateAndReject(rv, __func__); + } + + // Getting GC Heap Usage + JSObject* obj = aContext->GetWrapper(); + uint64_t GCHeapUsage = 0; + if (obj != nullptr) { + GCHeapUsage = js::GetGCHeapUsageForObjectZone(obj); + } + + // Getting Media sizes. + return GetMediaMemorySizes()->Then( + aEventTarget, __func__, + [GCHeapUsage, sizes](const MediaMemoryInfo& media) { + return MemoryPromise::CreateAndResolve( + PerformanceMemoryInfo(media, sizes.mDom, sizes.mStyle, sizes.mOther, + GCHeapUsage), + __func__); + }, + [](const nsresult rv) { + return MemoryPromise::CreateAndReject(rv, __func__); + }); +} + +} // namespace mozilla diff --git a/toolkit/components/perfmonitoring/PerformanceUtils.h b/toolkit/components/perfmonitoring/PerformanceUtils.h new file mode 100644 index 0000000000..fd57626413 --- /dev/null +++ b/toolkit/components/perfmonitoring/PerformanceUtils.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 PerformanceUtils_h +#define PerformanceUtils_h + +#include "mozilla/PerformanceTypes.h" + +class nsPIDOMWindowOuter; + +namespace mozilla { +namespace dom { +class BrowsingContext; +class DocGroup; +} // namespace dom +/** + * Returns an array of promises to asynchronously collect all performance + * info in the current process. + */ +nsTArray<RefPtr<PerformanceInfoPromise>> CollectPerformanceInfo(); + +/** + * Asynchronously collects memory info for a given window + */ +RefPtr<MemoryPromise> CollectMemoryInfo( + const RefPtr<dom::BrowsingContext>& aContext, + const RefPtr<AbstractThread>& aEventTarget); + +RefPtr<MemoryPromise> CollectMemoryInfo( + const RefPtr<dom::DocGroup>& aDocGroup, + const RefPtr<AbstractThread>& aEventTarget); + +} // namespace mozilla +#endif // PerformanceUtils_h diff --git a/toolkit/components/perfmonitoring/moz.build b/toolkit/components/perfmonitoring/moz.build new file mode 100644 index 0000000000..193e5df7db --- /dev/null +++ b/toolkit/components/perfmonitoring/moz.build @@ -0,0 +1,23 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +with Files("**"): + BUG_COMPONENT = ("Toolkit", "Performance Monitoring") + + +UNIFIED_SOURCES += ["PerformanceMetricsCollector.cpp", "PerformanceUtils.cpp"] + +EXPORTS.mozilla += [ + "PerformanceMetricsCollector.h", + "PerformanceTypes.h", + "PerformanceUtils.h", +] + +LOCAL_INCLUDES += ["/dom/base"] + +FINAL_LIBRARY = "xul" + +include("/ipc/chromium/chromium-config.mozbuild") |