Bug 1186786 - Replace nsBaseHashtable::EnumerateRead() calls in accessible/ with iterators. r=tbsaunde.

This commit is contained in:
Nicholas Nethercote 2015-10-19 17:52:43 -07:00
parent 557eeca835
commit e9d0adefb3
4 changed files with 51 additions and 118 deletions

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- 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/. */
@ -71,13 +72,19 @@ DocManager::GetDocAccessible(nsIDocument* aDocument)
Accessible*
DocManager::FindAccessibleInCache(nsINode* aNode) const
{
nsSearchAccessibleInCacheArg arg;
arg.mNode = aNode;
for (auto iter = mDocAccessibleCache.ConstIter(); !iter.Done(); iter.Next()) {
DocAccessible* docAccessible = iter.UserData();
NS_ASSERTION(docAccessible,
"No doc accessible for the object in doc accessible cache!");
mDocAccessibleCache.EnumerateRead(SearchAccessibleInDocCache,
static_cast<void*>(&arg));
return arg.mAccessible;
if (docAccessible) {
Accessible* accessible = docAccessible->GetAccessible(aNode);
if (accessible) {
return accessible;
}
}
}
return nullptr;
}
void
@ -112,11 +119,17 @@ DocManager::GetXPCDocument(DocAccessible* aDocument)
bool
DocManager::IsProcessingRefreshDriverNotification() const
{
bool isDocRefreshing = false;
mDocAccessibleCache.EnumerateRead(SearchIfDocIsRefreshing,
static_cast<void*>(&isDocRefreshing));
for (auto iter = mDocAccessibleCache.ConstIter(); !iter.Done(); iter.Next()) {
DocAccessible* docAccessible = iter.UserData();
NS_ASSERTION(docAccessible,
"No doc accessible for the object in doc accessible cache!");
return isDocRefreshing;
if (docAccessible && docAccessible->mNotificationController &&
docAccessible->mNotificationController->IsUpdating()) {
return true;
}
}
return false;
}
#endif
@ -488,66 +501,24 @@ DocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
////////////////////////////////////////////////////////////////////////////////
// DocManager static
PLDHashOperator
DocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
*reinterpret_cast<DocAccessible**>(aUserArg) = aDocAccessible;
return PL_DHASH_STOP;
}
void
DocManager::ClearDocCache()
{
DocAccessible* docAcc = nullptr;
while (mDocAccessibleCache.EnumerateRead(GetFirstEntryInDocCache, static_cast<void*>(&docAcc))) {
if (docAcc)
// This unusual do-one-element-per-iterator approach is required because each
// DocAccessible is removed elsewhere upon its Shutdown() method being
// called, which invalidates the existing iterator.
while (mDocAccessibleCache.Count() > 0) {
auto iter = mDocAccessibleCache.Iter();
MOZ_ASSERT(!iter.Done());
DocAccessible* docAcc = iter.UserData();
NS_ASSERTION(docAcc,
"No doc accessible for the object in doc accessible cache!");
if (docAcc) {
docAcc->Shutdown();
}
}
}
PLDHashOperator
DocManager::SearchAccessibleInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
if (aDocAccessible) {
nsSearchAccessibleInCacheArg* arg =
static_cast<nsSearchAccessibleInCacheArg*>(aUserArg);
arg->mAccessible = aDocAccessible->GetAccessible(arg->mNode);
if (arg->mAccessible)
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
#ifdef DEBUG
PLDHashOperator
DocManager::SearchIfDocIsRefreshing(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"No doc accessible for the object in doc accessible cache!");
if (aDocAccessible && aDocAccessible->mNotificationController &&
aDocAccessible->mNotificationController->IsUpdating()) {
*(static_cast<bool*>(aUserArg)) = true;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
#endif
void
DocManager::RemoteDocAdded(DocAccessibleParent* aDoc)
{

View File

@ -135,36 +135,11 @@ private:
*/
DocAccessible* CreateDocOrRootAccessible(nsIDocument* aDocument);
/**
* Get first entry of the document accessible from cache.
*/
static PLDHashOperator
GetFirstEntryInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg);
/**
* Clear the cache and shutdown the document accessibles.
*/
void ClearDocCache();
struct nsSearchAccessibleInCacheArg
{
Accessible* mAccessible;
nsINode* mNode;
};
static PLDHashOperator
SearchAccessibleInDocCache(const nsIDocument* aKey,
DocAccessible* aDocAccessible,
void* aUserArg);
#ifdef DEBUG
static PLDHashOperator
SearchIfDocIsRefreshing(const nsIDocument* aKey,
DocAccessible* aDocAccessible, void* aUserArg);
#endif
typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, DocAccessible>
DocAccessibleHashtable;
DocAccessibleHashtable mDocAccessibleCache;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- 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/. */
@ -113,7 +114,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DocAccessible, Accessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVirtualCursor)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildDocuments)
tmp->mDependentIDsHash.EnumerateRead(CycleCollectorTraverseDepIDsEntry, &cb);
for (auto iter = tmp->mDependentIDsHash.Iter(); !iter.Done(); iter.Next()) {
AttrRelProviderArray* providers = iter.UserData();
for (int32_t jdx = providers->Length() - 1; jdx >= 0; jdx--) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(
cb, "content of dependent ids hash entry of document accessible");
AttrRelProvider* provider = (*providers)[jdx];
cb.NoteXPCOMChild(provider->mContent);
NS_ASSERTION(provider->mContent->IsInDoc(),
"Referred content is not in document!");
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccessibleCache)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchorJumpElm)
for (uint32_t i = 0; i < tmp->mARIAOwnsInvalidationList.Length(); ++i) {
@ -2217,25 +2231,3 @@ DocAccessible::IsLoadEventTarget() const
return (treeItem->ItemType() == nsIDocShellTreeItem::typeContent);
}
PLDHashOperator
DocAccessible::CycleCollectorTraverseDepIDsEntry(const nsAString& aKey,
AttrRelProviderArray* aProviders,
void* aUserArg)
{
nsCycleCollectionTraversalCallback* cb =
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
for (int32_t jdx = aProviders->Length() - 1; jdx >= 0; jdx--) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
"content of dependent ids hash entry of document accessible");
AttrRelProvider* provider = (*aProviders)[jdx];
cb->NoteXPCOMChild(provider->mContent);
NS_ASSERTION(provider->mContent->IsInDoc(),
"Referred content is not in document!");
}
return PL_DHASH_NEXT;
}

View File

@ -658,11 +658,6 @@ protected:
*/
DependentIDsHashtable mDependentIDsHash;
static PLDHashOperator
CycleCollectorTraverseDepIDsEntry(const nsAString& aKey,
AttrRelProviderArray* aProviders,
void* aUserArg);
friend class RelatedAccIterator;
/**