Backed out changeset 48ac718556a0 (bug 1297474) for crash in Marionette test test_switch_remote_frame.py TestSwitchRemoteFrame.test_remote_frame_revisit. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 19 Nov 2016 09:25:27 +0100
changeset 323547 cc8f92af70ab9d5dc7a06e6ef26bbb3f72d46d56
parent 323546 48ac718556a01201c327e022ed83825c2dbe5f56
child 323548 528b50a82eabb4481e6c113f922823325d8c1753
push id21
push usermaklebus@msu.edu
push dateThu, 01 Dec 2016 06:22:08 +0000
reviewersbackout
bugs1297474
milestone53.0a1
backs out48ac718556a01201c327e022ed83825c2dbe5f56
Backed out changeset 48ac718556a0 (bug 1297474) for crash in Marionette test test_switch_remote_frame.py TestSwitchRemoteFrame.test_remote_frame_revisit. r=backout
accessible/base/DocManager.cpp
accessible/base/DocManager.h
accessible/base/nsAccessibilityService.cpp
accessible/tests/browser/browser.ini
accessible/tests/browser/browser_shutdown_acc_reference.js
accessible/tests/browser/browser_shutdown_doc_acc_reference.js
accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js
accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js
accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js
accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js
accessible/tests/browser/browser_shutdown_multi_reference.js
accessible/tests/browser/browser_shutdown_proxy_acc_reference.js
accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js
accessible/tests/browser/head.js
accessible/xpcom/xpcAccessibleDocument.cpp
accessible/xpcom/xpcAccessibleDocument.h
accessible/xpcom/xpcAccessibleGeneric.cpp
accessible/xpcom/xpcAccessibleGeneric.h
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -81,65 +81,46 @@ DocManager::FindAccessibleInCache(nsINod
         return accessible;
       }
     }
   }
   return nullptr;
 }
 
 void
-DocManager::RemoveFromXPCDocumentCache(DocAccessible* aDocument)
-{
-  xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
-  if (xpcDoc) {
-    xpcDoc->Shutdown();
-    mXPCDocumentCache.Remove(aDocument);
-  }
-
-  if (!HasXPCDocuments()) {
-    MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
-  }
-}
-
-void
 DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
                                      nsIDocument* aDOMDocument)
 {
   // We need to remove listeners in both cases, when document is being shutdown
   // or when accessibility service is being shut down as well.
   RemoveListeners(aDOMDocument);
 
   // Document will already be removed when accessibility service is shutting
   // down so we do not need to remove it twice.
   if (nsAccessibilityService::IsShutdown()) {
     return;
   }
 
-  RemoveFromXPCDocumentCache(aDocument);
+  xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
+  if (xpcDoc) {
+    xpcDoc->Shutdown();
+    mXPCDocumentCache.Remove(aDocument);
+  }
+
   mDocAccessibleCache.Remove(aDOMDocument);
 }
 
 void
-DocManager::RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc)
+DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
 {
   xpcAccessibleDocument* doc = GetCachedXPCDocument(aDoc);
   if (doc) {
     doc->Shutdown();
     sRemoteXPCDocumentCache->Remove(aDoc);
   }
-
-  if (sRemoteXPCDocumentCache->Count() == 0) {
-    MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
-  }
-}
-
-void
-DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
-{
-  RemoveFromRemoteXPCDocumentCache(aDoc);
 }
 
 xpcAccessibleDocument*
 DocManager::GetXPCDocument(DocAccessible* aDocument)
 {
   if (!aDocument)
     return nullptr;
 
--- a/accessible/base/DocManager.h
+++ b/accessible/base/DocManager.h
@@ -61,18 +61,16 @@ public:
   Accessible* FindAccessibleInCache(nsINode* aNode) const;
 
   /**
    * Called by document accessible when it gets shutdown.
    */
   void NotifyOfDocumentShutdown(DocAccessible* aDocument,
                                 nsIDocument* aDOMDocument);
 
-  void RemoveFromXPCDocumentCache(DocAccessible* aDocument);
-
   /**
    * Return XPCOM accessible document.
    */
   xpcAccessibleDocument* GetXPCDocument(DocAccessible* aDocument);
   xpcAccessibleDocument* GetCachedXPCDocument(DocAccessible* aDocument) const
     { return mXPCDocumentCache.GetWeak(aDocument); }
 
   /*
@@ -92,18 +90,16 @@ public:
   static const nsTArray<DocAccessibleParent*>* TopLevelRemoteDocs()
     { return sRemoteDocuments; }
 
   /**
    * Remove the xpc document for a remote document if there is one.
    */
   static void NotifyOfRemoteDocShutdown(DocAccessibleParent* adoc);
 
-  static void RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc);
-
   /**
    * Get a XPC document for a remote document.
    */
   static xpcAccessibleDocument* GetXPCDocument(DocAccessibleParent* aDoc);
   static xpcAccessibleDocument* GetCachedXPCDocument(const DocAccessibleParent* aDoc)
   {
     return sRemoteXPCDocumentCache ? sRemoteXPCDocumentCache->GetWeak(aDoc)
       : nullptr;
@@ -122,22 +118,16 @@ protected:
    */
   bool Init();
 
   /**
    * Shutdown the manager.
    */
   void Shutdown();
 
-  bool HasXPCDocuments()
-  {
-    return mXPCDocumentCache.Count() > 0 ||
-           (sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() > 0);
-  }
-
 private:
   DocManager(const DocManager&);
   DocManager& operator =(const DocManager&);
 
 private:
   /**
    * Create an accessible document if it was't created and fire accessibility
    * events if needed.
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -1810,18 +1810,17 @@ MaybeShutdownAccService(uint32_t aFormer
   nsAccessibilityService* accService =
     nsAccessibilityService::gAccessibilityService;
 
   if (!accService || accService->IsShutdown()) {
     return;
   }
 
   if (nsCoreUtils::AccEventObserversExist() ||
-      xpcAccessibilityService::IsInUse() ||
-      accService->HasXPCDocuments()) {
+      xpcAccessibilityService::IsInUse()) {
     // Still used by XPCOM
     nsAccessibilityService::gConsumers =
       (nsAccessibilityService::gConsumers & ~aFormerConsumer) |
       nsAccessibilityService::eXPCOM;
     return;
   }
 
   if (nsAccessibilityService::gConsumers & ~aFormerConsumer) {
--- a/accessible/tests/browser/browser.ini
+++ b/accessible/tests/browser/browser.ini
@@ -1,29 +1,17 @@
 [DEFAULT]
 
 support-files =
   head.js
   shared-head.js
 
-[browser_shutdown_acc_reference.js]
-[browser_shutdown_doc_acc_reference.js]
-[browser_shutdown_multi_acc_reference_obj.js]
-[browser_shutdown_multi_acc_reference_doc.js]
 [browser_shutdown_multi_reference.js]
 [browser_shutdown_parent_own_reference.js]
 skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
-[browser_shutdown_proxy_acc_reference.js]
-skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
-[browser_shutdown_proxy_doc_acc_reference.js]
-skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
-[browser_shutdown_multi_proxy_acc_reference_doc.js]
-skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
-[browser_shutdown_multi_proxy_acc_reference_obj.js]
-skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_no_reference.js]
 skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_only.js]
 skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_remote_own_reference.js]
 skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
 [browser_shutdown_scope_lifecycle.js]
 [browser_shutdown_start_restart.js]
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_acc_reference.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Create a11y service.
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-
-  yield a11yInit;
-  ok(accService, 'Service initialized');
-
-  // Accessible object reference will live longer than the scope of this
-  // function.
-  let acc = yield new Promise(resolve => {
-    let intervalId = setInterval(() => {
-      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
-      if (tabAcc) {
-        clearInterval(intervalId);
-        resolve(tabAcc);
-      }
-    }, 10);
-  });
-  ok(acc, 'Accessible object is created');
-
-  let canShutdown = false;
-  // This promise will resolve only if canShutdown flag is set to true. If
-  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
-  // down, the promise will reject.
-  let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-  accService = null;
-  ok(!accService, 'Service is removed');
-
-  // Force garbage collection that should not trigger shutdown because there is
-  // a reference to an accessible object.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Now allow a11y service to shutdown.
-  canShutdown = true;
-  // Remove a reference to an accessible object.
-  acc = null;
-  ok(!acc, 'Accessible object is removed');
-
-  // Force garbage collection that should now trigger shutdown.
-  forceGC();
-  yield a11yShutdown;
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_doc_acc_reference.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Create a11y service.
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-
-  yield a11yInit;
-  ok(accService, 'Service initialized');
-
-  // Accessible document reference will live longer than the scope of this
-  // function.
-  let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
-
-  let canShutdown = false;
-  // This promise will resolve only if canShutdown flag is set to true. If
-  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
-  // down, the promise will reject.
-  let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-  accService = null;
-  ok(!accService, 'Service is removed');
-
-  // Force garbage collection that should not trigger shutdown because there is
-  // a reference to an accessible document.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Now allow a11y service to shutdown.
-  canShutdown = true;
-  // Remove a reference to an accessible document.
-  docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
-
-  // Force garbage collection that should now trigger shutdown.
-  forceGC();
-  yield a11yShutdown;
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Create a11y service.
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-
-  yield a11yInit;
-  ok(accService, 'Service initialized');
-
-  let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
-
-  // Accessible object reference will live longer than the scope of this
-  // function.
-  let acc = yield new Promise(resolve => {
-    let intervalId = setInterval(() => {
-      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
-      if (tabAcc) {
-        clearInterval(intervalId);
-        resolve(tabAcc);
-      }
-    }, 10);
-  });
-  ok(acc, 'Accessible object is created');
-
-  let canShutdown = false;
-  // This promise will resolve only if canShutdown flag is set to true. If
-  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
-  // down, the promise will reject.
-  let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-  accService = null;
-  ok(!accService, 'Service is removed');
-
-  // Force garbage collection that should not trigger shutdown because there are
-  // references to accessible objects.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Remove a reference to an accessible object.
-  acc = null;
-  ok(!acc, 'Accessible object is removed');
-  // Force garbage collection that should not trigger shutdown because there is
-  // a reference to an accessible document.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Now allow a11y service to shutdown.
-  canShutdown = true;
-  // Remove a reference to an accessible document.
-  docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
-
-  // Force garbage collection that should now trigger shutdown.
-  forceGC();
-  yield a11yShutdown;
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Create a11y service.
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-
-  yield a11yInit;
-  ok(accService, 'Service initialized');
-
-  let docAcc = accService.getAccessibleFor(document);
-  ok(docAcc, 'Accessible document is created');
-
-  // Accessible object reference will live longer than the scope of this
-  // function.
-  let acc = yield new Promise(resolve => {
-    let intervalId = setInterval(() => {
-      let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
-      if (tabAcc) {
-        clearInterval(intervalId);
-        resolve(tabAcc);
-      }
-    }, 10);
-  });
-  ok(acc, 'Accessible object is created');
-
-  let canShutdown = false;
-  // This promise will resolve only if canShutdown flag is set to true. If
-  // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
-  // down, the promise will reject.
-  let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-  accService = null;
-  ok(!accService, 'Service is removed');
-
-  // Force garbage collection that should not trigger shutdown because there are
-  // references to accessible objects.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Remove a reference to an accessible document.
-  docAcc = null;
-  ok(!docAcc, 'Accessible document is removed');
-  // Force garbage collection that should not trigger shutdown because there is
-  // a reference to an accessible object.
-  forceGC();
-  // Have some breathing room when removing a11y service references.
-  yield new Promise(resolve => executeSoon(resolve));
-
-  // Now allow a11y service to shutdown.
-  canShutdown = true;
-  // Remove a reference to an accessible object.
-  acc = null;
-  ok(!acc, 'Accessible object is removed');
-
-  // Force garbage collection that should now trigger shutdown.
-  forceGC();
-  yield a11yShutdown;
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Making sure that the e10s is enabled on Windows for testing.
-  yield setE10sPrefs();
-
-  let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
-  yield a11yInit;
-
-  yield BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: `data:text/html,
-      <html>
-        <head>
-          <meta charset="utf-8"/>
-          <title>Accessibility Test</title>
-        </head>
-        <body id="body"><div id="div"></div></body>
-      </html>`
-  }, function*(browser) {
-    let docLoadedEvent = yield docLoaded;
-    let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
-    // Remove unnecessary dangling references
-    docLoaded = null;
-    docLoadedEvent = null;
-    forceGC();
-
-    let acc = docAcc.getChildAt(0);
-    ok(acc, 'Accessible proxy is created');
-
-    let canShutdown = false;
-    let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-    accService = null;
-    ok(!accService, 'Service is removed');
-    // Force garbage collection that should not trigger shutdown because there
-    // is a reference to an accessible proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Remove a reference to an accessible proxy.
-    acc = null;
-    ok(!acc, 'Accessible proxy is removed');
-    // Force garbage collection that should not trigger shutdown because there is
-    // a reference to an accessible document proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Now allow a11y service to shutdown.
-    canShutdown = true;
-    // Remove a last reference to an accessible document proxy.
-    docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
-
-    // Force garbage collection that should now trigger shutdown.
-    forceGC();
-    yield a11yShutdown;
-  });
-
-  // Unsetting e10s related preferences.
-  yield unsetE10sPrefs();
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Making sure that the e10s is enabled on Windows for testing.
-  yield setE10sPrefs();
-
-  let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
-  yield a11yInit;
-
-  yield BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: `data:text/html,
-      <html>
-        <head>
-          <meta charset="utf-8"/>
-          <title>Accessibility Test</title>
-        </head>
-        <body id="body"><div id="div"></div></body>
-      </html>`
-  }, function*(browser) {
-    let docLoadedEvent = yield docLoaded;
-    let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
-    // Remove unnecessary dangling references
-    docLoaded = null;
-    docLoadedEvent = null;
-    forceGC();
-
-    let acc = docAcc.getChildAt(0);
-    ok(acc, 'Accessible proxy is created');
-
-    let canShutdown = false;
-    let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-    accService = null;
-    ok(!accService, 'Service is removed');
-    // Force garbage collection that should not trigger shutdown because there
-    // is a reference to an accessible proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Remove a reference to an accessible document proxy.
-    docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
-    // Force garbage collection that should not trigger shutdown because there is
-    // a reference to an accessible proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Now allow a11y service to shutdown.
-    canShutdown = true;
-    // Remove a last reference to an accessible proxy.
-    acc = null;
-    ok(!acc, 'Accessible proxy is removed');
-
-    // Force garbage collection that should now trigger shutdown.
-    forceGC();
-    yield a11yShutdown;
-  });
-
-  // Unsetting e10s related preferences.
-  yield unsetE10sPrefs();
-});
--- a/accessible/tests/browser/browser_shutdown_multi_reference.js
+++ b/accessible/tests/browser/browser_shutdown_multi_reference.js
@@ -16,17 +16,17 @@ add_task(function* () {
   // Add another reference to a11y service. This will not trigger
   // 'a11y-init-or-shutdown' event
   let accService2 = Cc['@mozilla.org/accessibilityService;1'].getService(
     Ci.nsIAccessibilityService);
   ok(accService2, 'Service initialized');
 
   info('Removing all service references');
   let canShutdown = false;
-  // This promise will resolve only if canShutdown flag is set to true. If
+  // This promise will resolve only if canShutdonw flag is set to true. If
   // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
   // down, the promise will reject.
   let a11yShutdown = new Promise((resolve, reject) =>
     shutdownPromise().then(flag => canShutdown ?
       resolve() : reject('Accessible service was shut down incorrectly')));
   // Remove first a11y service reference.
   accService1 = null;
   ok(!accService1, 'Service is removed');
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Making sure that the e10s is enabled on Windows for testing.
-  yield setE10sPrefs();
-
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
-  yield a11yInit;
-
-  yield BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: `data:text/html,
-      <html>
-        <head>
-          <meta charset="utf-8"/>
-          <title>Accessibility Test</title>
-        </head>
-        <body><div id="div" style="visibility: hidden;"></div></body>
-      </html>`
-  }, function*(browser) {
-    let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, 'div');
-    yield invokeSetStyle(browser, 'div', 'visibility', 'visible');
-    let showEvent = yield onShow;
-    let divAcc = showEvent.accessible;
-    ok(divAcc, 'Accessible proxy is created');
-    // Remove unnecessary dangling references
-    onShow = null;
-    showEvent = null;
-    forceGC();
-
-    let canShutdown = false;
-    let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-    accService = null;
-    ok(!accService, 'Service is removed');
-    // Force garbage collection that should not trigger shutdown because there
-    // is a reference to an accessible proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Now allow a11y service to shutdown.
-    canShutdown = true;
-    // Remove a last reference to an accessible proxy.
-    divAcc = null;
-    ok(!divAcc, 'Accessible proxy is removed');
-
-    // Force garbage collection that should now trigger shutdown.
-    forceGC();
-    yield a11yShutdown;
-  });
-
-  // Unsetting e10s related preferences.
-  yield unsetE10sPrefs();
-});
deleted file mode 100644
--- a/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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/. */
-
-'use strict';
-
-add_task(function* () {
-  // Making sure that the e10s is enabled on Windows for testing.
-  yield setE10sPrefs();
-
-  let docLoaded = waitForEvent(
-    Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
-  let a11yInit = initPromise();
-  let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
-    Ci.nsIAccessibilityService);
-  ok(accService, 'Service initialized');
-  yield a11yInit;
-
-  yield BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: `data:text/html,
-      <html>
-        <head>
-          <meta charset="utf-8"/>
-          <title>Accessibility Test</title>
-        </head>
-        <body id="body"></body>
-      </html>`
-  }, function*(browser) {
-    let docLoadedEvent = yield docLoaded;
-    let docAcc = docLoadedEvent.accessibleDocument;
-    ok(docAcc, 'Accessible document proxy is created');
-    // Remove unnecessary dangling references
-    docLoaded = null;
-    docLoadedEvent = null;
-    forceGC();
-
-    let canShutdown = false;
-    let a11yShutdown = new Promise((resolve, reject) =>
-    shutdownPromise().then(flag => canShutdown ? resolve() :
-      reject('Accessible service was shut down incorrectly')));
-
-    accService = null;
-    ok(!accService, 'Service is removed');
-    // Force garbage collection that should not trigger shutdown because there
-    // is a reference to an accessible proxy.
-    forceGC();
-    // Have some breathing room when removing a11y service references.
-    yield new Promise(resolve => executeSoon(resolve));
-
-    // Now allow a11y service to shutdown.
-    canShutdown = true;
-    // Remove a last reference to an accessible document proxy.
-    docAcc = null;
-    ok(!docAcc, 'Accessible document proxy is removed');
-
-    // Force garbage collection that should now trigger shutdown.
-    forceGC();
-    yield a11yShutdown;
-  });
-
-  // Unsetting e10s related preferences.
-  yield unsetE10sPrefs();
-});
--- a/accessible/tests/browser/head.js
+++ b/accessible/tests/browser/head.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
 'use strict';
 
-/* exported initPromise, shutdownPromise, waitForEvent, setE10sPrefs,
-            unsetE10sPrefs, forceGC */
+/* exported initPromise, shutdownPromise,
+            setE10sPrefs, unsetE10sPrefs, forceGC */
 
 /**
  * Set e10s related preferences in the test environment.
  * @return {Promise} promise that resolves when preferences are set.
  */
 function setE10sPrefs() {
   return new Promise(resolve =>
     SpecialPowers.pushPrefEnv({
@@ -103,38 +103,14 @@ function shutdownPromise(contentBrowser)
     contentA11yInitOrShutdownPromise(contentBrowser) :
     a11yInitOrShutdownPromise();
   return promiseOK(a11yShutdownPromise, '0').then(
     () => ok(true, 'Service shutdown correctly'),
     () => ok(false, 'Service initialized incorrectly'));
 }
 
 /**
- * Simpler verions of waitForEvent defined in
- * accessible/tests/browser/e10s/events.js
- */
-function waitForEvent(eventType, expectedId) {
-  return new Promise(resolve => {
-    let eventObserver = {
-      observe(subject) {
-        let event = subject.QueryInterface(Ci.nsIAccessibleEvent);
-        if (event.eventType === eventType &&
-            event.accessible.id === expectedId) {
-          Services.obs.removeObserver(this, 'accessible-event');
-          resolve(event);
-        }
-      }
-    };
-    Services.obs.addObserver(eventObserver, 'accessible-event', false);
-  });
-}
-
-/**
  * Force garbage collection.
  */
 function forceGC() {
-  SpecialPowers.gc();
-  SpecialPowers.forceGC();
-  SpecialPowers.forceCC();
-  SpecialPowers.gc();
-  SpecialPowers.forceGC();
-  SpecialPowers.forceCC();
+  Cu.forceCC();
+  Cu.forceGC();
 }
--- a/accessible/xpcom/xpcAccessibleDocument.cpp
+++ b/accessible/xpcom/xpcAccessibleDocument.cpp
@@ -12,38 +12,36 @@
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible-inl.h"
 #include "nsIDOMDocument.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsISupports
+// nsISupports and cycle collection
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(xpcAccessibleDocument)
 
-NS_IMPL_QUERY_INTERFACE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText,
-                                  nsIAccessibleDocument)
-NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
-NS_IMETHODIMP_(MozExternalRefCountType) xpcAccessibleDocument::Release(void)
-{
-  nsrefcnt r = xpcAccessibleHyperText::Release();
-  NS_LOG_RELEASE(this, r, "xpcAccessibleDocument");
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(xpcAccessibleDocument,
+                                                  xpcAccessibleGeneric)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCache)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
-  // The only reference to the xpcAccessibleDocument is in DocManager's cache.
-  if (r == 1 && !mIntl.IsNull() && mCache.Count() == 0) {
-    if (mIntl.IsAccessible()) {
-      GetAccService()->RemoveFromXPCDocumentCache(
-        mIntl.AsAccessible()->AsDoc());
-    } else {
-      GetAccService()->RemoveFromRemoteXPCDocumentCache(
-        mIntl.AsProxy()->AsDoc());
-    }
-  }
-  return r;
-}
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(xpcAccessibleDocument,
+                                                xpcAccessibleGeneric)
+  tmp->mCache.Clear();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(xpcAccessibleDocument)
+  NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
+NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleHyperText)
+
+NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
+NS_IMPL_RELEASE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleDocument
 
 NS_IMETHODIMP
 xpcAccessibleDocument::GetURL(nsAString& aURL)
 {
   if (!Intl())
@@ -176,17 +174,17 @@ xpcAccessibleDocument::GetAccessible(Acc
   if (ToXPCDocument(aAccessible->Document()) != this) {
     NS_ERROR("This XPCOM document is not related with given internal accessible!");
     return nullptr;
   }
 
   if (aAccessible->IsDoc())
     return this;
 
-  xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
+  xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
   if (xpcAcc)
     return xpcAcc;
 
   if (aAccessible->IsImage())
     xpcAcc = new xpcAccessibleImage(aAccessible);
   else if (aAccessible->IsTable())
     xpcAcc = new xpcAccessibleTable(aAccessible);
   else if (aAccessible->IsTableCell())
@@ -204,27 +202,27 @@ xpcAccessibleGeneric*
 xpcAccessibleDocument::GetXPCAccessible(ProxyAccessible* aProxy)
 {
   MOZ_ASSERT(mRemote);
   MOZ_ASSERT(aProxy->Document() == mIntl.AsProxy());
   if (aProxy->IsDoc()) {
     return this;
   }
 
-  xpcAccessibleGeneric* acc = mCache.Get(aProxy);
+  xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
   if (acc) {
     return acc;
   }
 
   // XXX support exposing optional interfaces.
   uint8_t interfaces = 0;
   if (aProxy->mHasValue) {
     interfaces |= eValue;
   }
-
+  
   if (aProxy->mIsHyperLink) {
     interfaces |= eHyperLink;
   }
 
   if (aProxy->mIsHyperText) {
     interfaces |= eText;
     acc = new xpcAccessibleHyperText(aProxy, interfaces);
     mCache.Put(aProxy, acc);
--- a/accessible/xpcom/xpcAccessibleDocument.h
+++ b/accessible/xpcom/xpcAccessibleDocument.h
@@ -27,16 +27,18 @@ public:
   explicit xpcAccessibleDocument(DocAccessible* aIntl) :
     xpcAccessibleHyperText(aIntl), mCache(kDefaultCacheLength), mRemote(false) { }
 
   xpcAccessibleDocument(ProxyAccessible* aProxy, uint32_t aInterfaces) :
     xpcAccessibleHyperText(aProxy, aInterfaces), mCache(kDefaultCacheLength),
     mRemote(true) {}
 
   NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(xpcAccessibleDocument,
+                                           xpcAccessibleGeneric)
 
   // nsIAccessibleDocument
   NS_IMETHOD GetURL(nsAString& aURL) final override;
   NS_IMETHOD GetTitle(nsAString& aTitle) final override;
   NS_IMETHOD GetMimeType(nsAString& aType) final override;
   NS_IMETHOD GetDocType(nsAString& aType) final override;
   NS_IMETHOD GetDOMDocument(nsIDOMDocument** aDOMDocument) final override;
   NS_IMETHOD GetWindow(mozIDOMWindowProxy** aDOMWindow) final override;
@@ -68,53 +70,43 @@ private:
     }
 
     return nullptr;
   }
 
   void NotifyOfShutdown(Accessible* aAccessible)
   {
     MOZ_ASSERT(!mRemote);
-    xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible);
-    if (xpcAcc) {
+    xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
+    if (xpcAcc)
       xpcAcc->Shutdown();
-    }
 
     mCache.Remove(aAccessible);
-    if (mCache.Count() == 0 && mRefCnt == 1) {
-      GetAccService()->RemoveFromXPCDocumentCache(
-        mIntl.AsAccessible()->AsDoc());
-    }
   }
 
   void NotifyOfShutdown(ProxyAccessible* aProxy)
   {
     MOZ_ASSERT(mRemote);
-    xpcAccessibleGeneric* xpcAcc = mCache.Get(aProxy);
-    if (xpcAcc) {
-      xpcAcc->Shutdown();
+    xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
+    if (acc) {
+      acc->Shutdown();
     }
 
     mCache.Remove(aProxy);
-    if (mCache.Count() == 0 && mRefCnt == 1) {
-      GetAccService()->RemoveFromRemoteXPCDocumentCache(
-        mIntl.AsProxy()->AsDoc());
-    }
   }
 
   friend class DocManager;
   friend class DocAccessible;
   friend class ProxyAccessible;
   friend class ProxyAccessibleBase<ProxyAccessible>;
-  friend class xpcAccessibleGeneric;
 
   xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
   xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
 
-  nsDataHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric*> mCache;
+  nsRefPtrHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric> mCache;
   bool mRemote;
 };
 
 inline xpcAccessibleGeneric*
 ToXPC(Accessible* aAccessible)
 {
   if (!aAccessible)
     return nullptr;
--- a/accessible/xpcom/xpcAccessibleGeneric.cpp
+++ b/accessible/xpcom/xpcAccessibleGeneric.cpp
@@ -4,53 +4,33 @@
  * 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/. */
 
 #include "xpcAccessibleGeneric.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsISupports
+// nsISupports and cycle collection
 
-NS_INTERFACE_MAP_BEGIN(xpcAccessibleGeneric)
+NS_IMPL_CYCLE_COLLECTION_0(xpcAccessibleGeneric)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleGeneric)
   NS_INTERFACE_MAP_ENTRY(nsIAccessible)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleSelectable,
                                      mSupportedIfaces & eSelectable)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleValue,
                                      mSupportedIfaces & eValue)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleHyperLink,
                                      mSupportedIfaces & eHyperLink)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessible)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF(xpcAccessibleGeneric)
-NS_IMPL_RELEASE(xpcAccessibleGeneric)
-
-xpcAccessibleGeneric::~xpcAccessibleGeneric()
-{
-  if (mIntl.IsNull()) {
-    return;
-  }
-
-  xpcAccessibleDocument* xpcDoc = nullptr;
-  if (mIntl.IsAccessible()) {
-    Accessible* acc = mIntl.AsAccessible();
-    if (!acc->IsDoc() && !acc->IsApplication()) {
-      xpcDoc = GetAccService()->GetXPCDocument(acc->Document());
-      xpcDoc->NotifyOfShutdown(acc);
-    }
-  } else {
-    ProxyAccessible* proxy = mIntl.AsProxy();
-    if (!proxy->IsDoc()) {
-      xpcDoc = GetAccService()->GetXPCDocument(proxy->Document());
-      xpcDoc->NotifyOfShutdown(proxy);
-    }
-  }
-}
+NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleGeneric)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleGeneric)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
 Accessible*
 xpcAccessibleGeneric::ToInternalAccessible() const
 {
   return mIntl.AsAccessible();
--- a/accessible/xpcom/xpcAccessibleGeneric.h
+++ b/accessible/xpcom/xpcAccessibleGeneric.h
@@ -36,26 +36,27 @@ public:
       mSupportedIfaces |= eValue;
     if (aInternal->IsLink())
       mSupportedIfaces |= eHyperLink;
   }
 
   xpcAccessibleGeneric(ProxyAccessible* aProxy, uint8_t aInterfaces) :
     mIntl(aProxy), mSupportedIfaces(aInterfaces) {}
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(xpcAccessibleGeneric, nsIAccessible)
 
   // nsIAccessible
   virtual Accessible* ToInternalAccessible() const final override;
 
   // xpcAccessibleGeneric
   virtual void Shutdown();
 
 protected:
-  virtual ~xpcAccessibleGeneric();
+  virtual ~xpcAccessibleGeneric() {}
 
   AccessibleOrProxy mIntl;
 
   enum {
     eSelectable = 1 << 0,
     eValue = 1 << 1,
     eHyperLink = 1 << 2,
     eText = 1 << 3