Bug 1406727 - improve diagnostics in BuildDisplayList. r=froydnj a=abillings
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 06 Feb 2018 12:21:31 +1300
changeset 454728 01d3f0695fc4947d9a086d01f8d105816e94a3ce
parent 454727 58dc2e0f5a1562f390caf8ebfc517989348ddd0c
child 454729 e61fa00f6ebfc5c528ab639fe03f7a1ec3ad5b05
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)
reviewersfroydnj, abillings
bugs1406727
milestone59.0
Bug 1406727 - improve diagnostics in BuildDisplayList. r=froydnj a=abillings
layout/generic/nsFrame.cpp
xpcom/ds/ArenaAllocator.h
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2728,20 +2728,36 @@ ComputeClipForMaskItem(nsDisplayListBuil
     // The resulting clip is relative to the reference frame, but the caller
     // expects it to be relative to the masked frame, so adjust it.
     result -= toReferenceFrame;
     return Some(result);
   }
   return Nothing();
 }
 
+struct AutoCheckBuilder {
+  explicit AutoCheckBuilder(nsDisplayListBuilder* aBuilder)
+    : mBuilder(aBuilder)
+  {
+    aBuilder->Check();
+  }
+
+  ~AutoCheckBuilder()
+  {
+    mBuilder->Check();
+  }
+
+  nsDisplayListBuilder* mBuilder;
+};
+
 void
 nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
                                              nsDisplayList*        aList,
                                              bool*                 aCreatedContainerItem) {
+  AutoCheckBuilder check(aBuilder);
   if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
     return;
 
   // Replaced elements have their visibility handled here, because
   // they're visually atomic
   if (IsFrameOfType(eReplaced) && !IsVisibleForPainting(aBuilder))
     return;
 
@@ -3000,17 +3016,19 @@ nsIFrame::BuildDisplayListForStackingCon
     nsDisplayLayerEventRegions* eventRegions = nullptr;
     if (aBuilder->IsBuildingLayerEventRegions()) {
       eventRegions = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, this);
       eventRegions->AddFrame(aBuilder, this);
       aBuilder->SetLayerEventRegions(eventRegions);
     }
 
     MarkAbsoluteFramesForDisplayList(aBuilder);
+    aBuilder->Check();
     BuildDisplayList(aBuilder, set);
+    aBuilder->Check();
 
     // Blend modes are a real pain for retained display lists. We build a blend
     // container item if the built list contains any blend mode items within
     // the current stacking context. This can change without an invalidation
     // to the stacking context frame, or the blend mode frame (e.g. by moving
     // an intermediate frame).
     // When we gain/remove a blend container item, we need to mark this frame
     // as invalid and have the full display list for merging to track
@@ -3045,17 +3063,19 @@ nsIFrame::BuildDisplayListForStackingCon
         // If this is the root frame, then the previous call to
         // MarkAbsoluteFramesForDisplayList might have stored some fixed
         // background data. Clear that now.
         if (!GetParent()) {
           aBuilder->ClearFixedBackgroundDisplayData();
         }
 
         MarkAbsoluteFramesForDisplayList(aBuilder);
+        aBuilder->Check();
         BuildDisplayList(aBuilder, set);
+        aBuilder->Check();
       }
     }
 
     if (eventRegions) {
       // If the event regions item ended up empty, throw it away rather than
       // adding it to the display list.
       if (!eventRegions->IsEmpty()) {
         set.BorderBackground()->AppendToBottom(eventRegions);
@@ -3451,16 +3471,17 @@ DescendIntoChild(nsDisplayListBuilder* a
   return true;
 }
 
 void
 nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder*   aBuilder,
                                    nsIFrame*               aChild,
                                    const nsDisplayListSet& aLists,
                                    uint32_t                aFlags) {
+  AutoCheckBuilder check(aBuilder);
   // If painting is restricted to just the background of the top level frame,
   // then we have nothing to do here.
   if (aBuilder->IsBackgroundOnly())
     return;
 
   if (aBuilder->IsForGenerateGlyphMask() ||
       aBuilder->IsForPaintingSelectionBG()) {
     if (!aChild->IsTextFrame() && aChild->IsLeaf()) {
@@ -3518,17 +3539,19 @@ nsIFrame::BuildDisplayListForChild(nsDis
     }
     nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions();
     if (eventRegions) {
       eventRegions->AddFrame(aBuilder, child);
     }
 
     child->MarkAbsoluteFramesForDisplayList(aBuilder);
     aBuilder->AdjustWindowDraggingRegion(child);
+    aBuilder->Check();
     child->BuildDisplayList(aBuilder, aLists);
+    aBuilder->Check();
     aBuilder->DisplayCaret(child, aLists.Content());
 #ifdef DEBUG
     DisplayDebugBorders(aBuilder, child, aLists);
 #endif
     return;
   }
 
   bool isSVG = (child->GetStateBits() & NS_FRAME_SVG_LAYOUT);
@@ -3781,32 +3804,36 @@ nsIFrame::BuildDisplayListForChild(nsDis
     }
 
     if (!pseudoStackingContext) {
       // THIS IS THE COMMON CASE.
       // Not a pseudo or real stacking context. Do the simple thing and
       // return early.
 
       aBuilder->AdjustWindowDraggingRegion(child);
+      aBuilder->Check();
       child->BuildDisplayList(aBuilder, aLists);
+      aBuilder->Check();
       aBuilder->DisplayCaret(child, aLists.Content());
 #ifdef DEBUG
       DisplayDebugBorders(aBuilder, child, aLists);
 #endif
       return;
     }
 
     // A pseudo-stacking context (e.g., a positioned element with z-index auto).
     // We allow positioned descendants of the child to escape to our parent
     // stacking context's positioned descendant list, because they might be
     // z-index:non-auto
     nsDisplayListCollection pseudoStack(aBuilder);
     aBuilder->AdjustWindowDraggingRegion(child);
     nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
+    aBuilder->Check();
     child->BuildDisplayList(aBuilder, pseudoStack);
+    aBuilder->Check();
     if (aBuilder->DisplayCaret(child, pseudoStack.Content())) {
       canSkipWrapList = false;
     }
     wrapListASR = contASRTracker.GetContainerASR();
 
     list.AppendToTop(pseudoStack.BorderBackground());
     list.AppendToTop(pseudoStack.BlockBorderBackgrounds());
     list.AppendToTop(pseudoStack.Floats());
--- a/xpcom/ds/ArenaAllocator.h
+++ b/xpcom/ds/ArenaAllocator.h
@@ -123,18 +123,18 @@ public:
 
     return s;
   }
 
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   void Check()
   {
-    for (auto arena = mHead.next; arena; arena = arena->next) {
-      arena->canary.Check();
+    if (mCurrent) {
+      mCurrent->canary.Check();
     }
   }
 #endif
 
 private:
   struct ArenaHeader
   {
     /**