author | Jed Davis <jld@mozilla.com> |
Tue, 06 Jul 2021 07:42:42 +0000 | |
changeset 584823 | c49de061c1fab19f934574e959938c5500d1d080 |
parent 584822 | c1bd0996764c49174c9169fe5550905ce5dcef88 |
child 584824 | 476ff480c877b7d396fef6e41ba91288d6050f50 |
push id | 38588 |
push user | apavel@mozilla.com |
push date | Tue, 06 Jul 2021 21:42:42 +0000 |
treeherder | mozilla-central@5b4463c3dc93 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jgilbert, stransky, nika |
bugs | 1635451 |
milestone | 91.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -274,16 +274,17 @@ #ifdef MOZ_WIDGET_ANDROID # include "AndroidBridge.h" # include "mozilla/java/GeckoProcessManagerWrappers.h" # include "mozilla/java/GeckoProcessTypeWrappers.h" #endif #ifdef MOZ_WIDGET_GTK # include <gdk/gdk.h> +# include "mozilla/WidgetUtilsGtk.h" #endif #include "mozilla/RemoteSpellCheckEngineParent.h" #include "Crypto.h" #ifdef MOZ_WEBSPEECH # include "mozilla/dom/SpeechSynthesisParent.h" @@ -2540,16 +2541,25 @@ bool ContentParent::BeginSubprocessLaunc mSubprocess->DisableOSActivityMode(); } #endif nsCString parentBuildID(mozilla::PlatformBuildID()); extraArgs.push_back("-parentBuildID"); extraArgs.push_back(parentBuildID.get()); +#ifdef MOZ_WIDGET_GTK + // This is X11-only pending a solution for WebGL in Wayland mode. + if (StaticPrefs::dom_ipc_avoid_gtk() && + StaticPrefs::widget_non_native_theme_enabled() && + widget::GdkIsX11Display()) { + mSubprocess->SetEnv("MOZ_HEADLESS", "1"); + } +#endif + // See also ActorDealloc. mSelfRef = this; mLaunchYieldTS = TimeStamp::Now(); return mSubprocess->AsyncLaunch(std::move(extraArgs)); } void ContentParent::LaunchSubprocessReject() { NS_ERROR("failed to launch child in the parent");
--- a/dom/ipc/tests/browser.ini +++ b/dom/ipc/tests/browser.ini @@ -32,8 +32,11 @@ skip-if = !e10s support-files = file_dummy.html skip-if = !e10s [browser_bug1686194.js] support-files = file_dummy.html [browser_gc_schedule.js] skip-if = verify fission && os == "linux" && asan # Bug 1713905 - new Fission platform triage +[browser_very_fission.js] +support-files = file_dummy.html +run-if = widget == "gtk"
new file mode 100644 --- /dev/null +++ b/dom/ipc/tests/browser_very_fission.js @@ -0,0 +1,38 @@ +/* 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/. */ + +"use strict"; + +// This test creates a large number of content processes as a +// regression test for bug 1635451. + +const TEST_PAGE = + "http://mochi.test:8888/browser/dom/ipc/tests/file_dummy.html"; + +const NUM_TABS = 256; + +add_task(async () => { + let promises = []; + for (let i = 0; i < NUM_TABS; ++i) { + promises.push( + BrowserTestUtils.openNewForegroundTab({ + gBrowser, + opening: TEST_PAGE, + waitForLoad: true, + forceNewProcess: true, + }) + ); + } + + let tabs = []; + for (const p of promises) { + tabs.push(await p); + } + + ok(true, "All of the tabs loaded"); + + for (const t of tabs) { + BrowserTestUtils.removeTab(t); + } +});
--- a/gfx/gl/GLContextProviderWayland.cpp +++ b/gfx/gl/GLContextProviderWayland.cpp @@ -12,49 +12,59 @@ namespace mozilla::gl { using namespace mozilla::gfx; using namespace mozilla::widget; static class GLContextProviderX11 sGLContextProviderX11; static class GLContextProviderEGL sGLContextProviderEGL; +// Note that if there is no GTK display, `GdkIsX11Display` and +// `GdkIsWaylandDisplay` will both return false. That case can +// currently happen only in X11 mode if the pref `dom.ipc.avoid-gtk` +// is set (and applicable to this process). Thus, these conditionals +// check for the presence of Wayland rather than the absence of X11. +// +// In the future we'll want `dom.ipc.avoid-gtk` to also apply to +// Wayland; at that time we'll need another way to communicate the +// choice of window system. + already_AddRefed<GLContext> GLContextProviderWayland::CreateForCompositorWidget( CompositorWidget* aCompositorWidget, bool aHardwareWebRender, bool aForceAccelerated) { - if (GdkIsX11Display()) { - return sGLContextProviderX11.CreateForCompositorWidget( + if (GdkIsWaylandDisplay()) { + return sGLContextProviderEGL.CreateForCompositorWidget( aCompositorWidget, aHardwareWebRender, aForceAccelerated); } else { - return sGLContextProviderEGL.CreateForCompositorWidget( + return sGLContextProviderX11.CreateForCompositorWidget( aCompositorWidget, aHardwareWebRender, aForceAccelerated); } } /*static*/ already_AddRefed<GLContext> GLContextProviderWayland::CreateHeadless( const GLContextCreateDesc& desc, nsACString* const out_failureId) { - if (GdkIsX11Display()) { + if (GdkIsWaylandDisplay()) { + return sGLContextProviderEGL.CreateHeadless(desc, out_failureId); + } else { return sGLContextProviderX11.CreateHeadless(desc, out_failureId); - } else { - return sGLContextProviderEGL.CreateHeadless(desc, out_failureId); } } /*static*/ GLContext* GLContextProviderWayland::GetGlobalContext() { - if (GdkIsX11Display()) { + if (GdkIsWaylandDisplay()) { + return sGLContextProviderEGL.GetGlobalContext(); + } else { return sGLContextProviderX11.GetGlobalContext(); - } else { - return sGLContextProviderEGL.GetGlobalContext(); } } /*static*/ void GLContextProviderWayland::Shutdown() { - if (GdkIsX11Display()) { + if (GdkIsWaylandDisplay()) { + sGLContextProviderEGL.Shutdown(); + } else { sGLContextProviderX11.Shutdown(); - } else { - sGLContextProviderEGL.Shutdown(); } } } // namespace mozilla::gl
--- a/image/decoders/icon/gtk/nsIconChannel.cpp +++ b/image/decoders/icon/gtk/nsIconChannel.cpp @@ -10,18 +10,16 @@ #include "mozilla/DebugOnly.h" #include "mozilla/EndianUtils.h" #include "mozilla/NullPrincipal.h" #include "mozilla/CheckedInt.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/gfx/Swizzle.h" #include "mozilla/ipc/ByteBuf.h" -#include "mozilla/Preferences.h" -#include "mozilla/StaticPrefs_dom.h" #include <algorithm> #include <gio/gio.h> #include <gtk/gtk.h> #include "nsMimeTypes.h" #include "nsIMIMEService.h" @@ -402,18 +400,17 @@ nsresult nsIconChannel::GetIcon(nsIURI* return rv; } nsresult nsIconChannel::Init(nsIURI* aURI) { nsresult rv; nsCOMPtr<nsIInputStream> stream; using ContentChild = mozilla::dom::ContentChild; - auto* contentChild = ContentChild::GetSingleton(); - if (contentChild && mozilla::StaticPrefs::dom_ipc_remote_mozIcon()) { + if (auto* contentChild = ContentChild::GetSingleton()) { // Get the icon via IPC and translate the promise of a ByteBuf // into an actually-existing channel. RefPtr<ContentChild::GetSystemIconPromise> icon = contentChild->SendGetSystemIcon(aURI); if (!icon) { return NS_ERROR_UNEXPECTED; }
--- a/image/test/browser/browser_mozicon_file.js +++ b/image/test/browser/browser_mozicon_file.js @@ -1,24 +1,12 @@ /* 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/. */ "use strict"; add_task(async function test_mozicon_file_no_sandbox() { assertFileProcess(); - assertMozIconIsRemote(); await createMozIconInFile("txt"); await createMozIconInFile("exe"); await createMozIconInFile("non-existent-bidule"); }); - -add_task(async function test_mozicon_file_no_sandbox_no_remote() { - await SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.remote-mozIcon", false]], - }); - assertFileProcess(); - assertMozIconIsNotRemote(); - await createMozIconInFile("txt"); - await createMozIconInFile("exe"); - await createMozIconInFile("non-existent-bidule"); -});
--- a/image/test/browser/browser_mozicon_file_sandbox_headless.js +++ b/image/test/browser/browser_mozicon_file_sandbox_headless.js @@ -6,22 +6,8 @@ add_task(async function test_mozicon_file_with_sandbox() { assertFileProcess(); assertSandboxHeadless(); await createMozIconInFile("txt"); await createMozIconInFile("exe"); await createMozIconInFile("non-existent-bidule"); }); - -// https://bugzilla.mozilla.org/show_bug.cgi?id=1695381#c0 -// with sandbox and no remote enabled, this is expected to fail -add_task(async function test_mozicon_file_with_sandbox_no_remote() { - await SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.remote-mozIcon", false]], - }); - assertFileProcess(); - assertSandboxHeadless(); - assertMozIconIsNotRemote(); - await createMozIconInFile("txt", false); - await createMozIconInFile("exe", false); - await createMozIconInFile("non-existent-bidule", false); -});
--- a/image/test/browser/browser_sandbox_headless.ini +++ b/image/test/browser/browser_sandbox_headless.ini @@ -1,12 +1,8 @@ [DEFAULT] support-files = head.js prefs = security.sandbox.content.headless=true -skip-if = - (os != 'linux') # the pref is only used on linux - tsan # timeout on test_mozicon_file_with_sandbox_no_remote - asan # timeout on test_mozicon_file_with_sandbox_no_remote - ccov # timeout on test_mozicon_file_with_sandbox_no_remote +skip-if = (os != 'linux') # the pref is only used on linux [browser_mozicon_file_sandbox_headless.js]
--- a/image/test/browser/head.js +++ b/image/test/browser/head.js @@ -37,24 +37,16 @@ function assertFileProcess() { // Ensure that the file content process is enabled. assertPrefVal("browser.tabs.remote.separateFileUriProcess", true); } function assertSandboxHeadless() { assertPrefVal("security.sandbox.content.headless", true); } -function assertMozIconIsRemote() { - assertPrefVal("dom.ipc.remote-mozIcon", true); -} - -function assertMozIconIsNotRemote() { - assertPrefVal("dom.ipc.remote-mozIcon", false); -} - function getPage() { let filePage = undefined; const { Services } = ChromeUtils.import( "resource://gre/modules/Services.jsm" ); switch (Services.appinfo.OS) { case "WINNT": filePage = "file:///C:/";
--- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -598,16 +598,23 @@ class AutoCFTypeObject { // We start the unique IDs at 1 so that 0 can be used to mean that // a component has no unique ID assigned to it. uint32_t GeckoChildProcessHost::sNextUniqueID = 1; /* static */ uint32_t GeckoChildProcessHost::GetUniqueID() { return sNextUniqueID++; } +/* static */ +void GeckoChildProcessHost::SetEnv(const char* aKey, const char* aValue) { + MOZ_ASSERT(mLaunchOptions); + mLaunchOptions->env_map[ENVIRONMENT_STRING(aKey)] = + ENVIRONMENT_STRING(aValue); +} + void GeckoChildProcessHost::PrepareLaunch() { if (CrashReporter::GetEnabled()) { CrashReporter::OOPInit(); } #if defined(XP_LINUX) && defined(MOZ_SANDBOX) SandboxLaunchPrepare(mProcessType, mLaunchOptions.get()); #endif
--- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -79,16 +79,20 @@ class GeckoChildProcessHost : public Chi // otherwise, it could happen immediately. // // GeckoChildProcessHost instances must not be deleted except // through this method. void Destroy(); static uint32_t GetUniqueID(); + // Call this before launching to set an environment variable for the + // child process. The arguments must be UTF-8. + void SetEnv(const char* aKey, const char* aValue); + // Does not block. The IPC channel may not be initialized yet, and // the child process may or may not have been created when this // method returns. bool AsyncLaunch(StringVector aExtraOpts = StringVector()); virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0); // Block until the IPC channel for our subprocess is initialized and
--- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -2256,29 +2256,38 @@ # How often to check for CPOW timeouts (ms). CPOWs are only timed # out by the hang monitor. - name: dom.ipc.cpow.timeout type: uint32_t value: 500 mirror: always -# Temporary pref to allow disabling remoting of MozIcon -- name: dom.ipc.remote-mozIcon - type: bool - value: true - mirror: always - #ifdef MOZ_ENABLE_FORKSERVER - name: dom.ipc.forkserver.enable type: bool value: false mirror: once #endif +#ifdef MOZ_WIDGET_GTK +# +# Avoid the use of GTK in content processes if possible, by running +# them in headless mode, to conserve resources (e.g., connections to +# the X server). See the usage in `ContentParent.cpp` for the full +# definition of "if possible". +# +# This does not affect sandbox policies; content processes may still +# dynamically connect to the display server for, e.g., WebGL. +- name: dom.ipc.avoid-gtk + type: bool + value: true + mirror: always +#endif + # Whether or not to collect a paired minidump when force-killing a # content process. - name: dom.ipc.tabs.createKillHardCrashReports type: bool value: @IS_NOT_RELEASE_OR_BETA@ mirror: once # Allow Flash async drawing mode in 64-bit release builds.
--- a/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html +++ b/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html @@ -29,30 +29,32 @@ <p>blah blah blah blah</p> <p>blah blah blah blah</p> </div> <script class="testbody" type="text/javascript"> const kStrictKeyPressEvents = SpecialPowers.getBoolPref("dom.keyboardevent.keypress.dispatch_non_printable_keys_only_system_group_in_content"); const kStrictKeyDownKeyUpEvents = SpecialPowers.getBoolPref("dom.keyboardevent.dispatch_during_composition"); -const kIsHeadless = - SpecialPowers.Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).isHeadless; info("\nProfile::EventUtilsLoadTime: " + (loadTime - start) + "\n"); function starttest() { SimpleTest.waitForFocus( async function () { SimpleTest.waitForExplicitFinish(); var startTime = new Date(); var check = false; function doCheck() { check = true; } + const kIsHeadless = await SpecialPowers.spawnChrome([], () => { + return Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo).isHeadless; + }); + if (navigator.appVersion.includes("Android")) { // This is the workaround for test failure on debug build. await SpecialPowers.pushPrefEnv({set: [["apz.zoom-to-focused-input.enabled", false]]}); } /* test send* functions */ $("testMouseEvent").addEventListener("click", doCheck, {once: true}); sendMouseEvent({type:'click'}, "testMouseEvent");