Bug 1704812 - Broadcast newly-added FontList shm blocks to Content Processes instead of waiting and doing sync IPC. r=emilio,jld

Differential Revision: https://phabricator.services.mozilla.com/D112666
This commit is contained in:
Jonathan Kew 2021-05-13 11:45:48 +00:00
Родитель c94f215c05
Коммит 0ba5a52a62
9 изменённых файлов: 117 добавлений и 0 удалений

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

@ -2357,6 +2357,14 @@ mozilla::ipc::IPCResult ContentChild::RecvRebuildFontList(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvFontListShmBlockAdded(
const uint32_t& aGeneration, const uint32_t& aIndex,
const base::SharedMemoryHandle& aHandle) {
gfxPlatformFontList::PlatformFontList()->ShmBlockAdded(aGeneration, aIndex,
aHandle);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvUpdateAppLocales(
nsTArray<nsCString>&& aAppLocales) {
LocaleService::GetInstance()->AssignAppLocales(aAppLocales);

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

@ -352,6 +352,9 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvUpdateFontList(SystemFontList&&);
mozilla::ipc::IPCResult RecvRebuildFontList(const bool& aFullRebuild);
mozilla::ipc::IPCResult RecvFontListShmBlockAdded(
const uint32_t& aGeneration, const uint32_t& aIndex,
const base::SharedMemoryHandle& aHandle);
mozilla::ipc::IPCResult RecvUpdateAppLocales(
nsTArray<nsCString>&& aAppLocales);

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

@ -1632,6 +1632,21 @@ void ContentParent::BroadcastFontListChanged() {
}
}
void ContentParent::BroadcastShmBlockAdded(uint32_t aGeneration,
uint32_t aIndex) {
auto* pfl = gfxPlatformFontList::PlatformFontList();
for (auto* cp : AllProcesses(eLive)) {
base::SharedMemoryHandle handle =
pfl->ShareShmBlockToProcess(aIndex, cp->Pid());
if (handle == base::SharedMemory::NULLHandle()) {
// If something went wrong here, we just skip it; the child will need to
// request the block as needed, at some performance cost.
continue;
}
Unused << cp->SendFontListShmBlockAdded(aGeneration, aIndex, handle);
}
}
void ContentParent::BroadcastThemeUpdate(widget::ThemeChangeKind aKind) {
const FullLookAndFeel& lnf = *RemoteLookAndFeel::ExtractData();
for (auto* cp : AllProcesses(eLive)) {

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

@ -259,6 +259,7 @@ class ContentParent final
static void BroadcastStringBundle(const StringBundleDescriptor&);
static void BroadcastFontListChanged();
static void BroadcastShmBlockAdded(uint32_t aGeneration, uint32_t aIndex);
static void BroadcastThemeUpdate(widget::ThemeChangeKind);

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

@ -635,6 +635,13 @@ child:
*/
async FontListChanged();
/**
* A new shmem block has been added to the font list; the child process
* should map the new block and add to its index.
*/
async FontListShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
SharedMemoryHandle aHandle);
async UpdateAppLocales(nsCString[] appLocales);
async UpdateRequestedLocales(nsCString[] requestedLocales);

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

@ -266,6 +266,11 @@ class FontList {
void ShareBlocksToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
base::ProcessId aPid);
base::SharedMemoryHandle ShareBlockToProcess(uint32_t aIndex,
base::ProcessId aPid);
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
base::SharedMemoryHandle aHandle);
/**
* Support for memory reporter.
*/

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

@ -9,6 +9,7 @@
#include "nsReadableUtils.h"
#include "prerror.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/Logging.h"
#define LOG_FONTLIST(args) \
@ -625,9 +626,53 @@ bool FontList::AppendShmBlock(uint32_t aSizeNeeded) {
mReadOnlyShmems.AppendElement(std::move(readOnly));
// We don't need to broadcast the addition of the initial block,
// because child processes can't have initialized their list at all
// prior to the first block being set up.
if (mBlocks.Length() > 1) {
dom::ContentParent::BroadcastShmBlockAdded(GetGeneration(),
mBlocks.Length() - 1);
}
return true;
}
void FontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
base::SharedMemoryHandle aHandle) {
MOZ_ASSERT(!XRE_IsParentProcess());
MOZ_ASSERT(mBlocks.Length() > 0);
auto newShm = MakeUnique<base::SharedMemory>();
if (!newShm->IsHandleValid(aHandle)) {
return;
}
if (!newShm->SetHandle(aHandle, true)) {
MOZ_CRASH("failed to set shm handle");
}
if (aIndex != mBlocks.Length()) {
return;
}
if (aGeneration != GetGeneration()) {
return;
}
if (!newShm->Map(SHM_BLOCK_SIZE) || !newShm->memory()) {
MOZ_CRASH("failed to map shared memory");
}
uint32_t size = static_cast<BlockHeader*>(newShm->memory())->mBlockSize;
MOZ_ASSERT(size >= SHM_BLOCK_SIZE);
if (size != SHM_BLOCK_SIZE) {
newShm->Unmap();
if (!newShm->Map(size) || !newShm->memory()) {
MOZ_CRASH("failed to map shared memory");
}
}
mBlocks.AppendElement(new ShmBlock(std::move(newShm)));
}
void FontList::DetachShmBlocks() {
for (auto& i : mBlocks) {
i->mShmem = nullptr;
@ -696,6 +741,20 @@ void FontList::ShareBlocksToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
}
}
base::SharedMemoryHandle FontList::ShareBlockToProcess(uint32_t aIndex,
base::ProcessId aPid) {
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
MOZ_RELEASE_ASSERT(mReadOnlyShmems.Length() == mBlocks.Length());
MOZ_RELEASE_ASSERT(aIndex < mReadOnlyShmems.Length());
base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
if (mReadOnlyShmems[aIndex]->ShareToProcess(aPid, &handle)) {
return handle;
}
return base::SharedMemory::NULLHandle();
}
Pointer FontList::Alloc(uint32_t aSize) {
// Only the parent process does allocation.
MOZ_ASSERT(XRE_IsParentProcess());

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

@ -2657,6 +2657,19 @@ void gfxPlatformFontList::ShareFontListToProcess(
}
}
base::SharedMemoryHandle gfxPlatformFontList::ShareShmBlockToProcess(
uint32_t aIndex, base::ProcessId aPid) {
MOZ_RELEASE_ASSERT(SharedFontList());
return SharedFontList()->ShareBlockToProcess(aIndex, aPid);
}
void gfxPlatformFontList::ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
base::SharedMemoryHandle aHandle) {
if (SharedFontList()) {
SharedFontList()->ShmBlockAdded(aGeneration, aIndex, aHandle);
}
}
void gfxPlatformFontList::InitializeFamily(uint32_t aGeneration,
uint32_t aFamilyIndex,
bool aLoadCmaps) {

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

@ -277,6 +277,12 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
void ShareFontListToProcess(nsTArray<base::SharedMemoryHandle>* aBlocks,
base::ProcessId aPid);
void ShmBlockAdded(uint32_t aGeneration, uint32_t aIndex,
base::SharedMemoryHandle aHandle);
base::SharedMemoryHandle ShareShmBlockToProcess(uint32_t aIndex,
base::ProcessId aPid);
void SetCharacterMap(uint32_t aGeneration,
const mozilla::fontlist::Pointer& aFacePtr,
const gfxSparseBitSet& aMap);