Bug 1474253 - Improve ReportPerformanceInfo() - r=baku

- modifies how we get the top window id, adds isTopLevel
- renames pwid to windowId, worker to isWorker
- removes the wid field
- uses the url in case the host is empty

It also fixes PerformanceInfoDictionary.host type

MozReview-Commit-ID: 4AzO3UnJ2LM

--HG--
extra : rebase_source : 5dee8a650064fd45e7a9e694c2593d517f74d766
This commit is contained in:
Tarek Ziadé 2018-07-10 09:58:48 +02:00
parent d20ffc41ac
commit 47344f4b4a
7 changed files with 74 additions and 56 deletions

View File

@ -78,36 +78,41 @@ DocGroup::ReportPerformanceInfo()
#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");
bool isTopLevel = false;
nsCString host;
// iterating on documents until we find the top window
for (const auto& document : *this) {
// grabbing the host name of the first document
nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
MOZ_ASSERT(doc);
// looking for the top level document URI
nsPIDOMWindowInner* win = doc->GetInnerWindow();
if (!win) {
continue;
}
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
if (!outer) {
continue;
}
nsCOMPtr<nsPIDOMWindowOuter> top = outer->GetTop();
if (!top) {
continue;
}
nsCOMPtr<nsIURI> docURI = doc->GetDocumentURI();
if (!docURI) {
continue;
}
pwid = top->WindowID();
isTopLevel = top->IsTopLevelWindow();;
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();
}
}
// If the host is empty, using the url
if (host.IsEmpty()) {
docURI->GetSpec(host);
}
break;
}
duration = mPerformanceCounter->GetExecutionDuration();
@ -120,13 +125,13 @@ DocGroup::ReportPerformanceInfo()
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);
return PerformanceInfo(host, pid, pwid, duration, false, isTopLevel, items);
}
}
// setting back all counters to zero
mPerformanceCounter->ResetPerformanceCounters();
return PerformanceInfo(host, pid, wid, pwid, duration, false, items);
return PerformanceInfo(host, pid, pwid, duration, false, isTopLevel, items);
}
nsresult

View File

@ -368,12 +368,12 @@ dictionary CategoryDispatchDictionary
};
dictionary PerformanceInfoDictionary {
DOMString host = "";
ByteString host = "";
unsigned long pid = 0;
unsigned long long wid = 0;
unsigned long long pwid = 0;
unsigned long long windowId = 0;
unsigned long long duration = 0;
boolean worker = false;
boolean isWorker = false;
boolean isTopLevel = false;
sequence<CategoryDispatchDictionary> items = [];
};

View File

@ -132,7 +132,7 @@ struct CreatedWindowInfo
* PerformanceInfo is used to pass performance info stored
* in WorkerPrivate & DocGroup instances
*
* Each (host, pid, wid, pwid) is unique to a given DocGroup or
* Each (host, pid, windowId) is unique to a given DocGroup or
* Worker, and we collect the number of dispatches per Dispatch
* category and total execution duration.
*
@ -154,13 +154,13 @@ struct PerformanceInfo
// process id
uint32_t pid;
// window id
uint64_t wid;
// "parent" window id
uint64_t pwid;
uint64_t windowId;
// Execution time in microseconds
uint64_t duration;
// True if the data is collected in a worker
bool worker;
bool isWorker;
// True if the document window is the top window
bool isTopLevel;
// Counters per category. For workers, a single entry
CategoryDispatch[] items;
};

View File

@ -56,33 +56,40 @@ add_task(async function test() {
gBrowser, opening: "about:performance", forceNewProcess: true
});
let parent_process_event = false;
let worker_event = false;
// load a 4th tab with a worker
await BrowserTestUtils.withNewTab({ gBrowser, url: WORKER_URL },
async function(browser) {
// grab events..
let worker_duration = 0;
let worker_total = 0;
let workerDuration = 0;
let workerTotal = 0;
let duration = 0;
let total = 0;
let isTopLevel = false;
let aboutMemoryFound = false;
let parentProcessEvent = false;
let workerEvent = false;
function exploreResults(data) {
for (let entry of data) {
if (entry.pid == Services.appinfo.processID) {
parent_process_event = true;
if (entry.host == "example.com" && entry.isTopLevel) {
isTopLevel = true;
}
if (entry.worker) {
worker_event = true;
worker_duration += entry.duration;
if (entry.host == "about:memory") {
aboutMemoryFound = true;
}
if (entry.pid == Services.appinfo.processID) {
parentProcessEvent = true;
}
if (entry.isWorker) {
workerEvent = true;
workerDuration += entry.duration;
} else {
duration += entry.duration;
}
// let's look at the data we got back
for (let item of entry.items) {
if (entry.worker) {
worker_total += item.count;
if (entry.isWorker) {
workerTotal += item.count;
} else {
total += item.count;
}
@ -94,11 +101,13 @@ add_task(async function test() {
let results = await ChromeUtils.requestPerformanceMetrics();
exploreResults(results);
Assert.ok(worker_duration > 0, "Worker duration should be positive");
Assert.ok(worker_total > 0, "Worker count should be positive");
Assert.ok(workerDuration > 0, "Worker duration should be positive");
Assert.ok(workerTotal > 0, "Worker count should be positive");
Assert.ok(duration > 0, "Duration should be positive");
Assert.ok(total > 0, "Should get a positive count");
Assert.ok(parent_process_event, "parent process sent back some events");
Assert.ok(parentProcessEvent, "parent process sent back some events");
Assert.ok(isTopLevel, "example.com as a top level window");
Assert.ok(aboutMemoryFound, "about:memory");
});
BrowserTestUtils.removeTab(page1);

View File

@ -484,8 +484,8 @@ WorkerDebugger::ReportPerformanceInfo()
#else
uint32_t pid = getpid();
#endif
uint64_t wid = mWorkerPrivate->WindowID();
uint64_t pwid = wid;
bool isTopLevel= false;
uint64_t pwid = 0;
nsPIDOMWindowInner* win = mWorkerPrivate->GetWindow();
if (win) {
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
@ -493,6 +493,7 @@ WorkerDebugger::ReportPerformanceInfo()
nsCOMPtr<nsPIDOMWindowOuter> top = outer->GetTop();
if (top) {
pwid = top->WindowID();
isTopLevel = pwid == mWorkerPrivate->WindowID();
}
}
}
@ -513,14 +514,14 @@ WorkerDebugger::ReportPerformanceInfo()
CategoryDispatch item = CategoryDispatch(DispatchCategory::Worker.GetValue(), count);
if (!items.AppendElement(item, fallible)) {
NS_ERROR("Could not complete the operation");
return PerformanceInfo(uri->GetSpecOrDefault(), pid, wid, pwid, duration,
true, items);
return PerformanceInfo(uri->GetSpecOrDefault(), pid, pwid, duration,
true, isTopLevel, items);
}
perf->ResetPerformanceCounters();
}
return PerformanceInfo(uri->GetSpecOrDefault(), pid, wid, pwid, duration,
true, items);
return PerformanceInfo(uri->GetSpecOrDefault(), pid, pwid, duration,
true, isTopLevel, items);
}
} // dom namespace

View File

@ -78,11 +78,11 @@ AggregatedResults::AppendResult(const nsTArray<dom::PerformanceInfo>& aMetrics)
return;
}
data->mPid = result.pid();
data->mWid = result.wid();
data->mPwid = result.pwid();
data->mHost = *result.host().get();
data->mWindowId = result.windowId();
data->mHost.Assign(result.host());
data->mDuration = result.pid();
data->mWorker = result.worker();
data->mIsWorker = result.isWorker();
data->mIsTopLevel = result.isTopLevel();
data->mItems = items;
}

View File

@ -19,9 +19,12 @@ namespace mozilla {
void
CollectPerformanceInfo(nsTArray<PerformanceInfo>& aMetrics)
{
// collecting ReportPerformanceInfo from all DocGroup instances
for (const auto& tabChild : TabChild::GetAll()) {
TabGroup* tabGroup = tabChild->TabGroup();
// collecting ReportPerformanceInfo from all DocGroup instances
LinkedList<TabGroup>* tabGroups = TabGroup::GetTabGroupList();
for (TabGroup* tabGroup = tabGroups->getFirst(); tabGroup;
tabGroup =
static_cast<LinkedListElement<TabGroup>*>(tabGroup)->getNext()) {
for (auto iter = tabGroup->Iter(); !iter.Done(); iter.Next()) {
DocGroup* docGroup = iter.Get()->mDocGroup;
aMetrics.AppendElement(docGroup->ReportPerformanceInfo());