Changeset 153407 in webkit


Ignore:
Timestamp:
Jul 27, 2013, 5:05:11 PM (12 years ago)
Author:
ap@apple.com
Message:

HTMLParserScheduler gets into an inconsistent state when suspended for reasons
other than WillDeferLoading
https://bugs.webkit.org/show_bug.cgi?id=119172

Reviewed by Sam Weinig.

When loading is not deferred, even a suspended parser will be processing new data
from network, potentially starting its next chunk timer.

Limit suspending to when we can actually enforce it.

Here is what happens for each ReasonForSuspension:

  • JavaScriptDebuggerPaused: continuing to parse is probably wrong, but in practice,

this is unlikely to happen while debugging, and wasn't properly prevented before
this patch anyway.

  • WillDeferLoading: No change in behavior.
  • DocumentWillBecomeInactive: This is about page cache, and documents are only allowed

to be cached when fully loaded.

  • PageWillBeSuspended: This appears to be part of Frame::suspendActiveDOMObjectsAndAnimations()

implementation, I'm guessing that it is appropriate to continue loading.

  • dom/Document.cpp:

(WebCore::Document::suspendScheduledTasks):
(WebCore::Document::resumeScheduledTasks):
Only suspend/resume parsing when loading is deferred. This is not expressed directly,
but it's important to do this to avoid executing JS behind alerts and other modal dialogs.

  • html/parser/HTMLParserScheduler.h: Added m_suspended member variable for assertions.
  • html/parser/HTMLParserScheduler.cpp:

(WebCore::HTMLParserScheduler::HTMLParserScheduler):
(WebCore::HTMLParserScheduler::continueNextChunkTimerFired):
(WebCore::HTMLParserScheduler::scheduleForResume):
(WebCore::HTMLParserScheduler::suspend):
(WebCore::HTMLParserScheduler::resume):
Update m_suspended and assert as appropriate. No behavior changes for release mode.

  • page/Frame.cpp: (WebCore::Frame::suspendActiveDOMObjectsAndAnimations):

Added a FIXME.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r153406 r153407  
     12013-07-27  Alexey Proskuryakov  <ap@apple.com>
     2
     3        HTMLParserScheduler gets into an inconsistent state when suspended for reasons
     4        other than WillDeferLoading
     5        https://bugs.webkit.org/show_bug.cgi?id=119172
     6
     7        Reviewed by Sam Weinig.
     8
     9        When loading is not deferred, even a suspended parser will be processing new data
     10        from network, potentially starting its next chunk timer.
     11
     12        Limit suspending to when we can actually enforce it.
     13
     14        Here is what happens for each ReasonForSuspension:
     15        - JavaScriptDebuggerPaused: continuing to parse is probably wrong, but in practice,
     16        this is unlikely to happen while debugging, and wasn't properly prevented before
     17        this patch anyway.
     18        - WillDeferLoading: No change in behavior.
     19        - DocumentWillBecomeInactive: This is about page cache, and documents are only allowed
     20        to be cached when fully loaded.
     21        - PageWillBeSuspended: This appears to be part of Frame::suspendActiveDOMObjectsAndAnimations()
     22        implementation, I'm guessing that it is appropriate to continue loading.
     23
     24        * dom/Document.cpp:
     25        (WebCore::Document::suspendScheduledTasks):
     26        (WebCore::Document::resumeScheduledTasks):
     27        Only suspend/resume parsing when loading is deferred. This is not expressed directly,
     28        but it's important to do this to avoid executing JS behind alerts and other modal dialogs.
     29
     30        * html/parser/HTMLParserScheduler.h: Added m_suspended member variable for assertions.
     31
     32        * html/parser/HTMLParserScheduler.cpp:
     33        (WebCore::HTMLParserScheduler::HTMLParserScheduler):
     34        (WebCore::HTMLParserScheduler::continueNextChunkTimerFired):
     35        (WebCore::HTMLParserScheduler::scheduleForResume):
     36        (WebCore::HTMLParserScheduler::suspend):
     37        (WebCore::HTMLParserScheduler::resume):
     38        Update m_suspended and assert as appropriate. No behavior changes for release mode.
     39
     40        * page/Frame.cpp: (WebCore::Frame::suspendActiveDOMObjectsAndAnimations):
     41        Added a FIXME.
     42
    1432013-07-27  Alexey Proskuryakov  <ap@apple.com>
    244
  • trunk/Source/WebCore/dom/Document.cpp

    r153356 r153407  
    48174817    scriptRunner()->suspend();
    48184818    m_pendingTasksTimer.stop();
    4819     if (m_parser)
     4819
     4820    // Deferring loading and suspending parser is necessary when we need to prevent re-entrant JavaScript execution
     4821    // (e.g. while displaying an alert).
     4822    // It is not currently possible to suspend parser unless loading is deferred, because new data arriving from network
     4823    // will trigger parsing, and leave the scheduler in an inconsistent state where it doesn't know whether it's suspended or not.
     4824    if (reason == ActiveDOMObject::WillDeferLoading && m_parser)
    48204825        m_parser->suspendScheduledTasks();
    48214826
     
    48304835    ASSERT(m_scheduledTasksAreSuspended);
    48314836
    4832     if (m_parser)
     4837    if (reason == ActiveDOMObject::WillDeferLoading && m_parser)
    48334838        m_parser->resumeScheduledTasks();
    48344839    if (!m_pendingTasks.isEmpty())
  • trunk/Source/WebCore/html/parser/HTMLParserScheduler.cpp

    r147413 r153407  
    11/*
    22 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
     3 * Copyright (C) 2013 Apple, Inc. All Rights Reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    100101    , m_continueNextChunkTimer(this, &HTMLParserScheduler::continueNextChunkTimerFired)
    101102    , m_isSuspendedWithActiveTimer(false)
     103#if !ASSERT_DISABLED
     104    , m_suspended(false)
     105#endif
    102106{
    103107}
     
    110114void HTMLParserScheduler::continueNextChunkTimerFired(Timer<HTMLParserScheduler>* timer)
    111115{
     116    ASSERT(!m_suspended);
    112117    ASSERT_UNUSED(timer, timer == &m_continueNextChunkTimer);
    113118    // FIXME: The timer class should handle timer priorities instead of this code.
     
    133138void HTMLParserScheduler::scheduleForResume()
    134139{
     140    ASSERT(!m_suspended);
    135141    m_continueNextChunkTimer.startOneShot(0);
    136142}
    137143
    138 
    139144void HTMLParserScheduler::suspend()
    140145{
     146    ASSERT(!m_suspended);
    141147    ASSERT(!m_isSuspendedWithActiveTimer);
     148#if !ASSERT_DISABLED
     149    m_suspended = true;
     150#endif
     151
    142152    if (!m_continueNextChunkTimer.isActive())
    143153        return;
     
    148158void HTMLParserScheduler::resume()
    149159{
     160    ASSERT(m_suspended);
    150161    ASSERT(!m_continueNextChunkTimer.isActive());
     162#if !ASSERT_DISABLED
     163    m_suspended = false;
     164#endif
     165
    151166    if (!m_isSuspendedWithActiveTimer)
    152167        return;
  • trunk/Source/WebCore/html/parser/HTMLParserScheduler.h

    r151947 r153407  
    104104    Timer<HTMLParserScheduler> m_continueNextChunkTimer;
    105105    bool m_isSuspendedWithActiveTimer;
     106#if !ASSERT_DISABLED
     107    bool m_suspended;
     108#endif
    106109};
    107110
  • trunk/Source/WebCore/page/Frame.cpp

    r151949 r153407  
    964964        return;
    965965
     966    // FIXME: Suspend/resume calls will not match if the frame is navigated, and gets a new document.
    966967    if (document()) {
    967968        document()->suspendScriptedAnimationControllerCallbacks();
Note: See TracChangeset for help on using the changeset viewer.