Changeset 251924 in webkit


Ignore:
Timestamp:
Nov 1, 2019 10:04:36 AM (4 years ago)
Author:
rniwa@webkit.org
Message:

Don't leak documents with a pending requestIdleCallback
https://bugs.webkit.org/show_bug.cgi?id=203708

Reviewed by Simon Fraser.

Source/WebCore:

Remove all tasks associated with a stopped document right away instead of waiting for
WindowEventLoop::run to execute so that even when author scripts synchronously add and remove
multiple documents, we don't end up leaking all of them until we yield to the run loop.

Also moved the code to suspend & resume event loops from CachedFrame to Document's
ActiveDOMObjects related functions for consistency.

Test: requestidlecallback/requestidlecallback-document-gc.html

  • dom/Document.cpp:

(WebCore::Document::suspendActiveDOMObjects): Moved the code from CachedFrameBase::restore.
(WebCore::Document::resumeActiveDOMObjects): Ditto from CachedFrame.
(WebCore::Document::stopActiveDOMObjects): Remove all tasks associated with this document.

  • dom/Document.h:

(WebCore::Document::eventLoopIfExists): Deleted.

  • dom/WindowEventLoop.cpp:

(WebCore::WindowEventLoop::stop):
(WebCore::WindowEventLoop::run):

  • dom/WindowEventLoop.h:
  • history/CachedFrame.cpp:

(WebCore::CachedFrameBase::restore):
(WebCore::CachedFrame::CachedFrame):

LayoutTests:

Added a test for removing iframes with a pending idle callback and test that
the current documents of those iframes are collected immediately by GCController.collect.

  • requestidlecallback/requestidlecallback-document-gc-expected.txt: Added.
  • requestidlecallback/requestidlecallback-document-gc.html: Added.
Location:
trunk
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r251920 r251924  
     12019-11-01  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Don't leak documents with a pending requestIdleCallback
     4        https://bugs.webkit.org/show_bug.cgi?id=203708
     5
     6        Reviewed by Simon Fraser.
     7
     8        Added a test for removing iframes with a pending idle callback and test that
     9        the current documents of those iframes are collected immediately by GCController.collect.
     10
     11        * requestidlecallback/requestidlecallback-document-gc-expected.txt: Added.
     12        * requestidlecallback/requestidlecallback-document-gc.html: Added.
     13
    1142019-11-01  Peng Liu  <peng.liu6@apple.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r251920 r251924  
     12019-11-01  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Don't leak documents with a pending requestIdleCallback
     4        https://bugs.webkit.org/show_bug.cgi?id=203708
     5
     6        Reviewed by Simon Fraser.
     7
     8        Remove all tasks associated with a stopped document right away instead of waiting for
     9        WindowEventLoop::run to execute so that even when author scripts synchronously add and remove
     10        multiple documents, we don't end up leaking all of them until we yield to the run loop.
     11
     12        Also moved the code to suspend & resume event loops from CachedFrame to Document's
     13        ActiveDOMObjects related functions for consistency.
     14
     15        Test: requestidlecallback/requestidlecallback-document-gc.html
     16
     17        * dom/Document.cpp:
     18        (WebCore::Document::suspendActiveDOMObjects): Moved the code from CachedFrameBase::restore.
     19        (WebCore::Document::resumeActiveDOMObjects): Ditto from CachedFrame.
     20        (WebCore::Document::stopActiveDOMObjects): Remove all tasks associated with this document.
     21        * dom/Document.h:
     22        (WebCore::Document::eventLoopIfExists): Deleted.
     23        * dom/WindowEventLoop.cpp:
     24        (WebCore::WindowEventLoop::stop):
     25        (WebCore::WindowEventLoop::run):
     26        * dom/WindowEventLoop.h:
     27        * history/CachedFrame.cpp:
     28        (WebCore::CachedFrameBase::restore):
     29        (WebCore::CachedFrame::CachedFrame):
     30
    1312019-11-01  Peng Liu  <peng.liu6@apple.com>
    232
  • trunk/Source/WebCore/dom/Document.cpp

    r251867 r251924  
    26362636void Document::suspendActiveDOMObjects(ReasonForSuspension why)
    26372637{
     2638    if (m_eventLoop)
     2639        m_eventLoop->suspend(*this);
    26382640    ScriptExecutionContext::suspendActiveDOMObjects(why);
    26392641    suspendDeviceMotionAndOrientationUpdates();
     
    26432645void Document::resumeActiveDOMObjects(ReasonForSuspension why)
    26442646{
     2647    if (m_eventLoop)
     2648        m_eventLoop->resume(*this);
    26452649    ScriptExecutionContext::resumeActiveDOMObjects(why);
    26462650    resumeDeviceMotionAndOrientationUpdates();
     
    26502654void Document::stopActiveDOMObjects()
    26512655{
     2656    if (m_eventLoop)
     2657        m_eventLoop->stop(*this);
    26522658    ScriptExecutionContext::stopActiveDOMObjects();
    26532659    platformSuspendOrStopActiveDOMObjects();
  • trunk/Source/WebCore/dom/Document.h

    r251867 r251924  
    10641064
    10651065    AbstractEventLoop& eventLoop() final;
    1066     WindowEventLoop* eventLoopIfExists() { return m_eventLoop.get(); }
    10671066
    10681067    ScriptedAnimationController* scriptedAnimationController() { return m_scriptedAnimationController.get(); }
  • trunk/Source/WebCore/dom/WindowEventLoop.cpp

    r251792 r251924  
    5757}
    5858
     59void WindowEventLoop::stop(Document& document)
     60{
     61    m_tasks.removeAllMatching([identifier = document.identifier()] (auto& task) {
     62        return task.documentIdentifier == identifier;
     63    });
     64}
     65
    5966void WindowEventLoop::scheduleToRunIfNeeded()
    6067{
     
    7178void WindowEventLoop::run()
    7279{
     80    if (m_tasks.isEmpty())
     81        return;
     82
    7383    Vector<Task> tasks = WTFMove(m_tasks);
    7484    m_documentIdentifiersForSuspendedTasks.clear();
  • trunk/Source/WebCore/dom/WindowEventLoop.h

    r251792 r251924  
    4343    void suspend(Document&);
    4444    void resume(Document&);
     45    void stop(Document&);
    4546
    4647private:
  • trunk/Source/WebCore/history/CachedFrame.cpp

    r251258 r251924  
    108108            m_document->accessSVGExtensions().unpauseAnimations();
    109109
    110         if (auto* eventLoop = m_document->eventLoopIfExists())
    111             eventLoop->resume(*m_document);
    112 
    113110        m_document->resume(ReasonForSuspension::BackForwardCache);
    114111
     
    176173    m_document->suspend(ReasonForSuspension::BackForwardCache);
    177174
    178     if (auto* eventLoop = m_document->eventLoopIfExists())
    179         eventLoop->suspend(*m_document);
    180 
    181175    m_cachedFrameScriptData = makeUnique<ScriptCachedFrameData>(frame);
    182176
Note: See TracChangeset for help on using the changeset viewer.