Title: [287811] trunk/Source/WebCore
Revision
287811
Author
[email protected]
Date
2022-01-08 08:46:39 -0800 (Sat, 08 Jan 2022)

Log Message

AX: Improve WeakHashSet hygienics in AXObjectCache
https://bugs.webkit.org/show_bug.cgi?id=234961

Reviewed by Andres Gonzalez.

AXObjectCache owns four WeakHashSets. WeakHashSets are not notified
when the objects they hold are deleted[1], so we should be cleaning
them up in AXObjectCache::remove(Node&).

This patch also replaces range-based for loop iteration over these
WeakHashSets with WeakHashSet::forEach, which inherently checks that
each item is valid (non-null and contained in the hashset) before
using the item.

[1]: https://github.com/WebKit/WebKit/blob/main/Introduction.md#weakhashset

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::remove):
Delete the removed node from AXObjectCache's owned WeakHashSets.
(WebCore::filterWeakHashSetForRemoval): Added.
(WebCore::AXObjectCache::prepareForDocumentDestruction):
Use filterWeakHashSetForRemoval to remove soon-to-be-deleted nodes
from AXObjectCache's owned WeakHashSets.
(WebCore::AXObjectCache::performDeferredCacheUpdate):
Use WeakHashSet::forEach instead of range-based for loops.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287810 => 287811)


--- trunk/Source/WebCore/ChangeLog	2022-01-08 16:40:34 UTC (rev 287810)
+++ trunk/Source/WebCore/ChangeLog	2022-01-08 16:46:39 UTC (rev 287811)
@@ -1,5 +1,33 @@
 2022-01-08  Tyler Wilcock  <[email protected]>
 
+        AX: Improve WeakHashSet hygienics in AXObjectCache
+        https://bugs.webkit.org/show_bug.cgi?id=234961
+
+        Reviewed by Andres Gonzalez.
+
+        AXObjectCache owns four WeakHashSets. WeakHashSets are not notified
+        when the objects they hold are deleted[1], so we should be cleaning
+        them up in AXObjectCache::remove(Node&).
+
+        This patch also replaces range-based for loop iteration over these
+        WeakHashSets with WeakHashSet::forEach, which inherently checks that
+        each item is valid (non-null and contained in the hashset) before
+        using the item.
+
+        [1]: https://github.com/WebKit/WebKit/blob/main/Introduction.md#weakhashset
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::remove):
+        Delete the removed node from AXObjectCache's owned WeakHashSets.
+        (WebCore::filterWeakHashSetForRemoval): Added.
+        (WebCore::AXObjectCache::prepareForDocumentDestruction):
+        Use filterWeakHashSetForRemoval to remove soon-to-be-deleted nodes
+        from AXObjectCache's owned WeakHashSets.
+        (WebCore::AXObjectCache::performDeferredCacheUpdate):
+        Use WeakHashSet::forEach instead of range-based for loops.
+
+2022-01-08  Tyler Wilcock  <[email protected]>
+
         AX: AccessibilityObject::setFocused(true) should make the webpage focused, and make web content the first responder
         https://bugs.webkit.org/show_bug.cgi?id=234885
 

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (287810 => 287811)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-01-08 16:40:34 UTC (rev 287810)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2022-01-08 16:46:39 UTC (rev 287811)
@@ -863,6 +863,10 @@
         m_deferredTextFormControlValue.remove(downcast<Element>(&node));
         m_deferredAttributeChange.remove(downcast<Element>(&node));
         m_modalElementsSet.remove(downcast<Element>(&node));
+        m_deferredRecomputeIsIgnoredList.remove(downcast<Element>(node));
+        m_deferredSelectedChildredChangedList.remove(downcast<Element>(node));
+        m_deferredModalChangedList.remove(downcast<Element>(node));
+        m_deferredMenuListChange.remove(downcast<Element>(node));
     }
     m_deferredChildrenChangedNodeList.remove(&node);
     m_deferredTextChangedList.remove(&node);
@@ -3161,6 +3165,13 @@
         conditionallyAddNodeToFilterList(node, document, nodesToRemove);
 }
 
+static void filterWeakHashSetForRemoval(WeakHashSet<Element>& weakHashSet, const Document& document, HashSet<Ref<Node>>& nodesToRemove)
+{
+    weakHashSet.forEach([&] (auto& element) {
+        conditionallyAddNodeToFilterList(&element, document, nodesToRemove);
+    });
+}
+
 void AXObjectCache::prepareForDocumentDestruction(const Document& document)
 {
     HashSet<Ref<Node>> nodesToRemove;
@@ -3168,6 +3179,10 @@
     filterListForRemoval(m_modalElementsSet, document, nodesToRemove);
     filterListForRemoval(m_deferredTextChangedList, document, nodesToRemove);
     filterListForRemoval(m_deferredChildrenChangedNodeList, document, nodesToRemove);
+    filterWeakHashSetForRemoval(m_deferredRecomputeIsIgnoredList, document, nodesToRemove);
+    filterWeakHashSetForRemoval(m_deferredSelectedChildredChangedList, document, nodesToRemove);
+    filterWeakHashSetForRemoval(m_deferredModalChangedList, document, nodesToRemove);
+    filterWeakHashSetForRemoval(m_deferredMenuListChange, document, nodesToRemove);
     filterMapForRemoval(m_deferredTextFormControlValue, document, nodesToRemove);
     filterMapForRemoval(m_deferredAttributeChange, document, nodesToRemove);
     filterVectorPairForRemoval(m_deferredFocusedNodeChange, document, nodesToRemove);
@@ -3218,14 +3233,15 @@
         textChanged(node);
     m_deferredTextChangedList.clear();
 
-    for (auto& element : m_deferredRecomputeIsIgnoredList) {
+    m_deferredRecomputeIsIgnoredList.forEach([this] (auto& element) {
         if (auto* renderer = element.renderer())
             recomputeIsIgnored(renderer);
-    }
+    });
     m_deferredRecomputeIsIgnoredList.clear();
-    
-    for (auto& selectElement : m_deferredSelectedChildredChangedList)
+
+    m_deferredSelectedChildredChangedList.forEach([this] (auto& selectElement) {
         selectedChildrenChanged(&selectElement);
+    });
     m_deferredSelectedChildredChangedList.clear();
 
     for (auto& deferredFormControlContext : m_deferredTextFormControlValue) {
@@ -3246,12 +3262,14 @@
     }
     m_deferredFocusedNodeChange.clear();
 
-    for (auto& deferredModalChangedElement : m_deferredModalChangedList)
+    m_deferredModalChangedList.forEach([this] (auto& deferredModalChangedElement) {
         handleModalChange(deferredModalChangedElement);
+    });
     m_deferredModalChangedList.clear();
 
-    for (auto& deferredMenuListChangeElement : m_deferredMenuListChange)
+    m_deferredMenuListChange.forEach([this] (auto& deferredMenuListChangeElement) {
         postNotification(&deferredMenuListChangeElement, AXObjectCache::AXMenuListValueChanged);
+    });
     m_deferredMenuListChange.clear();
     
     platformPerformDeferredCacheUpdate();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to