Bug 1415013: Clear servo data from the flattened tree in DestroyFramesForAndRestyle. r?bz draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 07 Nov 2017 12:23:03 +0100
changeset 694176 8dcc375694927997a8a9f41c8be7a315c8a3d772
parent 694124 0ed4c77d1f0aefd2fd3e1c1b265273cec352e7ba
child 739279 3cfd2bd366f8ed79e635ee48a70f090f88f52cfd
push id88068
push userbmo:emilio@crisal.io
push dateTue, 07 Nov 2017 14:03:03 +0000
reviewersbz
bugs1415013
milestone58.0a1
Bug 1415013: Clear servo data from the flattened tree in DestroyFramesForAndRestyle. r?bz Otherwise we may end up leaving style Servo data on nodes that no longer are on the flattened tree, and thus incorrectly processing (or trying to process) restyles in them. Also devirtualize the function while at it. MozReview-Commit-ID: 19c1bWhzGVF
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsIPresShell.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -2927,17 +2927,17 @@ PresShell::CancelAllPendingReflows()
     GetPresContext()->RefreshDriver()->RemoveLayoutFlushObserver(this);
     mObservingLayoutFlushes = false;
   }
 
   ASSERT_REFLOW_SCHEDULED_STATE();
 }
 
 void
-PresShell::DestroyFramesForAndRestyle(Element* aElement)
+nsIPresShell::DestroyFramesForAndRestyle(Element* aElement)
 {
   MOZ_ASSERT(aElement);
   NS_ENSURE_TRUE_VOID(mPresContext);
   if (!mDidInitialize) {
     return;
   }
 
   nsAutoScriptBlocker scriptBlocker;
@@ -2945,16 +2945,20 @@ PresShell::DestroyFramesForAndRestyle(El
   // Mark ourselves as not safe to flush while we're doing frame destruction.
   ++mChangeNestCount;
 
   nsCSSFrameConstructor* fc = FrameConstructor();
   fc->BeginUpdate();
   bool didReconstruct = fc->DestroyFramesFor(aElement);
   fc->EndUpdate();
 
+  if (aElement->IsStyledByServo()) {
+    ServoRestyleManager::ClearServoDataFromSubtree(aElement);
+  }
+
   auto changeHint = didReconstruct
     ? nsChangeHint(0)
     : nsChangeHint_ReconstructFrame;
 
   // NOTE(emilio): eRestyle_Subtree is needed to force also a full subtree
   // restyle for the content (in Stylo, where the existence of frames != the
   // existence of styles).
   mPresContext->RestyleManager()->PostRestyleEvent(
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -125,17 +125,16 @@ public:
   virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
                                 nsFrameState aBitToAdd,
                                 ReflowRootHandling aRootHandling =
                                   eInferFromBitToAdd) override;
   virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
   virtual void CancelAllPendingReflows() override;
   virtual void DoFlushPendingNotifications(mozilla::FlushType aType) override;
   virtual void DoFlushPendingNotifications(mozilla::ChangesToFlush aType) override;
-  virtual void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement) override;
 
   /**
    * Post a callback that should be handled after reflow has finished.
    */
   virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
   virtual void CancelReflowCallback(nsIReflowCallback* aCallback) override;
 
   virtual void ClearFrameRefs(nsIFrame* aFrame) override;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -524,17 +524,17 @@ public:
   virtual void NotifyCounterStylesAreDirty() = 0;
 
   /**
    * Destroy the frames for aElement, and reconstruct them asynchronously if
    * needed.
    *
    * Note that this may destroy frames for an ancestor instead.
    */
-  virtual void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement) = 0;
+  void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement);
 
   void PostRecreateFramesFor(mozilla::dom::Element* aElement);
   void RestyleForAnimation(mozilla::dom::Element* aElement,
                            nsRestyleHint aHint);
 
   // ShadowRoot has APIs that can change styles so we only
   // want to restyle elements in the ShadowRoot and not the whole
   // document.