Bug 1525371 - Remove ArenaRefPtr. r=jwatt
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 05 Feb 2019 20:25:22 +0100
changeset 457594 56eeff69792c1809cd2dd51a77ea276cde635cdc
parent 457593 525e804dc7e63855e026be9557af15340d71455a
child 457595 d9be4af74c4b90d08a03fbce96bdabf7dca9faf8
push id35516
push userrmaries@mozilla.com
push dateFri, 08 Feb 2019 04:23:26 +0000
treeherdermozilla-central@d599d1a73a3a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1525371
milestone67.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 1525371 - Remove ArenaRefPtr. r=jwatt Differential Revision: https://phabricator.services.mozilla.com/D18735
layout/base/ArenaRefPtr.h
layout/base/ArenaRefPtrInlines.h
layout/base/PresShell.cpp
layout/base/moz.build
layout/base/nsIPresShell.h
layout/base/nsPresArena.cpp
layout/base/nsPresArena.h
layout/base/nsPresArenaObjectList.h
deleted file mode 100644
--- a/layout/base/ArenaRefPtr.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-/* smart pointer for strong references to nsPresArena-allocated objects
-   that might be held onto until the arena's destruction */
-
-#include "mozilla/Assertions.h"
-#include "mozilla/RefPtr.h"
-
-#ifndef mozilla_ArenaRefPtr_h
-#  define mozilla_ArenaRefPtr_h
-
-template <size_t ArenaSize>
-class nsPresArena;
-
-namespace mozilla {
-
-/**
- * A class for holding strong references to nsPresArena-allocated
- * objects.
- *
- * Since the arena's lifetime is not related to the refcounts
- * of the objects allocated within it, it is possible to have a strong
- * reference to an arena-allocated object that lives until the
- * destruction of the arena.  An ArenaRefPtr acts like a weak reference
- * in that it will clear its referent if the arena is about to go away.
- *
- * T must be a class that has these two methods:
- *
- *   static mozilla::ArenaObjectID ArenaObjectID();
- *   U* Arena();
- *
- * where U is a class that has these two methods:
- *
- *   void RegisterArenaRefPtr(ArenaRefPtr<T>*);
- *   void DeregisterArenaRefPtr(ArenaRefPtr<T>*);
- *
- * Currently, both nsPresArena and nsIPresShell can be used as U.
- *
- * The ArenaObjectID method must return the mozilla::ArenaObjectID that
- * uniquely identifies T, and the Arena method must return the nsPresArena
- * (or a proxy for it) in which the object was allocated.
- */
-template <typename T>
-class ArenaRefPtr {
-  template <size_t ArenaSize>
-  friend class ::nsPresArena;
-
- public:
-  ArenaRefPtr() { AssertValidType(); }
-
-  template <typename I>
-  MOZ_IMPLICIT ArenaRefPtr(already_AddRefed<I>& aRhs) {
-    AssertValidType();
-    assign(aRhs);
-  }
-
-  template <typename I>
-  MOZ_IMPLICIT ArenaRefPtr(already_AddRefed<I>&& aRhs) {
-    AssertValidType();
-    assign(aRhs);
-  }
-
-  MOZ_IMPLICIT ArenaRefPtr(T* aRhs) {
-    AssertValidType();
-    assign(aRhs);
-  }
-
-  template <typename I>
-  ArenaRefPtr<T>& operator=(already_AddRefed<I>& aRhs) {
-    assign(aRhs);
-    return *this;
-  }
-
-  template <typename I>
-  ArenaRefPtr<T>& operator=(already_AddRefed<I>&& aRhs) {
-    assign(aRhs);
-    return *this;
-  }
-
-  ArenaRefPtr<T>& operator=(T* aRhs) {
-    assign(aRhs);
-    return *this;
-  }
-
-  ~ArenaRefPtr() { assign(nullptr); }
-
-  operator T*() const& { return get(); }
-  operator T*() const&& = delete;
-  explicit operator bool() const { return !!mPtr; }
-  bool operator!() const { return !mPtr; }
-  T* operator->() const { return mPtr.operator->(); }
-  T& operator*() const { return *get(); }
-
-  T* get() const { return mPtr; }
-
- private:
-  void AssertValidType();
-
-  /**
-   * Clears the pointer to the arena-allocated object but skips the usual
-   * step of deregistering the ArenaRefPtr from the nsPresArena.  This
-   * method is called by nsPresArena when clearing all registered ArenaRefPtrs
-   * so that it can deregister them all at once, avoiding hash table churn.
-   */
-  void ClearWithoutDeregistering() { mPtr = nullptr; }
-
-  template <typename I>
-  void assign(already_AddRefed<I>& aSmartPtr) {
-    RefPtr<T> newPtr(aSmartPtr);
-    assignFrom(newPtr);
-  }
-
-  template <typename I>
-  void assign(already_AddRefed<I>&& aSmartPtr) {
-    RefPtr<T> newPtr(aSmartPtr);
-    assignFrom(newPtr);
-  }
-
-  void assign(T* aPtr) { assignFrom(aPtr); }
-
-  template <typename I>
-  void assignFrom(I& aPtr) {
-    if (aPtr == mPtr) {
-      return;
-    }
-    bool sameArena = mPtr && aPtr && mPtr->Arena() == aPtr->Arena();
-    if (mPtr && !sameArena) {
-      MOZ_ASSERT(mPtr->Arena());
-      mPtr->Arena()->DeregisterArenaRefPtr(this);
-    }
-    mPtr = std::move(aPtr);
-    if (mPtr && !sameArena) {
-      MOZ_ASSERT(mPtr->Arena());
-      mPtr->Arena()->RegisterArenaRefPtr(this);
-    }
-  }
-
-  RefPtr<T> mPtr;
-};
-
-}  // namespace mozilla
-
-#endif  // mozilla_ArenaRefPtr_h
deleted file mode 100644
--- a/layout/base/ArenaRefPtrInlines.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/.
- */
-
-/* inline methods that belong in ArenaRefPtr.h, except that they require
-   the inclusion of headers for all types that ArenaRefPtr can handle */
-
-#ifndef mozilla_ArenaRefPtrInlines_h
-#define mozilla_ArenaRefPtrInlines_h
-
-#include "mozilla/ArenaObjectID.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/ComputedStyle.h"
-#include "nsPresArena.h"
-#include "nsStyleStruct.h"
-
-namespace mozilla {
-
-template <typename T>
-void ArenaRefPtr<T>::AssertValidType() {
-  // If adding new types, please update
-  // nsPresArena::ClearArenaRefPtrWithoutDeregistering as well
-  static_assert(IsSame<T, ComputedStyle>::value,
-                "ArenaRefPtr<T> template parameter T must be declared in "
-                "nsPresArenaObjectList and explicitly handled in"
-                "nsPresArena.cpp");
-}
-
-}  // namespace mozilla
-
-#endif
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -1301,33 +1301,16 @@ void PresShell::Destroy() {
 
   if (mViewManager) {
     // Clear the view manager's weak pointer back to |this| in case it
     // was leaked.
     mViewManager->SetPresShell(nullptr);
     mViewManager = nullptr;
   }
 
-  // mFrameArena will be destroyed soon.  Clear out any ArenaRefPtrs
-  // pointing to objects in the arena now.  This is done:
-  //
-  //   (a) before mFrameArena's destructor runs so that our
-  //       mAllocatedPointers becomes empty and doesn't trip the assertion
-  //       in ~PresShell,
-  //   (b) before the mPresContext->DetachShell() below, so
-  //       that when we clear the ArenaRefPtrs they'll still be able to
-  //       get back to this PresShell to deregister themselves (e.g. note
-  //       how ComputedStyle::Arena returns the PresShell got from its
-  //       rule node's nsPresContext, which would return null if we'd already
-  //       called mPresContext->DetachShell()), and
-  //   (c) before the mStyleSet->BeginShutdown() call just below, so that
-  //       the ComputedStyles don't complain they're being destroyed later
-  //       than the rule tree is.
-  mFrameArena.ClearArenaRefPtrs();
-
   mStyleSet->BeginShutdown();
   nsRefreshDriver* rd = GetPresContext()->RefreshDriver();
 
   // This shell must be removed from the document before the frame
   // hierarchy is torn down to avoid finding deleted frames through
   // this presshell while the frames are being torn down
   if (mDocument) {
     NS_ASSERTION(mDocument->GetShell() == this, "Wrong shell?");
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -69,18 +69,16 @@ EXPORTS += [
     'UnitTransforms.h',
     'WordMovementType.h',
     'ZoomConstraintsClient.h',
 ]
 
 EXPORTS.mozilla += [
     'AccessibleCaretEventHub.h',
     'ArenaObjectID.h',
-    'ArenaRefPtr.h',
-    'ArenaRefPtrInlines.h',
     'GeometryUtils.h',
     'OverflowChangedTracker.h',
     'PresShell.h',
     'RestyleManager.h',
     'ScrollStyles.h',
     'ShapeUtils.h',
     'StaticPresData.h',
 ]
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -242,30 +242,16 @@ class nsIPresShell : public nsStubDocume
     return result;
   }
 
   void FreeByObjectID(mozilla::ArenaObjectID aID, void* aPtr) {
     RecordFree(aPtr);
     if (!mIsDestroying) mFrameArena.FreeByObjectID(aID, aPtr);
   }
 
-  template <typename T>
-  void RegisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr) {
-    mFrameArena.RegisterArenaRefPtr(aPtr);
-  }
-
-  template <typename T>
-  void DeregisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr) {
-    mFrameArena.DeregisterArenaRefPtr(aPtr);
-  }
-
-  void ClearArenaRefPtrs(mozilla::ArenaObjectID aObjectID) {
-    mFrameArena.ClearArenaRefPtrs(aObjectID);
-  }
-
   Document* GetDocument() const { return mDocument; }
 
   nsPresContext* GetPresContext() const { return mPresContext; }
 
   nsViewManager* GetViewManager() const { return mViewManager; }
 
   nsRefreshDriver* GetRefreshDriver() const;
 
--- a/layout/base/nsPresArena.cpp
+++ b/layout/base/nsPresArena.cpp
@@ -19,70 +19,29 @@
 #include "nsWindowSizes.h"
 
 #include <inttypes.h>
 
 using namespace mozilla;
 
 template <size_t ArenaSize>
 nsPresArena<ArenaSize>::~nsPresArena<ArenaSize>() {
-  ClearArenaRefPtrs();
-
 #if defined(MOZ_HAVE_MEM_CHECKS)
   for (FreeList* entry = mFreeLists; entry != ArrayEnd(mFreeLists); ++entry) {
     nsTArray<void*>::index_type len;
     while ((len = entry->mEntries.Length())) {
       void* result = entry->mEntries.ElementAt(len - 1);
       entry->mEntries.RemoveElementAt(len - 1);
       MOZ_MAKE_MEM_UNDEFINED(result, entry->mEntrySize);
     }
   }
 #endif
 }
 
 template <size_t ArenaSize>
-/* inline */ void nsPresArena<ArenaSize>::ClearArenaRefPtrWithoutDeregistering(
-    void* aPtr, ArenaObjectID aObjectID) {
-  switch (aObjectID) {
-    // We use ArenaRefPtr<ComputedStyle>, which can be ComputedStyle
-    // or GeckoComputedStyle. GeckoComputedStyle is actually arena managed,
-    // but ComputedStyle isn't.
-    case eArenaObjectID_GeckoComputedStyle:
-      static_cast<ArenaRefPtr<ComputedStyle>*>(aPtr)
-          ->ClearWithoutDeregistering();
-      return;
-    default:
-      MOZ_ASSERT(false, "unexpected ArenaObjectID value");
-      break;
-  }
-}
-
-template <size_t ArenaSize>
-void nsPresArena<ArenaSize>::ClearArenaRefPtrs() {
-  for (auto iter = mArenaRefPtrs.Iter(); !iter.Done(); iter.Next()) {
-    void* ptr = iter.Key();
-    ArenaObjectID id = iter.UserData();
-    ClearArenaRefPtrWithoutDeregistering(ptr, id);
-  }
-  mArenaRefPtrs.Clear();
-}
-
-template <size_t ArenaSize>
-void nsPresArena<ArenaSize>::ClearArenaRefPtrs(ArenaObjectID aObjectID) {
-  for (auto iter = mArenaRefPtrs.Iter(); !iter.Done(); iter.Next()) {
-    void* ptr = iter.Key();
-    ArenaObjectID id = iter.UserData();
-    if (id == aObjectID) {
-      ClearArenaRefPtrWithoutDeregistering(ptr, id);
-      iter.Remove();
-    }
-  }
-}
-
-template <size_t ArenaSize>
 void* nsPresArena<ArenaSize>::Allocate(uint32_t aCode, size_t aSize) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aSize > 0, "PresArena cannot allocate zero bytes");
   MOZ_ASSERT(aCode < ArrayLength(mFreeLists));
 
   // We only hand out aligned sizes
   aSize = mPool.AlignedSize(aSize);
 
--- a/layout/base/nsPresArena.h
+++ b/layout/base/nsPresArena.h
@@ -7,17 +7,16 @@
 
 /* arena allocation for the frame tree and closely-related objects */
 
 #ifndef nsPresArena_h___
 #define nsPresArena_h___
 
 #include "mozilla/ArenaAllocator.h"
 #include "mozilla/ArenaObjectID.h"
-#include "mozilla/ArenaRefPtr.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/MemoryChecking.h"  // Note: Do not remove this, needed for MOZ_HAVE_MEM_CHECKS below
 #include "mozilla/MemoryReporting.h"
 #include <stdint.h>
 #include "nscore.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
@@ -54,82 +53,37 @@ class nsPresArena {
   }
 
   void* AllocateByCustomID(uint32_t aID, size_t aSize) {
     return Allocate(aID, aSize);
   }
   void FreeByCustomID(uint32_t aID, void* ptr) { Free(aID, ptr); }
 
   /**
-   * Register an ArenaRefPtr to be cleared when this arena is about to
-   * be destroyed.
-   *
-   * (Defined in ArenaRefPtrInlines.h.)
-   *
-   * @param aPtr The ArenaRefPtr to clear.
-   * @param aObjectID The ArenaObjectID value that uniquely identifies
-   *   the type of object the ArenaRefPtr holds.
-   */
-  template <typename T>
-  void RegisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr) {
-    MOZ_ASSERT(!mArenaRefPtrs.Contains(aPtr));
-    mArenaRefPtrs.Put(aPtr, T::ArenaObjectID());
-  }
-
-  /**
-   * Deregister an ArenaRefPtr that was previously registered with
-   * RegisterArenaRefPtr.
-   */
-  template <typename T>
-  void DeregisterArenaRefPtr(mozilla::ArenaRefPtr<T>* aPtr) {
-    MOZ_ASSERT(mArenaRefPtrs.Contains(aPtr));
-    mArenaRefPtrs.Remove(aPtr);
-  }
-
-  /**
-   * Clears all currently registered ArenaRefPtrs.  This will be called during
-   * the destructor, but can be called by users of nsPresArena who want to
-   * ensure arena-allocated objects are released earlier.
-   */
-  void ClearArenaRefPtrs();
-
-  /**
-   * Clears all currently registered ArenaRefPtrs for the given ArenaObjectID.
-   * This is called when we reconstruct the rule tree so that ComputedStyles
-   * pointing into the old rule tree aren't released afterwards, triggering an
-   * assertion in ~ComputedStyle.
-   */
-  void ClearArenaRefPtrs(mozilla::ArenaObjectID aObjectID);
-
-  /**
    * Increment nsWindowSizes with sizes of interesting objects allocated in this
    * arena.
    */
   void AddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const;
 
   void Check() { mPool.Check(); }
 
  private:
   void* Allocate(uint32_t aCode, size_t aSize);
   void Free(uint32_t aCode, void* aPtr);
 
-  inline void ClearArenaRefPtrWithoutDeregistering(
-      void* aPtr, mozilla::ArenaObjectID aObjectID);
-
   class FreeList {
    public:
     nsTArray<void*> mEntries;
     size_t mEntrySize;
     size_t mEntriesEverAllocated;
 
     FreeList() : mEntrySize(0), mEntriesEverAllocated(0) {}
 
     size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
       return mEntries.ShallowSizeOfExcludingThis(aMallocSizeOf);
     }
   };
 
   FreeList mFreeLists[mozilla::eArenaObjectID_COUNT];
   mozilla::ArenaAllocator<ArenaSize, 8> mPool;
-  nsDataHashtable<nsPtrHashKey<void>, mozilla::ArenaObjectID> mArenaRefPtrs;
 };
 
 #endif
--- a/layout/base/nsPresArenaObjectList.h
+++ b/layout/base/nsPresArenaObjectList.h
@@ -4,18 +4,16 @@
  * 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/. */
 
 /* a list of all types that can be allocated in an nsPresArena, for
    preprocessing */
 
 // These are objects that can be stored in the pres arena
 
-PRES_ARENA_OBJECT(GeckoComputedStyle)
-
 PRES_ARENA_OBJECT(nsLineBox)
 PRES_ARENA_OBJECT(DisplayItemData)
 PRES_ARENA_OBJECT(nsFrameList)
 PRES_ARENA_OBJECT(CustomCounterStyle)
 PRES_ARENA_OBJECT(DependentBuiltinCounterStyle)
 PRES_ARENA_OBJECT(nsCallbackEventRequest)
 PRES_ARENA_OBJECT(nsIntervalSet_Interval)
 PRES_ARENA_OBJECT(CellData)