bug 822664 - only use the doc accessible cache for lifetime management r=surkov
authorTrevor Saunders <trev.saunders@gmail.com>
Fri, 02 Nov 2012 19:57:58 -0400
changeset 126265 29ce28a490c94e3c2bc4bb74674ed2087dab80aa
parent 126264 1faf3072fb8bc8d52fc9b0b1b521913903513dbd
child 126266 f301d0d6f54000d57795d4f0a90e07f565ea4985
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssurkov
bugs822664
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 822664 - only use the doc accessible cache for lifetime management r=surkov
accessible/src/base/DocManager.cpp
accessible/src/base/DocManager.h
accessible/src/base/Logging.cpp
accessible/src/base/nsAccessibilityService.cpp
accessible/src/generic/DocAccessible.cpp
--- a/accessible/src/base/DocManager.cpp
+++ b/accessible/src/base/DocManager.cpp
@@ -44,17 +44,17 @@ DocAccessible*
 DocManager::GetDocAccessible(nsIDocument* aDocument)
 {
   if (!aDocument)
     return nullptr;
 
   // Ensure CacheChildren is called before we query cache.
   ApplicationAcc()->EnsureChildren();
 
-  DocAccessible* docAcc = mDocAccessibleCache.GetWeak(aDocument);
+  DocAccessible* docAcc = GetExistingDocAccessible(aDocument);
   if (docAcc)
     return docAcc;
 
   return CreateDocOrRootAccessible(aDocument);
 }
 
 Accessible*
 DocManager::FindAccessibleInCache(nsINode* aNode) const
@@ -176,17 +176,17 @@ DocManager::OnStateChange(nsIWebProgress
   }
 
   // Document loading was started.
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocLoad))
     logging::DocLoad("start document loading", aWebProgress, aRequest, aStateFlags);
 #endif
 
-  DocAccessible* docAcc = mDocAccessibleCache.GetWeak(document);
+  DocAccessible* docAcc = GetExistingDocAccessible(document);
   if (!docAcc)
     return NS_OK;
 
   nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
   NS_ENSURE_STATE(docShell);
 
   bool isReloading = false;
@@ -275,17 +275,17 @@ DocManager::HandleEvent(nsIDOMEvent* aEv
     if (document->IsInitialDocument())
       return NS_OK;
 
     // Shutdown this one and sub document accessibles.
 
     // We're allowed to not remove listeners when accessible document is
     // shutdown since we don't keep strong reference on chrome event target and
     // listeners are removed automatically when chrome event target goes away.
-    DocAccessible* docAccessible = mDocAccessibleCache.GetWeak(document);
+    DocAccessible* docAccessible = GetExistingDocAccessible(document);
     if (docAccessible)
       docAccessible->Shutdown();
 
     return NS_OK;
   }
 
   // XXX: handle error pages loading separately since they get neither
   // webprogress notifications nor 'pageshow' event.
@@ -307,17 +307,17 @@ DocManager::HandleEvent(nsIDOMEvent* aEv
 // DocManager private
 
 void
 DocManager::HandleDOMDocumentLoad(nsIDocument* aDocument,
                                   uint32_t aLoadEventType)
 {
   // Document accessible can be created before we were notified the DOM document
   // was loaded completely. However if it's not created yet then create it.
-  DocAccessible* docAcc = mDocAccessibleCache.GetWeak(aDocument);
+  DocAccessible* docAcc = GetExistingDocAccessible(aDocument);
   if (!docAcc) {
     docAcc = CreateDocOrRootAccessible(aDocument);
     if (!docAcc)
       return;
   }
 
   docAcc->NotifyOfLoad(aLoadEventType);
 }
--- a/accessible/src/base/DocManager.h
+++ b/accessible/src/base/DocManager.h
@@ -55,24 +55,16 @@ public:
 
   /**
    * Search through all document accessibles for an accessible with the given
    * unique id.
    */
   Accessible* FindAccessibleInCache(nsINode* aNode) const;
 
   /**
-   * Return document accessible from the cache. Convenient method for testing.
-   */
-  inline DocAccessible* GetDocAccessibleFromCache(nsIDocument* aDocument) const
-  {
-    return mDocAccessibleCache.GetWeak(aDocument);
-  }
-
-  /**
    * Called by document accessible when it gets shutdown.
    */
   inline void NotifyOfDocumentShutdown(nsIDocument* aDocument)
   {
     mDocAccessibleCache.Remove(aDocument);
   }
 
 #ifdef DEBUG
@@ -149,12 +141,24 @@ private:
   static PLDHashOperator
     SearchIfDocIsRefreshing(const nsIDocument* aKey,
                             DocAccessible* aDocAccessible, void* aUserArg);
 #endif
 
   DocAccessibleHashtable mDocAccessibleCache;
 };
 
+/**
+ * Return the existing document accessible for the document if any.
+ * Note this returns the doc accessible for the primary pres shell if there is
+ * more than one.
+ */
+inline DocAccessible*
+GetExistingDocAccessible(const nsIDocument* aDocument)
+{
+  nsIPresShell* ps = aDocument->GetShell();
+  return ps ? ps->GetDocAccessible() : nullptr;
+}
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11_DocManager_h_
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -395,18 +395,17 @@ logging::DocLoad(const char* aMsg, nsIWe
   nsCOMPtr<nsIDOMDocument> DOMDocument;
   DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
   if (!DOMDocument) {
     MsgEnd();
     return;
   }
 
   nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(DOMDocument));
-  DocAccessible* document =
-    GetAccService()->GetDocAccessibleFromCache(documentNode);
+  DocAccessible* document = GetExistingDocAccessible(documentNode);
 
   LogDocInfo(documentNode, document);
 
   nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
   printf("\n    ");
   LogShellLoadType(docShell);
   printf("\n");
@@ -420,18 +419,17 @@ logging::DocLoad(const char* aMsg, nsIWe
   MsgEnd();
 }
 
 void
 logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode)
 {
   MsgBegin(sDocLoadTitle, aMsg);
 
-  DocAccessible* document =
-    GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
+  DocAccessible* document = GetExistingDocAccessible(aDocumentNode);
   LogDocInfo(aDocumentNode, document);
 
   MsgEnd();
 }
 
 void
 logging::DocCompleteLoad(DocAccessible* aDocument, bool aIsLoadEventTarget)
 {
@@ -481,29 +479,29 @@ logging::DocLoadEventHandled(AccEvent* a
   MsgEnd();
 }
 
 void
 logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
                    DocAccessible* aDocument)
 {
   DocAccessible* document = aDocument ?
-    aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
+    aDocument : GetExistingDocAccessible(aDocumentNode);
 
   MsgBegin(sDocCreateTitle, aMsg);
   LogDocInfo(aDocumentNode, document);
   MsgEnd();
 }
 
 void
 logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
                     DocAccessible* aDocument)
 {
   DocAccessible* document = aDocument ?
-    aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
+    aDocument : GetExistingDocAccessible(aDocumentNode);
 
   MsgBegin(sDocDestroyTitle, aMsg);
   LogDocInfo(aDocumentNode, document);
   MsgEnd();
 }
 
 void
 logging::OuterDocDestroy(OuterDocAccessible* aOuterDoc)
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -181,32 +181,32 @@ nsAccessibilityService::FireAccessibleEv
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService
 
 Accessible*
 nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
                                                   bool aCanCreate)
 {
+  nsIPresShell* ps = aPresShell;
   nsIDocument* documentNode = aPresShell->GetDocument();
   if (documentNode) {
     nsCOMPtr<nsISupports> container = documentNode->GetContainer();
     nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
     if (treeItem) {
       nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
       treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
       if (treeItem != rootTreeItem) {
         nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem));
         nsCOMPtr<nsIPresShell> presShell;
         docShell->GetPresShell(getter_AddRefs(presShell));
-        documentNode = presShell->GetDocument();
+        ps = presShell;
       }
 
-      return aCanCreate ?
-        GetDocAccessible(documentNode) : GetDocAccessibleFromCache(documentNode);
+      return aCanCreate ? GetDocAccessible(ps) : ps->GetDocAccessible();
     }
   }
   return nullptr;
 }
 
 already_AddRefed<Accessible>
 nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
                                                nsIContent* aContent,
@@ -401,25 +401,22 @@ nsAccessibilityService::UpdateImageMap(n
       RecreateAccessible(presShell, aImageFrame->GetContent());
     }
   }
 }
 
 void
 nsAccessibilityService::PresShellActivated(nsIPresShell* aPresShell)
 {
-  nsIDocument* DOMDoc = aPresShell->GetDocument();
-  if (DOMDoc) {
-    DocAccessible* document = GetDocAccessibleFromCache(DOMDoc);
-    if (document) {
-      RootAccessible* rootDocument = document->RootAccessible();
-      NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
-      if (rootDocument)
-        rootDocument->DocumentActivated(document);
-    }
+  DocAccessible* document = aPresShell->GetDocAccessible();
+  if (document) {
+    RootAccessible* rootDocument = document->RootAccessible();
+    NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
+    if (rootDocument)
+      rootDocument->DocumentActivated(document);
   }
 }
 
 void
 nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
                                            nsIContent* aContent)
 {
   DocAccessible* document = GetDocAccessible(aPresShell);
@@ -645,17 +642,17 @@ nsAccessibilityService::GetAccessibleFro
   // our cache of document accessibles (document cache). Note usually shutdown
   // document accessibles are not stored in the document cache, however an
   // "unofficially" shutdown document (i.e. not from DocManager) can still
   // exist in the document cache.
   Accessible* accessible = FindAccessibleInCache(node);
   if (!accessible) {
     nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
     if (document)
-      accessible = GetDocAccessibleFromCache(document);
+      accessible = GetExistingDocAccessible(document);
   }
 
   NS_IF_ADDREF(*aAccessible = accessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -587,18 +587,16 @@ DocAccessible::Shutdown()
   if (!mPresShell) // already shutdown
     return;
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocDestroy))
     logging::DocDestroy("document shutdown", mDocumentNode, this);
 #endif
 
-  mPresShell->SetDocAccessible(nullptr);
-
   if (mNotificationController) {
     mNotificationController->Shutdown();
     mNotificationController = nullptr;
   }
 
   RemoveEventListeners();
 
   // Mark the document as shutdown before AT is notified about the document
@@ -624,16 +622,17 @@ DocAccessible::Shutdown()
 
   mChildDocuments.Clear();
 
   if (mVirtualCursor) {
     mVirtualCursor->RemoveObserver(this);
     mVirtualCursor = nullptr;
   }
 
+  mPresShell->SetDocAccessible(nullptr);
   mPresShell = nullptr;  // Avoid reentrancy
 
   mDependentIDsHash.Clear();
   mNodeToAccessibleMap.Clear();
   ClearCache(mAccessibleCache);
 
   HyperTextAccessibleWrap::Shutdown();