LCOV - code coverage report
Current view: top level - layout/base - ArenaRefPtr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 24 28 85.7 %
Date: 2017-07-14 16:53:18 Functions: 9 11 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim: set ts=2 sw=2 et tw=78:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       6             :  */
       7             : 
       8             : /* smart pointer for strong references to nsPresArena-allocated objects
       9             :    that might be held onto until the arena's destruction */
      10             : 
      11             : #include "mozilla/Assertions.h"
      12             : #include "mozilla/RefPtr.h"
      13             : 
      14             : #ifndef mozilla_ArenaRefPtr_h
      15             : #define mozilla_ArenaRefPtr_h
      16             : 
      17             : class nsPresArena;
      18             : 
      19             : namespace mozilla {
      20             : 
      21             : /**
      22             :  * A class for holding strong references to nsPresArena-allocated
      23             :  * objects.
      24             :  *
      25             :  * Since the arena's lifetime is not related to the refcounts
      26             :  * of the objects allocated within it, it is possible to have a strong
      27             :  * reference to an arena-allocated object that lives until the
      28             :  * destruction of the arena.  An ArenaRefPtr acts like a weak reference
      29             :  * in that it will clear its referent if the arena is about to go away.
      30             :  *
      31             :  * T must be a class that has these two methods:
      32             :  *
      33             :  *   static mozilla::ArenaObjectID ArenaObjectID();
      34             :  *   U* Arena();
      35             :  *
      36             :  * where U is a class that has these two methods:
      37             :  *
      38             :  *   void RegisterArenaRefPtr(ArenaRefPtr<T>*);
      39             :  *   void DeregisterArenaRefPtr(ArenaRefPtr<T>*);
      40             :  *
      41             :  * Currently, both nsPresArena and nsIPresShell can be used as U.
      42             :  *
      43             :  * The ArenaObjectID method must return the mozilla::ArenaObjectID that
      44             :  * uniquely identifies T, and the Arena method must return the nsPresArena
      45             :  * (or a proxy for it) in which the object was allocated.
      46             :  */
      47             : template<typename T>
      48             : class ArenaRefPtr
      49             : {
      50             :   friend class ::nsPresArena;
      51             : 
      52             : public:
      53           4 :   ArenaRefPtr()
      54           4 :   {
      55           4 :     AssertValidType();
      56           4 :   }
      57             : 
      58             :   template<typename I>
      59             :   MOZ_IMPLICIT ArenaRefPtr(already_AddRefed<I>& aRhs)
      60             :   {
      61             :     AssertValidType();
      62             :     assign(aRhs);
      63             :   }
      64             : 
      65             :   template<typename I>
      66             :   MOZ_IMPLICIT ArenaRefPtr(already_AddRefed<I>&& aRhs)
      67             :   {
      68             :     AssertValidType();
      69             :     assign(aRhs);
      70             :   }
      71             : 
      72             :   MOZ_IMPLICIT ArenaRefPtr(T* aRhs)
      73             :   {
      74             :     AssertValidType();
      75             :     assign(aRhs);
      76             :   }
      77             : 
      78             :   template<typename I>
      79             :   ArenaRefPtr<T>& operator=(already_AddRefed<I>& aRhs)
      80             :   {
      81             :     assign(aRhs);
      82             :     return *this;
      83             :   }
      84             : 
      85             :   template<typename I>
      86             :   ArenaRefPtr<T>& operator=(already_AddRefed<I>&& aRhs)
      87             :   {
      88             :     assign(aRhs);
      89             :     return *this;
      90             :   }
      91             : 
      92          12 :   ArenaRefPtr<T>& operator=(T* aRhs)
      93             :   {
      94          12 :     assign(aRhs);
      95          12 :     return *this;
      96             :   }
      97             : 
      98           0 :   ~ArenaRefPtr() { assign(nullptr); }
      99             : 
     100           4 :   operator T*() const & { return get(); }
     101             :   operator T*() const && = delete;
     102           4 :   explicit operator bool() const { return !!mPtr; }
     103          12 :   bool operator!() const { return !mPtr; }
     104           4 :   T* operator->() const { return mPtr.operator->(); }
     105             :   T& operator*() const { return *get(); }
     106             : 
     107           4 :   T* get() const { return mPtr; }
     108             : 
     109             : private:
     110             :   void AssertValidType();
     111             : 
     112             :   /**
     113             :    * Clears the pointer to the arena-allocated object but skips the usual
     114             :    * step of deregistering the ArenaRefPtr from the nsPresArena.  This
     115             :    * method is called by nsPresArena when clearing all registered ArenaRefPtrs
     116             :    * so that it can deregister them all at once, avoiding hash table churn.
     117             :    */
     118           0 :   void ClearWithoutDeregistering()
     119             :   {
     120           0 :     mPtr = nullptr;
     121           0 :   }
     122             : 
     123             :   template<typename I>
     124             :   void assign(already_AddRefed<I>& aSmartPtr)
     125             :   {
     126             :     RefPtr<T> newPtr(aSmartPtr);
     127             :     assignFrom(newPtr);
     128             :   }
     129             : 
     130             :   template<typename I>
     131             :   void assign(already_AddRefed<I>&& aSmartPtr)
     132             :   {
     133             :     RefPtr<T> newPtr(aSmartPtr);
     134             :     assignFrom(newPtr);
     135             :   }
     136             : 
     137          12 :   void assign(T* aPtr) { assignFrom(aPtr); }
     138             : 
     139             :   template<typename I>
     140          12 :   void assignFrom(I& aPtr)
     141             :   {
     142          12 :     if (aPtr == mPtr) {
     143           4 :       return;
     144             :     }
     145           8 :     bool sameArena = mPtr && aPtr && mPtr->Arena() == aPtr->Arena();
     146           8 :     if (mPtr && !sameArena) {
     147           4 :       MOZ_ASSERT(mPtr->Arena());
     148           4 :       mPtr->Arena()->DeregisterArenaRefPtr(this);
     149             :     }
     150           8 :     mPtr = Move(aPtr);
     151           8 :     if (mPtr && !sameArena) {
     152           4 :       MOZ_ASSERT(mPtr->Arena());
     153           4 :       mPtr->Arena()->RegisterArenaRefPtr(this);
     154             :     }
     155             :   }
     156             : 
     157             :   RefPtr<T> mPtr;
     158             : };
     159             : 
     160             : } // namespace mozilla
     161             : 
     162             : #endif // mozilla_ArenaRefPtr_h

Generated by: LCOV version 1.13