Bug 1311149 - Remove the b2g preallocated app support; r=baku

This commit is contained in:
Ehsan Akhgari 2016-10-18 21:54:12 -04:00
parent eac76d9772
commit 569f181508
23 changed files with 18 additions and 899 deletions

View File

@ -613,9 +613,6 @@ pref("hal.processPriorityManager.gonk.MASTER.OomScoreAdjust", 0);
pref("hal.processPriorityManager.gonk.MASTER.KillUnderKB", 4096);
pref("hal.processPriorityManager.gonk.MASTER.cgroup", "");
pref("hal.processPriorityManager.gonk.PREALLOC.OomScoreAdjust", 67);
pref("hal.processPriorityManager.gonk.PREALLOC.cgroup", "apps/bg_non_interactive");
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.OomScoreAdjust", 67);
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.KillUnderKB", 5120);
pref("hal.processPriorityManager.gonk.FOREGROUND_HIGH.cgroup", "apps/critical");
@ -693,12 +690,6 @@ pref("gonk.notifySoftLowMemUnderKB", 43008);
// blocked on a poll(), and this pref has no effect.)
pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);
// Enable pre-launching content processes for improved startup time
// (hiding latency).
pref("dom.ipc.processPrelaunch.enabled", true);
// Wait this long before pre-launching a new subprocess.
pref("dom.ipc.processPrelaunch.delayMs", 5000);
pref("dom.ipc.reuse_parent_app", false);
// When a process receives a system message, we hold a CPU wake lock on its

View File

@ -13,7 +13,5 @@ support-files =
[test_Simple.html]
[test_HighPriority.html]
[test_Preallocated.html]
disabled = bug 968604, bug 987164
[test_WebGLContextLost.html]
disabled = bug 865844

View File

@ -1,71 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
Test that the preallocated process starts up with priority BACKGROUND.
-->
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="../browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7">
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
browserElementTestHelpers.enableProcessPriorityManager();
var preallocationEnabledPref = null;
try {
preallocationEnabledPref = SpecialPowers.getBoolPref('dom.ipc.processPrelaunch.enabled');
}
catch(e) {
preallocationEnabledPref = null;
}
var childID = null;
var cleanedUp = false;
function cleanUp()
{
if (cleanedUp) {
return;
}
cleanedUp = true;
}
// Even if this test times out, we still want to run cleanUp so as to set the
// pref back.
addEventListener('unload', cleanUp);
function runTest()
{
if (preallocationEnabledPref) {
ok(false, "dom.ipc.processPrelaunch.enabled must be " +
"false for this test to work.");
SimpleTest.finish();
return;
}
// Ensure that the preallocated process initially gets BACKGROUND priority.
// That's it.
expectProcessCreated('PREALLOC').then(function() {
// We need to set the pref asynchoronously or the preallocated process won't
// be shut down.
SimpleTest.executeSoon(function(){
cleanUp();
SimpleTest.finish();
});
});
}
// Setting this pref to true should cause us to prelaunch a process.
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set':[["dom.ipc.processPrelaunch.enabled",true]]},runTest);
});
</script>
</body>
</html>

View File

@ -592,7 +592,6 @@ ContentChild::Init(MessageLoop* aIOLoop,
#endif
SendGetProcessAttributes(&mID, &mIsForBrowser);
InitProcessAttributes();
#ifdef NS_PRINTING
// Force the creation of the nsPrintingProxy so that it's IPC counterpart,
@ -600,21 +599,9 @@ ContentChild::Init(MessageLoop* aIOLoop,
RefPtr<nsPrintingProxy> printingProxy = nsPrintingProxy::GetInstance();
#endif
return true;
}
void
ContentChild::InitProcessAttributes()
{
#ifdef MOZ_WIDGET_GONK
if (mIsForBrowser) {
SetProcessName(NS_LITERAL_STRING("Browser"), false);
} else {
SetProcessName(NS_LITERAL_STRING("(Preallocated app)"), false);
}
#else
SetProcessName(NS_LITERAL_STRING("Web Content"), true);
#endif
return true;
}
void
@ -1490,14 +1477,6 @@ ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL,
return IPC_OK();
}
static CancelableRunnable* sFirstIdleTask;
static void FirstIdle(void)
{
MOZ_ASSERT(sFirstIdleTask);
sFirstIdleTask = nullptr;
ContentChild::GetSingleton()->SendFirstIdle();
}
mozilla::jsipc::PJavaScriptChild *
ContentChild::AllocPJavaScriptChild()
@ -1561,22 +1540,6 @@ ContentChild::RecvPBrowserConstructor(PBrowserChild* aActor,
os->NotifyObservers(tc, "tab-child-created", nullptr);
}
static bool hasRunOnce = false;
if (!hasRunOnce) {
hasRunOnce = true;
MOZ_ASSERT(!sFirstIdleTask);
RefPtr<CancelableRunnable> firstIdleTask = NewCancelableRunnableFunction(FirstIdle);
sFirstIdleTask = firstIdleTask;
MessageLoop::current()->PostIdleTask(firstIdleTask.forget());
// Redo InitProcessAttributes() when the app or browser is really
// launching so the attributes will be correct.
mID = aCpID;
mIsForBrowser = aIsForBrowser;
InitProcessAttributes();
}
return IPC_OK();
}
@ -2086,9 +2049,6 @@ ContentChild::ActorDestroy(ActorDestroyReason why)
// keep persistent state.
ProcessChild::QuickExit();
#else
if (sFirstIdleTask) {
sFirstIdleTask->Cancel();
}
nsHostObjectProtocolHandler::RemoveDataEntries();
@ -2392,19 +2352,6 @@ ContentChild::RecvCycleCollect()
return IPC_OK();
}
static void
PreloadSlowThings()
{
// This fetches and creates all the built-in stylesheets.
//
// XXXheycam In the future we might want to preload the Servo-flavoured
// UA sheets too, but for now that will be a waste of time.
nsLayoutStylesheetCache::For(StyleBackendType::Gecko)->UserContentSheet();
TabChild::PreloadSlowThings();
}
mozilla::ipc::IPCResult
ContentChild::RecvAppInfo(const nsCString& version, const nsCString& buildID,
const nsCString& name, const nsCString& UAName,
@ -2420,25 +2367,6 @@ ContentChild::RecvAppInfo(const nsCString& version, const nsCString& buildID,
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvAppInit()
{
if (!Preferences::GetBool("dom.ipc.processPrelaunch.enabled", false)) {
return IPC_OK();
}
// If we're part of the mozbrowser machinery, go ahead and start
// preloading things. We can only do this for mozbrowser because
// PreloadSlowThings() may set the docshell of the first TabChild
// inactive, and we can only safely restore it to active from
// BrowserElementChild.js.
if (mIsForBrowser) {
PreloadSlowThings();
}
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig)
{

View File

@ -96,8 +96,6 @@ public:
base::ProcessId aParentPid,
IPC::Channel* aChannel);
void InitProcessAttributes();
void InitXPCOM();
void InitGraphicsDeviceData();
@ -426,8 +424,6 @@ public:
const nsCString& name, const nsCString& UAName,
const nsCString& ID, const nsCString& vendor) override;
virtual mozilla::ipc::IPCResult RecvAppInit() override;
virtual mozilla::ipc::IPCResult
RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig) override;

View File

@ -157,7 +157,6 @@
#include "nsThreadUtils.h"
#include "nsToolkitCompsCID.h"
#include "nsWidgetsCID.h"
#include "PreallocatedProcessManager.h"
#include "ProcessPriorityManager.h"
#include "SandboxHal.h"
#include "ScreenManagerParent.h"
@ -553,25 +552,6 @@ static const char* sObserverTopics[] = {
"cacheservice:empty-cache",
};
// PreallocateAppProcess is called by the PreallocatedProcessManager.
// ContentParent then takes this process back within
// GetNewOrPreallocatedAppProcess.
/*static*/ already_AddRefed<ContentParent>
ContentParent::PreallocateAppProcess()
{
RefPtr<ContentParent> process =
new ContentParent(/* aOpener = */ nullptr,
/* isForBrowserElement = */ false,
/* isForPreallocated = */ true);
if (!process->LaunchSubprocess(PROCESS_PRIORITY_PREALLOC)) {
return nullptr;
}
process->Init();
return process.forget();
}
/*static*/ void
ContentParent::StartUp()
{
@ -605,9 +585,6 @@ ContentParent::StartUp()
BackgroundChild::Startup();
// Try to preallocate a process that we can transform into an app later.
PreallocatedProcessManager::AllocateAfterDelay();
sDisableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
@ -720,23 +697,15 @@ ContentParent::GetNewOrUsedBrowserProcess(bool aForBrowserElement,
} while (currIdx != startIdx);
}
// Try to take and transform the preallocated process into browser.
RefPtr<ContentParent> p = PreallocatedProcessManager::Take();
if (p) {
p->TransformPreallocatedIntoBrowser(aOpener);
} else {
// Failed in using the preallocated process: fork from the chrome process.
p = new ContentParent(aOpener,
aForBrowserElement,
/* isForPreallocated = */ false);
RefPtr<ContentParent> p = new ContentParent(aOpener,
aForBrowserElement);
if (!p->LaunchSubprocess(aPriority)) {
return nullptr;
}
p->Init();
if (!p->LaunchSubprocess(aPriority)) {
return nullptr;
}
p->Init();
p->mLargeAllocationProcess = aLargeAllocationProcess;
p->ForwardKnownInfo();
@ -791,12 +760,6 @@ ContentParent::SendAsyncUpdate(nsIWidget* aWidget)
}
#endif // defined(XP_WIN)
bool
ContentParent::PreallocatedProcessReady()
{
return true;
}
mozilla::ipc::IPCResult
ContentParent::RecvCreateChildProcess(const IPCTabContext& aContext,
const hal::ProcessPriority& aPriority,
@ -1263,15 +1226,6 @@ ContentParent::SetPriorityAndCheckIsAlive(ProcessPriority aPriority)
return true;
}
void
ContentParent::TransformPreallocatedIntoBrowser(ContentParent* aOpener)
{
// Reset mIsForBrowser and mOSPrivileges for browser.
mMetamorphosed = true;
mOpener = aOpener;
mIsForBrowser = true;
}
void
ContentParent::ShutDownProcess(ShutDownMethod aMethod)
{
@ -1843,20 +1797,14 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR
}
ContentParent::ContentParent(ContentParent* aOpener,
bool aIsForBrowser,
bool aIsForPreallocated)
bool aIsForBrowser)
: nsIContentParent()
, mOpener(aOpener)
, mIsForBrowser(aIsForBrowser)
, mIsPreallocated(aIsForPreallocated)
, mLargeAllocationProcess(false)
{
InitializeMembers(); // Perform common initialization.
// No more than one of aIsForBrowser and aIsForPreallocated should be
// true.
MOZ_ASSERT(aIsForBrowser + aIsForPreallocated <= 1);
mMetamorphosed = true;
// Insert ourselves into the global linked list of ContentParent objects.
@ -1969,11 +1917,6 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
}
}
if (gAppData) {
// Sending all information to content process.
Unused << SendAppInit();
}
nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
if (sheetService) {
// This looks like a lot of work, but in a normal browser session we just
@ -2333,17 +2276,6 @@ ContentParent::RecvGetShowPasswordSetting(bool* showPassword)
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvFirstIdle()
{
// When the ContentChild goes idle, it sends us a FirstIdle message
// which we use as a good time to prelaunch another process. If we
// prelaunch any sooner than this, then we'll be competing with the
// child process and slowing it down.
PreallocatedProcessManager::AllocateAfterDelay();
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
const bool& aHidden)
@ -2839,19 +2771,11 @@ ContentParent::KillHard(const char* aReason)
otherProcessHandle, /*force=*/true));
}
bool
ContentParent::IsPreallocated() const
{
return mIsPreallocated;
}
void
ContentParent::FriendlyName(nsAString& aName, bool aAnonymize)
{
aName.Truncate();
if (IsPreallocated()) {
aName.AssignLiteral("(Preallocated)");
} else if (mIsForBrowser) {
if (mIsForBrowser) {
aName.AssignLiteral("Browser");
} else if (aAnonymize) {
aName.AssignLiteral("<anonymized-name>");

View File

@ -122,8 +122,6 @@ public:
*/
static void JoinAllSubprocesses();
static bool PreallocatedProcessReady();
/**
* Get or create a content process for:
* 1. browser iframe
@ -137,11 +135,6 @@ public:
ContentParent* aOpener = nullptr,
bool aLargeAllocationProcess = false);
/**
* Create a subprocess suitable for use as a preallocated app process.
*/
static already_AddRefed<ContentParent> PreallocateAppProcess();
/**
* Get or create a content process for the given TabContext. aFrameElement
* should be the frame/iframe element with which this process will
@ -359,8 +352,6 @@ public:
ContentParentId ChildID() const override { return mChildID; }
bool IsPreallocated() const;
/**
* Get a user-friendly name for this ContentParent. We make no guarantees
* about this name: It might not be unique, apps can spoof special names,
@ -583,11 +574,8 @@ private:
FORWARD_SHMEM_ALLOCATOR_TO(PContentParent)
// No more than one of aIsForBrowser, and aIsForPreallocated may be
// true.
ContentParent(ContentParent* aOpener,
bool aIsForBrowser,
bool aIsForPreallocated);
bool aIsForBrowser);
// The common initialization for the constructors.
void InitializeMembers();
@ -616,10 +604,6 @@ private:
// unlikely that the process will be killed after this point.
bool SetPriorityAndCheckIsAlive(hal::ProcessPriority aPriority);
// Transform a pre-allocated app process into a browser process. If this
// returns false, the child process has died.
void TransformPreallocatedIntoBrowser(ContentParent* aOpener);
/**
* Mark this ContentParent as dead for the purposes of Get*().
* This method is idempotent.
@ -927,8 +911,6 @@ private:
virtual mozilla::ipc::IPCResult RecvPrivateDocShellsExist(const bool& aExist) override;
virtual mozilla::ipc::IPCResult RecvFirstIdle() override;
virtual mozilla::ipc::IPCResult RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
const bool& aHidden) override;
@ -1100,7 +1082,6 @@ private:
bool mSendPermissionUpdates;
bool mIsForBrowser;
bool mIsPreallocated;
// These variables track whether we've called Close() and KillHard() on our
// channel.

View File

@ -520,7 +520,6 @@ child:
async AppInfo(nsCString version, nsCString buildID, nsCString name, nsCString UAName,
nsCString ID, nsCString vendor);
async AppInit();
/**
* Send ServiceWorkerRegistrationData to child process.
@ -904,9 +903,6 @@ parent:
// Notify the parent of the presence or absence of private docshells
async PrivateDocShellsExist(bool aExist);
// Tell the parent that the child has gone idle for the first time
async FirstIdle();
async AudioChannelServiceStatus(bool aActiveTelephonyChannel,
bool aContentOrNormalChannel,
bool aAnyActiveChannel);

View File

@ -1,252 +0,0 @@
/* -*- 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/. */
#include "mozilla/PreallocatedProcessManager.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsIPropertyBag2.h"
#include "ProcessPriorityManager.h"
#include "nsServiceManagerUtils.h"
// This number is fairly arbitrary ... the intention is to put off
// launching another app process until the last one has finished
// loading its content, to reduce CPU/memory/IO contention.
#define DEFAULT_ALLOCATE_DELAY 1000
using namespace mozilla;
using namespace mozilla::hal;
using namespace mozilla::dom;
namespace {
/**
* This singleton class implements the static methods on
* PreallocatedProcessManager.
*/
class PreallocatedProcessManagerImpl final
: public nsIObserver
{
public:
static PreallocatedProcessManagerImpl* Singleton();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
// See comments on PreallocatedProcessManager for these methods.
void AllocateAfterDelay();
void AllocateOnIdle();
void AllocateNow();
already_AddRefed<ContentParent> Take();
private:
static mozilla::StaticRefPtr<PreallocatedProcessManagerImpl> sSingleton;
PreallocatedProcessManagerImpl();
~PreallocatedProcessManagerImpl() {}
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManagerImpl);
void Init();
void RereadPrefs();
void Enable();
void Disable();
void ObserveProcessShutdown(nsISupports* aSubject);
bool mEnabled;
bool mShutdown;
RefPtr<ContentParent> mPreallocatedAppProcess;
};
/* static */ StaticRefPtr<PreallocatedProcessManagerImpl>
PreallocatedProcessManagerImpl::sSingleton;
/* static */ PreallocatedProcessManagerImpl*
PreallocatedProcessManagerImpl::Singleton()
{
if (!sSingleton) {
sSingleton = new PreallocatedProcessManagerImpl();
sSingleton->Init();
ClearOnShutdown(&sSingleton);
}
return sSingleton;
}
NS_IMPL_ISUPPORTS(PreallocatedProcessManagerImpl, nsIObserver)
PreallocatedProcessManagerImpl::PreallocatedProcessManagerImpl()
:
mEnabled(false)
, mShutdown(false)
{}
void
PreallocatedProcessManagerImpl::Init()
{
Preferences::AddStrongObserver(this, "dom.ipc.processPrelaunch.enabled");
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->AddObserver(this, "ipc:content-shutdown",
/* weakRef = */ false);
os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
/* weakRef = */ false);
}
{
RereadPrefs();
}
}
NS_IMETHODIMP
PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp("ipc:content-shutdown", aTopic)) {
ObserveProcessShutdown(aSubject);
} else if (!strcmp("nsPref:changed", aTopic)) {
// The only other observer we registered was for our prefs.
RereadPrefs();
} else if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
mShutdown = true;
} else {
MOZ_ASSERT(false);
}
return NS_OK;
}
void
PreallocatedProcessManagerImpl::RereadPrefs()
{
if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled")) {
Enable();
} else {
Disable();
}
}
already_AddRefed<ContentParent>
PreallocatedProcessManagerImpl::Take()
{
return mPreallocatedAppProcess.forget();
}
void
PreallocatedProcessManagerImpl::Enable()
{
if (mEnabled) {
return;
}
mEnabled = true;
AllocateAfterDelay();
}
void
PreallocatedProcessManagerImpl::AllocateAfterDelay()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
MessageLoop::current()->PostDelayedTask(
NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateOnIdle),
Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
DEFAULT_ALLOCATE_DELAY));
}
void
PreallocatedProcessManagerImpl::AllocateOnIdle()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
MessageLoop::current()->PostIdleTask(NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateNow));
}
void
PreallocatedProcessManagerImpl::AllocateNow()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
mPreallocatedAppProcess = ContentParent::PreallocateAppProcess();
}
void
PreallocatedProcessManagerImpl::Disable()
{
if (!mEnabled) {
return;
}
mEnabled = false;
if (mPreallocatedAppProcess) {
mPreallocatedAppProcess->Close();
mPreallocatedAppProcess = nullptr;
}
}
void
PreallocatedProcessManagerImpl::ObserveProcessShutdown(nsISupports* aSubject)
{
if (!mPreallocatedAppProcess) {
return;
}
nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
NS_ENSURE_TRUE_VOID(props);
uint64_t childID = CONTENT_PROCESS_ID_UNKNOWN;
props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), &childID);
NS_ENSURE_TRUE_VOID(childID != CONTENT_PROCESS_ID_UNKNOWN);
if (childID == mPreallocatedAppProcess->ChildID()) {
mPreallocatedAppProcess = nullptr;
}
}
inline PreallocatedProcessManagerImpl* GetPPMImpl()
{
return PreallocatedProcessManagerImpl::Singleton();
}
} // namespace
namespace mozilla {
/* static */ void
PreallocatedProcessManager::AllocateAfterDelay()
{
GetPPMImpl()->AllocateAfterDelay();
}
/* static */ void
PreallocatedProcessManager::AllocateOnIdle()
{
GetPPMImpl()->AllocateOnIdle();
}
/* static */ void
PreallocatedProcessManager::AllocateNow()
{
GetPPMImpl()->AllocateNow();
}
/* static */ already_AddRefed<ContentParent>
PreallocatedProcessManager::Take()
{
return GetPPMImpl()->Take();
}
} // namespace mozilla

View File

@ -1,88 +0,0 @@
/* -*- 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 mozilla_PreallocatedProcessManager_h
#define mozilla_PreallocatedProcessManager_h
#include "base/basictypes.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
/**
* This class manages a ContentParent that it starts up ahead of any particular
* need. You can then call Take() to get this process and use it. Since we
* already started it up, it should be ready for use faster than if you'd
* created the process when you needed it.
*
* This class watches the dom.ipc.processPrelaunch.enabled pref. If it changes
* from false to true, it preallocates a process. If it changes from true to
* false, it kills the preallocated process, if any.
*
* We don't expect this pref to flip between true and false in production, but
* flipping the pref is important for tests.
*
* The static methods here are implemented by forwarding calls on to a
* PreallocatedProcessManagerImpl singleton class, so if you add a new static
* method here, you'll need to write a corresponding public method on the
* singleton.
*/
class PreallocatedProcessManager final
{
typedef mozilla::dom::ContentParent ContentParent;
public:
/**
* Create a process after a delay. We wait for a period of time (specified
* by the dom.ipc.processPrelaunch.delayMs pref), then wait for this process
* to go idle, then allocate the new process.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateAfterDelay();
/**
* Create a process once this process goes idle.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateOnIdle();
/**
* Create a process right now.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateNow();
/**
* Take the preallocated process, if we have one. If we don't have one, this
* returns null.
*
* If you call Take() twice in a row, the second call is guaranteed to return
* null.
*
* After you Take() the preallocated process, you need to call one of the
* Allocate* functions (or change the dom.ipc.processPrelaunch pref from
* false to true) before we'll create a new process.
*/
static already_AddRefed<ContentParent> Take();
private:
PreallocatedProcessManager();
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManager);
};
} // namespace mozilla
#endif // defined mozilla_PreallocatedProcessManager_h

View File

@ -301,7 +301,6 @@ public:
int32_t Pid() const;
uint64_t ChildID() const;
bool IsPreallocated() const;
/**
* Used in logging, this method returns the ContentParent's name followed by
@ -618,15 +617,12 @@ ProcessPriorityManagerImpl::NotifyProcessPriorityChanged(
ProcessPriority aOldPriority)
{
ProcessPriority newPriority = aParticularManager->CurrentPriority();
bool isPreallocated = aParticularManager->IsPreallocated();
if (newPriority == PROCESS_PRIORITY_BACKGROUND &&
aOldPriority != PROCESS_PRIORITY_BACKGROUND &&
!isPreallocated) {
aOldPriority != PROCESS_PRIORITY_BACKGROUND) {
mBackgroundLRUPool.Add(aParticularManager);
} else if (newPriority != PROCESS_PRIORITY_BACKGROUND &&
aOldPriority == PROCESS_PRIORITY_BACKGROUND &&
!isPreallocated) {
aOldPriority == PROCESS_PRIORITY_BACKGROUND) {
mBackgroundLRUPool.Remove(aParticularManager);
}
@ -809,12 +805,6 @@ ParticularProcessPriorityManager::Pid() const
return mContentParent ? mContentParent->Pid() : -1;
}
bool
ParticularProcessPriorityManager::IsPreallocated() const
{
return mContentParent ? mContentParent->IsPreallocated() : false;
}
const nsAutoCString&
ParticularProcessPriorityManager::NameWithComma()
{

View File

@ -326,8 +326,6 @@ private:
};
namespace {
StaticRefPtr<TabChild> sPreallocatedTab;
std::map<TabId, RefPtr<TabChild>>&
NestedTabChildMap()
{
@ -348,89 +346,12 @@ TabChild::FindTabChild(const TabId& aTabId)
return tabChild.forget();
}
static void
PreloadSlowThingsPostFork(void* aUnused)
{
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
observerService->NotifyObservers(nullptr, "preload-postfork", nullptr);
MOZ_ASSERT(sPreallocatedTab);
// Initialize initial reflow of the PresShell has to happen after fork
// because about:blank content viewer is created in the above observer
// notification.
nsCOMPtr<nsIDocShell> docShell =
do_GetInterface(sPreallocatedTab->WebNavigation());
if (nsIPresShell* presShell = docShell->GetPresShell()) {
// Initialize and do an initial reflow of the about:blank
// PresShell to let it preload some things for us.
presShell->Initialize(0, 0);
nsIDocument* doc = presShell->GetDocument();
doc->FlushPendingNotifications(Flush_Layout);
// ... but after it's done, make sure it doesn't do any more
// work.
presShell->MakeZombie();
}
}
static bool sPreloaded = false;
/*static*/ void
TabChild::PreloadSlowThings()
{
if (sPreloaded) {
// If we are alredy initialized in Nuwa, don't redo preloading.
return;
}
sPreloaded = true;
// Pass nullptr to aManager since at this point the TabChild is
// not connected to any manager. Any attempt to use the TabChild
// in IPC will crash.
RefPtr<TabChild> tab(new TabChild(nullptr,
TabId(0),
TabContext(), /* chromeFlags */ 0));
if (NS_FAILED(tab->Init()) ||
!tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) {
return;
}
// Just load and compile these scripts, but don't run them.
tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
// Load, compile, and run these scripts.
tab->RecvLoadRemoteScript(
NS_LITERAL_STRING("chrome://global/content/preload.js"),
true);
sPreallocatedTab = tab;
ClearOnShutdown(&sPreallocatedTab);
PreloadSlowThingsPostFork(nullptr);
}
/*static*/ already_AddRefed<TabChild>
TabChild::Create(nsIContentChild* aManager,
const TabId& aTabId,
const TabContext &aContext,
uint32_t aChromeFlags)
{
if (sPreallocatedTab &&
sPreallocatedTab->mChromeFlags == aChromeFlags &&
aContext.IsMozBrowser()) {
RefPtr<TabChild> child = sPreallocatedTab.get();
sPreallocatedTab = nullptr;
MOZ_ASSERT(!child->mTriedBrowserInit);
child->mManager = aManager;
child->SetTabId(aTabId);
child->SetTabContext(aContext);
child->NotifyTabContextUpdated(true);
return child.forget();
}
RefPtr<TabChild> iframe = new TabChild(aManager, aTabId,
aContext, aChromeFlags);
return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr;
@ -621,13 +542,6 @@ TabChild::DoUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const Maybe<ZoomConstraints>& aConstraints)
{
if (sPreallocatedTab == this) {
// If we're the preallocated tab, bail out because doing IPC will crash.
// Once we get used for something we'll get another zoom constraints update
// and all will be well.
return true;
}
if (!mApzcTreeManager) {
return false;
}
@ -2529,7 +2443,7 @@ TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
}
bool
TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
TabChild::InitTabChildGlobal()
{
if (!mGlobal && !mTabChildGlobal) {
nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
@ -2553,7 +2467,7 @@ TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading)
root->SetParentTarget(scope);
}
if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) {
if (!mTriedBrowserInit) {
mTriedBrowserInit = true;
// Initialize the child side of the browser element machinery,
// if appropriate.

View File

@ -280,13 +280,6 @@ public:
nsresult Init();
/**
* This is expected to be called off the critical path to content
* startup. This is an opportunity to load things that are slow
* on the critical path.
*/
static void PreloadSlowThings();
/** Return a TabChild with the given attributes. */
static already_AddRefed<TabChild>
Create(nsIContentChild* aManager, const TabId& aTabId,
@ -724,9 +717,7 @@ private:
void ActorDestroy(ActorDestroyReason why) override;
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
bool InitTabChildGlobal();
void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,

View File

@ -9,4 +9,3 @@ toolkit.jar:
content/global/BrowserElementChildPreload.js (../browser-element/BrowserElementChildPreload.js)
content/global/BrowserElementCopyPaste.js (../browser-element/BrowserElementCopyPaste.js)
content/global/manifestMessages.js (manifestMessages.js)
content/global/preload.js (preload.js)

View File

@ -40,7 +40,6 @@ EXPORTS.mozilla.dom += [
EXPORTS.mozilla += [
'AppProcessChecker.h',
'PreallocatedProcessManager.h',
'ProcessHangMonitor.h',
'ProcessHangMonitorIPC.h',
'ProcessPriorityManager.h',
@ -60,7 +59,6 @@ UNIFIED_SOURCES += [
'nsIContentChild.cpp',
'nsIContentParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
'ScreenManagerParent.cpp',
'StructuredCloneData.cpp',

View File

@ -1,130 +0,0 @@
/* 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/. */
// Preload some things, in an attempt to make app startup faster.
//
// This script is run when the preallocated process starts. It is injected as
// a frame script.
var BrowserElementIsPreloaded = true;
var DoPreloadPostfork = function(aCallback) {
Services.obs.addObserver({
_callback: aCallback,
observe: function() {
this._callback();
Services.obs.removeObserver(this, "preload-postfork");
}
}, "preload-postfork", false);
};
(function (global) {
"use strict";
let Cu = Components.utils;
let Cc = Components.classes;
let Ci = Components.interfaces;
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Geometry.jsm");
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
Cc["@mozilla.org/base/telemetry;1"].getService(Ci["nsITelemetry"]);
Cc["@mozilla.org/categorymanager;1"].getService(Ci["nsICategoryManager"]);
Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci["nsIMessageSender"]);
Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConsoleService"]);
Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci["nsIURIFixup"]);
Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci["nsIDOMRequestService"]);
Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci["nsIPromptService"]);
Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci["nsIWindowWatcher"]);
Cc["@mozilla.org/eventlistenerservice;1"].getService(Ci["nsIEventListenerService"]);
Cc["@mozilla.org/focus-manager;1"].getService(Ci["nsIFocusManager"]);
Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci["nsILocaleService"]);
Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci["nsIStringBundleService"]);
Cc["@mozilla.org/layout/content-policy;1"].getService(Ci["nsIContentPolicy"]);
Cc["@mozilla.org/message-loop;1"].getService(Ci["nsIMessageLoop"]);
Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci["mozIJSSubScriptLoader"]);
Cc["@mozilla.org/network/application-cache-service;1"].getService(Ci["nsIApplicationCacheService"]);
Cc["@mozilla.org/network/dns-service;1"].getService(Ci["nsIDNSService"]);
Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci["nsIEffectiveTLDService"]);
Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci["nsIScriptSecurityManager"]);
Cc["@mozilla.org/storage/service;1"].getService(Ci["mozIStorageService"]);
Cc["@mozilla.org/system-info;1"].getService(Ci["nsIPropertyBag2"]);
Cc["@mozilla.org/thread-manager;1"].getService(Ci["nsIThreadManager"]);
Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci["nsIAppStartup"]);
Cc["@mozilla.org/uriloader;1"].getService(Ci["nsIURILoader"]);
Cc["@mozilla.org/cspcontext;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
Cc["@mozilla.org/settingsManager;1"].createInstance(Ci["nsISupports"]);
/* Applications Specific Helper */
try {
if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
Cc["@mozilla.org/system-message-manager;1"].getService(Ci["nsIDOMNavigatorSystemMessages"]);
}
} catch(e) {
}
try {
if (Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
Services.scriptloader.loadSubScript("chrome://global/content/forms.js", global);
}
} catch (e) {
}
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", global);
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", global);
Services.io.getProtocolHandler("app");
Services.io.getProtocolHandler("default");
// Register an observer for topic "preload_postfork" after we fork a content
// process.
DoPreloadPostfork(function () {
// Load AppsServiceChild.jsm after fork since it sends an async message to
// the chrome process in its init() function.
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
// Load nsIAppsService after fork since its implementation loads
// AppsServiceChild.jsm
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
// Load nsICookieService after fork since it sends an IPC constructor
// message to the chrome process.
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
// Load nsIPermissionManager after fork since it sends a message to the
// chrome process to read permissions.
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
// Load nsIProtocolProxyService after fork since it asynchronously accesses
// the "Proxy Resolution" thread after it's frozen.
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
// Call docShell.createAboutBlankContentViewer() after fork since it has IPC
// activity in the PCompositor protocol.
docShell.createAboutBlankContentViewer(null);
docShell.isActive = false;
});
})(this);

View File

@ -1574,12 +1574,6 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
ContentParent::GetAll(cplist);
for (uint32_t i = 0; i < cplist.Length(); ++i) {
ContentParent* cp = cplist[i];
// On platforms where we use a preallocated template process we don't
// want to notify this process about session specific permissions so
// new tabs or apps created on it won't inherit the session permissions.
if (cp->IsPreallocated() &&
aExpireType == nsIPermissionManager::EXPIRE_SESSION)
continue;
if (cp->NeedsPermissionsUpdate())
Unused << cp->SendAddPermission(permission);
}

View File

@ -915,8 +915,6 @@ ProcessPriorityToString(ProcessPriority aPriority)
switch (aPriority) {
case PROCESS_PRIORITY_MASTER:
return "MASTER";
case PROCESS_PRIORITY_PREALLOC:
return "PREALLOC";
case PROCESS_PRIORITY_FOREGROUND_HIGH:
return "FOREGROUND_HIGH";
case PROCESS_PRIORITY_FOREGROUND:

View File

@ -60,9 +60,6 @@ enum ProcessPriority {
PROCESS_PRIORITY_BACKGROUND,
PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE,
PROCESS_PRIORITY_FOREGROUND_KEYBOARD,
// The special class for the preallocated process, high memory priority but
// low CPU priority.
PROCESS_PRIORITY_PREALLOC,
// Any priority greater than or equal to FOREGROUND is considered
// "foreground" for the purposes of priority testing, for example
// CurrentProcessIsForeground().

View File

@ -205,18 +205,6 @@ public:
bool IsDestroying() { return mIsDestroying; }
/**
* Make a one-way transition into a "zombie" state. In this state,
* no reflow is done, no painting is done, and no refresh driver
* ticks are processed. This is a dangerous state: it can leave
* areas of the composition target unpainted if callers aren't
* careful. (Don't let your zombie presshell out of the shed.)
*
* This is used in cases where a presshell is created for reasons
* other than reflow/painting.
*/
virtual void MakeZombie() = 0;
/**
* All frames owned by the shell are allocated from an arena. They
* are also recycled using free lists. Separate free lists are
@ -1810,7 +1798,6 @@ protected:
bool mStylesHaveChanged : 1;
bool mDidInitialize : 1;
bool mIsDestroying : 1;
bool mIsZombie : 1;
bool mIsReflowing : 1;
// For all documents we initially lock down painting.

View File

@ -1358,13 +1358,6 @@ PresShell::Destroy()
mTouchManager.Destroy();
}
void
PresShell::MakeZombie()
{
mIsZombie = true;
CancelAllPendingReflows();
}
nsRefreshDriver*
nsIPresShell::GetRefreshDriver() const
{
@ -4026,10 +4019,6 @@ PresShell::FlushPendingNotifications(mozFlushType aType)
void
PresShell::FlushPendingNotifications(mozilla::ChangesToFlush aFlush)
{
if (mIsZombie) {
return;
}
/**
* VERY IMPORTANT: If you add some sort of new flushing to this
* method, make sure to add the relevant SetNeedLayoutFlush or
@ -6274,7 +6263,7 @@ PresShell::Paint(nsView* aViewToPaint,
MOZ_ASSERT(!mApproximateFrameVisibilityVisited, "Should have been cleared");
if (!mIsActive || mIsZombie) {
if (!mIsActive) {
return;
}
@ -9229,10 +9218,6 @@ PresShell::ScheduleReflowOffTimer()
bool
PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
{
if (mIsZombie) {
return true;
}
gfxTextPerfMetrics* tp = mPresContext->GetTextPerfMetrics();
TimeStamp timeStart;
if (tp) {

View File

@ -103,7 +103,6 @@ public:
void Init(nsIDocument* aDocument, nsPresContext* aPresContext,
nsViewManager* aViewManager, mozilla::StyleSetHandle aStyleSet);
virtual void Destroy() override;
virtual void MakeZombie() override;
virtual void UpdatePreferenceStyles() override;

View File

@ -27,12 +27,6 @@ function run_test() {
// We finish in clean_up()
do_test_pending();
try {
if (pb.getCharPref('dom.ipc.processPrelaunch.enabled')) {
dump('WARNING: Content process may already have launched, so this test may not be meaningful.');
}
} catch(e) { }
initialValue = pb.getCharPref(kPrefName);
test_user_setting();
@ -73,4 +67,4 @@ function clean_up() {
check_child_pref_info_eq(function () {
do_test_finished();
});
}
}