author | Carsten "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 id | 30978 |
push user | cbook@mozilla.com |
push date | Mon, 21 Nov 2016 14:44:46 +0000 |
treeherder | mozilla-central@0534254e9a40 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1297474 |
milestone | 53.0a1 |
backs out | e79129082f4a6e327d20cf8d88324fd517277b7b |
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
|
--- 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