Bug 1415013: Clear servo data on flattened tree changes. r=bz
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 09 Nov 2017 18:43:51 +0100
changeset 446314 b8067f9bf9a76fca35349c77ece7d5cd23cce145
parent 446313 b58d7dbfcf60e3dabbca270ff0c4c4d1b233edf0
child 446315 7452d18793ab5ad68f76e2074a5d81d4e9582058
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1415013
milestone59.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 1415013: Clear servo data on flattened tree changes. r=bz MozReview-Commit-ID: 3TsM8tbzPMV
dom/base/Element.h
layout/base/PresShell.cpp
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -1776,16 +1776,19 @@ private:
   nsRect GetClientAreaRect();
 
   nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr,
                                      FlushType aFlushType = FlushType::Layout);
 
   // Data members
   EventStates mState;
   // Per-node data managed by Servo.
+  //
+  // There should not be data on nodes that are in the flattened tree, or
+  // descendants of display: none elements.
   mozilla::ServoCell<ServoNodeData*> mServoData;
 };
 
 class RemoveFromBindingManagerRunnable : public mozilla::Runnable
 {
 public:
   RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
                                    nsIContent* aContent,
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -2945,16 +2945,44 @@ 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()) {
+    if (aElement->GetFlattenedTreeParentNode()) {
+      // The element is still in the flat tree, but their children may not be
+      // anymore in a second.
+      //
+      // This is the case of a new shadow root or XBL binding about to be
+      // attached.
+      //
+      // Clear the style data from all the flattened tree descendants, but _not_
+      // from us, since otherwise we wouldn't see the reframe.
+      //
+      // FIXME(emilio): It'd be more ergonomic to just map the no data -> data
+      // case to a reframe from the style system.
+      StyleChildrenIterator iter(aElement);
+      for (nsIContent* child = iter.GetNextChild();
+           child;
+           child = iter.GetNextChild()) {
+        if (child->IsElement()) {
+          ServoRestyleManager::ClearServoDataFromSubtree(child->AsElement());
+        }
+      }
+    } else {
+      // This is the case of an element that was redistributed but is no longer
+      // bound to any insertion point. Just forget about all the data.
+      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(