Backed out changeset e79129082f4a (bug 1297474) for crashes in m-oth windows tests
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 21 Nov 2016 10:33:49 +0100
changeset 323580 c7be1246b30124324539133b4e10645bc6b5155f
parent 323579 1eb14c93e19767628f50051ade4362941f8c85d8
child 323581 0534254e9a40b4bade2577c631fe4cfa0b5db41d
child 323667 c207eec1dcd85389bd4b796b0b10e80a3c5b5b4f
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1297474
milestone53.0a1
backs oute79129082f4a6e327d20cf8d88324fd517277b7b
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
Backed out changeset e79129082f4a (bug 1297474) for crashes in m-oth windows tests
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 && 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