Bug 1492584, part 1 - Eagerly initialize nsLayoutModule in the component manager. r=froydnj

nsLayoutModule must be initialized in order to call into JS, but I
don't want to have to rely on calling a service in that
module. Instead, always initialize the module very early in component
manager initialization. This also makes initialization more
consistent, so things like errors in manifests won't affect when it
happens, which can result in different behavior in different builds.

I also made nsLayoutModule initialization infallible, because I can't
imagine that we can do much that is useful without it.

Another change I made is that gInitialized is set to true even in a
GPU process. This simplifies checking whether initialization has
happened already when we start up the layout module.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew McCreight 2018-10-24 16:10:29 +00:00
parent 9fa26ec6f1
commit 681cefeb09
4 changed files with 47 additions and 20 deletions

View File

@ -210,19 +210,11 @@ static bool gInitialized = false;
// Perform our one-time intialization for this module
static nsresult
Initialize()
void
nsLayoutModuleInitialize()
{
if (gInitialized) {
MOZ_CRASH("Recursive layout module initialization");
return NS_ERROR_FAILURE;
}
if (XRE_GetProcessType() == GeckoProcessType_GPU) {
// We mark the layout module as being available in the GPU process so that
// XPCOM's component manager initializes the power manager service, which
// is needed for nsAppShell. However, we don't actually need anything in
// the layout module itself.
return NS_OK;
}
static_assert(sizeof(uintptr_t) == sizeof(void*),
@ -231,18 +223,22 @@ Initialize()
gInitialized = true;
nsresult rv;
rv = xpcModuleCtor();
if (NS_FAILED(rv))
return rv;
rv = nsLayoutStatics::Initialize();
if (NS_FAILED(rv)) {
Shutdown();
return rv;
if (XRE_GetProcessType() == GeckoProcessType_GPU) {
// We mark the layout module as being available in the GPU process so that
// XPCOM's component manager initializes the power manager service, which
// is needed for nsAppShell. However, we don't actually need anything in
// the layout module itself.
return;
}
return NS_OK;
if (NS_FAILED(xpcModuleCtor())) {
MOZ_CRASH("xpcModuleCtor failed");
}
if (NS_FAILED(nsLayoutStatics::Initialize())) {
Shutdown();
MOZ_CRASH("nsLayoutStatics::Initialize failed");
}
}
// Shutdown this module, releasing all of the module resources
@ -686,6 +682,14 @@ static const mozilla::Module::CategoryEntry kLayoutCategories[] = {
// clang-format on
};
static nsresult
Initialize()
{
// nsLayoutModuleInitialize should be called first.
MOZ_RELEASE_ASSERT(gInitialized);
return NS_OK;
}
static void
LayoutModuleDtor()
{

View File

@ -0,0 +1,17 @@
/* -*- 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 nsLayoutModule_h
#define nsLayoutModule_h
#include "nscore.h"
// This function initializes various layout statics, as well as XPConnect.
// It should be called only once, and before the first time any XPCOM module in
// nsLayoutModule is used.
void nsLayoutModuleInitialize();
#endif // nsLayoutModule_h

View File

@ -47,6 +47,7 @@ LOCAL_INCLUDES += [
'../ds',
'/chrome',
'/js/xpconnect/loader',
'/layout/build',
'/modules/libjar',
]

View File

@ -17,6 +17,7 @@
#include "nsDirectoryServiceDefs.h"
#include "nsCategoryManager.h"
#include "nsCategoryManagerUtils.h"
#include "nsLayoutModule.h"
#include "mozilla/MemoryReporting.h"
#include "nsIConsoleService.h"
#include "nsIObserverService.h"
@ -354,6 +355,10 @@ nsComponentManagerImpl::Init()
RegisterModule((*sExtraStaticModules)[i]);
}
// This needs to be called very early, before anything in nsLayoutModule is
// used, and before any calls are made into the JS engine.
nsLayoutModuleInitialize();
bool loadChromeManifests = (XRE_GetProcessType() != GeckoProcessType_GPU);
if (loadChromeManifests) {
// The overall order in which chrome.manifests are expected to be treated