Title: [259160] trunk/Source/WebCore
Revision
259160
Author
[email protected]
Date
2020-03-28 10:21:44 -0700 (Sat, 28 Mar 2020)

Log Message

[RenderTreeBuilder] Destroy the child first in RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers
https://bugs.webkit.org/show_bug.cgi?id=209695

Reviewed by Antti Koivisto.

The render tree tear down direction is usually leaf first (there are some non-trivial cases where we end up going container first).
Being able to access the ancestor chain helps with some final cleanup activities (e.g repaints).
This patch makes the renderer-inside-an-anonymous-wrapper case similar to the normal case as we destroy the leaf renderer first.
However the anonymous ancestor chain tear down is still container first (see r228606).

* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers):
(WebCore::isAnonymousAndSafeToDelete): Deleted.
(WebCore::findDestroyRootIncludingAnonymous): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (259159 => 259160)


--- trunk/Source/WebCore/ChangeLog	2020-03-28 16:45:56 UTC (rev 259159)
+++ trunk/Source/WebCore/ChangeLog	2020-03-28 17:21:44 UTC (rev 259160)
@@ -1,3 +1,20 @@
+2020-03-28  Zalan Bujtas  <[email protected]>
+
+        [RenderTreeBuilder] Destroy the child first in RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers
+        https://bugs.webkit.org/show_bug.cgi?id=209695
+
+        Reviewed by Antti Koivisto.
+
+        The render tree tear down direction is usually leaf first (there are some non-trivial cases where we end up going container first).
+        Being able to access the ancestor chain helps with some final cleanup activities (e.g repaints).
+        This patch makes the renderer-inside-an-anonymous-wrapper case similar to the normal case as we destroy the leaf renderer first.
+        However the anonymous ancestor chain tear down is still container first (see r228606).      
+
+        * rendering/updating/RenderTreeBuilder.cpp:
+        (WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers):
+        (WebCore::isAnonymousAndSafeToDelete): Deleted.
+        (WebCore::findDestroyRootIncludingAnonymous): Deleted.
+
 2020-03-28  Antti Koivisto  <[email protected]>
 
         Nullptr crash in InlineTextBox::emphasisMarkExistsAndIsAbove

Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp (259159 => 259160)


--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2020-03-28 16:45:56 UTC (rev 259159)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp	2020-03-28 17:21:44 UTC (rev 259160)
@@ -762,47 +762,46 @@
     removeAnonymousWrappersForInlineChildrenIfNeeded(*child.parent());
 }
 
-static bool isAnonymousAndSafeToDelete(RenderElement& element)
+void RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(RenderObject& rendererToDestroy)
 {
-    if (!element.isAnonymous())
-        return false;
-    if (element.isRenderView() || element.isRenderFragmentedFlow())
-        return false;
-    return true;
-}
-
-static RenderObject& findDestroyRootIncludingAnonymous(RenderObject& renderer)
-{
-    auto* destroyRoot = &renderer;
-    while (true) {
-        auto& destroyRootParent = *destroyRoot->parent();
-        if (!isAnonymousAndSafeToDelete(destroyRootParent))
-            break;
-        bool destroyingOnlyChild = destroyRootParent.firstChild() == destroyRoot && destroyRootParent.lastChild() == destroyRoot;
-        if (!destroyingOnlyChild)
-            break;
-        destroyRoot = &destroyRootParent;
-    }
-    return *destroyRoot;
-}
-
-void RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(RenderObject& child)
-{
     // If the tree is destroyed, there is no need for a clean-up phase.
-    if (child.renderTreeBeingDestroyed()) {
-        destroy(child);
+    if (rendererToDestroy.renderTreeBeingDestroyed()) {
+        destroy(rendererToDestroy);
         return;
     }
 
     // Remove intruding floats from sibling blocks before detaching.
-    if (is<RenderBox>(child) && child.isFloatingOrOutOfFlowPositioned())
-        downcast<RenderBox>(child).removeFloatingOrPositionedChildFromBlockLists();
-    auto& destroyRoot = findDestroyRootIncludingAnonymous(child);
+    if (is<RenderBox>(rendererToDestroy) && rendererToDestroy.isFloatingOrOutOfFlowPositioned())
+        downcast<RenderBox>(rendererToDestroy).removeFloatingOrPositionedChildFromBlockLists();
+
+    auto isAnonymousAndSafeToDelete = [] (const auto& renderer) {
+        return renderer.isAnonymous() && !renderer.isRenderView() && !renderer.isRenderFragmentedFlow();
+    };
+
+    auto destroyRootIncludingAnonymous = [&] () -> RenderObject& {
+        auto* destroyRoot = &rendererToDestroy;
+        while (!is<RenderView>(*destroyRoot)) {
+            auto& destroyRootParent = *destroyRoot->parent();
+            if (!isAnonymousAndSafeToDelete(destroyRootParent))
+                break;
+            bool destroyingOnlyChild = destroyRootParent.firstChild() == destroyRoot && destroyRootParent.lastChild() == destroyRoot;
+            if (!destroyingOnlyChild)
+                break;
+            destroyRoot = &destroyRootParent;
+        }
+        return *destroyRoot;
+    };
+
+    auto& destroyRoot = destroyRootIncludingAnonymous();
     if (is<RenderTableRow>(destroyRoot))
         tableBuilder().collapseAndDestroyAnonymousSiblingRows(downcast<RenderTableRow>(destroyRoot));
 
     // FIXME: Do not try to collapse/cleanup the anonymous wrappers inside destroy (see webkit.org/b/186746).
     auto destroyRootParent = makeWeakPtr(*destroyRoot.parent());
+    if (&rendererToDestroy != &destroyRoot) {
+        // Destroy the child renderer first, before we start tearing down the anonymous wrapper ancestor chain.
+        destroy(rendererToDestroy);
+    }
     destroy(destroyRoot);
     if (!destroyRootParent)
         return;
@@ -811,7 +810,7 @@
     // Anonymous parent might have become empty, try to delete it too.
     if (isAnonymousAndSafeToDelete(*destroyRootParent) && !destroyRootParent->firstChild())
         destroyAndCleanUpAnonymousWrappers(*destroyRootParent);
-    // WARNING: child is deleted here.
+    // WARNING: rendererToDestroy is deleted here.
 }
 
 void RenderTreeBuilder::updateAfterDescendants(RenderElement& renderer)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to