Backed out 6 changesets (bug 1159042) for crashtest failures. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Tue, 27 Nov 2018 06:30:07 +0200
changeset 507397 d5a15c64bd401768c581663b1b13f45e66080616
parent 507396 63cbd79e897de14cb164992d37b15700fec420f0
child 507398 e321cef882b8caf0063cf9d17eec89a8b3170606
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1159042
milestone65.0a1
backs outfe77c09dee3107e675162b760a6efa9b5f0bcce3
db0e173a6ed2ed65c22a2e60bc3f358e3d19d82c
080b9ceee8eca10edabc249172d7f113c3642873
6a5191742ca1666d8ca6412993195a9096604128
3a86c3e65d440cee062e7ab2446b9f1c35c6fe28
845bc8316b05f3186d87e143c110f7f768625836
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
Backed out 6 changesets (bug 1159042) for crashtest failures. CLOSED TREE Backed out changeset fe77c09dee31 (bug 1159042) Backed out changeset db0e173a6ed2 (bug 1159042) Backed out changeset 080b9ceee8ec (bug 1159042) Backed out changeset 6a5191742ca1 (bug 1159042) Backed out changeset 3a86c3e65d44 (bug 1159042) Backed out changeset 845bc8316b05 (bug 1159042)
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsIPresShell.h
layout/generic/ReflowInput.cpp
layout/generic/ReflowInput.h
layout/generic/nsFrameStateBits.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -91,17 +91,16 @@
 #include "nsRegion.h"
 #include "nsAutoLayoutPhase.h"
 #ifdef MOZ_GECKO_PROFILER
 #include "AutoProfilerStyleMarker.h"
 #endif
 #ifdef MOZ_REFLOW_PERF
 #include "nsFontMetrics.h"
 #endif
-#include "OverflowChangedTracker.h"
 #include "PositionedEventTargeting.h"
 
 #include "nsIReflowCallback.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsFocusManager.h"
 #include "nsIObjectFrame.h"
 #include "nsIObjectLoadingContent.h"
@@ -585,91 +584,16 @@ public:
   }
 
 private:
   RefPtr<PresShell> mShell;
   AutoWeakFrame mWeakFrame;
   nsIContent** mTargetContent;
 };
 
-void
-nsIPresShell::DirtyRootsList::Add(nsIFrame* aFrame)
-{
-  // Is this root already scheduled for reflow?
-  // FIXME: This could possibly be changed to a uniqueness assertion, with some
-  // work in ResizeReflowIgnoreOverride (and maybe others?)
-  if (mList.Contains(aFrame)) {
-    // We don't expect frame to change depths.
-    MOZ_ASSERT(aFrame->GetDepthInFrameTree() ==
-               mList[mList.IndexOf(aFrame)].mDepth);
-    return;
-  }
-
-  mList.InsertElementSorted(
-    FrameAndDepth{ aFrame, aFrame->GetDepthInFrameTree() },
-    FrameAndDepth::CompareByReverseDepth{});
-}
-
-void
-nsIPresShell::DirtyRootsList::Remove(nsIFrame* aFrame)
-{
-  mList.RemoveElement(aFrame);
-}
-
-nsIFrame*
-nsIPresShell::DirtyRootsList::PopShallowestRoot()
-{
-  // List is sorted in order of decreasing depth, so there are no deeper
-  // frames than the last one.
-  const FrameAndDepth& lastFAD = mList.LastElement();
-  nsIFrame* frame = lastFAD.mFrame;
-  // We don't expect frame to change depths.
-  MOZ_ASSERT(frame->GetDepthInFrameTree() == lastFAD.mDepth);
-  mList.RemoveLastElement();
-  return frame;
-}
-
-void
-nsIPresShell::DirtyRootsList::Clear()
-{
-  mList.Clear();
-}
-
-bool
-nsIPresShell::DirtyRootsList::Contains(nsIFrame* aFrame) const
-{
-  return mList.Contains(aFrame);
-}
-
-bool
-nsIPresShell::DirtyRootsList::IsEmpty() const
-{
-  return mList.IsEmpty();
-}
-
-bool
-nsIPresShell::DirtyRootsList::FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const
-{
-  MOZ_ASSERT(aFrame);
-
-  // Look for a path from any dirty roots to aFrame, following GetParent().
-  // This check mirrors what FrameNeedsReflow() would have done if the reflow
-  // root didn't get in the way.
-  for (nsIFrame* dirtyFrame : mList) {
-    do {
-      if (dirtyFrame == aFrame) {
-        return true;
-      }
-      dirtyFrame = dirtyFrame->GetParent();
-    } while (dirtyFrame);
-  }
-
-  return false;
-}
-
 bool PresShell::sDisableNonTestMouseEvents = false;
 
 mozilla::LazyLogModule PresShell::gLog("PresShell");
 
 mozilla::TimeStamp PresShell::sLastInputCreated;
 mozilla::TimeStamp PresShell::sLastInputProcessed;
 
 bool PresShell::sProcessInteractable = false;
@@ -2091,27 +2015,27 @@ PresShell::ResizeReflowIgnoreOverride(ns
       {
         nsAutoCauseReflowNotifier crNotifier(this);
         WillDoReflow();
 
         // Kick off a top-down reflow
         AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
         nsViewManager::AutoDisableRefresh refreshBlocker(viewManager);
 
-        mDirtyRoots.Remove(rootFrame);
-        DoReflow(rootFrame, true, nullptr);
+        mDirtyRoots.RemoveElement(rootFrame);
+        DoReflow(rootFrame, true);
 
         if (shrinkToFit) {
           const bool reflowAgain = wm.IsVertical() ?
                                 mPresContext->GetVisibleArea().width > aWidth :
                                 mPresContext->GetVisibleArea().height > aHeight;
 
           if (reflowAgain) {
             mPresContext->SetVisibleArea(nsRect(0, 0, aWidth, aHeight));
-            DoReflow(rootFrame, true, nullptr);
+            DoReflow(rootFrame, true);
           }
         }
       }
 
       // the first DoReflow above should've set our bsize if it was
       // NS_UNCONSTRAINEDSIZE, and the isize shouldn't be NS_UNCONSTRAINEDSIZE
       // anyway
       NS_ASSERTION(
@@ -2227,17 +2151,22 @@ PresShell::NotifyDestroyingFrame(nsIFram
 
   if (!mIgnoreFrameDestruction) {
     if (aFrame->HasImageRequest()) {
       mDocument->StyleImageLoader()->DropRequestsForFrame(aFrame);
     }
 
     mFrameConstructor->NotifyDestroyingFrame(aFrame);
 
-    mDirtyRoots.Remove(aFrame);
+    for (int32_t idx = mDirtyRoots.Length(); idx; ) {
+      --idx;
+      if (mDirtyRoots[idx] == aFrame) {
+        mDirtyRoots.RemoveElementAt(idx);
+      }
+    }
 
     // Remove frame properties
     aFrame->DeleteAllProperties();
 
     if (aFrame == mCurrentEventFrame) {
       mCurrentEventContent = aFrame->GetContent();
       mCurrentEventFrame = nullptr;
     }
@@ -2732,18 +2661,17 @@ PresShell::VerifyHasDirtyRootAncestor(ns
   // handles the root frame correctly.
   if (!aFrame->GetParent()) {
     return;
   }
 
   // Make sure that there is a reflow root ancestor of |aFrame| that's
   // in mDirtyRoots already.
   while (aFrame && (aFrame->GetStateBits() & NS_FRAME_HAS_DIRTY_CHILDREN)) {
-    if ((aFrame->HasAnyStateBits(NS_FRAME_REFLOW_ROOT |
-                                 NS_FRAME_DYNAMIC_REFLOW_ROOT) ||
+    if (((aFrame->GetStateBits() & NS_FRAME_REFLOW_ROOT) ||
          !aFrame->GetParent()) &&
         mDirtyRoots.Contains(aFrame)) {
       return;
     }
 
     aFrame = aFrame->GetParent();
   }
 
@@ -2817,19 +2745,18 @@ PresShell::FrameNeedsReflow(nsIFrame *aF
       case eNoPositionOrSizeChange:
         targetNeedsReflowFromParent = false;
         break;
       case eInferFromBitToAdd:
         targetNeedsReflowFromParent = (aBitToAdd == NS_FRAME_IS_DIRTY);
         break;
     }
 
-#define FRAME_IS_REFLOW_ROOT(_f)                                              \
-  (_f->HasAnyStateBits(NS_FRAME_REFLOW_ROOT |                                 \
-                       NS_FRAME_DYNAMIC_REFLOW_ROOT) &&                       \
+#define FRAME_IS_REFLOW_ROOT(_f)                   \
+  ((_f->GetStateBits() & NS_FRAME_REFLOW_ROOT) &&  \
    (_f != subtreeRoot || !targetNeedsReflowFromParent))
 
 
     // Mark the intrinsic widths as dirty on the frame, all of its ancestors,
     // and all of its descendants, if needed:
 
     if (aIntrinsicDirty != nsIPresShell::eResize) {
       // Mark argument and all ancestors dirty. (Unless we hit a reflow
@@ -2887,17 +2814,17 @@ PresShell::FrameNeedsReflow(nsIFrame *aF
     // Set NS_FRAME_HAS_DIRTY_CHILDREN bits (via nsIFrame::ChildIsDirty)
     // up the tree until we reach either a frame that's already dirty or
     // a reflow root.
     nsIFrame *f = subtreeRoot;
     for (;;) {
       if (FRAME_IS_REFLOW_ROOT(f) || !f->GetParent()) {
         // we've hit a reflow root or the root frame
         if (!wasDirty) {
-          mDirtyRoots.Add(f);
+          mDirtyRoots.AppendElement(f);
           SetNeedLayoutFlush();
         }
 #ifdef DEBUG
         else {
           VerifyHasDirtyRootAncestor(f);
         }
 #endif
 
@@ -4695,17 +4622,32 @@ PresShell::NotifyCounterStylesAreDirty()
 {
   nsAutoCauseReflowNotifier reflowNotifier(this);
   mFrameConstructor->NotifyCounterStylesAreDirty();
 }
 
 bool
 nsIPresShell::FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const
 {
-  return mDirtyRoots.FrameIsAncestorOfDirtyRoot(aFrame);
+  MOZ_ASSERT(aFrame);
+
+  // Look for a path from any dirty roots to aFrame, following GetParent().
+  // This check mirrors what FrameNeedsReflow() would have done if the reflow
+  // root didn't get in the way.
+  for (nsIFrame* dirtyFrame : mDirtyRoots) {
+    while (dirtyFrame) {
+      if (dirtyFrame == aFrame) {
+        return true;
+      }
+
+      dirtyFrame = dirtyFrame->GetParent();
+    }
+  }
+
+  return false;
 }
 
 void
 PresShell::ReconstructFrames()
 {
   MOZ_ASSERT(!mFrameConstructor->GetRootFrame() || mDidInitialize,
              "Must not have root frame before initial reflow");
   if (!mDidInitialize || mIsDestroying) {
@@ -8951,18 +8893,17 @@ PresShell::ScheduleReflowOffTimer()
         "sReflowContinueCallback",
         mDocument->EventTargetFor(TaskCategory::Other));
     return NS_SUCCEEDED(rv);
   }
   return true;
 }
 
 bool
-PresShell::DoReflow(nsIFrame* target, bool aInterruptible,
-                    OverflowChangedTracker* aOverflowTracker)
+PresShell::DoReflow(nsIFrame* target, bool aInterruptible)
 {
 #ifdef MOZ_GECKO_PROFILER
   nsIURI* uri = mDocument->GetDocumentURI();
   AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(
     "PresShell::DoReflow", LAYOUT,
     uri ? uri->GetSpecOrDefault() : NS_LITERAL_CSTRING("N/A"));
 #endif
 
@@ -8998,56 +8939,47 @@ PresShell::DoReflow(nsIFrame* target, bo
   mReflowCause = nullptr;
 #endif
 
   if (mReflowContinueTimer) {
     mReflowContinueTimer->Cancel();
     mReflowContinueTimer = nullptr;
   }
 
-  const bool isRoot = target == mFrameConstructor->GetRootFrame();
-
-  MOZ_ASSERT(isRoot || aOverflowTracker,
-             "caller must provide overflow tracker when reflowing "
-             "non-root frames");
+  nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
 
   // CreateReferenceRenderingContext can return nullptr
   RefPtr<gfxContext> rcx(CreateReferenceRenderingContext());
 
 #ifdef DEBUG
   mCurrentReflowRoot = target;
 #endif
 
   // If the target frame is the root of the frame hierarchy, then
   // use all the available space. If it's simply a `reflow root',
   // then use the target frame's size as the available space.
   WritingMode wm = target->GetWritingMode();
   LogicalSize size(wm);
-  if (isRoot) {
+  if (target == rootFrame) {
     size = LogicalSize(wm, mPresContext->GetVisibleArea().Size());
   } else {
     size = target->GetLogicalSize();
   }
 
-  nsOverflowAreas oldOverflow; // initialized and used only when !isRoot
-  if (!isRoot) {
-    oldOverflow = target->GetOverflowAreas();
-  }
-
   NS_ASSERTION(!target->GetNextInFlow() && !target->GetPrevInFlow(),
                "reflow roots should never split");
 
   // Don't pass size directly to the reflow state, since a
   // constrained height implies page/column breaking.
   LogicalSize reflowSize(wm, size.ISize(wm), NS_UNCONSTRAINEDSIZE);
   ReflowInput reflowInput(mPresContext, target, rcx, reflowSize,
                                 ReflowInput::CALLER_WILL_INIT);
   reflowInput.mOrthogonalLimit = size.BSize(wm);
 
-  if (isRoot) {
+  if (rootFrame == target) {
     reflowInput.Init(mPresContext);
 
     // When the root frame is being reflowed with unconstrained block-size
     // (which happens when we're called from
     // nsDocumentViewer::SizeToContent), we're effectively doing a
     // resize in the block direction, since it changes the meaning of
     // percentage block-sizes even if no block-sizes actually changed.
     // The same applies when we reflow again after that computation. This is
@@ -9089,22 +9021,28 @@ PresShell::DoReflow(nsIFrame* target, bo
   ReflowOutput desiredSize(reflowInput);
   target->Reflow(mPresContext, desiredSize, reflowInput, status);
 
   // If an incremental reflow is initiated at a frame other than the
   // root frame, then its desired size had better not change!  If it's
   // initiated at the root, then the size better not change unless its
   // height was unconstrained to start with.
   nsRect boundsRelativeToTarget = nsRect(0, 0, desiredSize.Width(), desiredSize.Height());
-  NS_ASSERTION((isRoot &&
+  NS_ASSERTION((target == rootFrame &&
                 size.BSize(wm) == NS_UNCONSTRAINEDSIZE) ||
                (desiredSize.ISize(wm) == size.ISize(wm) &&
                 desiredSize.BSize(wm) == size.BSize(wm)),
                "non-root frame's desired size changed during an "
                "incremental reflow");
+  NS_ASSERTION(target == rootFrame ||
+               desiredSize.VisualOverflow().IsEqualInterior(boundsRelativeToTarget),
+               "non-root reflow roots must not have visible overflow");
+  NS_ASSERTION(target == rootFrame ||
+               desiredSize.ScrollableOverflow().IsEqualEdges(boundsRelativeToTarget),
+               "non-root reflow roots must not have scrollable overflow");
   NS_ASSERTION(status.IsEmpty(),
                "reflow roots should never split");
 
   target->SetSize(boundsRelativeToTarget.Size());
 
   // Always use boundsRelativeToTarget here, not desiredSize.GetVisualOverflowArea(),
   // because for root frames (where they could be different, since root frames
   // are allowed to have overflow) the root view bounds need to match the
@@ -9112,30 +9050,24 @@ PresShell::DoReflow(nsIFrame* target, bo
   nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, target,
                                              target->GetView(),
                                              boundsRelativeToTarget);
   nsContainerFrame::SyncWindowProperties(mPresContext, target,
                                          target->GetView(), rcx,
                                          nsContainerFrame::SET_ASYNC);
 
   target->DidReflow(mPresContext, nullptr);
-  if (isRoot && size.BSize(wm) == NS_UNCONSTRAINEDSIZE) {
+  if (target == rootFrame && size.BSize(wm) == NS_UNCONSTRAINEDSIZE) {
     mPresContext->SetVisibleArea(boundsRelativeToTarget);
   }
 
 #ifdef DEBUG
   mCurrentReflowRoot = nullptr;
 #endif
 
-  if (!isRoot && oldOverflow != target->GetOverflowAreas()) {
-    // The overflow area changed.  Propagate this change to ancestors.
-    aOverflowTracker->AddFrame(target->GetParent(),
-                               OverflowChangedTracker::CHILDREN_CHANGED);
-  }
-
   NS_ASSERTION(mPresContext->HasPendingInterrupt() ||
                mFramesToDirty.Count() == 0,
                "Why do we need to dirty anything if not interrupted?");
 
   mIsReflowing = false;
   bool interrupted = mPresContext->HasPendingInterrupt();
   if (interrupted) {
     // Make sure target gets reflowed again.
@@ -9149,17 +9081,17 @@ PresShell::DoReflow(nsIFrame* target, bo
 
         if (f == target) {
           break;
         }
       }
     }
 
     NS_ASSERTION(NS_SUBTREE_DIRTY(target), "Why is the target not dirty?");
-    mDirtyRoots.Add(target);
+    mDirtyRoots.AppendElement(target);
     SetNeedLayoutFlush();
 
     // Clear mFramesToDirty after we've done the NS_SUBTREE_DIRTY(target)
     // assertion so that if it fails it's easier to see what's going on.
 #ifdef NOISY_INTERRUPTIBLE_REFLOW
     printf("mFramesToDirty.Count() == %u\n", mFramesToDirty.Count());
 #endif /* NOISY_INTERRUPTIBLE_REFLOW */
     mFramesToDirty.Clear();
@@ -9242,39 +9174,37 @@ PresShell::ProcessReflowCommands(bool aI
 
     // Scope for the reflow entry point
     {
       nsAutoScriptBlocker scriptBlocker;
       WillDoReflow();
       AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
       nsViewManager::AutoDisableRefresh refreshBlocker(mViewManager);
 
-      OverflowChangedTracker overflowTracker;
-
       do {
         // Send an incremental reflow notification to the target frame.
-        nsIFrame *target = mDirtyRoots.PopShallowestRoot();
+        int32_t idx = mDirtyRoots.Length() - 1;
+        nsIFrame *target = mDirtyRoots[idx];
+        mDirtyRoots.RemoveElementAt(idx);
 
         if (!NS_SUBTREE_DIRTY(target)) {
           // It's not dirty anymore, which probably means the notification
           // was posted in the middle of a reflow (perhaps with a reflow
           // root in the middle).  Don't do anything.
           continue;
         }
 
-        interrupted = !DoReflow(target, aInterruptible, &overflowTracker);
+        interrupted = !DoReflow(target, aInterruptible);
 
         // Keep going until we're out of reflow commands, or we've run
         // past our deadline, or we're interrupted.
       } while (!interrupted && !mDirtyRoots.IsEmpty() &&
                (!aInterruptible || PR_IntervalNow() < deadline));
 
       interrupted = !mDirtyRoots.IsEmpty();
-
-      overflowTracker.Flush();
     }
 
     // Exiting the scriptblocker might have killed us
     if (!mIsDestroying) {
       DidDoReflow(aInterruptible);
     }
 
     // DidDoReflow might have killed us
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -46,17 +46,16 @@ class AutoPointerEventTargetUpdater;
 namespace mozilla {
 
 namespace dom {
 class Element;
 class Selection;
 }  // namespace dom
 
 class EventDispatchingCallback;
-class OverflowChangedTracker;
 
 // A set type for tracking visible frames, for use by the visibility code in
 // PresShell. The set contains nsIFrame* pointers.
 typedef nsTHashtable<nsPtrHashKey<nsIFrame>> VisibleFrames;
 
 // This is actually pref-controlled, but we use this value if we fail
 // to get the pref for any reason.
 #ifdef MOZ_WIDGET_ANDROID
@@ -447,20 +446,17 @@ private:
   // called off a timer, otherwise it is called directly.
   void     MaybeScheduleReflow();
   // Actually schedules a reflow.  This should only be called by
   // MaybeScheduleReflow and the reflow timer ScheduleReflowOffTimer
   // sets up.
   void     ScheduleReflow();
 
   // DoReflow returns whether the reflow finished without interruption
-  // If aFrame is not the root frame, the caller must pass a non-null
-  // aOverflowTracker.
-  bool DoReflow(nsIFrame* aFrame, bool aInterruptible,
-                mozilla::OverflowChangedTracker* aOverflowTracker);
+  bool DoReflow(nsIFrame* aFrame, bool aInterruptible);
 #ifdef DEBUG
   void DoVerifyReflow();
   void VerifyHasDirtyRootAncestor(nsIFrame* aFrame);
 #endif
 
   // Helper for ScrollContentIntoView
   void DoScrollContentIntoView();
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1779,65 +1779,18 @@ protected:
   nsPoint                   mVisualViewportOffset;
 
   // A list of stack weak frames. This is a pointer to the last item in the list.
   AutoWeakFrame*            mAutoWeakFrames;
 
   // A hash table of heap allocated weak frames.
   nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
 
-  class DirtyRootsList
-  {
-  public:
-    // Add a dirty root.
-    void Add(nsIFrame* aFrame);
-    // Remove this frame if present.
-    void Remove(nsIFrame* aFrame);
-    // Remove and return one of the shallowest dirty roots from the list.
-    // (If two roots are at the same depth, order is indeterminate.)
-    nsIFrame* PopShallowestRoot();
-    // Remove all dirty roots.
-    void Clear();
-    // Is this frame one of the dirty roots?
-    bool Contains(nsIFrame* aFrame) const;
-    // Are there no dirty roots?
-    bool IsEmpty() const;
-    // Is the given frame an ancestor of any dirty root?
-    bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
-
-  private:
-    struct FrameAndDepth
-    {
-      nsIFrame* mFrame;
-      const uint32_t mDepth;
-
-      // Easy conversion to nsIFrame*, as it's the most likely need.
-      operator nsIFrame*() const { return mFrame; }
-
-      // Used to sort by reverse depths, i.e., deeper < shallower.
-      class CompareByReverseDepth
-      {
-      public:
-        bool Equals(const FrameAndDepth& aA, const FrameAndDepth& aB) const
-        {
-          return aA.mDepth == aB.mDepth;
-        }
-        bool LessThan(const FrameAndDepth& aA, const FrameAndDepth& aB) const
-        {
-          // Reverse depth! So '>' instead of '<'.
-          return aA.mDepth > aB.mDepth;
-        }
-      };
-    };
-    // List of all known dirty roots, sorted by decreasing depths.
-    nsTArray<FrameAndDepth> mList;
-  };
-
   // Reflow roots that need to be reflowed.
-  DirtyRootsList mDirtyRoots;
+  nsTArray<nsIFrame*> mDirtyRoots;
 
 #ifdef MOZ_GECKO_PROFILER
   // These two fields capture call stacks of any changes that require a restyle
   // or a reflow. Only the first change per restyle / reflow is recorded (the
   // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
   UniqueProfilerBacktrace mStyleCause;
   UniqueProfilerBacktrace mReflowCause;
 #endif
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -424,17 +424,16 @@ ReflowInput::Init(nsPresContext*     aPr
   LogicalSize cbSize(mWritingMode, -1, -1);
   if (aContainingBlockSize) {
     cbSize = *aContainingBlockSize;
   }
 
   InitConstraints(aPresContext, cbSize, aBorder, aPadding, type);
 
   InitResizeFlags(aPresContext, type);
-  InitDynamicReflowRoot();
 
   nsIFrame *parent = mFrame->GetParent();
   if (parent &&
       (parent->GetStateBits() & NS_FRAME_IN_CONSTRAINED_BSIZE) &&
       !(parent->IsScrollFrame() &&
         parent->StyleDisplay()->mOverflowY != NS_STYLE_OVERFLOW_HIDDEN)) {
     mFrame->AddStateBits(NS_FRAME_IN_CONSTRAINED_BSIZE);
   } else if (type == LayoutFrameType::SVGForeignObject) {
@@ -828,110 +827,16 @@ ReflowInput::InitResizeFlags(nsPresConte
   }
   if (mFrame->GetStateBits() & NS_FRAME_IS_DIRTY) {
     // If we're reflowing everything, then we'll find out if we need
     // to re-set this.
     mFrame->RemoveStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
   }
 }
 
-static inline bool
-IsIntrinsicKeyword(const nsStyleCoord& aCoord)
-{
-  if (aCoord.GetUnit() != eStyleUnit_Enumerated) {
-    return false;
-  }
-
-  // All of the keywords except for '-moz-available' depend on intrinsic sizes.
-  return aCoord.GetIntValue() != NS_STYLE_WIDTH_AVAILABLE;
-}
-
-void
-ReflowInput::InitDynamicReflowRoot()
-{
-  auto display = mStyleDisplay->mDisplay;
-  if (mFrame->IsFrameOfType(nsIFrame::eLineParticipant) ||
-      nsStyleDisplay::IsRubyDisplayType(display) ||
-      mFrameType == NS_CSS_FRAME_TYPE_INTERNAL_TABLE ||
-      display == StyleDisplay::Table ||
-      display == StyleDisplay::TableCaption ||
-      display == StyleDisplay::InlineTable ||
-      (mFrame->GetParent() && mFrame->GetParent()->IsXULBoxFrame())) {
-    // We have a display type where 'width' and 'height' don't actually
-    // set the width or height (i.e., the size depends on content).
-    NS_ASSERTION(!(mFrame->GetStateBits() & NS_FRAME_DYNAMIC_REFLOW_ROOT),
-                 "should not have dynamic reflow root bit");
-    return;
-  }
-
-  bool canBeDynamicReflowRoot = true;
-
-  // We can't do this if our used 'width' and 'height' might be influenced by
-  // content.
-  // FIXME: For display:block, we should probably optimize inline-size
-  // being auto.
-  // FIXME: Other flex and grid cases?
-  const nsStyleCoord& width = mStylePosition->mWidth;
-  const nsStyleCoord& height = mStylePosition->mHeight;
-  if (!width.IsCoordPercentCalcUnit() ||
-      width.HasPercent() ||
-      !height.IsCoordPercentCalcUnit() ||
-      height.HasPercent() ||
-      IsIntrinsicKeyword(mStylePosition->mMinWidth) ||
-      IsIntrinsicKeyword(mStylePosition->mMaxWidth) ||
-      IsIntrinsicKeyword(mStylePosition->mMinHeight) ||
-      IsIntrinsicKeyword(mStylePosition->mMaxHeight) ||
-      ((mStylePosition->mMinWidth.GetUnit() == eStyleUnit_Auto ||
-        mStylePosition->mMinHeight.GetUnit() == eStyleUnit_Auto) &&
-       mFrame->IsFlexOrGridItem())) {
-    canBeDynamicReflowRoot = false;
-  }
-
-  if (mFrame->IsFlexItem()) {
-    // If our flex-basis is 'auto', it'll defer to 'width' (or 'height') which
-    // we've already checked. Otherwise, it preempts them, so we need to
-    // perform the same "could-this-value-be-influenced-by-content" checks that
-    // we performed for 'width' and 'height' above.
-    const nsStyleCoord& flexBasis = mStylePosition->mFlexBasis;
-    if (flexBasis.GetUnit() != eStyleUnit_Auto &&
-        (!flexBasis.IsCoordPercentCalcUnit() || flexBasis.HasPercent())) {
-      canBeDynamicReflowRoot = false;
-    }
-  }
-
-  if (!mFrame->IsFixedPosContainingBlock()) {
-    // We can't treat this frame as a reflow root, since dynamic changes
-    // to absolutely-positioned frames inside of it require that we
-    // reflow the placeholder before we reflow the absolutely positioned
-    // frame.
-    // FIXME:  Alternatively, we could sort the reflow roots in
-    // PresShell::ProcessReflowCommands by depth in the tree, from
-    // deepest to least deep.  However, for performance (FIXME) we
-    // should really be sorting them in the opposite order!
-    canBeDynamicReflowRoot = false;
-  } else {
-    MOZ_ASSERT(mFrame->IsAbsPosContainingBlock(),
-               "we need the frame to be both an abs-pos and fixed-pos cb");
-  }
-
-  // If we participate in a container's block reflow context, or margins
-  // can collapse through us, we can't be a dynamic reflow root.
-  if (canBeDynamicReflowRoot &&
-      mFrame->IsFrameOfType(nsIFrame::eBlockFrame) &&
-      !mFrame->HasAllStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT)) {
-    canBeDynamicReflowRoot = false;
-  }
-
-  if (canBeDynamicReflowRoot) {
-    mFrame->AddStateBits(NS_FRAME_DYNAMIC_REFLOW_ROOT);
-  } else {
-    mFrame->RemoveStateBits(NS_FRAME_DYNAMIC_REFLOW_ROOT);
-  }
-}
-
 nscoord
 ReflowInput::GetContainingBlockContentISize(WritingMode aWritingMode) const
 {
   if (!mCBReflowInput) {
     return 0;
   }
   return mCBReflowInput->GetWritingMode().IsOrthogonalTo(aWritingMode)
     ? mCBReflowInput->ComputedBSize()
@@ -2688,20 +2593,18 @@ SizeComputationInput::InitOffsets(Writin
     needPaddingProp = false;
   }
   else if (nsSVGUtils::IsInSVGTextSubtree(mFrame)) {
     ComputedPhysicalPadding().SizeTo(0, 0, 0, 0);
     needPaddingProp = false;
   }
   else if (aPadding) { // padding is an input arg
     ComputedPhysicalPadding() = *aPadding;
-    needPaddingProp =
-      mFrame->StylePadding()->IsWidthDependent() ||
-      mFrame->HasAnyStateBits(NS_FRAME_REFLOW_ROOT |
-                              NS_FRAME_DYNAMIC_REFLOW_ROOT);
+    needPaddingProp = mFrame->StylePadding()->IsWidthDependent() ||
+    (mFrame->GetStateBits() & NS_FRAME_REFLOW_ROOT);
   }
   else {
     needPaddingProp = ComputePadding(aWM, aPercentBasis, aFrameType);
   }
 
   // Add [align|justify]-content:baseline padding contribution.
   typedef const FramePropertyDescriptor<SmallValueHolder<nscoord>>* Prop;
   auto ApplyBaselinePadding = [this, &needPaddingProp]
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -958,17 +958,16 @@ public:
                                        void* aValue);
 #endif
 
 protected:
   void InitFrameType(LayoutFrameType aFrameType);
   void InitCBReflowInput();
   void InitResizeFlags(nsPresContext* aPresContext,
                        mozilla::LayoutFrameType aFrameType);
-  void InitDynamicReflowRoot();
 
   void InitConstraints(nsPresContext* aPresContext,
                        const mozilla::LogicalSize& aContainingBlockSize,
                        const nsMargin* aBorder,
                        const nsMargin* aPadding,
                        mozilla::LayoutFrameType aFrameType);
 
   // Returns the nearest containing block or block frame (whether or not
--- a/layout/generic/nsFrameStateBits.h
+++ b/layout/generic/nsFrameStateBits.h
@@ -230,19 +230,18 @@ FRAME_STATE_BIT(Generic, 43, NS_FRAME_SV
 // ColumnSetWrapperFrame nested inside a column does have this bit set.
 //
 // All the children of the column-spanners or any other type of frames which
 // create their own block formatting context do not have this bit set because
 // they are not in the same block formatting context created by a multi-column
 // ancestor.
 FRAME_STATE_BIT(Generic, 44, NS_FRAME_HAS_MULTI_COLUMN_ANCESTOR)
 
-// If this bit is set, then reflow may be dispatched from the current
-// frame instead of the root frame.
-FRAME_STATE_BIT(Generic, 45, NS_FRAME_DYNAMIC_REFLOW_ROOT)
+// Bits 45 is currently unused, but be kind and check with bug 1465474
+// first please :-)
 
 // This bit indicates that we're tracking visibility for this frame, and that
 // the frame has a VisibilityStateProperty property.
 FRAME_STATE_BIT(Generic, 46, NS_FRAME_VISIBILITY_IS_TRACKED)
 
 // The frame is a descendant of SVGTextFrame and is thus used for SVG
 // text layout.
 FRAME_STATE_BIT(Generic, 47, NS_FRAME_IS_SVG_TEXT)
@@ -292,19 +291,17 @@ FRAME_STATE_BIT(Generic, 58, NS_FRAME_MA
 // This state bit is set on frames within token MathML elements if the
 // token represents an <mi> tag whose inner HTML consists of a single
 // non-whitespace character to allow special rendering behaviour.
 FRAME_STATE_BIT(Generic, 59, NS_FRAME_IS_IN_SINGLE_CHAR_MI)
 
 // NOTE: Bits 20-31 and 60-63 of the frame state are reserved for specific
 // frame classes.
 
-// NOTE: No more unused bits. If needed, investigate removing obsolete bits by
-// adjusting logic, or moving infrequently-used bits elsewhere. If more space
-// for frame state is still needed, look for bit field gaps in nsIFrame.
+// NOTE: Currently unused and available bit(s): 45.
 
 
 // == Frame state bits that apply to box frames ===============================
 
 FRAME_STATE_GROUP(Box, nsBoxFrame)
 
 FRAME_STATE_BIT(Box, 20, NS_STATE_BOX_CHILD_RESERVED)
 FRAME_STATE_BIT(Box, 21, NS_STATE_STACK_NOT_POSITIONED)