mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-03 07:01:19 +00:00
Bug 1470365: Part 3 - Use shared memory for StringBundles loaded in the content process. r=erahm,smaug
MozReview-Commit-ID: LunnQyndnBf --HG-- extra : rebase_source : f67e08fc83e8c2e280d886b2d69150c09fb48200 extra : absorb_source : 3b9b226aaca168e3b6537f3031ff22275bd27133
This commit is contained in:
parent
d89b3482b9
commit
e6da28f1ce
@ -3962,6 +3962,18 @@ nsContentUtils::EnsureStringBundle(PropertiesFile aFile)
|
||||
void
|
||||
nsContentUtils::AsyncPrecreateStringBundles()
|
||||
{
|
||||
// We only ever want to pre-create bundles in the parent process.
|
||||
//
|
||||
// All nsContentUtils bundles are shared between the parent and child
|
||||
// precesses, and the shared memory regions that back them *must* be created
|
||||
// in the parent, and then sent to all children.
|
||||
//
|
||||
// If we attempt to create a bundle in the child before its memory region is
|
||||
// available, we need to create a temporary non-shared bundle, and later
|
||||
// replace that with the shared memory copy. So attempting to pre-load in the
|
||||
// child is wasteful and unnecessary.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
for (uint32_t bundleIndex = 0; bundleIndex < PropertiesFile_COUNT; ++bundleIndex) {
|
||||
nsresult rv = NS_IdleDispatchToCurrentThread(
|
||||
NS_NewRunnableFunction("AsyncPrecreateStringBundles",
|
||||
|
@ -85,6 +85,7 @@
|
||||
#include "GMPServiceChild.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIWorkerDebuggerManager.h"
|
||||
|
||||
#if !defined(XP_WIN)
|
||||
@ -2262,11 +2263,6 @@ ContentChild::RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
|
||||
static_cast<nsChromeRegistryContent*>(registrySvc.get());
|
||||
chromeRegistry->RegisterRemoteChrome(packages, resources, overrides,
|
||||
locale, reset);
|
||||
static bool preloadDone = false;
|
||||
if (!preloadDone) {
|
||||
preloadDone = true;
|
||||
nsContentUtils::AsyncPrecreateStringBundles();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -2536,6 +2532,20 @@ ContentChild::RecvAsyncMessage(const nsString& aMsg,
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvRegisterStringBundles(nsTArray<mozilla::dom::StringBundleDescriptor>&& aDescriptors)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
services::GetStringBundleService();
|
||||
|
||||
for (auto& descriptor : aDescriptors) {
|
||||
stringBundleService->RegisterContentBundle(descriptor.bundleURL(), descriptor.mapFile(),
|
||||
descriptor.mapSize());
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition)
|
||||
{
|
||||
|
@ -394,6 +394,8 @@ public:
|
||||
const IPC::Principal& aPrincipal,
|
||||
const ClonedMessageData& aData) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvRegisterStringBundles(nsTArray<StringBundleDescriptor>&& stringBundles) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvGeolocationError(const uint16_t& errorCode) override;
|
||||
|
@ -146,6 +146,7 @@
|
||||
#include "nsISiteSecurityService.h"
|
||||
#include "nsISound.h"
|
||||
#include "nsISpellChecker.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIURIFixup.h"
|
||||
@ -1277,6 +1278,17 @@ ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::BroadcastStringBundle(const StringBundleDescriptor& aBundle)
|
||||
{
|
||||
AutoTArray<StringBundleDescriptor, 1> array;
|
||||
array.AppendElement(aBundle);
|
||||
|
||||
for (auto* cp : AllProcesses(eLive)) {
|
||||
Unused << cp->SendRegisterStringBundles(array);
|
||||
}
|
||||
}
|
||||
|
||||
const nsAString&
|
||||
ContentParent::GetRemoteType() const
|
||||
{
|
||||
@ -2317,6 +2329,10 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority)
|
||||
static_cast<nsChromeRegistryChrome*>(registrySvc.get());
|
||||
chromeRegistry->SendRegisteredChrome(this);
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
services::GetStringBundleService();
|
||||
stringBundleService->SendContentBundles(this);
|
||||
|
||||
if (gAppData) {
|
||||
nsCString version(gAppData->version);
|
||||
nsCString buildID(gAppData->buildID);
|
||||
|
@ -204,6 +204,8 @@ public:
|
||||
|
||||
static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
|
||||
|
||||
static void BroadcastStringBundle(const StringBundleDescriptor&);
|
||||
|
||||
const nsAString& GetRemoteType() const;
|
||||
|
||||
virtual void DoGetRemoteType(nsAString& aRemoteType, ErrorResult& aError) const override
|
||||
|
@ -289,6 +289,13 @@ struct XPCOMInitData
|
||||
DynamicScalarDefinition[] dynamicScalarDefs;
|
||||
};
|
||||
|
||||
struct StringBundleDescriptor
|
||||
{
|
||||
nsCString bundleURL;
|
||||
FileDescriptor mapFile;
|
||||
uint32_t mapSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* The PContent protocol is a top-level protocol between the UI process
|
||||
* and a content process. There is exactly one PContentParent/PContentChild pair
|
||||
@ -457,6 +464,8 @@ child:
|
||||
|
||||
async ClearSiteDataReloadNeeded(nsString origin);
|
||||
|
||||
async RegisterStringBundles(StringBundleDescriptor[] stringBundles);
|
||||
|
||||
// nsIPermissionManager messages
|
||||
async AddPermission(Permission permission);
|
||||
|
||||
|
@ -9,6 +9,15 @@
|
||||
%{C++
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class ContentParent;
|
||||
}
|
||||
namespace ipc {
|
||||
class FileDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
// Define Contractid and CID
|
||||
// {D85A17C1-AA7C-11d2-9B8C-00805F8A16D9}
|
||||
#define NS_STRINGBUNDLESERVICE_CID \
|
||||
@ -99,5 +108,11 @@ interface nsIStringBundleService : nsISupports
|
||||
|
||||
%{C++
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
|
||||
|
||||
virtual void SendContentBundles(mozilla::dom::ContentParent* aContentParent) const = 0;
|
||||
|
||||
virtual void RegisterContentBundle(const nsCString& aBundleURL,
|
||||
const mozilla::ipc::FileDescriptor& aMapFile,
|
||||
size_t aMapSize) = 0;
|
||||
%}
|
||||
};
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/URLPreloader.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ipc/SharedStringMap.h"
|
||||
|
||||
// for async loading
|
||||
@ -42,6 +43,8 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using mozilla::dom::ContentParent;
|
||||
using mozilla::dom::StringBundleDescriptor;
|
||||
using mozilla::dom::ipc::SharedStringMap;
|
||||
using mozilla::dom::ipc::SharedStringMapBuilder;
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
@ -223,6 +226,17 @@ public:
|
||||
|
||||
bool Initialized() const { return mStringMap || mMapFile.isSome(); }
|
||||
|
||||
StringBundleDescriptor GetDescriptor() const
|
||||
{
|
||||
MOZ_ASSERT(Initialized());
|
||||
|
||||
StringBundleDescriptor descriptor;
|
||||
descriptor.bundleURL() = BundleURL();
|
||||
descriptor.mapFile() = CloneFileDescriptor();
|
||||
descriptor.mapSize() = MapSize();
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
static SharedStringBundle* Cast(nsIStringBundle* aStringBundle)
|
||||
@ -462,6 +476,9 @@ SharedStringBundle::LoadProperties()
|
||||
}
|
||||
|
||||
mStringMap = new SharedStringMap(std::move(builder));
|
||||
|
||||
ContentParent::BroadcastStringBundle(GetDescriptor());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -998,6 +1015,52 @@ nsStringBundleService::FlushBundles()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsStringBundleService::SendContentBundles(ContentParent* aContentParent) const
|
||||
{
|
||||
nsTArray<StringBundleDescriptor> bundles;
|
||||
|
||||
for (auto* entry : mSharedBundles) {
|
||||
auto bundle = SharedStringBundle::Cast(entry->mBundle);
|
||||
|
||||
if (bundle->Initialized()) {
|
||||
bundles.AppendElement(bundle->GetDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
Unused << aContentParent->SendRegisterStringBundles(std::move(bundles));
|
||||
}
|
||||
|
||||
void
|
||||
nsStringBundleService::RegisterContentBundle(const nsCString& aBundleURL,
|
||||
const FileDescriptor& aMapFile,
|
||||
size_t aMapSize)
|
||||
{
|
||||
RefPtr<StringBundleProxy> proxy;
|
||||
|
||||
bundleCacheEntry_t* cacheEntry = mBundleMap.Get(aBundleURL);
|
||||
if (cacheEntry) {
|
||||
if (RefPtr<SharedStringBundle> shared = do_QueryObject(cacheEntry->mBundle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
proxy = do_QueryObject(cacheEntry->mBundle);
|
||||
MOZ_ASSERT(proxy);
|
||||
cacheEntry->remove();
|
||||
delete cacheEntry;
|
||||
}
|
||||
|
||||
auto bundle = MakeRefPtr<SharedStringBundle>(aBundleURL.get(), mOverrideStrings);
|
||||
bundle->SetMapFile(aMapFile, aMapSize);
|
||||
|
||||
if (proxy) {
|
||||
proxy->Retarget(bundle);
|
||||
}
|
||||
|
||||
cacheEntry = insertIntoCache(bundle.forget(), aBundleURL);
|
||||
mSharedBundles.insertBack(cacheEntry);
|
||||
}
|
||||
|
||||
void
|
||||
nsStringBundleService::getStringBundle(const char *aURLSpec,
|
||||
nsIStringBundle **aResult)
|
||||
@ -1063,7 +1126,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
|
||||
|
||||
bundleCacheEntry_t *
|
||||
nsStringBundleService::insertIntoCache(already_AddRefed<nsIStringBundle> aBundle,
|
||||
const nsCString &aHashKey)
|
||||
const nsACString& aHashKey)
|
||||
{
|
||||
bundleCacheEntry_t *cacheEntry;
|
||||
|
||||
|
@ -51,6 +51,12 @@ public:
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
|
||||
|
||||
void SendContentBundles(mozilla::dom::ContentParent* aContentParent) const override;
|
||||
|
||||
void RegisterContentBundle(const nsCString& aBundleURL,
|
||||
const mozilla::ipc::FileDescriptor& aMapFile,
|
||||
size_t aMapSize) override;
|
||||
|
||||
private:
|
||||
virtual ~nsStringBundleService();
|
||||
|
||||
@ -61,8 +67,8 @@ private:
|
||||
|
||||
void flushBundleCache();
|
||||
|
||||
bundleCacheEntry_t *insertIntoCache(already_AddRefed<nsIStringBundle> aBundle,
|
||||
const nsCString &aHashKey);
|
||||
bundleCacheEntry_t* insertIntoCache(already_AddRefed<nsIStringBundle> aBundle,
|
||||
const nsACString &aHashKey);
|
||||
|
||||
nsDataHashtable<nsCStringHashKey, bundleCacheEntry_t*> mBundleMap;
|
||||
mozilla::LinkedList<bundleCacheEntry_t> mBundleCache;
|
||||
|
Loading…
x
Reference in New Issue
Block a user