Bug 1693541 - Improve uses of nsBaseHashtable and descendants and avoid multiple subsequent lookups in accessible. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D106093
This commit is contained in:
Simon Giesecke 2021-03-01 09:59:30 +00:00
parent 2586ff14b9
commit 1a4038f6e7
6 changed files with 84 additions and 86 deletions

View File

@ -117,10 +117,18 @@ void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
for (LocalAccessible* acc = visibleAcc; acc && acc != docAcc->LocalParent();
acc = acc->LocalParent()) {
if (inViewAccs.Contains(acc->UniqueID())) {
const bool alreadyPresent =
inViewAccs.WithEntryHandle(acc->UniqueID(), [&](auto&& entry) {
if (entry) {
return true;
}
entry.Insert(RefPtr{acc});
return false;
});
if (alreadyPresent) {
break;
}
inViewAccs.InsertOrUpdate(acc->UniqueID(), RefPtr{acc});
}
}

View File

@ -140,12 +140,8 @@ void DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc) {
xpcAccessibleDocument* DocManager::GetXPCDocument(DocAccessible* aDocument) {
if (!aDocument) return nullptr;
xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
if (!xpcDoc) {
xpcDoc = new xpcAccessibleDocument(aDocument);
mXPCDocumentCache.InsertOrUpdate(aDocument, RefPtr{xpcDoc});
}
return xpcDoc;
return mXPCDocumentCache.LookupOrInsertWith(
aDocument, [&] { return MakeRefPtr<xpcAccessibleDocument>(aDocument); });
}
xpcAccessibleDocument* DocManager::GetXPCDocument(DocAccessibleParent* aDoc) {

View File

@ -593,18 +593,20 @@ void DocAccessible::ScrollTimerCallback(nsITimer* aTimer, void* aClosure) {
void DocAccessible::HandleScroll(nsINode* aTarget) {
const uint32_t kScrollEventInterval = 100;
TimeStamp now = TimeStamp::Now();
TimeStamp lastDispatch;
// If we haven't dispatched a scrolling event for a target in at least
// kScrollEventInterval milliseconds, dispatch one now.
if (!mLastScrollingDispatch.Get(aTarget, &lastDispatch) ||
(now - lastDispatch).ToMilliseconds() >= kScrollEventInterval) {
// We can't fire events on a document whose tree isn't constructed yet.
if (HasLoadState(eTreeConstructed)) {
DispatchScrollingEvent(aTarget, nsIAccessibleEvent::EVENT_SCROLLING);
mLastScrollingDispatch.WithEntryHandle(aTarget, [&](auto&& lastDispatch) {
const TimeStamp now = TimeStamp::Now();
if (!lastDispatch ||
(now - lastDispatch.Data()).ToMilliseconds() >= kScrollEventInterval) {
// We can't fire events on a document whose tree isn't constructed yet.
if (HasLoadState(eTreeConstructed)) {
DispatchScrollingEvent(aTarget, nsIAccessibleEvent::EVENT_SCROLLING);
}
lastDispatch.InsertOrUpdate(now);
}
mLastScrollingDispatch.InsertOrUpdate(aTarget, now);
}
});
// If timer callback is still pending, push it 100ms into the future.
// When scrolling ends and we don't fire this callback anymore, the

View File

@ -174,29 +174,27 @@ uint32_t MsaaIdGenerator::GetContentProcessIDFor(
ClearOnShutdown(&sContentParentIdMap);
}
uint32_t value = 0;
if (sContentParentIdMap->Get(aIPCContentProcessID, &value)) {
return value;
}
uint32_t index = 0;
for (; index < ArrayLength(sContentProcessIdBitmap); ++index) {
if (sContentProcessIdBitmap[index] == UINT64_MAX) {
continue;
return sContentParentIdMap->LookupOrInsertWith(aIPCContentProcessID, [] {
uint32_t value = 0;
uint32_t index = 0;
for (; index < ArrayLength(sContentProcessIdBitmap); ++index) {
if (sContentProcessIdBitmap[index] == UINT64_MAX) {
continue;
}
uint32_t bitIndex =
CountTrailingZeroes64(~sContentProcessIdBitmap[index]);
MOZ_ASSERT(!(sContentProcessIdBitmap[index] & (1ULL << bitIndex)));
MOZ_ASSERT(bitIndex != 0 || index != 0);
sContentProcessIdBitmap[index] |= (1ULL << bitIndex);
value = index * kBitsPerElement + bitIndex;
break;
}
uint32_t bitIndex = CountTrailingZeroes64(~sContentProcessIdBitmap[index]);
MOZ_ASSERT(!(sContentProcessIdBitmap[index] & (1ULL << bitIndex)));
MOZ_ASSERT(bitIndex != 0 || index != 0);
sContentProcessIdBitmap[index] |= (1ULL << bitIndex);
value = index * kBitsPerElement + bitIndex;
break;
}
// If we run out of content process IDs, we're in trouble
MOZ_RELEASE_ASSERT(index < ArrayLength(sContentProcessIdBitmap));
// If we run out of content process IDs, we're in trouble
MOZ_RELEASE_ASSERT(index < ArrayLength(sContentProcessIdBitmap));
sContentParentIdMap->InsertOrUpdate(aIPCContentProcessID, value);
return value;
return value;
});
}
void MsaaIdGenerator::ReleaseContentProcessIDFor(

View File

@ -157,23 +157,22 @@ xpcAccessibleGeneric* xpcAccessibleDocument::GetAccessible(
if (aAccessible->IsDoc()) return this;
xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
if (xpcAcc) return xpcAcc;
return mCache.LookupOrInsertWith(aAccessible, [&]() -> xpcAccessibleGeneric* {
if (aAccessible->IsImage()) {
return new xpcAccessibleImage(aAccessible);
}
if (aAccessible->IsTable()) {
return new xpcAccessibleTable(aAccessible);
}
if (aAccessible->IsTableCell()) {
return new xpcAccessibleTableCell(aAccessible);
}
if (aAccessible->IsHyperText()) {
return new xpcAccessibleHyperText(aAccessible);
}
if (aAccessible->IsImage()) {
xpcAcc = new xpcAccessibleImage(aAccessible);
} else if (aAccessible->IsTable()) {
xpcAcc = new xpcAccessibleTable(aAccessible);
} else if (aAccessible->IsTableCell()) {
xpcAcc = new xpcAccessibleTableCell(aAccessible);
} else if (aAccessible->IsHyperText()) {
xpcAcc = new xpcAccessibleHyperText(aAccessible);
} else {
xpcAcc = new xpcAccessibleGeneric(aAccessible);
}
mCache.InsertOrUpdate(aAccessible, xpcAcc);
return xpcAcc;
return new xpcAccessibleGeneric(aAccessible);
});
}
xpcAccessibleGeneric* xpcAccessibleDocument::GetXPCAccessible(
@ -184,33 +183,24 @@ xpcAccessibleGeneric* xpcAccessibleDocument::GetXPCAccessible(
return this;
}
xpcAccessibleGeneric* acc = mCache.Get(aProxy);
if (acc) {
return acc;
}
return mCache.LookupOrInsertWith(aProxy, [&]() -> xpcAccessibleGeneric* {
// XXX support exposing optional interfaces.
uint8_t interfaces = 0;
if (aProxy->mHasValue) {
interfaces |= eValue;
}
// XXX support exposing optional interfaces.
uint8_t interfaces = 0;
if (aProxy->mHasValue) {
interfaces |= eValue;
}
if (aProxy->mIsHyperLink) {
interfaces |= eHyperLink;
}
if (aProxy->mIsHyperLink) {
interfaces |= eHyperLink;
}
if (aProxy->mIsHyperText) {
interfaces |= eText;
return new xpcAccessibleHyperText(aProxy, interfaces);
}
if (aProxy->mIsHyperText) {
interfaces |= eText;
acc = new xpcAccessibleHyperText(aProxy, interfaces);
mCache.InsertOrUpdate(aProxy, acc);
return acc;
}
acc = new xpcAccessibleGeneric(aProxy, interfaces);
mCache.InsertOrUpdate(aProxy, acc);
return acc;
return new xpcAccessibleGeneric(aProxy, interfaces);
});
}
void xpcAccessibleDocument::Shutdown() {

View File

@ -438,17 +438,21 @@ LocalAccessible* XULTreeAccessible::GetTreeItemAccessible(int32_t aRow) const {
if (NS_FAILED(rv) || aRow >= rowCount) return nullptr;
void* key = reinterpret_cast<void*>(intptr_t(aRow));
LocalAccessible* cachedTreeItem = mAccessibleCache.GetWeak(key);
if (cachedTreeItem) return cachedTreeItem;
return mAccessibleCache.WithEntryHandle(
key, [&](auto&& entry) -> LocalAccessible* {
if (entry) {
return entry->get();
}
RefPtr<LocalAccessible> treeItem = CreateTreeItemAccessible(aRow);
if (treeItem) {
mAccessibleCache.InsertOrUpdate(key, RefPtr{treeItem});
Document()->BindToDocument(treeItem, nullptr);
return treeItem;
}
RefPtr<LocalAccessible> treeItem = CreateTreeItemAccessible(aRow);
if (treeItem) {
entry.Insert(RefPtr{treeItem});
Document()->BindToDocument(treeItem, nullptr);
return treeItem.get();
}
return nullptr;
return nullptr;
});
}
void XULTreeAccessible::InvalidateCache(int32_t aRow, int32_t aCount) {