зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1646505 - Fix about:performance for Fission. r=tarek
With fission it's not possible to use nsPIDOMWindowOuter::GetInProcessTop and expect to find the top-level window, since it might be in another process. Instead we use BrowsingContext::Top. Another issue is that it's not possible to traverse children by recursively calling GetTabSizes, instead we need to use BrowsingContext traversal mechanics. Memory reporting is a bit tricky, since now doc gropus belonging to a cross process top level browsing context needs to report it's memory usage and can't skip it, so this is also handled. Differential Revision: https://phabricator.services.mozilla.com/D97312
This commit is contained in:
Родитель
cbf9cc6b39
Коммит
1b5787e10a
|
@ -12,9 +12,11 @@
|
|||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ThrottledEventQueue.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/CustomElementRegistry.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/JSExecutionManager.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "nsIDirectTaskDispatcher.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
@ -220,38 +222,35 @@ RefPtr<PerformanceInfoPromise> DocGroup::ReportPerformanceInfo() {
|
|||
uint64_t windowID = 0;
|
||||
uint16_t count = 0;
|
||||
uint64_t duration = 0;
|
||||
bool isTopLevel = false;
|
||||
nsCString host;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> top;
|
||||
RefPtr<AbstractThread> mainThread;
|
||||
bool isTopLevel = false;
|
||||
RefPtr<BrowsingContext> top;
|
||||
RefPtr<AbstractThread> mainThread =
|
||||
AbstractMainThreadFor(TaskCategory::Performance);
|
||||
|
||||
// iterating on documents until we find the top window
|
||||
for (const auto& document : *this) {
|
||||
nsCOMPtr<Document> doc = document;
|
||||
MOZ_ASSERT(doc);
|
||||
nsCOMPtr<nsIURI> docURI = doc->GetDocumentURI();
|
||||
if (!docURI) {
|
||||
continue;
|
||||
}
|
||||
docURI->GetHost(host);
|
||||
// If the host is empty, using the url
|
||||
if (host.IsEmpty()) {
|
||||
host = docURI->GetSpecOrDefault();
|
||||
nsCOMPtr<nsIURI> docURI = document->GetDocumentURI();
|
||||
if (!docURI) {
|
||||
continue;
|
||||
}
|
||||
|
||||
docURI->GetHost(host);
|
||||
if (host.IsEmpty()) {
|
||||
host = docURI->GetSpecOrDefault();
|
||||
}
|
||||
}
|
||||
// looking for the top level document URI
|
||||
nsPIDOMWindowOuter* win = doc->GetWindow();
|
||||
if (!win) {
|
||||
|
||||
BrowsingContext* context = document->GetBrowsingContext();
|
||||
if (!context) {
|
||||
continue;
|
||||
}
|
||||
top = win->GetInProcessTop();
|
||||
if (!top) {
|
||||
continue;
|
||||
}
|
||||
windowID = top->WindowID();
|
||||
isTopLevel = win->GetBrowsingContext()->IsTop();
|
||||
mainThread = AbstractMainThreadFor(TaskCategory::Performance);
|
||||
|
||||
top = context->Top();
|
||||
isTopLevel = context->IsTop();
|
||||
windowID = top->GetCurrentWindowContext()->OuterWindowId();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
MOZ_ASSERT(!host.IsEmpty());
|
||||
duration = mPerformanceCounter->GetExecutionDuration();
|
||||
|
@ -268,7 +267,7 @@ RefPtr<PerformanceInfoPromise> DocGroup::ReportPerformanceInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
if (!isTopLevel) {
|
||||
if (!isTopLevel && top && top->IsInProcess()) {
|
||||
return PerformanceInfoPromise::CreateAndResolve(
|
||||
PerformanceInfo(host, pid, windowID, duration,
|
||||
mPerformanceCounter->GetID(), false, isTopLevel,
|
||||
|
@ -279,8 +278,8 @@ RefPtr<PerformanceInfoPromise> DocGroup::ReportPerformanceInfo() {
|
|||
|
||||
MOZ_ASSERT(mainThread);
|
||||
RefPtr<DocGroup> self = this;
|
||||
|
||||
return CollectMemoryInfo(top, mainThread)
|
||||
return (isTopLevel ? CollectMemoryInfo(top, mainThread)
|
||||
: CollectMemoryInfo(self, mainThread))
|
||||
->Then(
|
||||
mainThread, __func__,
|
||||
[self, host, pid, windowID, duration, isTopLevel,
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
#include "WorkerDebugger.h"
|
||||
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/PerformanceUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
@ -457,7 +459,7 @@ void WorkerDebugger::ReportErrorToDebuggerOnMainThread(
|
|||
|
||||
RefPtr<PerformanceInfoPromise> WorkerDebugger::ReportPerformanceInfo() {
|
||||
AssertIsOnMainThread();
|
||||
nsCOMPtr<nsPIDOMWindowOuter> top;
|
||||
RefPtr<BrowsingContext> top;
|
||||
RefPtr<WorkerDebugger> self = this;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -476,12 +478,12 @@ RefPtr<PerformanceInfoPromise> WorkerDebugger::ReportPerformanceInfo() {
|
|||
}
|
||||
nsPIDOMWindowInner* win = wp->GetWindow();
|
||||
if (win) {
|
||||
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
|
||||
if (outer) {
|
||||
top = outer->GetInProcessTop();
|
||||
BrowsingContext* context = win->GetBrowsingContext();
|
||||
if (context) {
|
||||
top = context->Top();
|
||||
if (top) {
|
||||
windowID = top->WindowID();
|
||||
isTopLevel = outer->GetBrowsingContext()->IsTop();
|
||||
windowID = top->GetCurrentWindowContext()->OuterWindowId();
|
||||
isTopLevel = context->IsTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,37 +82,73 @@ void AddWindowTabSizes(nsGlobalWindowOuter* aWindow, nsTabSizes* aSizes) {
|
|||
aSizes->mOther += sizes.mOther;
|
||||
}
|
||||
|
||||
nsresult GetTabSizes(nsGlobalWindowOuter* aWindow, nsTabSizes* aSizes) {
|
||||
// Add the window (and inner window) sizes. Might be cached.
|
||||
AddWindowTabSizes(aWindow, aSizes);
|
||||
|
||||
BrowsingContext* bc = aWindow->GetBrowsingContext();
|
||||
if (!bc) {
|
||||
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& frame : bc->Children()) {
|
||||
if (auto* childWin = nsGlobalWindowOuter::Cast(frame->GetDOMWindow())) {
|
||||
MOZ_TRY(GetTabSizes(childWin, aSizes));
|
||||
}
|
||||
for (const auto& child : aContext->Children()) {
|
||||
MOZ_TRY(GetTabSizes(child, aSizes));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<MemoryPromise> CollectMemoryInfo(
|
||||
const nsCOMPtr<nsPIDOMWindowOuter>& aWindow,
|
||||
const RefPtr<DocGroup>& aDocGroup,
|
||||
const RefPtr<AbstractThread>& aEventTarget) {
|
||||
// Getting Dom sizes. -- XXX should we reimplement GetTabSizes to async here ?
|
||||
nsGlobalWindowOuter* window = nsGlobalWindowOuter::Cast(aWindow);
|
||||
nsTabSizes sizes;
|
||||
nsresult rv = GetTabSizes(window, &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 = window->GetGlobalJSObject();
|
||||
JSObject* obj = aContext->GetWrapper();
|
||||
uint64_t GCHeapUsage = 0;
|
||||
if (obj != nullptr) {
|
||||
GCHeapUsage = js::GetGCHeapUsageForObjectZone(obj);
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
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.
|
||||
|
@ -22,7 +25,11 @@ nsTArray<RefPtr<PerformanceInfoPromise>> CollectPerformanceInfo();
|
|||
* Asynchronously collects memory info for a given window
|
||||
*/
|
||||
RefPtr<MemoryPromise> CollectMemoryInfo(
|
||||
const nsCOMPtr<nsPIDOMWindowOuter>& aWindow,
|
||||
const RefPtr<dom::BrowsingContext>& aContext,
|
||||
const RefPtr<AbstractThread>& aEventTarget);
|
||||
|
||||
RefPtr<MemoryPromise> CollectMemoryInfo(
|
||||
const RefPtr<dom::DocGroup>& aDocGroup,
|
||||
const RefPtr<AbstractThread>& aEventTarget);
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
Загрузка…
Ссылка в новой задаче