Bug 1606492 - Add nsAutoScriptBlocker to PresShell::DidDoReflow(). r=emilio
authorTing-Yu Lin <tlin@mozilla.com>
Tue, 07 Jan 2020 22:58:37 +0000
changeset 509292 f7b4438f499f2598fee82412bf00a91cb0a02c4d
parent 509291 fce0d0696080c4e6e52d5860b4f8875a3072d19c
child 509293 678115088f82111341ae09792756447f42a5d090
push id36993
push userdluca@mozilla.com
push dateWed, 08 Jan 2020 09:41:58 +0000
treeherdermozilla-central@12fb5e522dd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1606492
milestone74.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1606492 - Add nsAutoScriptBlocker to PresShell::DidDoReflow(). r=emilio Add a script block to prevent reflow observers from running the scripts, which may flush layout, until the end of DidDoReflow(). Specifically, Document::MaybeInitializeFinalizeFrameLoaders() can flush layout somewhere down in the stack as bug 1606492 comment 0 shows. Adding a script block can force it to schedule its runnable to run at the end of DidDoReflow(). Also, HandlePostedReflowCallbacks() can flush layout. It's better to check `mIsDestroying` before proceeding. Differential Revision: https://phabricator.services.mozilla.com/D59015
layout/base/PresShell.cpp
layout/base/crashtests/1606492.html
layout/base/crashtests/crashtests.list
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -8960,17 +8960,21 @@ void PresShell::WillDoReflow() {
 
   mPresContext->FlushFontFeatureValues();
 
   mLastReflowStart = GetPerformanceNowUnclamped();
 }
 
 void PresShell::DidDoReflow(bool aInterruptible) {
   HandlePostedReflowCallbacks(aInterruptible);
-
+  if (mIsDestroying) {
+    return;
+  }
+
+  nsAutoScriptBlocker scriptBlocker;
   AutoAssertNoFlush noReentrantFlush(*this);
   if (nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell()) {
     DOMHighResTimeStamp now = GetPerformanceNowUnclamped();
     docShell->NotifyReflowObservers(aInterruptible, mLastReflowStart, now);
   }
 
   if (!mPresContext->HasPendingInterrupt()) {
     mDocument->ScheduleResizeObserversNotification();
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/1606492.html
@@ -0,0 +1,21 @@
+<script>
+function go() {
+  var a = document.createElement("e")
+  document.body.appendChild(a)
+  a.addEventListener("DOMSubtreeModified", () => {
+    c.src = ""
+    d.replaceWith(b)
+    f.srcdoc = ""
+  })
+  document.execCommand("selectAll", false)
+  a.setAttribute("s", "")
+}
+</script>
+<div>
+<output id="b"></output>
+<iframe id="c" sandbox="allow-same-origin"></iframe>
+<ul contenteditable="true">
+<li id="d">A</li>
+</ul>
+<iframe id="f"></iframe>
+<audio onloadstart="go()" src="">
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -553,8 +553,9 @@ load 1576972-1.html
 load 1578844-1.html
 load 1578844-2.html
 load 1579953-1.html
 load 1580576.html
 load empty-mask.html
 load 1586600.html
 load 1599518.html
 load 1599532.html
+pref(layout.accessiblecaret.enabled,true) load 1606492.html