Modified: trunk/Source/WebCore/ChangeLog (223695 => 223696)
--- trunk/Source/WebCore/ChangeLog 2017-10-19 18:37:23 UTC (rev 223695)
+++ trunk/Source/WebCore/ChangeLog 2017-10-19 18:39:39 UTC (rev 223696)
@@ -1,3 +1,22 @@
+2017-10-19 Zalan Bujtas <[email protected]>
+
+ [FrameView::layout cleanup] Do not reenter FrameView::performPostLayoutTasks
+ https://bugs.webkit.org/show_bug.cgi?id=178518
+ <rdar://problem/35075409>
+
+ Reviewed by Antti Koivisto.
+
+ This patch tightens existing reentrancy policy on performPostLayoutTasks.
+
+ Covered by existing test cases.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::FrameView):
+ (WebCore::FrameView::reset):
+ (WebCore::FrameView::layout):
+ (WebCore::FrameView::performPostLayoutTasks):
+ * page/FrameView.h:
+
2017-10-19 Chris Dumez <[email protected]>
Unreviewed, revert r223650 as it caused crashes on the bots.
Modified: trunk/Source/WebCore/page/FrameView.cpp (223695 => 223696)
--- trunk/Source/WebCore/page/FrameView.cpp 2017-10-19 18:37:23 UTC (rev 223695)
+++ trunk/Source/WebCore/page/FrameView.cpp 2017-10-19 18:39:39 UTC (rev 223696)
@@ -242,7 +242,6 @@
, m_canHaveScrollbars(true)
, m_layoutTimer(*this, &FrameView::layoutTimerFired)
, m_layoutPhase(OutsideLayout)
- , m_inSynchronousPostLayout(false)
, m_postLayoutTasksTimer(*this, &FrameView::performPostLayoutTasks)
, m_updateEmbeddedObjectsTimer(*this, &FrameView::updateEmbeddedObjectsTimerFired)
, m_isTransparent(false)
@@ -341,7 +340,6 @@
m_needsFullRepaint = true;
m_layoutSchedulingEnabled = true;
m_layoutPhase = OutsideLayout;
- m_inSynchronousPostLayout = false;
m_layoutCount = 0;
m_postLayoutTasksTimer.stop();
m_updateEmbeddedObjectsTimer.stop();
@@ -1395,13 +1393,9 @@
bool isSubtreeLayout = false;
{
SetForScope<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
-
- if (!isLayoutNested() && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !isInChildFrameWithFrameFlattening()) {
- // This is a new top-level layout. If there are any remaining tasks from the previous
- // layout, finish them now.
- SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
+ // If this is a new top-level layout and there are any remaining tasks from the previous layout, finish them now.
+ if (!isLayoutNested() && m_postLayoutTasksTimer.isActive() && !isInChildFrameWithFrameFlattening())
performPostLayoutTasks();
- }
// Viewport-dependent media queries may cause us to need completely different style information.
auto* styleResolver = document.styleScope().resolverIfExists();
@@ -1553,16 +1547,14 @@
frame().document()->markers().invalidateRectsForAllMarkers();
if (!m_postLayoutTasksTimer.isActive()) {
- if (!m_inSynchronousPostLayout) {
+ if (!m_inPerformPostLayoutTasks) {
if (isInChildFrameWithFrameFlattening())
updateWidgetPositions();
- else {
- SetForScope<bool> inSynchronousPostLayoutChange(m_inSynchronousPostLayout, true);
+ else
performPostLayoutTasks(); // Calls resumeScheduledEvents().
- }
}
- if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || isInChildFrameWithFrameFlattening())) {
+ if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inPerformPostLayoutTasks || isInChildFrameWithFrameFlattening())) {
// If we need layout or are already in a synchronous call to postLayoutTasks(),
// defer widget updates and event dispatch until after we return. postLayoutTasks()
// can make us need to update again, and we can get stuck in a nasty cycle unless
@@ -3501,6 +3493,10 @@
void FrameView::performPostLayoutTasks()
{
+ if (m_inPerformPostLayoutTasks)
+ return;
+
+ SetForScope<bool> inPerformPostLayoutTasks(m_inPerformPostLayoutTasks, true);
// FIXME: We should not run any _javascript_ code in this function.
LOG(Layout, "FrameView %p performPostLayoutTasks", this);
Modified: trunk/Source/WebCore/page/FrameView.h (223695 => 223696)
--- trunk/Source/WebCore/page/FrameView.h 2017-10-19 18:37:23 UTC (rev 223695)
+++ trunk/Source/WebCore/page/FrameView.h 2017-10-19 18:39:39 UTC (rev 223696)
@@ -805,7 +805,7 @@
LayoutPhase m_layoutPhase;
bool m_layoutSchedulingEnabled;
- bool m_inSynchronousPostLayout;
+ bool m_inPerformPostLayoutTasks { false };
int m_layoutCount;
enum class LayoutNestedState { NotInLayout, NotNested, Nested };
LayoutNestedState m_layoutNestedState { LayoutNestedState::NotInLayout };