Bug 1443443 - Extend PContent to retrieve Performance Counters in the parent process - r=baku

Adds the IPDL layer to asynchronously retrieve in the parent process the performance counters.

MozReview-Commit-ID: RbKstNx8pi

--HG--
extra : rebase_source : d7c00f2ef16623dbbd88ede0f6636ca56501e151
This commit is contained in:
Tarek Ziadé 2018-03-20 20:07:41 +01:00
Родитель 3eacaf6b89
Коммит 255bc818dc
21 изменённых файлов: 565 добавлений и 0 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/IdleDeadline.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
@ -653,6 +654,19 @@ ChromeUtils::ClearRecentJSDevError(GlobalObject&)
}
#endif // NIGHTLY_BUILD
#ifndef RELEASE_OR_BETA
/* static */ void
ChromeUtils::RequestPerformanceMetrics(GlobalObject&)
{
MOZ_ASSERT(XRE_IsParentProcess());
nsTArray<ContentParent*> children;
ContentParent::GetAll(children);
for (uint32_t i = 0; i < children.Length(); i++) {
mozilla::Unused << children[i]->SendRequestPerformanceMetrics();
}
}
#endif
constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude;
/* static */ void

Просмотреть файл

@ -155,6 +155,10 @@ public:
static void ClearRecentJSDevError(GlobalObject& aGlobal);
#ifndef RELEASE_OR_BETA
static void RequestPerformanceMetrics(GlobalObject& aGlobal);
#endif
static void Import(const GlobalObject& aGlobal,
const nsAString& aResourceURI,
const Optional<JS::Handle<JSObject*>>& aTargetObj,

Просмотреть файл

@ -5,10 +5,16 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/Telemetry.h"
#include "nsIDocShell.h"
#include "nsDOMMutationObserver.h"
#if defined(XP_WIN)
#include <processthreadsapi.h> // for GetCurrentProcessId()
#else
#include <unistd.h> // for getpid()
#endif // defined(XP_WIN)
namespace mozilla {
namespace dom {
@ -61,6 +67,68 @@ DocGroup::~DocGroup()
mTabGroup->mDocGroups.RemoveEntry(mKey);
}
#ifndef RELEASE_OR_BETA
PerformanceInfo
DocGroup::ReportPerformanceInfo()
{
AssertIsOnMainThread();
#if defined(XP_WIN)
uint32_t pid = GetCurrentProcessId();
#else
uint32_t pid = getpid();
#endif
uint64_t wid = 0;
uint64_t pwid = 0;
uint16_t count = 0;
uint64_t duration = 0;
nsCString host = NS_LITERAL_CSTRING("None");
for (const auto& document : *this) {
// grabbing the host name of the first document
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
MOZ_ASSERT(doc);
nsCOMPtr<nsIURI> docURI = doc->GetDocumentURI();
if (!docURI) {
continue;
}
docURI->GetHost(host);
wid = doc->OuterWindowID();
// getting the top window id - if not possible
// pwid gets the same value than wid
pwid = wid;
nsPIDOMWindowInner* win = doc->GetInnerWindow();
if (win) {
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
if (outer) {
nsCOMPtr<nsPIDOMWindowOuter> top = outer->GetTop();
if (top) {
pwid = top->WindowID();
}
}
}
}
duration = mPerformanceCounter->GetExecutionDuration();
FallibleTArray<CategoryDispatch> items;
// now that we have the host and window ids, let's look at the perf counters
for (uint32_t index = 0; index < (uint32_t)TaskCategory::Count; index++) {
TaskCategory category = static_cast<TaskCategory>(index);
count = mPerformanceCounter->GetDispatchCount(DispatchCategory(category));
CategoryDispatch item = CategoryDispatch(index, count);
if (!items.AppendElement(item, fallible)) {
NS_ERROR("Could not complete the operation");
return PerformanceInfo(host, pid, wid, pwid, duration, false, items);
}
}
// setting back all counters to zero
mPerformanceCounter->ResetPerformanceCounters();
return PerformanceInfo(host, pid, wid, pwid, duration, false, items);
}
#endif
nsresult
DocGroup::Dispatch(TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable)

Просмотреть файл

@ -23,6 +23,8 @@ namespace mozilla {
class AbstractThread;
namespace dom {
class PerformanceInfo;
// Two browsing contexts are considered "related" if they are reachable from one
// another through window.opener, window.parent, or window.frames. This is the
// spec concept of a "unit of related browsing contexts"
@ -61,6 +63,9 @@ public:
{
return mPerformanceCounter;
}
PerformanceInfo
ReportPerformanceInfo();
#endif
TabGroup* GetTabGroup()
{

Просмотреть файл

@ -26,6 +26,7 @@ XPIDL_SOURCES += [
'nsIImageLoadingContent.idl',
'nsIMessageManager.idl',
'nsIObjectLoadingContent.idl',
'nsIPerformanceMetrics.idl',
'nsIRemoteWindowContext.idl',
'nsIScriptChannel.idl',
'nsISelection.idl',
@ -105,6 +106,7 @@ EXPORTS += [
'nsNameSpaceManager.h',
'nsNodeInfoManager.h',
'nsNodeUtils.h',
'nsPerformanceMetrics.h',
'nsPIDOMWindow.h',
'nsPIDOMWindowInlines.h',
'nsPIWindowRoot.h',
@ -313,6 +315,7 @@ UNIFIED_SOURCES += [
'nsNodeInfoManager.cpp',
'nsNodeUtils.cpp',
'nsOpenURIInFrameParams.cpp',
'nsPerformanceMetrics.cpp',
'nsPlainTextSerializer.cpp',
'nsPropertyTable.cpp',
'nsQueryContentEventResult.cpp',

Просмотреть файл

@ -0,0 +1,49 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 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 "nsISupports.idl"
#include "nsIArray.idl"
/*
* nsIPerformanceMetricsData is used to store performance data collected
* in all content processes by nsThread and nsWorkerThread.
*
* Each (host, category, pid, wid, pwid) is unique to a given DocGroup or
* Worker, and we collect the number of dispatches and execution duration.
*
* This XPCOM interface reflects the data collected in Performance counters.
* see xpcom/threads/PerformanceCounter.h
*/
[scriptable, builtinclass, uuid(1f9a58c9-be37-4463-8996-c7f5b9a5bef8)]
interface nsIPerformanceMetricsDispatchCategory : nsISupports
{
// DispatchCategory value
readonly attribute unsigned long category;
// Number of dispatch.
readonly attribute unsigned long count;
};
[scriptable, builtinclass, uuid(02b0cdc6-4be2-4154-a8a9-e8d462073200)]
interface nsIPerformanceMetricsData : nsISupports
{
// Host of the document, if any
readonly attribute AUTF8String host;
// process id
readonly attribute unsigned long pid;
// window id
readonly attribute unsigned long long wid;
// "parent" window id
readonly attribute unsigned long long pwid;
// Execution time in microseconds
readonly attribute unsigned long long duration;
// True if the data is collected in a worker
readonly attribute bool worker;
// Dispatch Category counters
readonly attribute nsIArray items;
};

Просмотреть файл

@ -0,0 +1,124 @@
/* -*- 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/. */
#include <nsIMutableArray.h>
#include <nsArrayUtils.h>
#include <nsPerformanceMetrics.h>
/* ------------------------------------------------------
*
* class PerformanceMetricsDispatchCategory
*
*/
PerformanceMetricsDispatchCategory::PerformanceMetricsDispatchCategory(uint32_t aCategory, uint32_t aCount)
: mCategory(aCategory), mCount(aCount)
{
}
NS_IMPL_ISUPPORTS(PerformanceMetricsDispatchCategory,
nsIPerformanceMetricsDispatchCategory);
NS_IMETHODIMP
PerformanceMetricsDispatchCategory::GetCategory(uint32_t* aCategory)
{
*aCategory = mCategory;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsDispatchCategory::GetCount(uint32_t* aCount)
{
*aCount = mCount;
return NS_OK;
};
/* ------------------------------------------------------
*
* class PerformanceMetricsData
*
*/
PerformanceMetricsData::PerformanceMetricsData(uint32_t aPid, uint64_t aWid,
uint64_t aPwid, const nsCString& aHost,
uint64_t aDuration, bool aWorker,
nsIArray* aItems)
: mPid(aPid), mWid(aWid), mPwid(aPwid), mHost(aHost)
, mDuration(aDuration), mWorker(aWorker)
{
uint32_t len;
nsresult rv = aItems->GetLength(&len);
if (NS_FAILED(rv)) {
NS_ASSERTION(rv == NS_OK, "Failed to ge the length");
}
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsIPerformanceMetricsDispatchCategory> item = do_QueryElementAt(aItems, i);
mItems.AppendElement(item);
}
};
NS_IMPL_ISUPPORTS(PerformanceMetricsData, nsIPerformanceMetricsData);
NS_IMETHODIMP
PerformanceMetricsData::GetHost(nsACString& aHost)
{
aHost = mHost;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetWorker(bool* aWorker)
{
*aWorker = mWorker;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetPid(uint32_t* aPid)
{
*aPid = mPid;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetWid(uint64_t* aWid)
{
*aWid = mWid;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetDuration(uint64_t* aDuration)
{
*aDuration = mDuration;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetPwid(uint64_t* aPwid)
{
*aPwid = mPwid;
return NS_OK;
};
NS_IMETHODIMP
PerformanceMetricsData::GetItems(nsIArray** aItems)
{
NS_ENSURE_ARG_POINTER(aItems);
*aItems = nullptr;
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> items =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t len = mItems.Length();
for (uint32_t i = 0; i < len; i++) {
items->AppendElement(mItems[i]);
}
items.forget(aItems);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- 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 nsPerformanceMetrics_h___
#define nsPerformanceMetrics_h___
#include "nsIPerformanceMetrics.h"
class PerformanceMetricsDispatchCategory final : public nsIPerformanceMetricsDispatchCategory
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPERFORMANCEMETRICSDISPATCHCATEGORY
PerformanceMetricsDispatchCategory(uint32_t aCategory, uint32_t aCount);
private:
~PerformanceMetricsDispatchCategory() = default;
uint32_t mCategory;
uint32_t mCount;
};
class PerformanceMetricsData final : public nsIPerformanceMetricsData
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPERFORMANCEMETRICSDATA
PerformanceMetricsData(uint32_t aPid, uint64_t aWid, uint64_t aPwid, const nsCString& aHost,
uint64_t aDuration, bool aWorker, nsIArray* aItems);
private:
~PerformanceMetricsData() = default;
uint32_t mPid;
uint64_t mWid;
uint64_t mPwid;
nsCString mHost;
uint64_t mDuration;
bool mWorker;
nsCOMArray<nsIPerformanceMetricsDispatchCategory> mItems;
};
#endif // end nsPerformanceMetrics_h__

Просмотреть файл

@ -123,6 +123,10 @@ namespace ChromeUtils {
void clearRecentJSDevError();
#endif // NIGHTLY_BUILD
#ifndef RELEASE_OR_BETA
void requestPerformanceMetrics();
#endif
/**
* IF YOU ADD NEW METHODS HERE, MAKE SURE THEY ARE THREAD-SAFE.
*/

Просмотреть файл

@ -43,6 +43,8 @@
#include "mozilla/dom/TabGroup.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/URLClassifierChild.h"
#include "mozilla/dom/WorkerDebugger.h"
#include "mozilla/dom/WorkerDebuggerManager.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/psm/PSMContentListener.h"
@ -78,6 +80,9 @@
#include "imgLoader.h"
#include "GMPServiceChild.h"
#include "NullPrincipal.h"
#include "nsIPerformanceMetrics.h"
#include "nsISimpleEnumerator.h"
#include "nsIWorkerDebuggerManager.h"
#if !defined(XP_WIN)
#include "mozilla/Omnijar.h"
@ -1371,6 +1376,38 @@ ContentChild::GetResultForRenderingInitFailure(base::ProcessId aOtherPid)
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvRequestPerformanceMetrics()
{
#ifndef RELEASE_OR_BETA
// iterate on all WorkerDebugger
RefPtr<WorkerDebuggerManager> wdm = WorkerDebuggerManager::GetOrCreate();
if (NS_WARN_IF(!wdm)) {
return IPC_OK();
}
for (uint32_t index = 0; index < wdm->GetDebuggersLength(); index++) {
WorkerDebugger* debugger = wdm->GetDebuggerAt(index);
MOZ_ASSERT(debugger);
SendAddPerformanceMetrics(debugger->ReportPerformanceInfo());
}
// iterate on all DocGroup
nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
for (const auto& tabChild : tabs) {
TabGroup* tabGroup = tabChild->TabGroup();
for (auto iter = tabGroup->Iter(); !iter.Done(); iter.Next()) {
RefPtr<DocGroup> docGroup = iter.Get()->mDocGroup;
SendAddPerformanceMetrics(docGroup->ReportPerformanceInfo());
}
}
return IPC_OK();
#endif
#ifdef RELEASE_OR_BETA
return IPC_OK();
#endif
}
mozilla::ipc::IPCResult
ContentChild::RecvInitRendering(Endpoint<PCompositorManagerChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,

Просмотреть файл

@ -189,6 +189,9 @@ public:
Endpoint<PVideoDecoderManagerChild>&& aVideoManager,
nsTArray<uint32_t>&& namespaces) override;
mozilla::ipc::IPCResult
RecvRequestPerformanceMetrics() override;
mozilla::ipc::IPCResult
RecvReinitRendering(
Endpoint<PCompositorManagerChild>&& aCompositor,

Просмотреть файл

@ -192,6 +192,7 @@
#include "nsHostObjectProtocolHandler.h"
#include "nsICaptivePortalService.h"
#include "nsIObjectLoadingContent.h"
#include "nsPerformanceMetrics.h"
#include "nsIBidiKeyboard.h"
@ -3329,6 +3330,44 @@ ContentParent::RecvFinishMemoryReport(const uint32_t& aGeneration)
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvAddPerformanceMetrics(const PerformanceInfo& aMetrics)
{
#ifndef RELEASE_OR_BETA
// converting the data we get from a child as a notification
if (aMetrics.items().IsEmpty()) {
return IPC_OK();
}
nsCOMPtr<nsIMutableArray> xpItems = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (NS_WARN_IF(!xpItems)) {
return IPC_FAIL_NO_REASON(this);
}
for (uint32_t i = 0; i<aMetrics.items().Length(); i++) {
const CategoryDispatch& entry = aMetrics.items()[i];
nsCOMPtr<nsIPerformanceMetricsDispatchCategory> item =
new PerformanceMetricsDispatchCategory(entry.category(),
entry.count());
xpItems->AppendElement(item);
}
nsCOMPtr<nsIPerformanceMetricsData> data =
new PerformanceMetricsData(aMetrics.pid(), aMetrics.wid(), aMetrics.pwid(),
aMetrics.host(), aMetrics.duration(),
aMetrics.worker(), xpItems);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
return IPC_FAIL_NO_REASON(this);
}
obs->NotifyObservers(data, "performance-metrics", nullptr);
return IPC_OK();
#endif
#ifdef RELEASE_OR_BETA
return IPC_OK();
#endif
}
PCycleCollectWithLogsParent*
ContentParent::AllocPCycleCollectWithLogsParent(const bool& aDumpAllTraces,
const FileDescriptor& aGCLog,

Просмотреть файл

@ -848,6 +848,7 @@ private:
mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport) override;
mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration) override;
mozilla::ipc::IPCResult RecvAddPerformanceMetrics(const PerformanceInfo& aMetrics) override;
virtual bool
DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override;

Просмотреть файл

@ -124,5 +124,43 @@ struct CreatedWindowInfo
DimensionInfo dimensions;
};
/**
* PerformanceInfo is used to pass performance info stored
* in WorkerPrivate & DocGroup instances
*
* Each (host, pid, wid, pwid) is unique to a given DocGroup or
* Worker, and we collect the number of dispatches per Dispatch
* category and total execution duration.
*
* This IPDL struct reflects the data collected in Performance counters.
* see xpcom/threads/PerformanceCounter.h
*/
struct CategoryDispatch
{
// DispatchCategory value
uint16_t category;
// Number of dispatch
uint16_t count;
};
struct PerformanceInfo
{
// Host of the document, if any
nsCString host;
// process id
uint16_t pid;
// window id
uint64_t wid;
// "parent" window id
uint64_t pwid;
// Execution time in microseconds
uint64_t duration;
// True if the data is collected in a worker
bool worker;
// Counters per category. For workers, a single entry
CategoryDispatch[] items;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -400,6 +400,7 @@ child:
bool anonymize,
bool minimizeMemoryUsage,
MaybeFileDesc DMDFile);
async RequestPerformanceMetrics();
/**
* Communication between the PuppetBidiKeyboard and the actual
@ -1133,6 +1134,8 @@ parent:
async MaybeReloadPlugins();
async BHRThreadHang(HangDetails aHangDetails);
async AddPerformanceMetrics(PerformanceInfo aMetrics);
both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData);

Просмотреть файл

@ -72,3 +72,4 @@ support-files =
test_noopener_source.html
test_noopener_target.html
[browser_noopener_null_uri.js]
[browser_test_performance_metrics.js]

Просмотреть файл

@ -0,0 +1,55 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=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/. */
const TEST_URL = "http://example.com/browser/dom/tests/browser/dummy.html";
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
add_task(async function test() {
if (!AppConstants.RELEASE_OR_BETA) {
SpecialPowers.setBoolPref('dom.performance.enable_scheduler_timing', true);
waitForExplicitFinish();
await BrowserTestUtils.withNewTab({ gBrowser, url: "http://example.com" },
async function(browser) {
// grab events..
var events = [];
function getInfoFromService(subject, topic, value) {
subject = subject.QueryInterface(Ci.nsIPerformanceMetricsData);
if (subject.host == "example.com") {
events.push(subject);
}
}
Services.obs.addObserver(getInfoFromService, "performance-metrics");
// trigger an IPDL call
ChromeUtils.requestPerformanceMetrics();
// wait until we get the events back
await BrowserTestUtils.waitForCondition(() => {
return events.length > 0;
}, "wait for events to come in", 100, 20);
// let's check the last example.com tab event we got
let last = events[0];
Assert.equal(last.host, "example.com", "host should be example.com");
Assert.ok(last.duration > 0, "Duration should be positive");
// let's look at the XPCOM data we got back
let items = last.items.QueryInterface(Ci.nsIMutableArray);
let enumerator = items.enumerate();
let total = 0;
while (enumerator.hasMoreElements()) {
let item = enumerator.getNext();
item = item.QueryInterface(Ci.nsIPerformanceMetricsDispatchCategory);
total += item.count;
}
Assert.ok(total > 0);
});
SpecialPowers.clearUserPref('dom.performance.enable_scheduler_timing');
}
});

Просмотреть файл

@ -17,6 +17,11 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "WorkerScope.h"
#if defined(XP_WIN)
#include <processthreadsapi.h> // for GetCurrentProcessId()
#else
#include <unistd.h> // for getpid()
#endif // defined(XP_WIN)
namespace mozilla {
namespace dom {
@ -471,6 +476,44 @@ WorkerDebugger::ReportErrorToDebuggerOnMainThread(const nsAString& aFilename,
WorkerErrorReport::LogErrorToConsole(report, 0);
}
#ifndef RELEASE_OR_BETA
PerformanceInfo
WorkerDebugger::ReportPerformanceInfo()
{
AssertIsOnMainThread();
#if defined(XP_WIN)
uint32_t pid = GetCurrentProcessId();
#else
uint32_t pid = getpid();
#endif
uint64_t wid = mWorkerPrivate->WindowID();
uint64_t pwid = wid;
nsPIDOMWindowInner* win = mWorkerPrivate->GetWindow();
if (win) {
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
if (outer) {
nsCOMPtr<nsPIDOMWindowOuter> top = outer->GetTop();
if (top) {
pwid = top->WindowID();
}
}
}
RefPtr<PerformanceCounter> perf = mWorkerPrivate->GetPerformanceCounter();
uint16_t count = perf->GetTotalDispatchCount();
uint64_t duration = perf->GetExecutionDuration();
RefPtr<nsIURI> uri = mWorkerPrivate->GetResolvedScriptURI();
CategoryDispatch item = CategoryDispatch(DispatchCategory::Worker.GetValue(), count);
FallibleTArray<CategoryDispatch> items;
if (!items.AppendElement(item, fallible)) {
NS_ERROR("Could not complete the operation");
return PerformanceInfo(uri->GetSpecOrDefault(), pid, wid, pwid, duration,
true, items);
}
perf->ResetPerformanceCounters();
return PerformanceInfo(uri->GetSpecOrDefault(), pid, wid, pwid, duration,
true, items);
}
#endif
} // dom namespace
} // mozilla namespace

Просмотреть файл

@ -7,6 +7,7 @@
#ifndef mozilla_dom_workers_WorkerDebugger_h
#define mozilla_dom_workers_WorkerDebugger_h
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/WorkerCommon.h"
#include "nsIWorkerDebugger.h"
@ -43,6 +44,15 @@ public:
ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
const nsAString& aMessage);
#ifndef RELEASE_OR_BETA
/*
* Sends back a PerformanceInfo struct from the counters
* in mWorkerPrivate. Counters are reset to zero after this call.
*/
PerformanceInfo
ReportPerformanceInfo();
#endif
private:
virtual
~WorkerDebugger();

Просмотреть файл

@ -361,5 +361,17 @@ WorkerDebuggerManager::UnregisterDebuggerMainThread(
aWorkerPrivate->SetIsDebuggerRegistered(false);
}
uint32_t
WorkerDebuggerManager::GetDebuggersLength() const
{
return mDebuggers.Length();
}
WorkerDebugger*
WorkerDebuggerManager::GetDebuggerAt(uint32_t aIndex) const
{
return mDebuggers.SafeElementAt(aIndex, nullptr);
}
} // dom namespace
} // mozilla namespace

Просмотреть файл

@ -74,6 +74,12 @@ public:
void
UnregisterDebuggerMainThread(WorkerPrivate* aWorkerPrivate);
uint32_t
GetDebuggersLength() const;
WorkerDebugger*
GetDebuggerAt(uint32_t aIndex) const;
private:
virtual ~WorkerDebuggerManager();
};