Changeset 192298 in webkit


Ignore:
Timestamp:
Nov 11, 2015 12:39:42 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

Merge r192133 - Crash when subtree layout is set on FrameView while auto size mode is enabled.
https://bugs.webkit.org/show_bug.cgi?id=150995
rdar://problem/22785262

Reviewed by Beth Dakin.

Autosizing initiates multiple synchronous layouts to calculate preferred view width for current content.
FrameView::autoSizeIfEnabled() is called from FrameView::layout() while we are in InPreLayout state.
It is safe to do during full layout.
However, since we setup the subtree state just before the autoSizeIfEnabled() call, reentering it with
a newly issued layout confuses SubtreeLayoutStateMaintainer.

This patch reverses the order of autoSizeIfEnabled() call and the subtree layout state setup.
It also ensures that the first layout requested by autoSizeIfEnabled() always runs on the whole tree.

Source/WebCore:

Test: fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html

  • page/FrameView.cpp:

(WebCore::FrameView::layout):
(WebCore::FrameView::convertSubtreeLayoutToFullLayout):
(WebCore::FrameView::scheduleRelayout):
(WebCore::FrameView::scheduleRelayoutOfSubtree):
(WebCore::FrameView::autoSizeIfEnabled):

  • page/FrameView.h:
  • testing/Internals.cpp:

(WebCore::Internals::enableAutoSizeMode):

  • testing/Internals.h:
  • testing/Internals.idl:

LayoutTests:

  • fast/dynamic/crash-subtree-layout-when-auto-size-enabled-expected.txt: Added.
  • fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html: Added.
Location:
releases/WebKitGTK/webkit-2.10
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.10/LayoutTests/ChangeLog

    r192296 r192298  
     12015-11-07  Zalan Bujtas  <zalan@apple.com>
     2
     3        Crash when subtree layout is set on FrameView while auto size mode is enabled.
     4        https://bugs.webkit.org/show_bug.cgi?id=150995
     5        rdar://problem/22785262
     6
     7        Reviewed by Beth Dakin.
     8
     9        Autosizing initiates multiple synchronous layouts to calculate preferred view width for current content.
     10        FrameView::autoSizeIfEnabled() is called from FrameView::layout() while we are in InPreLayout state.
     11        It is safe to do during full layout.
     12        However, since we setup the subtree state just before the autoSizeIfEnabled() call, reentering it with
     13        a newly issued layout confuses SubtreeLayoutStateMaintainer.
     14
     15        This patch reverses the order of autoSizeIfEnabled() call and the subtree layout state setup.
     16        It also ensures that the first layout requested by autoSizeIfEnabled() always runs on the whole tree. 
     17
     18        * fast/dynamic/crash-subtree-layout-when-auto-size-enabled-expected.txt: Added.
     19        * fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html: Added.
     20
    1212015-11-06  Myles C. Maxfield  <mmaxfield@apple.com>
    222
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/ChangeLog

    r192297 r192298  
     12015-11-07  Zalan Bujtas  <zalan@apple.com>
     2
     3        Crash when subtree layout is set on FrameView while auto size mode is enabled.
     4        https://bugs.webkit.org/show_bug.cgi?id=150995
     5        rdar://problem/22785262
     6
     7        Reviewed by Beth Dakin.
     8
     9        Autosizing initiates multiple synchronous layouts to calculate preferred view width for current content.
     10        FrameView::autoSizeIfEnabled() is called from FrameView::layout() while we are in InPreLayout state.
     11        It is safe to do during full layout.
     12        However, since we setup the subtree state just before the autoSizeIfEnabled() call, reentering it with
     13        a newly issued layout confuses SubtreeLayoutStateMaintainer.
     14
     15        This patch reverses the order of autoSizeIfEnabled() call and the subtree layout state setup.
     16        It also ensures that the first layout requested by autoSizeIfEnabled() always runs on the whole tree. 
     17
     18        Test: fast/dynamic/crash-subtree-layout-when-auto-size-enabled.html
     19
     20        * page/FrameView.cpp:
     21        (WebCore::FrameView::layout):
     22        (WebCore::FrameView::convertSubtreeLayoutToFullLayout):
     23        (WebCore::FrameView::scheduleRelayout):
     24        (WebCore::FrameView::scheduleRelayoutOfSubtree):
     25        (WebCore::FrameView::autoSizeIfEnabled):
     26        * page/FrameView.h:
     27        * testing/Internals.cpp:
     28        (WebCore::Internals::enableAutoSizeMode):
     29        * testing/Internals.h:
     30        * testing/Internals.idl:
     31
    1322015-11-07  Michael Catanzaro  <mcatanzaro@igalia.com>
    233
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/page/FrameView.cpp

    r189685 r192298  
    12551255    AnimationUpdateBlock animationUpdateBlock(&frame().animation());
    12561256   
    1257     if (!allowSubtree && m_layoutRoot) {
    1258         m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
    1259         m_layoutRoot = nullptr;
    1260     }
     1257    if (!allowSubtree && m_layoutRoot)
     1258        convertSubtreeLayoutToFullLayout();
    12611259
    12621260    ASSERT(frame().view() == this);
     
    12651263    Document& document = *frame().document();
    12661264    ASSERT(!document.inPageCache());
    1267 
    1268     bool subtree;
    1269     RenderElement* root;
    12701265
    12711266    {
     
    12981293        // the layout beats any sort of style recalc update that needs to occur.
    12991294        document.updateStyleIfNeeded();
    1300         m_layoutPhase = InPreLayout;
    1301 
    1302         subtree = m_layoutRoot;
    1303 
    1304         // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
     1295        // If there is only one ref to this view left, then its going to be destroyed as soon as we exit,
    13051296        // so there's no point to continuing to layout
    13061297        if (hasOneRef())
    13071298            return;
    13081299
    1309         root = subtree ? m_layoutRoot : document.renderView();
    1310         if (!root) {
    1311             // FIXME: Do we need to set m_size here?
    1312             return;
    1313         }
    1314 
    13151300        // Close block here so we can set up the font cache purge preventer, which we will still
    13161301        // want in scope even after we want m_layoutSchedulingEnabled to be restored again.
     
    13181303    }
    13191304
    1320     RenderLayer* layer;
     1305    m_layoutPhase = InPreLayout;
     1306
     1307    RenderLayer* layer = nullptr;
     1308    bool subtree = false;
     1309    RenderElement* root = nullptr;
    13211310
    13221311    ++m_nestedLayoutCount;
     
    13241313    {
    13251314        TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
     1315
     1316        autoSizeIfEnabled();
     1317
     1318        root = m_layoutRoot ? m_layoutRoot : document.renderView();
     1319        if (!root)
     1320            return;
     1321        subtree = m_layoutRoot;
    13261322
    13271323        if (!m_layoutRoot) {
     
    13391335            if (m_firstLayout && !frame().ownerElement())
    13401336                printf("Elapsed time before first layout: %lld\n", document.elapsedTime().count());
    1341 #endif       
     1337#endif
    13421338        }
    1343 
    1344         autoSizeIfEnabled();
    13451339
    13461340        m_needsFullRepaint = !subtree && (m_firstLayout || downcast<RenderView>(*root).printing());
     
    25612555    }
    25622556}
     2557void FrameView::convertSubtreeLayoutToFullLayout()
     2558{
     2559    ASSERT(m_layoutRoot);
     2560    m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
     2561    m_layoutRoot = nullptr;
     2562}
    25632563
    25642564void FrameView::layoutTimerFired()
     
    25772577    ASSERT(frame().view() == this);
    25782578
    2579     if (m_layoutRoot) {
    2580         m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
    2581         m_layoutRoot = nullptr;
    2582     }
     2579    if (m_layoutRoot)
     2580        convertSubtreeLayoutToFullLayout();
    25832581    if (!m_layoutSchedulingEnabled)
    25842582        return;
     
    26692667
    26702668    // Just do a full relayout.
    2671     m_layoutRoot->markContainingBlocksForLayout(ScheduleRelayout::No);
    2672     m_layoutRoot = nullptr;
     2669    convertSubtreeLayoutToFullLayout();
    26732670    newRelayoutRoot.markContainingBlocksForLayout(ScheduleRelayout::No);
    26742671    InspectorInstrumentation::didInvalidateLayout(frame());
     
    32133210        return;
    32143211
     3212    if (m_layoutRoot)
     3213        convertSubtreeLayoutToFullLayout();
    32153214    // Start from the minimum size and allow it to grow.
    32163215    resize(m_minAutoSize.width(), m_minAutoSize.height());
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/page/FrameView.h

    r189685 r192298  
    677677    void notifyWidgets(WidgetNotification);
    678678
     679    void convertSubtreeLayoutToFullLayout();
     680
    679681    RenderElement* viewportRenderer() const;
    680682
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/testing/Internals.cpp

    r188348 r192298  
    24002400}
    24012401
     2402void Internals::enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight)
     2403{
     2404    Document* document = contextDocument();
     2405    if (!document || !document->view())
     2406        return;
     2407    document->view()->enableAutoSizeMode(enabled, IntSize(minimumWidth, minimumHeight), IntSize(maximumWidth, maximumHeight));
     2408}
     2409
    24022410#if ENABLE(ENCRYPTED_MEDIA_V2)
    24032411void Internals::initializeMockCDM()
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/testing/Internals.h

    r187588 r192298  
    339339    void forceReload(bool endToEnd);
    340340
     341    void enableAutoSizeMode(bool enabled, int minimumWidth, int minimumHeight, int maximumWidth, int maximumHeight);
     342
    341343#if ENABLE(ENCRYPTED_MEDIA_V2)
    342344    void initializeMockCDM();
  • releases/WebKitGTK/webkit-2.10/Source/WebCore/testing/Internals.idl

    r187588 r192298  
    331331    void forceReload(boolean endToEnd);
    332332
     333    void enableAutoSizeMode(boolean enabled, long minimumWidth, long minimumHeight, long maximumWidth, long maximumHeight);
     334
    333335    [Conditional=VIDEO] void simulateAudioInterruption(Node node);
    334336    [Conditional=VIDEO, RaisesException] boolean mediaElementHasCharacteristic(Node node, DOMString characteristic);
Note: See TracChangeset for help on using the changeset viewer.