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