Drop the render tree for documents in the page cache.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Dec 2016 08:54:25 +0000 (08:54 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Dec 2016 08:54:25 +0000 (08:54 +0000)
<https://webkit.org/b/121798>

Reviewed by Darin Adler.

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.

(WebCore::Document::setPageCacheState): Tear down the render tree right before setting
the in-cache flag. From now on, there should not exist render objects for documents in
the page cache.

* 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): Make this a no-op if the render tree is being
torn down. This fixes assertions firing on animation tests.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210206 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/history/CachedFrame.cpp
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/page/animation/AnimationBase.cpp

index f7f3bc9..6942c73 100644 (file)
@@ -1,3 +1,36 @@
+2016-12-30  Andreas Kling  <akling@apple.com>
+
+        Drop the render tree for documents in the page cache.
+        <https://webkit.org/b/121798>
+
+        Reviewed by Darin Adler.
+
+        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.
+
+        (WebCore::Document::setPageCacheState): Tear down the render tree right before setting
+        the in-cache flag. From now on, there should not exist render objects for documents in
+        the page cache.
+
+        * 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): Make this a no-op if the render tree is being
+        torn down. This fixes assertions firing on animation tests.
+
 2016-12-29  Chris Fleizach  <cfleizach@apple.com>
 
         AX: Need to expose frames to iOS Accessibility
index 7f14cad..0fe2d7f 100644 (file)
@@ -2221,7 +2221,6 @@ void Document::frameDestroyed()
 void Document::destroyRenderTree()
 {
     ASSERT(hasLivingRenderTree());
-    ASSERT(m_pageCacheState != InPageCache);
 
     SetForScope<bool> change(m_renderTreeBeingDestroyed, true);
 
@@ -4524,6 +4523,13 @@ void Document::setPageCacheState(PageCacheState state)
     if (m_pageCacheState == state)
         return;
 
+    if (state == InPageCache) {
+        // 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.
+        if (hasLivingRenderTree())
+            destroyRenderTree();
+    }
+
     m_pageCacheState = state;
 
     FrameView* v = view();
index 2946003..f2c90f4 100644 (file)
@@ -130,6 +130,7 @@ void CachedFrameBase::restore()
         m_document->page()->chrome().client().needTouchEvents(true);
 #endif
 
+    frame.view()->didRestoreFromPageCache();
 }
 
 CachedFrame::CachedFrame(Frame& frame)
index 9605cf0..77075fd 100644 (file)
@@ -636,6 +636,13 @@ Ref<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
     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())
index 81806ee..23a7fd1 100644 (file)
@@ -587,6 +587,8 @@ public:
 
     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;
index 6eabc34..1c47e3d 100644 (file)
@@ -89,9 +89,11 @@ AnimationBase::AnimationBase(const Animation& animation, RenderElement* renderer
 
 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