Bug 1362886 part 2 - Devirtualize the IsLeaf() method by doing an array lookup instead. r=jfkthame
authorMats Palmgren <mats@mozilla.com>
Fri, 26 May 2017 12:11:12 +0200
changeset 360848 d904a186e908c790e1aa8cb9b1ef498b02ede0d4
parent 360847 13074ff6822b77ecb37d2c28a6ecf1a1761cf552
child 360849 62f8db64e839b3168c8b85005860766beb8ead57
push id31903
push userryanvm@gmail.com
push dateFri, 26 May 2017 19:44:10 +0000
treeherdermozilla-central@bce03a8eac30 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1362886
milestone55.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 1362886 part 2 - Devirtualize the IsLeaf() method by doing an array lookup instead. r=jfkthame MozReview-Commit-ID: 1zm9rFhRVZ3
layout/forms/nsColorControlFrame.h
layout/forms/nsFileControlFrame.h
layout/forms/nsGfxButtonControlFrame.cpp
layout/forms/nsGfxButtonControlFrame.h
layout/forms/nsMeterFrame.h
layout/forms/nsNumberControlFrame.h
layout/forms/nsProgressFrame.h
layout/forms/nsRangeFrame.h
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/nsAtomicContainerFrame.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsFrameSetFrame.h
layout/generic/nsIFrame.h
layout/generic/nsVideoFrame.cpp
layout/generic/nsVideoFrame.h
layout/mathml/nsMathMLmspaceFrame.cpp
layout/mathml/nsMathMLmspaceFrame.h
layout/svg/nsSVGUseFrame.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
--- a/layout/forms/nsColorControlFrame.h
+++ b/layout/forms/nsColorControlFrame.h
@@ -39,17 +39,16 @@ public:
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
   // nsIFrame
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) override;
-  virtual bool IsLeaf() const override { return true; }
   virtual nsContainerFrame* GetContentInsertionFrame() override;
 
   virtual Element* GetPseudoElement(CSSPseudoElementType aType) override;
 
   // Refresh the color swatch, using associated input's value
   nsresult UpdateColor();
 
 private:
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -50,20 +50,16 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) override;
   virtual void ContentStatesChanged(mozilla::EventStates aStates) override;
-  virtual bool IsLeaf() const override
-  {
-    return true;
-  }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -171,22 +171,16 @@ nsGfxButtonControlFrame::AttributeChange
 
   // defer to HTMLButtonControlFrame
   } else {
     rv = nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
   }
   return rv;
 }
 
-bool
-nsGfxButtonControlFrame::IsLeaf() const
-{
-  return true;
-}
-
 nsContainerFrame*
 nsGfxButtonControlFrame::GetContentInsertionFrame()
 {
   return this;
 }
 
 nsresult
 nsGfxButtonControlFrame::HandleEvent(nsPresContext* aPresContext, 
--- a/layout/forms/nsGfxButtonControlFrame.h
+++ b/layout/forms/nsGfxButtonControlFrame.h
@@ -41,18 +41,16 @@ public:
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) override;
 
-  virtual bool IsLeaf() const override;
-
   virtual nsContainerFrame* GetContentInsertionFrame() override;
 
 protected:
   nsresult GetDefaultLabel(nsXPIDLString& aLabel) const;
 
   nsresult GetLabel(nsXPIDLString& aLabel);
 
   virtual bool IsInput() override { return true; }
--- a/layout/forms/nsMeterFrame.h
+++ b/layout/forms/nsMeterFrame.h
@@ -33,18 +33,16 @@ public:
                       nsReflowStatus&          aStatus) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("Meter"), aResult);
   }
 #endif
 
-  virtual bool IsLeaf() const override { return true; }
-
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) override;
--- a/layout/forms/nsNumberControlFrame.h
+++ b/layout/forms/nsNumberControlFrame.h
@@ -43,17 +43,16 @@ class nsNumberControlFrame final : publi
   explicit nsNumberControlFrame(nsStyleContext* aContext);
 
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS(nsNumberControlFrame)
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
   virtual void ContentStatesChanged(mozilla::EventStates aStates) override;
-  virtual bool IsLeaf() const override { return true; }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
   virtual nscoord GetMinISize(nsRenderingContext* aRenderingContext) override;
 
   virtual nscoord GetPrefISize(nsRenderingContext* aRenderingContext) override;
--- a/layout/forms/nsProgressFrame.h
+++ b/layout/forms/nsProgressFrame.h
@@ -41,18 +41,16 @@ public:
                       nsReflowStatus&          aStatus) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("Progress"), aResult);
   }
 #endif
 
-  virtual bool IsLeaf() const override { return true; }
-
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
                                     int32_t  aModType) override;
--- a/layout/forms/nsRangeFrame.h
+++ b/layout/forms/nsRangeFrame.h
@@ -51,18 +51,16 @@ public:
                       nsReflowStatus&          aStatus) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override {
     return MakeFrameName(NS_LITERAL_STRING("Range"), aResult);
   }
 #endif
 
-  virtual bool IsLeaf() const override { return true; }
-
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -609,22 +609,16 @@ nsTextControlFrame::GetXULMinSize(nsBoxL
 
 bool
 nsTextControlFrame::IsXULCollapsed()
 {
   // We're never collapsed in the box sense.
   return false;
 }
 
-bool
-nsTextControlFrame::IsLeaf() const
-{
-  return true;
-}
-
 NS_IMETHODIMP
 nsTextControlFrame::ScrollOnFocusEvent::Run()
 {
   if (mFrame) {
     nsCOMPtr<nsITextControlElement> txtCtrl = do_QueryInterface(mFrame->GetContent());
     NS_ASSERTION(txtCtrl, "Content not a text control element");
     nsISelectionController* selCon = txtCtrl->GetSelectionController();
     if (selCon) {
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -82,18 +82,16 @@ public:
     } else {
       *aBaseline = BSize(aWM) - mFirstBaseline;
     }
     return true;
   }
 
   virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override;
   virtual bool IsXULCollapsed() override;
-
-  virtual bool IsLeaf() const override;
   
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override
   {
--- a/layout/generic/nsAtomicContainerFrame.h
+++ b/layout/generic/nsAtomicContainerFrame.h
@@ -19,17 +19,16 @@
  */
 class nsAtomicContainerFrame : public nsContainerFrame
 {
 public:
   NS_DECL_ABSTRACT_FRAME(nsAtomicContainerFrame)
 
   // Bypass the nsContainerFrame/nsSplittableFrame impl of the following
   // methods so we behave like a leaf frame.
-  bool IsLeaf() const override { return true; }
   FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) override
   {
     return nsFrame::PeekOffsetNoAmount(aForward, aOffset);
   }
   FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                         bool aRespectClusters = true) override
   {
     return nsFrame::PeekOffsetCharacter(aForward, aOffset, aRespectClusters);
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -346,22 +346,16 @@ nsContainerFrame::BuildDisplayListForNon
 /* virtual */ void
 nsContainerFrame::ChildIsDirty(nsIFrame* aChild)
 {
   NS_ASSERTION(NS_SUBTREE_DIRTY(aChild), "child isn't actually dirty");
 
   AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
-bool
-nsContainerFrame::IsLeaf() const
-{
-  return false;
-}
-
 nsIFrame::FrameSearchResult
 nsContainerFrame::PeekOffsetNoAmount(bool aForward, int32_t* aOffset)
 {
   NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
   // Don't allow the caret to stay in an empty (leaf) container frame.
   return CONTINUE_EMPTY;
 }
 
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -60,17 +60,16 @@ public:
     return this;
   }
 
   virtual const nsFrameList& GetChildList(ChildListID aList) const override;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
   virtual void ChildIsDirty(nsIFrame* aChild) override;
 
-  virtual bool IsLeaf() const override;
   virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) override;
   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) override;
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) override;
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6292,22 +6292,16 @@ nsIFrame::GetNearestWidget(nsPoint& aOff
   nsPoint offsetToView;
   nsPoint offsetToWidget;
   nsIWidget* widget =
     GetClosestView(&offsetToView)->GetNearestWidget(&offsetToWidget);
   aOffset = offsetToView + offsetToWidget;
   return widget;
 }
 
-bool
-nsIFrame::IsLeaf() const
-{
-  return true;
-}
-
 Matrix4x4
 nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
                              nsIFrame** aOutAncestor)
 {
   NS_PRECONDITION(aOutAncestor, "Need a place to put the ancestor!");
 
   /* If we're transformed, we want to hand back the combination
    * transform/translate matrix that will apply our current transform, then
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -1097,23 +1097,16 @@ nsHTMLFramesetFrame::Reflow(nsPresContex
 nsresult
 nsHTMLFramesetFrame::GetFrameName(nsAString& aResult) const
 {
   return MakeFrameName(NS_LITERAL_STRING("Frameset"), aResult);
 }
 #endif
 
 bool
-nsHTMLFramesetFrame::IsLeaf() const
-{
-  // We handle constructing our kids manually
-  return true;
-}
-
-bool
 nsHTMLFramesetFrame::CanResize(bool aVertical,
                                bool aLeft)
 {
   int32_t childX;
   int32_t startX;
   if (aVertical) {
     startX = (aLeft) ? 0 : mNumCols-1;
     for (childX = startX; childX < mNonBorderChildCount; childX += mNumCols) {
--- a/layout/generic/nsFrameSetFrame.h
+++ b/layout/generic/nsFrameSetFrame.h
@@ -103,18 +103,16 @@ public:
                       ReflowOutput&     aDesiredSize,
                       const ReflowInput& aReflowInput,
                       nsReflowStatus&          aStatus) override;
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
-  virtual bool IsLeaf() const override;
-  
   void StartMouseDrag(nsPresContext* aPresContext,
                       nsHTMLFramesetBorderFrame* aBorder,
                       mozilla::WidgetGUIEvent* aEvent);
 
   void MouseDrag(nsPresContext* aPresContext, 
                  mozilla::WidgetGUIEvent* aEvent);
 
   void EndMouseDrag(nsPresContext* aPresContext);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2833,17 +2833,25 @@ public:
    * Is this a leaf frame?  Frames that want the frame constructor to be able
    * to construct kids for them should return false, all others should return
    * true.  Note that returning true here does not mean that the frame _can't_
    * have kids.  It could still have kids created via
    * nsIAnonymousContentCreator.  Returning true indicates that "normal"
    * (non-anonymous, XBL-bound, CSS generated content, etc) children should not
    * be constructed.
    */
-  virtual bool IsLeaf() const;
+  bool IsLeaf() const
+  {
+    MOZ_ASSERT(uint8_t(mClass) < mozilla::ArrayLength(sFrameClassBits));
+    FrameClassBits bits = sFrameClassBits[uint8_t(mClass)];
+    if (MOZ_UNLIKELY(bits & eFrameClassBitsDynamicLeaf)) {
+      return IsLeafDynamic();
+    }
+    return bits & eFrameClassBitsLeaf;
+  }
 
   /**
    * Marks all display items created by this frame as needing a repaint,
    * and calls SchedulePaint() if requested and one is not already pending.
    *
    * This includes all display items created by this frame, including
    * container types.
    *
@@ -3815,16 +3823,23 @@ protected:
 
   /**
    * Reparent this frame's view if it has one.
    */
   void ReparentFrameViewTo(nsViewManager* aViewManager,
                            nsView*        aNewParentView,
                            nsView*        aOldParentView);
 
+  /**
+   * To be overridden by frame classes that have a varying IsLeaf() state and
+   * is indicating that with DynamicLeaf in nsFrameIdList.h.
+   * @see IsLeaf()
+   */
+  virtual bool IsLeafDynamic() const { return false; }
+
   // Members
   nsRect           mRect;
   nsIContent*      mContent;
   nsStyleContext*  mStyleContext;
 private:
   nsContainerFrame* mParent;
   nsIFrame*        mNextSibling;  // doubly-linked list of frames
   nsIFrame*        mPrevSibling;  // Do not touch outside SetNextSibling!
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -177,22 +177,16 @@ void
 nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsContentUtils::DestroyAnonymousContent(&mCaptionDiv);
   nsContentUtils::DestroyAnonymousContent(&mVideoControls);
   nsContentUtils::DestroyAnonymousContent(&mPosterImage);
   nsContainerFrame::DestroyFrom(aDestructRoot);
 }
 
-bool
-nsVideoFrame::IsLeaf() const
-{
-  return true;
-}
-
 already_AddRefed<Layer>
 nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
                          LayerManager* aManager,
                          nsDisplayItem* aItem,
                          const ContainerLayerParameters& aContainerParameters)
 {
   nsRect area = GetContentRectRelativeToSelf() + aItem->ToReferenceFrame();
   HTMLVideoElement* element = static_cast<HTMLVideoElement*>(GetContent());
--- a/layout/generic/nsVideoFrame.h
+++ b/layout/generic/nsVideoFrame.h
@@ -64,17 +64,16 @@ public:
               nscoord aAvailableISize,
               const mozilla::LogicalSize& aMargin,
               const mozilla::LogicalSize& aBorder,
               const mozilla::LogicalSize& aPadding,
               ComputeSizeFlags aFlags) override;
   nscoord GetMinISize(nsRenderingContext *aRenderingContext) override;
   nscoord GetPrefISize(nsRenderingContext *aRenderingContext) override;
   void DestroyFrom(nsIFrame* aDestructRoot) override;
-  bool IsLeaf() const override;
 
   void Reflow(nsPresContext*     aPresContext,
               ReflowOutput&      aDesiredSize,
               const ReflowInput& aReflowInput,
               nsReflowStatus&    aStatus) override;
 
 #ifdef ACCESSIBILITY
   mozilla::a11y::AccType AccessibleType() override;
--- a/layout/mathml/nsMathMLmspaceFrame.cpp
+++ b/layout/mathml/nsMathMLmspaceFrame.cpp
@@ -20,22 +20,16 @@ NS_NewMathMLmspaceFrame(nsIPresShell* aP
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmspaceFrame)
 
 nsMathMLmspaceFrame::~nsMathMLmspaceFrame()
 {
 }
 
-bool
-nsMathMLmspaceFrame::IsLeaf() const
-{
-  return true;
-}
-
 void
 nsMathMLmspaceFrame::ProcessAttributes(nsPresContext* aPresContext)
 {
   nsAutoString value;
   float fontSizeInflation = nsLayoutUtils::FontSizeInflationFor(this);
 
   // width 
   //
--- a/layout/mathml/nsMathMLmspaceFrame.h
+++ b/layout/mathml/nsMathMLmspaceFrame.h
@@ -22,18 +22,16 @@ public:
   NS_IMETHOD
   TransmitAutomaticData() override {
     // The REC defines the following elements to be space-like:
     // * an mtext, mspace, maligngroup, or malignmark element;
     mPresentationData.flags |= NS_MATHML_SPACE_LIKE;
     return NS_OK;
   }
 
-  virtual bool IsLeaf() const override;
-
   virtual void
   Reflow(nsPresContext*          aPresContext,
          ReflowOutput&     aDesiredSize,
          const ReflowInput& aReflowInput,
          nsReflowStatus&          aStatus) override;
   
 protected:
   explicit nsMathMLmspaceFrame(nsStyleContext* aContext) :
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -35,18 +35,16 @@ public:
                     nsIFrame*         aPrevInFlow) override;
 
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      int32_t         aModType) override;
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
 
-  virtual bool IsLeaf() const override;
-
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGUse"), aResult);
   }
 #endif
 
   // nsSVGDisplayableFrame interface:
@@ -152,22 +150,16 @@ nsSVGUseFrame::AttributeChanged(int32_t 
 void
 nsSVGUseFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   RefPtr<SVGUseElement> use = static_cast<SVGUseElement*>(mContent);
   nsSVGGFrame::DestroyFrom(aDestructRoot);
   use->DestroyAnonymousContent();
 }
 
-bool
-nsSVGUseFrame::IsLeaf() const
-{
-  return true;
-}
-
 
 //----------------------------------------------------------------------
 // nsSVGDisplayableFrame methods
 
 void
 nsSVGUseFrame::ReflowSVG()
 {
   // We only handle x/y offset here, since any width/height that is in force is
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -429,17 +429,17 @@ nsMenuPopupFrame::SetInitialChildList(Ch
   // unless the list is empty, indicate that children have been generated.
   if (aListID == kPrincipalList && aChildList.NotEmpty()) {
     mGeneratedChildren = true;
   }
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
 }
 
 bool
-nsMenuPopupFrame::IsLeaf() const
+nsMenuPopupFrame::IsLeafDynamic() const
 {
   if (mGeneratedChildren)
     return false;
 
   if (mPopupType != ePopupTypeMenu) {
     // any panel with a type attribute, such as the autocomplete popup,
     // is always generated right away.
     return !mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::type);
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -241,17 +241,17 @@ public:
   void EnsureWidget(bool aRecreate = false);
 
   nsresult CreateWidgetForView(nsView* aView);
   uint8_t GetShadowStyle();
 
   virtual void SetInitialChildList(ChildListID  aListID,
                                    nsFrameList& aChildList) override;
 
-  virtual bool IsLeaf() const override;
+  virtual bool IsLeafDynamic() const override;
 
   // layout, position and display the popup as needed
   void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
                    nsIFrame* aAnchor, bool aSizedToPopup);
 
   nsView* GetRootViewForPopup(nsIFrame* aStartFrame);
 
   // Set the position of the popup either relative to the anchor aAnchorFrame