- Revision
- 210226
- Author
- [email protected]
- Date
- 2017-01-02 13:16:09 -0800 (Mon, 02 Jan 2017)
Log Message
Drop the render tree for documents in the page cache.
<https://webkit.org/b/121798>
Reviewed by Antti Koivisto.
To save memory and reduce complexity, have documents tear down their render tree
when entering the page cache. I've wanted to do this for a long time and it seems
like we can actually do it now.
This patch will enable a number of clean-ups since it's no longer valid for renderers
to exist while the document is in page cache.
* dom/Document.cpp:
(WebCore::Document::destroyRenderTree): Remove assertion that we're not in the page cache
since we will now be tearing down render trees right as they enter the page cache.
* dom/PageCache.cpp:
(WebCore::destroyRenderTree):
(WebCore::PageCache::addIfCacheable): Tear down the render tree right before setting
the in-cache flag. The render tree is destroyed in bottom-up order to ensure that the
main frame renderers die last.
* history/CachedFrame.cpp:
(WebCore::CachedFrameBase::restore):
* page/FrameView.h:
* page/FrameView.cpp:
(WebCore::FrameView::didRestoreFromPageCache): Update the scollable area set after restoring
a frame from the page cache. This dirties the scrolling tree, which was covered by tests.
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::setNeedsStyleRecalc):
* page/animation/AnimationController.cpp:
(WebCore::AnimationController::cancelAnimations): Make these no-ops if called
while the render tree is being torn down. This fixes some assertion failures
on layout tests and avoids pointless style invalidation.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (210225 => 210226)
--- trunk/Source/WebCore/ChangeLog 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/ChangeLog 2017-01-02 21:16:09 UTC (rev 210226)
@@ -1,5 +1,43 @@
2017-01-02 Andreas Kling <[email protected]>
+ Drop the render tree for documents in the page cache.
+ <https://webkit.org/b/121798>
+
+ Reviewed by Antti Koivisto.
+
+ To save memory and reduce complexity, have documents tear down their render tree
+ when entering the page cache. I've wanted to do this for a long time and it seems
+ like we can actually do it now.
+
+ This patch will enable a number of clean-ups since it's no longer valid for renderers
+ to exist while the document is in page cache.
+
+ * dom/Document.cpp:
+ (WebCore::Document::destroyRenderTree): Remove assertion that we're not in the page cache
+ since we will now be tearing down render trees right as they enter the page cache.
+
+ * dom/PageCache.cpp:
+ (WebCore::destroyRenderTree):
+ (WebCore::PageCache::addIfCacheable): Tear down the render tree right before setting
+ the in-cache flag. The render tree is destroyed in bottom-up order to ensure that the
+ main frame renderers die last.
+
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrameBase::restore):
+ * page/FrameView.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::didRestoreFromPageCache): Update the scollable area set after restoring
+ a frame from the page cache. This dirties the scrolling tree, which was covered by tests.
+
+ * page/animation/AnimationBase.cpp:
+ (WebCore::AnimationBase::setNeedsStyleRecalc):
+ * page/animation/AnimationController.cpp:
+ (WebCore::AnimationController::cancelAnimations): Make these no-ops if called
+ while the render tree is being torn down. This fixes some assertion failures
+ on layout tests and avoids pointless style invalidation.
+
+2017-01-02 Andreas Kling <[email protected]>
+
Discard media controls JS/CSS caches under memory pressure.
<https://webkit.org/b/166639>
Modified: trunk/Source/WebCore/dom/Document.cpp (210225 => 210226)
--- trunk/Source/WebCore/dom/Document.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -2202,7 +2202,6 @@
void Document::destroyRenderTree()
{
ASSERT(hasLivingRenderTree());
- ASSERT(m_pageCacheState != InPageCache);
SetForScope<bool> change(m_renderTreeBeingDestroyed, true);
Modified: trunk/Source/WebCore/history/CachedFrame.cpp (210225 => 210226)
--- trunk/Source/WebCore/history/CachedFrame.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/history/CachedFrame.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -130,6 +130,7 @@
m_document->page()->chrome().client().needTouchEvents(true);
#endif
+ frame.view()->didRestoreFromPageCache();
}
CachedFrame::CachedFrame(Frame& frame)
Modified: trunk/Source/WebCore/history/PageCache.cpp (210225 => 210226)
--- trunk/Source/WebCore/history/PageCache.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/history/PageCache.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -364,6 +364,20 @@
}
}
+// When entering page cache, tear down the render tree before setting the in-cache flag.
+// This maintains the invariant that render trees are never present in the page cache.
+// Note that destruction happens bottom-up so that the main frame's tree dies last.
+static void destroyRenderTree(MainFrame& mainFrame)
+{
+ for (Frame* frame = mainFrame.tree().traversePreviousWithWrap(true); frame; frame = frame->tree().traversePreviousWithWrap(false)) {
+ if (!frame->document())
+ continue;
+ auto& document = *frame->document();
+ if (document.hasLivingRenderTree())
+ document.destroyRenderTree();
+ }
+}
+
static void firePageHideEventRecursively(Frame& frame)
{
auto* document = frame.document();
@@ -407,6 +421,8 @@
return;
}
+ destroyRenderTree(page->mainFrame());
+
setPageCacheState(*page, Document::InPageCache);
// Make sure we no longer fire any JS events past this point.
Modified: trunk/Source/WebCore/page/FrameView.cpp (210225 => 210226)
--- trunk/Source/WebCore/page/FrameView.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/page/FrameView.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -636,6 +636,13 @@
return ScrollView::createScrollbar(orientation);
}
+void FrameView::didRestoreFromPageCache()
+{
+ // When restoring from page cache, the main frame stays in place while subframes get swapped in.
+ // We update the scrollable area set to ensure that scrolling data structures get invalidated.
+ updateScrollableAreaSet();
+}
+
void FrameView::setContentsSize(const IntSize& size)
{
if (size == contentsSize())
Modified: trunk/Source/WebCore/page/FrameView.h (210225 => 210226)
--- trunk/Source/WebCore/page/FrameView.h 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/page/FrameView.h 2017-01-02 21:16:09 UTC (rev 210226)
@@ -587,6 +587,8 @@
bool shouldPlaceBlockDirectionScrollbarOnLeft() const final;
+ void didRestoreFromPageCache();
+
protected:
bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) override;
void scrollContentsSlowPath(const IntRect& updateRect) override;
Modified: trunk/Source/WebCore/page/animation/AnimationBase.cpp (210225 => 210226)
--- trunk/Source/WebCore/page/animation/AnimationBase.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/page/animation/AnimationBase.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -89,9 +89,11 @@
void AnimationBase::setNeedsStyleRecalc(Element* element)
{
- ASSERT(!element || element->document().pageCacheState() == Document::NotInPageCache);
- if (element)
- element->invalidateStyleAndLayerComposition();
+ if (!element || element->document().renderTreeBeingDestroyed())
+ return;
+
+ ASSERT(element->document().pageCacheState() == Document::NotInPageCache);
+ element->invalidateStyleAndLayerComposition();
}
double AnimationBase::duration() const
Modified: trunk/Source/WebCore/page/animation/AnimationController.cpp (210225 => 210226)
--- trunk/Source/WebCore/page/animation/AnimationController.cpp 2017-01-02 16:41:11 UTC (rev 210225)
+++ trunk/Source/WebCore/page/animation/AnimationController.cpp 2017-01-02 21:16:09 UTC (rev 210226)
@@ -588,9 +588,10 @@
return;
Element* element = renderer.element();
- ASSERT(!element || element->document().pageCacheState() == Document::NotInPageCache);
- if (element)
- element->invalidateStyleAndLayerComposition();
+ if (!element || element->document().renderTreeBeingDestroyed())
+ return;
+ ASSERT(element->document().pageCacheState() == Document::NotInPageCache);
+ element->invalidateStyleAndLayerComposition();
}
bool AnimationController::updateAnimations(RenderElement& renderer, const RenderStyle& newStyle, std::unique_ptr<RenderStyle>& animatedStyle)