Bug 1569077 - Part 3: Add --capture-profile argument to the layout debugger. r=dbaron

Differential Revision: https://phabricator.services.mozilla.com/D39469

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Cameron McCormack 2019-08-25 23:38:30 +00:00
Родитель 712f284101
Коммит 79a431d339
3 изменённых файлов: 109 добавлений и 20 удалений

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

@ -99,10 +99,12 @@ nsLayoutDebugCLH::Handle(nsICommandLine* aCmdLine) {
nsString url;
bool autoclose = false;
double delay = 0.0;
bool captureProfile = false;
nsString profileFilename;
rv =
HandleFlagWithOptionalArgument(aCmdLine, NS_LITERAL_STRING("layoutdebug"),
EmptyString(), url, flagPresent);
rv = HandleFlagWithOptionalArgument(
aCmdLine, NS_LITERAL_STRING("layoutdebug"),
NS_LITERAL_STRING("about:blank"), url, flagPresent);
NS_ENSURE_SUCCESS(rv, rv);
if (!flagPresent) {
@ -113,21 +115,24 @@ nsLayoutDebugCLH::Handle(nsICommandLine* aCmdLine) {
0.0, delay, autoclose);
NS_ENSURE_SUCCESS(rv, rv);
rv = HandleFlagWithOptionalArgument(
aCmdLine, NS_LITERAL_STRING("capture-profile"),
NS_LITERAL_STRING("profile.json"), profileFilename, captureProfile);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMutableArray> argsArray = nsArray::Create();
if (!url.IsEmpty()) {
nsCOMPtr<nsIURI> uri;
nsAutoCString resolvedSpec;
nsCOMPtr<nsIURI> uri;
nsAutoCString resolvedSpec;
rv = aCmdLine->ResolveURI(url, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
rv = aCmdLine->ResolveURI(url, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
rv = uri->GetSpec(resolvedSpec);
NS_ENSURE_SUCCESS(rv, rv);
rv = uri->GetSpec(resolvedSpec);
NS_ENSURE_SUCCESS(rv, rv);
rv = AppendArg(argsArray, NS_ConvertUTF8toUTF16(resolvedSpec));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = AppendArg(argsArray, NS_ConvertUTF8toUTF16(resolvedSpec));
NS_ENSURE_SUCCESS(rv, rv);
if (autoclose) {
nsString arg;
@ -137,6 +142,15 @@ nsLayoutDebugCLH::Handle(nsICommandLine* aCmdLine) {
NS_ENSURE_SUCCESS(rv, rv);
}
if (captureProfile) {
nsString arg;
arg.AppendLiteral("profile=");
arg.Append(profileFilename);
rv = AppendArg(argsArray, arg);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIWindowWatcher> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID);
NS_ENSURE_TRUE(wwatch, NS_ERROR_FAILURE);
@ -154,6 +168,10 @@ nsLayoutDebugCLH::GetHelpInfo(nsACString& aResult) {
" --layoutdebug [<url>] Start with Layout Debugger\n"
" --autoclose [<seconds>] Automatically close the Layout Debugger once\n"
" the page has loaded, after delaying the specified\n"
" number of seconds (which defaults to 0).\n");
" number of seconds (which defaults to 0).\n"
" --capture-profile [<filename>] Capture a profile of the Layout\n"
" Debugger using the Gecko Profiler, and save the\n"
" profile to the specified file (which defaults to\n"
" profile.json).\n");
return NS_OK;
}

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

@ -10,10 +10,13 @@ var gMultiProcessBrowser = window.docShell.QueryInterface(Ci.nsILoadContext)
.useRemoteTabs;
var gFissionBrowser = window.docShell.QueryInterface(Ci.nsILoadContext)
.useRemoteSubframes;
var gWritingProfile = false;
var gWrittenProfile = false;
const { E10SUtils } = ChromeUtils.import(
"resource://gre/modules/E10SUtils.jsm"
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { Preferences } = ChromeUtils.import(
"resource://gre/modules/Preferences.jsm"
);
@ -177,10 +180,13 @@ nsLDBBrowserContentListener.prototype = {
// This does mean that --autoclose doesn't work when the URL on
// the command line is about:blank (or not specified), but that's
// not a big deal.
setTimeout(
() => Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit),
gArgs.delay * 1000
);
setTimeout(function() {
if (gArgs.profile && Services.profiler) {
dumpProfile();
} else {
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
}
}, gArgs.delay * 1000);
}
}
},
@ -234,11 +240,15 @@ function parseArguments() {
if (window.arguments) {
args.url = window.arguments[0];
for (let i = 1; i < window.arguments.length; ++i) {
if (/^autoclose=(.*)$/.test(window.arguments[i])) {
let arg = window.arguments[i];
if (/^autoclose=(.*)$/.test(arg)) {
args.autoclose = true;
args.delay = +RegExp.$1;
} else if (/^profile=(.*)$/.test(arg)) {
args.profile = true;
args.profileFilename = RegExp.$1;
} else {
throw `Unknown option ${window.arguments[i]}`;
throw `Unknown option ${arg}`;
}
}
}
@ -262,6 +272,29 @@ function OnLDBLoad() {
};
gArgs = parseArguments();
if (gArgs.profile) {
if (Services.profiler) {
let env = Cc["@mozilla.org/process/environment;1"].getService(
Ci.nsIEnvironment
);
if (!env.exists("MOZ_PROFILER_SYMBOLICATE")) {
dump(
"Warning: MOZ_PROFILER_SYMBOLICATE environment variable not set; " +
"profile will not be symbolicated.\n"
);
}
Services.profiler.StartProfiler(
1 << 20,
1,
["default"],
["GeckoMain", "Compositor", "Renderer", "RenderBackend", "StyleThread"]
);
} else {
dump("Cannot profile Layout Debugger; profiler was not compiled in.\n");
}
}
if (gArgs.url) {
loadURI(gArgs.url);
}
@ -283,6 +316,43 @@ function checkPersistentMenus() {
checkPersistentMenu("reflowCounts");
}
function dumpProfile() {
gWritingProfile = true;
let cwd = Services.dirsvc.get("CurWorkD", Ci.nsIFile).path;
let filename = OS.Path.join(cwd, gArgs.profileFilename);
dump(`Writing profile to ${filename}...\n`);
Services.profiler.dumpProfileToFileAsync(filename).then(function() {
gWritingProfile = false;
gWrittenProfile = true;
dump(`done\n`);
Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
});
}
function OnLDBBeforeUnload(event) {
if (gArgs.profile && Services.profiler) {
if (gWrittenProfile) {
// We've finished writing the profile. Allow the window to close.
return;
}
event.preventDefault();
if (gWritingProfile) {
// Wait for the profile to finish being written out.
return;
}
// The dumpProfileToFileAsync call can block for a while, so run it off a
// timeout to avoid annoying the window manager if we're doing this in
// response to clicking the window's close button.
setTimeout(dumpProfile, 0);
}
}
function OnLDBUnload() {
gDebugger.detachBrowser();
}

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

@ -28,6 +28,7 @@
titlemenuseparator=" - "
windowtype="mozapp:layoutdebug"
onload="OnLDBLoad();"
onclose="OnLDBBeforeUnload(event);"
onunload="OnLDBUnload();"
width="1024" height="768"
screenX="4" screenY="4"