Title: [256630] trunk/Source/WebCore
Revision
256630
Author
andresg...@apple.com
Date
2020-02-14 11:22:33 -0800 (Fri, 14 Feb 2020)

Log Message

When updating a subtree of the IsolatedTree, first remove the entire subtree, not just the subtree root.
https://bugs.webkit.org/show_bug.cgi?id=207759

Reviewed by Chris Fleizach.

When updating an IsolatedTree subtree, we were removing just the root
of the subtree. Added AXIsolatedTree::removeSubtree that is now used in
updateIsolatedTree.

* accessibility/AXObjectCache.cpp:
(WebCore::createIsolatedTreeHierarchy): If the wrapper is attached
during creation, set it to null in the NodeChange so that it is not
re-attached on the AX thread.
(WebCore::AXObjectCache::updateIsolatedTree): removeSubtree instead of
removeNode.
* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::~AXIsolatedObject): When an IsolatedObject
is destroyed, it must have been detached from its wrapper.
* accessibility/isolatedtree/AXIsolatedObject.h:
* accessibility/isolatedtree/AXIsolatedTree.cpp:
(WebCore::AXIsolatedTree::NodeChange::NodeChange): Constructors now
take an IsolatedObject instead of a Ref.
(WebCore::AXIsolatedTree::removeNode):
(WebCore::AXIsolatedTree::removeSubtree):
(WebCore::AXIsolatedTree::applyPendingChanges): Attach wrappers only if
not null. The IsolatedObject refCount must be 2 at that point.
* accessibility/isolatedtree/AXIsolatedTree.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (256629 => 256630)


--- trunk/Source/WebCore/ChangeLog	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/ChangeLog	2020-02-14 19:22:33 UTC (rev 256630)
@@ -1,3 +1,33 @@
+2020-02-14  Andres Gonzalez  <andresg...@apple.com>
+
+        When updating a subtree of the IsolatedTree, first remove the entire subtree, not just the subtree root.
+        https://bugs.webkit.org/show_bug.cgi?id=207759
+
+        Reviewed by Chris Fleizach.
+
+        When updating an IsolatedTree subtree, we were removing just the root
+        of the subtree. Added AXIsolatedTree::removeSubtree that is now used in
+        updateIsolatedTree.
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::createIsolatedTreeHierarchy): If the wrapper is attached
+        during creation, set it to null in the NodeChange so that it is not
+        re-attached on the AX thread.
+        (WebCore::AXObjectCache::updateIsolatedTree): removeSubtree instead of
+        removeNode.
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::~AXIsolatedObject): When an IsolatedObject
+        is destroyed, it must have been detached from its wrapper.
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+        * accessibility/isolatedtree/AXIsolatedTree.cpp:
+        (WebCore::AXIsolatedTree::NodeChange::NodeChange): Constructors now
+        take an IsolatedObject instead of a Ref.
+        (WebCore::AXIsolatedTree::removeNode):
+        (WebCore::AXIsolatedTree::removeSubtree):
+        (WebCore::AXIsolatedTree::applyPendingChanges): Attach wrappers only if
+        not null. The IsolatedObject refCount must be 2 at that point.
+        * accessibility/isolatedtree/AXIsolatedTree.h:
+
 2020-02-14  Antoine Quint  <grao...@webkit.org>
 
         [Web Animations] Style changes due to Web Animations should not trigger CSS Transitions 

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (256629 => 256630)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-02-14 19:22:33 UTC (rev 256630)
@@ -3075,9 +3075,15 @@
 static Ref<AXIsolatedObject> createIsolatedTreeHierarchy(AXCoreObject& object, AXIsolatedTreeID treeID, AXID parentID, bool attachWrapper, Vector<AXIsolatedTree::NodeChange>& nodeChanges)
 {
     auto isolatedObject = AXIsolatedObject::create(object, treeID, parentID);
-    nodeChanges.append(AXIsolatedTree::NodeChange(isolatedObject, object.wrapper()));
-    if (attachWrapper)
+    if (attachWrapper) {
         isolatedObject->attachPlatformWrapper(object.wrapper());
+        // Since this object has already an attached wrapper, set the wrapper
+        // in the NodeChange to null so that it is not re-attached.
+        nodeChanges.append(AXIsolatedTree::NodeChange(isolatedObject, nullptr));
+    } else {
+        // Set the wrapper in the NodeChange so that it is set on the AX thread.
+        nodeChanges.append(AXIsolatedTree::NodeChange(isolatedObject, object.wrapper()));
+    }
 
     for (const auto& child : object.children()) {
         auto staticChild = createIsolatedTreeHierarchy(*child, treeID, isolatedObject->objectID(), attachWrapper, nodeChanges);
@@ -3128,7 +3134,7 @@
     case AXCheckedStateChanged:
     case AXChildrenChanged:
     case AXValueChanged: {
-        tree->removeNode(object->objectID());
+        tree->removeSubtree(object->objectID());
         auto* parent = object->parentObject();
         AXID parentID = parent ? parent->objectID() : InvalidAXID;
         Vector<AXIsolatedTree::NodeChange> nodeChanges;

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (256629 => 256630)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2020-02-14 19:22:33 UTC (rev 256630)
@@ -48,7 +48,10 @@
     return adoptRef(*new AXIsolatedObject(object, treeID, parentID));
 }
 
-AXIsolatedObject::~AXIsolatedObject() = default;
+AXIsolatedObject::~AXIsolatedObject()
+{
+    ASSERT(!wrapper());
+}
 
 void AXIsolatedObject::initializeAttributeData(AXCoreObject& object, bool isRoot)
 {

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (256629 => 256630)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2020-02-14 19:22:33 UTC (rev 256630)
@@ -46,6 +46,7 @@
 class AXIsolatedTree;
 
 class AXIsolatedObject final : public AXCoreObject {
+    friend class AXIsolatedTree;
 public:
     static Ref<AXIsolatedObject> create(AXCoreObject&, AXIsolatedTreeID, AXID parentID);
     ~AXIsolatedObject();

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp (256629 => 256630)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp	2020-02-14 19:22:33 UTC (rev 256630)
@@ -42,14 +42,14 @@
     return ++s_currentTreeID;
 }
 
-AXIsolatedTree::NodeChange::NodeChange(const Ref<AXIsolatedObject>& isolatedObject, AccessibilityObjectWrapper* wrapper)
-    : m_isolatedObject(isolatedObject.copyRef())
+AXIsolatedTree::NodeChange::NodeChange(AXIsolatedObject& isolatedObject, AccessibilityObjectWrapper* wrapper)
+    : m_isolatedObject(isolatedObject)
     , m_wrapper(wrapper)
 {
 }
 
 AXIsolatedTree::NodeChange::NodeChange(const NodeChange& other)
-    : m_isolatedObject(other.m_isolatedObject.copyRef())
+    : m_isolatedObject(other.m_isolatedObject.get())
     , m_wrapper(other.m_wrapper)
 {
 }
@@ -164,9 +164,25 @@
 void AXIsolatedTree::removeNode(AXID axID)
 {
     LockHolder locker { m_changeLogLock };
+    ASSERT(m_readerThreadNodeMap.contains(axID));
     m_pendingRemovals.append(axID);
 }
 
+void AXIsolatedTree::removeSubtree(AXID axID)
+{
+    LockHolder locker { m_changeLogLock };
+    m_pendingRemovals.append(axID);
+
+    auto object = nodeForID(axID);
+    if (!object)
+        return;
+    auto childrenIDs(object->m_childrenIDs);
+    locker.unlockEarly();
+
+    for (const auto& childID : childrenIDs)
+        removeSubtree(childID);
+}
+
 void AXIsolatedTree::appendNodeChanges(const Vector<NodeChange>& log)
 {
     LockHolder locker { m_changeLogLock };
@@ -181,17 +197,25 @@
 
     m_focusedNodeID = m_pendingFocusedNodeID;
 
-    for (const auto& item : m_pendingRemovals) {
-        if (auto object = nodeForID(item))
+    for (const auto& axID : m_pendingRemovals) {
+        if (auto object = nodeForID(axID))
             object->detach(AccessibilityDetachmentType::ElementDestroyed);
-        m_readerThreadNodeMap.remove(item);
+        m_readerThreadNodeMap.remove(axID);
     }
     m_pendingRemovals.clear();
 
-    for (auto& item : m_pendingAppends) {
-        ASSERT(item.m_wrapper);
-        item.m_isolatedObject->attachPlatformWrapper(item.m_wrapper);
-        m_readerThreadNodeMap.add(item.m_isolatedObject->objectID(), item.m_isolatedObject.copyRef());
+    for (const auto& item : m_pendingAppends) {
+        ASSERT(!m_readerThreadNodeMap.contains(item.m_isolatedObject->objectID())
+            || item.m_isolatedObject->objectID() == m_rootNodeID);
+
+        if (item.m_wrapper)
+            item.m_isolatedObject->attachPlatformWrapper(item.m_wrapper);
+
+        m_readerThreadNodeMap.add(item.m_isolatedObject->objectID(), item.m_isolatedObject.get());
+        // The reference count of the just added IsolatedObject must be 2
+        // because it is referenced by m_readerThreadNodeMap and m_pendingAppends.
+        // When m_pendingAppends is cleared, the object will be held only by m_readerThreadNodeMap.
+        ASSERT(m_readerThreadNodeMap.get(item.m_isolatedObject->objectID())->refCount() == 2);
     }
     m_pendingAppends.clear();
 }

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h (256629 => 256630)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2020-02-14 19:09:32 UTC (rev 256629)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.h	2020-02-14 19:22:33 UTC (rev 256630)
@@ -64,7 +64,7 @@
     struct NodeChange {
         Ref<AXIsolatedObject> m_isolatedObject;
         AccessibilityObjectWrapper* m_wrapper;
-        NodeChange(const Ref<AXIsolatedObject>&, AccessibilityObjectWrapper*);
+        NodeChange(AXIsolatedObject&, AccessibilityObjectWrapper*);
         NodeChange(const NodeChange&);
     };
 
@@ -71,6 +71,7 @@
     // Call on main thread
     void appendNodeChanges(const Vector<NodeChange>&);
     void removeNode(AXID);
+    void removeSubtree(AXID);
 
     void setRootNode(Ref<AXIsolatedObject>&);
     void setFocusedNodeID(AXID);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to