Bug 1526972 - P3: De-virtualize HasDeletedFrame(). r=miko
☠☠ backed out by 9f0f38c38ccc ☠ ☠
authorDan Glastonbury <dan.glastonbury@gmail.com>
Mon, 15 Apr 2019 00:23:11 +0000
changeset 469449 ddd57e4372286632c4759d84d86cba27b30fc3a2
parent 469448 54b14df56e6f06c730b57c5d503955b02d6c7963
child 469450 8543b9d465212a64ee52a84f1da4760cfda702fa
push id112792
push userncsoregi@mozilla.com
push dateMon, 15 Apr 2019 09:49:11 +0000
treeherdermozilla-inbound@a57f27d3ccd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko
bugs1526972
milestone68.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 1526972 - P3: De-virtualize HasDeletedFrame(). r=miko To avoid expensive virtual dispatch in PreProcessDisplayList(). Depends on D24460 Differential Revision: https://phabricator.services.mozilla.com/D26136
layout/ipc/RenderFrame.cpp
layout/ipc/RenderFrame.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/ipc/RenderFrame.cpp
+++ b/layout/ipc/RenderFrame.cpp
@@ -190,21 +190,16 @@ mozilla::LayerState nsDisplayRemote::Get
     nsDisplayListBuilder* aBuilder, LayerManager* aManager,
     const ContainerLayerParameters& aParameters) {
   if (IsTempLayerManager(aManager)) {
     return mozilla::LAYER_NONE;
   }
   return mozilla::LAYER_ACTIVE_FORCE;
 }
 
-bool nsDisplayRemote::HasDeletedFrame() const {
-  // RenderFrame might change without invalidating nsSubDocumentFrame.
-  return !GetFrameLoader() || nsDisplayItem::HasDeletedFrame();
-}
-
 already_AddRefed<Layer> nsDisplayRemote::BuildLayer(
     nsDisplayListBuilder* aBuilder, LayerManager* aManager,
     const ContainerLayerParameters& aContainerParameters) {
   MOZ_ASSERT(mFrame, "Makes no sense to have a shadow tree without a frame");
 
   if (IsTempLayerManager(aManager)) {
     // This can happen if aManager is a "temporary" manager, or if the
     // widget's layer manager changed out from under us.  We need to
--- a/layout/ipc/RenderFrame.h
+++ b/layout/ipc/RenderFrame.h
@@ -85,31 +85,31 @@ class RenderFrame final {
 }  // namespace layout
 }  // namespace mozilla
 
 /**
  * A nsDisplayRemote will graft a remote frame's shadow layer tree (for a given
  * nsFrameLoader) into its parent frame's layer tree.
  */
 class nsDisplayRemote final : public nsDisplayItem {
+  friend class nsDisplayItem;
+
   typedef mozilla::dom::TabId TabId;
   typedef mozilla::gfx::Matrix4x4 Matrix4x4;
   typedef mozilla::layers::EventRegionsOverride EventRegionsOverride;
   typedef mozilla::layers::Layer Layer;
   typedef mozilla::layers::LayersId LayersId;
   typedef mozilla::layers::RefLayer RefLayer;
   typedef mozilla::layout::RenderFrame RenderFrame;
   typedef mozilla::LayoutDeviceRect LayoutDeviceRect;
   typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
 
  public:
   nsDisplayRemote(nsDisplayListBuilder* aBuilder, nsSubDocumentFrame* aFrame);
 
-  bool HasDeletedFrame() const override;
-
   LayerState GetLayerState(
       nsDisplayListBuilder* aBuilder, LayerManager* aManager,
       const ContainerLayerParameters& aParameters) override;
 
   already_AddRefed<Layer> BuildLayer(
       nsDisplayListBuilder* aBuilder, LayerManager* aManager,
       const ContainerLayerParameters& aContainerParameters) override;
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -96,16 +96,17 @@
 #include "nsSliderFrame.h"
 #include "ClientLayerManager.h"
 #include "mozilla/layers/RenderRootStateManager.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/layers/WebRenderMessages.h"
 #include "mozilla/layers/WebRenderScrollData.h"
+#include "mozilla/layout/RenderFrame.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 using namespace mozilla::gfx;
 
 typedef ScrollableLayerGuid::ViewID ViewID;
@@ -3215,16 +3216,22 @@ bool nsDisplayItem::ForceActiveLayers() 
   if (!sForceCached) {
     Preferences::AddBoolVarCache(&sForce, "layers.force-active", false);
     sForceCached = true;
   }
 
   return sForce;
 }
 
+bool nsDisplayItem::HasDeletedFrame() const {
+  return mItemFlags.contains(ItemFlag::DeletedFrame) ||
+         (GetType() == DisplayItemType::TYPE_REMOTE &&
+          !static_cast<const nsDisplayRemote*>(this)->GetFrameLoader());
+}
+
 int32_t nsDisplayItem::ZIndex() const { return mFrame->ZIndex(); }
 
 bool nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                       nsRegion* aVisibleRegion) {
   return !GetPaintRect().IsEmpty() &&
          !IsInvisibleInRect(aVisibleRegion->GetBounds());
 }
 
@@ -3290,16 +3297,18 @@ void nsDisplayItem::FuseClipChainUpTo(ns
 
   if (mClipChain) {
     mClip = &mClipChain->mClip;
   } else {
     mClip = nullptr;
   }
 }
 
+void nsDisplayItem::SetDeletedFrame() { mItemFlags += ItemFlag::DeletedFrame; }
+
 bool nsDisplayItem::ShouldUseAdvancedLayer(LayerManager* aManager,
                                            PrefFunc aFunc) const {
   return CanUseAdvancedLayer(aManager) ? aFunc() : false;
 }
 
 bool nsDisplayItem::CanUseAdvancedLayer(LayerManager* aManager) const {
   return gfxPrefs::LayersAdvancedBasicLayerEnabled() || !aManager ||
          aManager->GetBackendType() == layers::LayersBackend::LAYERS_WR;
@@ -6687,23 +6696,20 @@ nsDisplaySubDocument::~nsDisplaySubDocum
     mSubDocFrame->RemoveDisplayItem(this);
   }
 }
 
 nsIFrame* nsDisplaySubDocument::FrameForInvalidation() const {
   return mSubDocFrame ? mSubDocFrame : mFrame;
 }
 
-bool nsDisplaySubDocument::HasDeletedFrame() const {
-  return !mSubDocFrame || nsDisplayItem::HasDeletedFrame();
-}
-
 void nsDisplaySubDocument::RemoveFrame(nsIFrame* aFrame) {
   if (aFrame == mSubDocFrame) {
     mSubDocFrame = nullptr;
+    SetDeletedFrame();
   }
   nsDisplayItem::RemoveFrame(aFrame);
 }
 
 void nsDisplaySubDocument::Disown() {
   if (mFrame) {
     mFrame->RemoveDisplayItem(this);
     mFrame = nullptr;
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2185,16 +2185,17 @@ class nsDisplayItem : public nsDisplayIt
     mClip = mState.mClip;
     mItemFlags -= ItemFlag::DisableSubpixelAA;
   }
 
   virtual void RemoveFrame(nsIFrame* aFrame) {
     if (mFrame && aFrame == mFrame) {
       MOZ_ASSERT(!mFrame->HasDisplayItem(this));
       mFrame = nullptr;
+      SetDeletedFrame();
       SetDisplayItemData(nullptr, nullptr);
     }
   }
 
   /**
    * Downcasts this item to nsDisplayWrapList, if possible.
    */
   virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; }
@@ -2296,17 +2297,17 @@ class nsDisplayItem : public nsDisplayIt
   }
 
   /**
    * @return the nsIFrame that provides the style data, and should
    * be checked when deciding if this display item can be reused.
    */
   virtual nsIFrame* FrameForInvalidation() const { return mFrame; }
 
-  virtual bool HasDeletedFrame() const { return !mFrame; }
+  bool HasDeletedFrame() const;
 
   virtual nsIFrame* StyleFrame() const { return mFrame; }
 
   /**
    * Compute the used z-index of our frame; returns zero for elements to which
    * z-index does not apply, and for z-index:auto.
    * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
    */
@@ -2984,21 +2985,24 @@ class nsDisplayItem : public nsDisplayIt
 
   virtual bool HasHitTestInfo() const { return false; }
 
 #ifdef DEBUG
   virtual bool IsHitTestItem() const { return false; }
 #endif
 
  protected:
+  void SetDeletedFrame();
+
   typedef bool (*PrefFunc)(void);
   bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
   bool CanUseAdvancedLayer(LayerManager* aManager) const;
 
   enum class ItemFlag {
+    DeletedFrame,
     ForceNotVisible,
     DisableSubpixelAA,
     CantBeReused,
     ReusedItem,
     BackfaceHidden,
     Combines3DTransformWithAncestors,
     PaintRectValid,
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
@@ -4538,23 +4542,20 @@ class nsDisplayTableBackgroundImage : pu
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   bool IsInvalid(nsRect& aRect) const override;
 
   nsIFrame* FrameForInvalidation() const override { return mStyleFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mStyleFrame || nsDisplayBackgroundImage::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mStyleFrame) {
       mStyleFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayBackgroundImage::RemoveFrame(aFrame);
   }
 
  protected:
   nsIFrame* StyleFrame() const override { return mStyleFrame; }
 
   nsIFrame* mStyleFrame;
@@ -4669,23 +4670,20 @@ class nsDisplayTableThemedBackground : p
 
   uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mAncestorFrame || nsDisplayThemedBackground::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mAncestorFrame) {
       mAncestorFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayThemedBackground::RemoveFrame(aFrame);
   }
 
  protected:
   nsIFrame* StyleFrame() const override { return mAncestorFrame; }
   nsIFrame* mAncestorFrame;
   TableType mTableType;
@@ -4849,23 +4847,20 @@ class nsDisplayTableBackgroundColor : pu
       mAncestorFrame->RemoveDisplayItem(this);
     }
   }
 
   NS_DISPLAY_DECL_NAME("TableBackgroundColor", TYPE_TABLE_BACKGROUND_COLOR)
 
   nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mAncestorFrame || nsDisplayBackgroundColor::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mAncestorFrame) {
       mAncestorFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayBackgroundColor::RemoveFrame(aFrame);
   }
 
   uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
@@ -5671,23 +5666,20 @@ class nsDisplayTableBlendMode : public n
   NS_DISPLAY_DECL_NAME("TableBlendMode", TYPE_TABLE_BLEND_MODE)
 
   nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override {
     return MakeDisplayItem<nsDisplayTableBlendMode>(aBuilder, *this);
   }
 
   nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mAncestorFrame || nsDisplayBlendMode::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mAncestorFrame) {
       mAncestorFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayBlendMode::RemoveFrame(aFrame);
   }
 
   uint32_t GetPerFrameKey() const override {
     return (mIndex << (TYPE_BITS +
                        static_cast<uint8_t>(TableTypeBits::COUNT))) |
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
@@ -5778,23 +5770,20 @@ class nsDisplayTableBlendContainer : pub
   NS_DISPLAY_DECL_NAME("TableBlendContainer", TYPE_TABLE_BLEND_CONTAINER)
 
   nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override {
     return MakeDisplayItem<nsDisplayTableBlendContainer>(aBuilder, *this);
   }
 
   nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mAncestorFrame || nsDisplayBlendContainer::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mAncestorFrame) {
       mAncestorFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayBlendContainer::RemoveFrame(aFrame);
   }
 
   uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
@@ -6011,17 +6000,16 @@ class nsDisplaySubDocument : public nsDi
   nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                            bool* aSnap) const override;
 
   mozilla::UniquePtr<ScrollMetadata> ComputeScrollMetadata(
       LayerManager* aLayerManager,
       const ContainerLayerParameters& aContainerParameters);
 
   nsIFrame* FrameForInvalidation() const override;
-  bool HasDeletedFrame() const override;
   void RemoveFrame(nsIFrame* aFrame) override;
 
   void Disown();
 
  protected:
   ViewID mScrollParentId;
   bool mForceDispatchToContentRegion;
   bool mShouldFlatten;
@@ -6193,23 +6181,20 @@ class nsDisplayTableFixedPosition : publ
   NS_DISPLAY_DECL_NAME("TableFixedPosition", TYPE_TABLE_FIXED_POSITION)
 
   nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override {
     return MakeDisplayItem<nsDisplayTableFixedPosition>(aBuilder, *this);
   }
 
   nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
-  bool HasDeletedFrame() const override {
-    return !mAncestorFrame || nsDisplayFixedPosition::HasDeletedFrame();
-  }
-
   void RemoveFrame(nsIFrame* aFrame) override {
     if (aFrame == mAncestorFrame) {
       mAncestorFrame = nullptr;
+      SetDeletedFrame();
     }
     nsDisplayFixedPosition::RemoveFrame(aFrame);
   }
 
   uint32_t GetPerFrameKey() const override {
     return (mIndex << (TYPE_BITS +
                        static_cast<uint8_t>(TableTypeBits::COUNT))) |
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |