Bug 1515192 - Replace handcrafted FrameChildListIDs class with EnumSet. r=mats
authorTing-Yu Lin <aethanyc@gmail.com>
Wed, 19 Dec 2018 00:50:09 +0000
changeset 451275 2aeb562c9c1c1a80ce53adf5adeb546e20a8da57
parent 451274 80bd4f3c0fcfb6080048f5d859142876c05d3eb1
child 451276 283ebb9fc26f7ea9e296e520ef23a5d36f2c0931
push id35232
push userebalazs@mozilla.com
push dateWed, 19 Dec 2018 15:45:00 +0000
treeherdermozilla-central@335cc6f2cbb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1515192
milestone66.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 1515192 - Replace handcrafted FrameChildListIDs class with EnumSet. r=mats The following APIs are changed. 1. Contains() needs to become contains(). (EnumSet's methods have lowercase names.) 2. Use list constructor rather than "|" like a plain enum. 3. Use operator+= instead of operator|=. Differential Revision: https://phabricator.services.mozilla.com/D14908
layout/base/PresShell.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/DetailsFrame.cpp
layout/generic/FrameChildList.cpp
layout/generic/FrameChildList.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameList.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGridContainerFrame.cpp
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -5558,21 +5558,21 @@ void PresShell::MarkFramesInSubtreeAppro
       rect = rect.Intersect(scrollFrame->GetScrollPortRect());
     }
     rect = scrollFrame->ExpandRectToNearlyVisible(rect);
   }
 
   bool preserves3DChildren = aFrame->Extend3DContext();
 
   // We assume all frames in popups are visible, so we skip them here.
-  const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
-                                    nsIFrame::kSelectPopupList);
+  const nsIFrame::ChildListIDs skip = {nsIFrame::kPopupList,
+                                       nsIFrame::kSelectPopupList};
   for (nsIFrame::ChildListIterator childLists(aFrame); !childLists.IsDone();
        childLists.Next()) {
-    if (skip.Contains(childLists.CurrentID())) {
+    if (skip.contains(childLists.CurrentID())) {
       continue;
     }
 
     for (nsIFrame* child : childLists.CurrentList()) {
       nsRect r = rect - child->GetPosition();
       if (!r.IntersectRect(r, child->GetVisualOverflowRect())) {
         continue;
       }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -517,21 +517,22 @@ bool nsLayoutUtils::IsContentSelectEnabl
 
   return sContentSelectEnabled;
 }
 
 void nsLayoutUtils::UnionChildOverflow(nsIFrame* aFrame,
                                        nsOverflowAreas& aOverflowAreas,
                                        FrameChildListIDs aSkipChildLists) {
   // Iterate over all children except pop-ups.
-  FrameChildListIDs skip =
-      aSkipChildLists | nsIFrame::kSelectPopupList | nsIFrame::kPopupList;
+  FrameChildListIDs skip(aSkipChildLists);
+  skip += {nsIFrame::kSelectPopupList, nsIFrame::kPopupList};
+
   for (nsIFrame::ChildListIterator childLists(aFrame); !childLists.IsDone();
        childLists.Next()) {
-    if (skip.Contains(childLists.CurrentID())) {
+    if (skip.contains(childLists.CurrentID())) {
       continue;
     }
 
     nsFrameList children = childLists.CurrentList();
     for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
       nsIFrame* child = e.get();
       nsOverflowAreas childOverflow =
           child->GetOverflowAreas() + child->GetPosition();
@@ -6163,28 +6164,28 @@ static nscoord CalculateBlockContentBEnd
   MOZ_ASSERT(aFrame, "null ptr");
 
   nscoord contentBEnd = aFrame->BSize(aWM);
 
   // We want scrollable overflow rather than visual because this
   // calculation is intended to affect layout.
   LogicalSize overflowSize(aWM, aFrame->GetScrollableOverflowRect().Size());
   if (overflowSize.BSize(aWM) > contentBEnd) {
-    nsIFrame::ChildListIDs skip(nsIFrame::kOverflowList |
-                                nsIFrame::kExcessOverflowContainersList |
-                                nsIFrame::kOverflowOutOfFlowList);
+    nsIFrame::ChildListIDs skip = {nsIFrame::kOverflowList,
+                                   nsIFrame::kExcessOverflowContainersList,
+                                   nsIFrame::kOverflowOutOfFlowList};
     nsBlockFrame* blockFrame = GetAsBlock(aFrame);
     if (blockFrame) {
       contentBEnd =
           std::max(contentBEnd, CalculateBlockContentBEnd(aWM, blockFrame));
-      skip |= nsIFrame::kPrincipalList;
+      skip += nsIFrame::kPrincipalList;
     }
     nsIFrame::ChildListIterator lists(aFrame);
     for (; !lists.IsDone(); lists.Next()) {
-      if (!skip.Contains(lists.CurrentID())) {
+      if (!skip.contains(lists.CurrentID())) {
         nsFrameList::Enumerator childFrames(lists.CurrentList());
         for (; !childFrames.AtEnd(); childFrames.Next()) {
           nsIFrame* child = childFrames.get();
           nscoord offset =
               child->GetLogicalNormalPosition(aWM, aFrame->GetSize()).B(aWM);
           contentBEnd =
               std::max(contentBEnd, CalculateContentBEnd(aWM, child) + offset);
         }
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -110,20 +110,20 @@ nsresult DetailsFrame::CreateAnonymousCo
 void DetailsFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                             uint32_t aFilter) {
   if (mDefaultSummary) {
     aElements.AppendElement(mDefaultSummary);
   }
 }
 
 bool DetailsFrame::HasMainSummaryFrame(nsIFrame* aSummaryFrame) {
-  const ChildListIDs flowLists(kPrincipalList | kOverflowList);
+  const ChildListIDs flowLists = {kPrincipalList, kOverflowList};
   for (nsIFrame* frag = this; frag; frag = frag->GetNextInFlow()) {
     for (ChildListIterator lists(frag); !lists.IsDone(); lists.Next()) {
-      if (!flowLists.Contains(lists.CurrentID())) {
+      if (!flowLists.contains(lists.CurrentID())) {
         continue;
       }
       for (nsIFrame* child : lists.CurrentList()) {
         child = nsPlaceholderFrame::GetRealFrameFor(child);
         // We skip any non-primary frames such as a list-style-position:inside
         // bullet frame for the <details> itself.
         if (child->IsPrimaryFrame()) {
           return aSummaryFrame == child;
--- a/layout/generic/FrameChildList.cpp
+++ b/layout/generic/FrameChildList.cpp
@@ -14,18 +14,18 @@ namespace layout {
 FrameChildListIterator::FrameChildListIterator(const nsIFrame* aFrame)
     : FrameChildListArrayIterator(mLists) {
   aFrame->GetChildLists(&mLists);
 #ifdef DEBUG
   // Make sure that there are no duplicate list IDs.
   FrameChildListIDs ids;
   uint32_t count = mLists.Length();
   for (uint32_t i = 0; i < count; ++i) {
-    NS_ASSERTION(!ids.Contains(mLists[i].mID), "Duplicate item found!");
-    ids |= mLists[i].mID;
+    NS_ASSERTION(!ids.contains(mLists[i].mID), "Duplicate item found!");
+    ids += mLists[i].mID;
   }
 #endif
 }
 
 #ifdef DEBUG_FRAME_DUMP
 const char* ChildListName(FrameChildListID aListID) {
   switch (aListID) {
     case kPrincipalList:
--- a/layout/generic/FrameChildList.h
+++ b/layout/generic/FrameChildList.h
@@ -2,59 +2,32 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef FrameChildList_h_
 #define FrameChildList_h_
 
+#include "mozilla/EnumSet.h"
 #include "nsFrameList.h"
 #include "nsTArray.h"
 
 class nsIFrame;
 
 namespace mozilla {
 namespace layout {
 
 // enum FrameChildListID lives in nsFrameList.h to solve circular dependencies.
 
 #ifdef DEBUG_FRAME_DUMP
 extern const char* ChildListName(FrameChildListID aListID);
 #endif
 
-class FrameChildListIDs {
-  friend class FrameChildListIterator;
-
- public:
-  FrameChildListIDs() : mIDs(0) {}
-  FrameChildListIDs(const FrameChildListIDs& aOther) : mIDs(aOther.mIDs) {}
-  MOZ_IMPLICIT FrameChildListIDs(FrameChildListID aListID) : mIDs(aListID) {}
-
-  FrameChildListIDs operator|(FrameChildListIDs aOther) const {
-    return FrameChildListIDs(mIDs | aOther.mIDs);
-  }
-  FrameChildListIDs& operator|=(FrameChildListIDs aOther) {
-    mIDs |= aOther.mIDs;
-    return *this;
-  }
-  bool operator==(FrameChildListIDs aOther) const {
-    return mIDs == aOther.mIDs;
-  }
-  bool operator!=(const FrameChildListIDs& aOther) const {
-    return !(*this == aOther);
-  }
-  bool Contains(FrameChildListIDs aOther) const {
-    return (mIDs & aOther.mIDs) == aOther.mIDs;
-  }
-
- protected:
-  explicit FrameChildListIDs(uint32_t aIDs) : mIDs(aIDs) {}
-  uint32_t mIDs;
-};
+using FrameChildListIDs = EnumSet<FrameChildListID>;
 
 class FrameChildList {
  public:
   FrameChildList(const nsFrameList& aList, FrameChildListID aID)
       : mList(aList), mID(aID) {}
   nsFrameList mList;
   FrameChildListID mID;
 };
@@ -92,29 +65,16 @@ class MOZ_STACK_CLASS FrameChildListIter
     : public FrameChildListArrayIterator {
  public:
   explicit FrameChildListIterator(const nsIFrame* aFrame);
 
  protected:
   AutoTArray<FrameChildList, 4> mLists;
 };
 
-inline mozilla::layout::FrameChildListIDs operator|(
-    mozilla::layout::FrameChildListID aLeftOp,
-    mozilla::layout::FrameChildListID aRightOp) {
-  return mozilla::layout::FrameChildListIDs(aLeftOp) |
-         mozilla::layout::FrameChildListIDs(aRightOp);
-}
-
-inline mozilla::layout::FrameChildListIDs operator|(
-    mozilla::layout::FrameChildListID aLeftOp,
-    const mozilla::layout::FrameChildListIDs& aRightOp) {
-  return mozilla::layout::FrameChildListIDs(aLeftOp) | aRightOp;
-}
-
 }  // namespace layout
 }  // namespace mozilla
 
 inline void nsFrameList::AppendIfNonempty(
     nsTArray<mozilla::layout::FrameChildList>* aLists,
     mozilla::layout::FrameChildListID aListID) const {
   if (NotEmpty()) {
     aLists->AppendElement(mozilla::layout::FrameChildList(*this, aListID));
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -410,19 +410,19 @@ void nsBlockFrame::List(FILE* out, const
       line->List(out, nestedPfx.get(), aFlags);
     }
     fprintf_stderr(out, "%s>\n", pfx.get());
   }
 
   // skip the principal list - we printed the lines above
   // skip the overflow list - we printed the overflow lines above
   ChildListIterator lists(this);
-  ChildListIDs skip(kPrincipalList | kOverflowList);
+  ChildListIDs skip = {kPrincipalList, kOverflowList};
   for (; !lists.IsDone(); lists.Next()) {
-    if (skip.Contains(lists.CurrentID())) {
+    if (skip.contains(lists.CurrentID())) {
       continue;
     }
     fprintf_stderr(out, "%s%s %p <\n", pfx.get(),
                    mozilla::layout::ChildListName(lists.CurrentID()),
                    &GetChildList(lists.CurrentID()));
     nsCString nestedPfx(pfx);
     nestedPfx += "  ";
     nsFrameList::Enumerator childFrames(lists.CurrentList());
@@ -1815,17 +1815,17 @@ void nsBlockFrame::UnionChildOverflow(ns
 
     line->SetOverflowAreas(lineAreas);
     aOverflowAreas.UnionWith(lineAreas);
   }
 
   // Union with child frames, skipping the principal and float lists
   // since we already handled those using the line boxes.
   nsLayoutUtils::UnionChildOverflow(this, aOverflowAreas,
-                                    kPrincipalList | kFloatList);
+                                    {kPrincipalList, kFloatList});
 }
 
 bool nsBlockFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) {
   bool found;
   nscoord blockEndEdgeOfChildren =
       GetProperty(BlockEndEdgeOfChildrenProperty(), &found);
   if (found) {
     ConsiderBlockEndEdgeOfChildren(GetWritingMode(), blockEndEdgeOfChildren,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -8676,22 +8676,22 @@ static nsRect UnionBorderBoxes(
   }
 
   const nsStyleEffects* effects = aFrame->StyleEffects();
   Maybe<nsRect> clipPropClipRect =
       aFrame->GetClipPropClipRect(disp, effects, bounds.Size());
 
   // Iterate over all children except pop-up, absolutely-positioned, and
   // float ones.
-  const nsIFrame::ChildListIDs skip(
-      nsIFrame::kPopupList | nsIFrame::kSelectPopupList |
-      nsIFrame::kAbsoluteList | nsIFrame::kFixedList | nsIFrame::kFloatList);
+  const nsIFrame::ChildListIDs skip = {
+      nsIFrame::kPopupList, nsIFrame::kSelectPopupList, nsIFrame::kAbsoluteList,
+      nsIFrame::kFixedList, nsIFrame::kFloatList};
   for (nsIFrame::ChildListIterator childLists(aFrame); !childLists.IsDone();
        childLists.Next()) {
-    if (skip.Contains(childLists.CurrentID())) {
+    if (skip.contains(childLists.CurrentID())) {
       continue;
     }
 
     nsFrameList children = childLists.CurrentList();
     for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
       nsIFrame* child = e.get();
       if (child->IsPlaceholderFrame()) {
         continue;
--- a/layout/generic/nsFrameList.h
+++ b/layout/generic/nsFrameList.h
@@ -26,34 +26,34 @@ class nsIFrame;
 class nsIPresShell;
 class nsPresContext;
 
 namespace mozilla {
 namespace layout {
 class FrameChildList;
 enum FrameChildListID {
   // The individual concrete child lists.
-  kPrincipalList = 0x1,
-  kPopupList = 0x2,
-  kCaptionList = 0x4,
-  kColGroupList = 0x8,
-  kSelectPopupList = 0x10,
-  kAbsoluteList = 0x20,
-  kFixedList = 0x40,
-  kOverflowList = 0x80,
-  kOverflowContainersList = 0x100,
-  kExcessOverflowContainersList = 0x200,
-  kOverflowOutOfFlowList = 0x400,
-  kFloatList = 0x800,
-  kBulletList = 0x1000,
-  kPushedFloatsList = 0x2000,
-  kBackdropList = 0x4000,
+  kPrincipalList,
+  kPopupList,
+  kCaptionList,
+  kColGroupList,
+  kSelectPopupList,
+  kAbsoluteList,
+  kFixedList,
+  kOverflowList,
+  kOverflowContainersList,
+  kExcessOverflowContainersList,
+  kOverflowOutOfFlowList,
+  kFloatList,
+  kBulletList,
+  kPushedFloatsList,
+  kBackdropList,
   // A special alias for kPrincipalList that suppress the reflow request that
   // is normally done when manipulating child lists.
-  kNoReflowPrincipalList = 0x8000
+  kNoReflowPrincipalList,
 };
 
 // A helper class for nsIFrame::Destroy[From].  It's defined here because
 // nsFrameList needs it and we can't use nsIFrame here.
 struct PostFrameDestroyData {
   PostFrameDestroyData(const PostFrameDestroyData&) = delete;
   PostFrameDestroyData() = default;
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -861,20 +861,20 @@ static Element* GetBrowserRoot(nsIConten
 // and the size of scrollbar thumbs to change during scrolling, we compute the
 // scrollable overflow by determining the scroll position at which the child
 // becomes completely visible within the scrollport rather than using the union
 // of the overflow areas at their current position.
 static void GetScrollableOverflowForPerspective(
     nsIFrame* aScrolledFrame, nsIFrame* aCurrentFrame, const nsRect aScrollPort,
     nsPoint aOffset, nsRect& aScrolledFrameOverflowArea) {
   // Iterate over all children except pop-ups.
-  FrameChildListIDs skip = nsIFrame::kSelectPopupList | nsIFrame::kPopupList;
+  FrameChildListIDs skip = {nsIFrame::kSelectPopupList, nsIFrame::kPopupList};
   for (nsIFrame::ChildListIterator childLists(aCurrentFrame);
        !childLists.IsDone(); childLists.Next()) {
-    if (skip.Contains(childLists.CurrentID())) {
+    if (skip.contains(childLists.CurrentID())) {
       continue;
     }
 
     for (nsIFrame* child : childLists.CurrentList()) {
       nsPoint offset = aOffset;
 
       // When we reach a direct child of the scroll, then we record the offset
       // to convert from that frame's coordinate into the scroll frame's
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -6295,22 +6295,22 @@ void nsGridContainerFrame::InsertFrames(
                                         nsFrameList& aFrameList) {
   NoteNewChildren(aListID, aFrameList);
   nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
 }
 
 void nsGridContainerFrame::RemoveFrame(ChildListID aListID,
                                        nsIFrame* aOldFrame) {
 #ifdef DEBUG
-  ChildListIDs supportedLists =
-      kAbsoluteList | kFixedList | kPrincipalList | kNoReflowPrincipalList;
+  ChildListIDs supportedLists = {kAbsoluteList, kFixedList, kPrincipalList,
+                                 kNoReflowPrincipalList};
   // We don't handle the kBackdropList frames in any way, but it only contains
   // a placeholder for ::backdrop which is OK to not reflow (for now anyway).
-  supportedLists |= kBackdropList;
-  MOZ_ASSERT(supportedLists.Contains(aListID), "unexpected child list");
+  supportedLists += kBackdropList;
+  MOZ_ASSERT(supportedLists.contains(aListID), "unexpected child list");
 
   // Note that kPrincipalList doesn't mean aOldFrame must be on that list.
   // It can also be on kOverflowList, in which case it might be a pushed
   // item, and if it's the only pushed item our DID_PUSH_ITEMS bit will lie.
   if (aListID == kPrincipalList && !aOldFrame->GetPrevInFlow()) {
     // Since the bit may lie, set the mDidPushItemsBitMayLie value to true for
     // ourself and for all our contiguous previous-in-flow
     // nsGridContainerFrames.
@@ -6499,22 +6499,22 @@ void nsGridContainerFrame::CalculateBase
 nsresult nsGridContainerFrame::GetFrameName(nsAString& aResult) const {
   return MakeFrameName(NS_LITERAL_STRING("GridContainer"), aResult);
 }
 #endif
 
 void nsGridContainerFrame::NoteNewChildren(ChildListID aListID,
                                            const nsFrameList& aFrameList) {
 #ifdef DEBUG
-  ChildListIDs supportedLists =
-      kAbsoluteList | kFixedList | kPrincipalList | kNoReflowPrincipalList;
+  ChildListIDs supportedLists = {kAbsoluteList, kFixedList, kPrincipalList,
+                                 kNoReflowPrincipalList};
   // We don't handle the kBackdropList frames in any way, but it only contains
   // a placeholder for ::backdrop which is OK to not reflow (for now anyway).
-  supportedLists |= kBackdropList;
-  MOZ_ASSERT(supportedLists.Contains(aListID), "unexpected child list");
+  supportedLists += kBackdropList;
+  MOZ_ASSERT(supportedLists.contains(aListID), "unexpected child list");
 #endif
 
   nsIPresShell* shell = PresShell();
   for (auto pif = GetPrevInFlow(); pif; pif = pif->GetPrevInFlow()) {
     if (aListID == kPrincipalList) {
       pif->AddStateBits(NS_STATE_GRID_DID_PUSH_ITEMS);
     }
     shell->FrameNeedsReflow(pif, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
@@ -6615,38 +6615,38 @@ nsGridContainerFrame::FindLastItemInGrid
   }
   return result;
 }
 
 #ifdef DEBUG
 void nsGridContainerFrame::SetInitialChildList(ChildListID aListID,
                                                nsFrameList& aChildList) {
 #ifdef DEBUG
-  ChildListIDs supportedLists = kAbsoluteList | kFixedList | kPrincipalList;
+  ChildListIDs supportedLists = {kAbsoluteList, kFixedList, kPrincipalList};
   // We don't handle the kBackdropList frames in any way, but it only contains
   // a placeholder for ::backdrop which is OK to not reflow (for now anyway).
-  supportedLists |= kBackdropList;
-  MOZ_ASSERT(supportedLists.Contains(aListID), "unexpected child list");
+  supportedLists += kBackdropList;
+  MOZ_ASSERT(supportedLists.contains(aListID), "unexpected child list");
 #endif
 
   return nsContainerFrame::SetInitialChildList(aListID, aChildList);
 }
 
 void nsGridContainerFrame::SanityCheckGridItemsBeforeReflow() const {
-  ChildListIDs absLists = kAbsoluteList | kFixedList | kOverflowContainersList |
-                          kExcessOverflowContainersList;
-  ChildListIDs itemLists = kPrincipalList | kOverflowList;
+  ChildListIDs absLists = {kAbsoluteList, kFixedList, kOverflowContainersList,
+                           kExcessOverflowContainersList};
+  ChildListIDs itemLists = {kPrincipalList, kOverflowList};
   for (const nsIFrame* f = this; f; f = f->GetNextInFlow()) {
     MOZ_ASSERT(!f->HasAnyStateBits(NS_STATE_GRID_DID_PUSH_ITEMS),
                "At start of reflow, we should've pulled items back from all "
                "NIFs and cleared NS_STATE_GRID_DID_PUSH_ITEMS in the process");
     for (nsIFrame::ChildListIterator childLists(f); !childLists.IsDone();
          childLists.Next()) {
-      if (!itemLists.Contains(childLists.CurrentID())) {
-        MOZ_ASSERT(absLists.Contains(childLists.CurrentID()) ||
+      if (!itemLists.contains(childLists.CurrentID())) {
+        MOZ_ASSERT(absLists.contains(childLists.CurrentID()) ||
                        childLists.CurrentID() == kBackdropList,
                    "unexpected non-empty child list");
         continue;
       }
       for (auto child : childLists.CurrentList()) {
         MOZ_ASSERT(f == this || child->GetPrevInFlow(),
                    "all pushed items must be pulled up before reflow");
       }