LCOV - code coverage report
Current view: top level - xpcom/base - nsCycleCollectionParticipant.h (source / functions) Hit Total Coverage
Test: output.info Lines: 20 45 44.4 %
Date: 2017-07-14 16:53:18 Functions: 165 1482 11.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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             : #ifndef nsCycleCollectionParticipant_h__
       8             : #define nsCycleCollectionParticipant_h__
       9             : 
      10             : #include "mozilla/MacroArgs.h"
      11             : #include "mozilla/MacroForEach.h"
      12             : #include "nsCycleCollectionNoteChild.h"
      13             : #include "js/RootingAPI.h"
      14             : 
      15             : #define NS_XPCOMCYCLECOLLECTIONPARTICIPANT_IID                                 \
      16             : {                                                                              \
      17             :     0x9674489b,                                                                \
      18             :     0x1f6f,                                                                    \
      19             :     0x4550,                                                                    \
      20             :     { 0xa7, 0x30, 0xcc, 0xae, 0xdd, 0x10, 0x4c, 0xf9 }                         \
      21             : }
      22             : 
      23             : /**
      24             :  * Special IID to get at the base nsISupports for a class. Usually this is the
      25             :  * canonical nsISupports pointer, but in the case of tearoffs for example it is
      26             :  * the base nsISupports pointer of the tearoff. This allow the cycle collector
      27             :  * to have separate nsCycleCollectionParticipant's for tearoffs or aggregated
      28             :  * classes.
      29             :  */
      30             : #define NS_CYCLECOLLECTIONISUPPORTS_IID                                        \
      31             : {                                                                              \
      32             :     0xc61eac14,                                                                \
      33             :     0x5f7a,                                                                    \
      34             :     0x4481,                                                                    \
      35             :     { 0x96, 0x5e, 0x7e, 0xaa, 0x6e, 0xff, 0xa8, 0x5f }                         \
      36             : }
      37             : 
      38             : /**
      39             :  * Just holds the IID so NS_GET_IID works.
      40             :  */
      41             : class nsCycleCollectionISupports
      42             : {
      43             : public:
      44             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONISUPPORTS_IID)
      45             : };
      46             : 
      47             : NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports,
      48             :                               NS_CYCLECOLLECTIONISUPPORTS_IID)
      49             : 
      50             : namespace JS {
      51             : template<class T> class Heap;
      52             : } /* namespace JS */
      53             : 
      54             : /*
      55             :  * A struct defining pure virtual methods which are called when tracing cycle
      56             :  * collection paticipants.  The appropriate method is called depending on the
      57             :  * type of JS GC thing.
      58             :  */
      59        8853 : struct TraceCallbacks
      60             : {
      61             :   virtual void Trace(JS::Heap<JS::Value>* aPtr, const char* aName,
      62             :                      void* aClosure) const = 0;
      63             :   virtual void Trace(JS::Heap<jsid>* aPtr, const char* aName,
      64             :                      void* aClosure) const = 0;
      65             :   virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
      66             :                      void* aClosure) const = 0;
      67             :   virtual void Trace(JSObject** aPtr, const char* aName,
      68             :                      void* aClosure) const = 0;
      69             :   virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
      70             :                      void* aClosure) const = 0;
      71             :   virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName,
      72             :                      void* aClosure) const = 0;
      73             :   virtual void Trace(JS::Heap<JSScript*>* aPtr, const char* aName,
      74             :                      void* aClosure) const = 0;
      75             :   virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
      76             :                      void* aClosure) const = 0;
      77             : };
      78             : 
      79             : /*
      80             :  * An implementation of TraceCallbacks that calls a single function for all JS
      81             :  * GC thing types encountered. Implemented in nsCycleCollectorTraceJSHelpers.cpp.
      82             :  */
      83             : struct TraceCallbackFunc : public TraceCallbacks
      84             : {
      85             :   typedef void (*Func)(JS::GCCellPtr aPtr, const char* aName, void* aClosure);
      86             : 
      87        5144 :   explicit TraceCallbackFunc(Func aCb) : mCallback(aCb) {}
      88             : 
      89             :   virtual void Trace(JS::Heap<JS::Value>* aPtr, const char* aName,
      90             :                      void* aClosure) const override;
      91             :   virtual void Trace(JS::Heap<jsid>* aPtr, const char* aName,
      92             :                      void* aClosure) const override;
      93             :   virtual void Trace(JS::Heap<JSObject*>* aPtr, const char* aName,
      94             :                      void* aClosure) const override;
      95             :   virtual void Trace(JSObject** aPtr, const char* aName,
      96             :                      void* aClosure) const override;
      97             :   virtual void Trace(JS::TenuredHeap<JSObject*>* aPtr, const char* aName,
      98             :                      void* aClosure) const override;
      99             :   virtual void Trace(JS::Heap<JSString*>* aPtr, const char* aName,
     100             :                      void* aClosure) const override;
     101             :   virtual void Trace(JS::Heap<JSScript*>* aPtr, const char* aName,
     102             :                      void* aClosure) const override;
     103             :   virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char* aName,
     104             :                      void* aClosure) const override;
     105             : 
     106             : private:
     107             :   Func mCallback;
     108             : };
     109             : 
     110             : /**
     111             :  * Participant implementation classes
     112             :  */
     113           8 : class NS_NO_VTABLE nsCycleCollectionParticipant
     114             : {
     115             : public:
     116           0 :   constexpr explicit nsCycleCollectionParticipant(bool aSkip,
     117             :                                                   bool aTraverseShouldTrace = false)
     118           0 :     : mMightSkip(aSkip)
     119           0 :     , mTraverseShouldTrace(aTraverseShouldTrace)
     120             :   {
     121           0 :   }
     122             : 
     123             :   NS_IMETHOD TraverseNative(void* aPtr, nsCycleCollectionTraversalCallback& aCb) = 0;
     124             : 
     125        2572 :   nsresult TraverseNativeAndJS(void* aPtr,
     126             :                                nsCycleCollectionTraversalCallback& aCb)
     127             :   {
     128        2572 :     nsresult rv = TraverseNative(aPtr, aCb);
     129        2572 :     if (mTraverseShouldTrace) {
     130             :       // Note, we always call Trace, even if Traverse returned
     131             :       // NS_SUCCESS_INTERRUPTED_TRAVERSE.
     132        2572 :       TraceCallbackFunc noteJsChild(&nsCycleCollectionParticipant::NoteJSChild);
     133        2572 :       Trace(aPtr, noteJsChild, &aCb);
     134             :     }
     135        2572 :     return rv;
     136             :   }
     137             : 
     138             :     // Implemented in nsCycleCollectorTraceJSHelpers.cpp.
     139             :   static void NoteJSChild(JS::GCCellPtr aGCThing, const char* aName,
     140             :                           void* aClosure);
     141             : 
     142             :   NS_IMETHOD_(void) Root(void* aPtr) = 0;
     143             :   NS_IMETHOD_(void) Unlink(void* aPtr) = 0;
     144             :   NS_IMETHOD_(void) Unroot(void* aPtr) = 0;
     145             :   NS_IMETHOD_(const char*) ClassName() = 0;
     146             : 
     147         315 :   NS_IMETHOD_(void) Trace(void* aPtr, const TraceCallbacks& aCb,
     148         315 :                           void* aClosure) {}
     149             : 
     150             :   // CanSkip is called during nsCycleCollector_forgetSkippable.  If it returns
     151             :   // true, aPtr is removed from the purple buffer and therefore might be left
     152             :   // out from the cycle collector graph the next time that's constructed (unless
     153             :   // it's reachable in some other way).
     154             :   //
     155             :   // CanSkip is allowed to expand the set of certainly-alive objects by removing
     156             :   // other objects from the purple buffer, marking JS things black (in the GC
     157             :   // sense), and so forth.  Furthermore, if aRemovingAllowed is true, this call
     158             :   // is allowed to remove aPtr itself from the purple buffer.
     159             :   //
     160             :   // Things can return true from CanSkip if either they know they have no
     161             :   // outgoing edges at all in the cycle collection graph (because then they
     162             :   // can't be parts of a cycle) or they know for sure they're alive.
     163           0 :   bool CanSkip(void* aPtr, bool aRemovingAllowed)
     164             :   {
     165           0 :     return mMightSkip ? CanSkipReal(aPtr, aRemovingAllowed) : false;
     166             :   }
     167             : 
     168             :   // CanSkipInCC is called during construction of the initial set of roots for
     169             :   // the cycle collector graph.  If it returns true, aPtr is left out of that
     170             :   // set of roots.  Note that the set of roots includes whatever is in the
     171             :   // purple buffer (after earlier CanSkip calls) plus various other sources of
     172             :   // roots, so an object can end up having CanSkipInCC called on it even if it
     173             :   // returned true from CanSkip.  One example of this would be an object that
     174             :   // can potentially trace JS things.
     175             :   //
     176             :   // CanSkipInCC is allowed to remove other objects from the purple buffer but
     177             :   // should not remove aPtr and should not mark JS things black.  It should also
     178             :   // not modify any reference counts.
     179             :   //
     180             :   // Things can return true from CanSkipInCC if either they know they have no
     181             :   // outgoing edges at all in the cycle collection graph or they know for sure
     182             :   // they're alive _and_ none of their outgoing edges are to gray (in the GC
     183             :   // sense) gcthings.  See also nsWrapperCache::HasNothingToTrace and
     184             :   // nsWrapperCache::IsBlackAndDoesNotNeedTracing.  The restriction on not
     185             :   // having outgoing edges to gray gcthings is because if we _do_ have them that
     186             :   // means we have a "strong" edge to a JS thing and since we're alive we need
     187             :   // to trace through it and mark keep them alive.  Outgoing edges to C++ things
     188             :   // don't matter here, because the criteria for when a CC participant is
     189             :   // considered alive are slightly different for JS and C++ things: JS things
     190             :   // are only considered alive when reachable via an edge from a live thing,
     191             :   // while C++ things are also considered alive when their refcount exceeds the
     192             :   // number of edges via which they are reachable.
     193           0 :   bool CanSkipInCC(void* aPtr)
     194             :   {
     195           0 :     return mMightSkip ? CanSkipInCCReal(aPtr) : false;
     196             :   }
     197             : 
     198             :   // CanSkipThis is called during construction of the cycle collector graph,
     199             :   // when we traverse an edge to aPtr and consider adding it to the graph.  If
     200             :   // it returns true, aPtr is not added to the graph.
     201             :   //
     202             :   // CanSkipThis is not allowed to change the liveness or reference count of any
     203             :   // objects.
     204             :   //
     205             :   // Things can return true from CanSkipThis if either they know they have no
     206             :   // outgoing edges at all in the cycle collection graph or they know for sure
     207             :   // they're alive.
     208             :   //
     209             :   // Note that CanSkipThis doesn't have to worry about outgoing edges to gray GC
     210             :   // things, because if this object could have those it already got added to the
     211             :   // graph during root set construction.  An object should never have
     212             :   // CanSkipThis called on it if it has outgoing strong references to JS things.
     213           0 :   bool CanSkipThis(void* aPtr)
     214             :   {
     215           0 :     return mMightSkip ? CanSkipThisReal(aPtr) : false;
     216             :   }
     217             : 
     218             :   NS_IMETHOD_(void) DeleteCycleCollectable(void* aPtr) = 0;
     219             : 
     220             : protected:
     221           0 :   NS_IMETHOD_(bool) CanSkipReal(void* aPtr, bool aRemovingAllowed)
     222             :   {
     223           0 :     NS_ASSERTION(false, "Forgot to implement CanSkipReal?");
     224           0 :     return false;
     225             :   }
     226           0 :   NS_IMETHOD_(bool) CanSkipInCCReal(void* aPtr)
     227             :   {
     228           0 :     NS_ASSERTION(false, "Forgot to implement CanSkipInCCReal?");
     229           0 :     return false;
     230             :   }
     231           0 :   NS_IMETHOD_(bool) CanSkipThisReal(void* aPtr)
     232             :   {
     233           0 :     NS_ASSERTION(false, "Forgot to implement CanSkipThisReal?");
     234           0 :     return false;
     235             :   }
     236             : 
     237             : private:
     238             :   const bool mMightSkip;
     239             :   const bool mTraverseShouldTrace;
     240             : };
     241             : 
     242             : class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
     243             : {
     244             : public:
     245           0 :   constexpr explicit nsScriptObjectTracer(bool aSkip)
     246           0 :     : nsCycleCollectionParticipant(aSkip, true)
     247             :   {
     248           0 :   }
     249             : 
     250             :   NS_IMETHOD_(void) Trace(void* aPtr, const TraceCallbacks& aCb,
     251             :                           void* aClosure) override = 0;
     252             : 
     253             : };
     254             : 
     255             : class NS_NO_VTABLE nsXPCOMCycleCollectionParticipant : public nsScriptObjectTracer
     256             : {
     257             : public:
     258           0 :   constexpr explicit nsXPCOMCycleCollectionParticipant(bool aSkip)
     259           0 :     : nsScriptObjectTracer(aSkip)
     260             :   {
     261           0 :   }
     262             : 
     263             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XPCOMCYCLECOLLECTIONPARTICIPANT_IID)
     264             : 
     265             :   NS_IMETHOD_(void) Root(void* aPtr) override;
     266             :   NS_IMETHOD_(void) Unroot(void* aPtr) override;
     267             : 
     268             :   NS_IMETHOD_(void) Trace(void* aPtr, const TraceCallbacks& aCb,
     269             :                           void* aClosure) override;
     270             : 
     271             :   static bool CheckForRightISupports(nsISupports* aSupports);
     272             : };
     273             : 
     274             : NS_DEFINE_STATIC_IID_ACCESSOR(nsXPCOMCycleCollectionParticipant,
     275             :                               NS_XPCOMCYCLECOLLECTIONPARTICIPANT_IID)
     276             : 
     277             : ///////////////////////////////////////////////////////////////////////////////
     278             : // Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
     279             : ///////////////////////////////////////////////////////////////////////////////
     280             : 
     281             : #define NS_CYCLE_COLLECTION_CLASSNAME(_class)                                  \
     282             :         _class::NS_CYCLE_COLLECTION_INNERCLASS
     283             : 
     284             : #define NS_IMPL_QUERY_CYCLE_COLLECTION(_class)                                 \
     285             :   if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) {          \
     286             :     *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(_class);                   \
     287             :     return NS_OK;                                                              \
     288             :   } else
     289             : 
     290             : #define NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)                       \
     291             :   if ( aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ) {                 \
     292             :     *aInstancePtr = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this);       \
     293             :     return NS_OK;                                                              \
     294             :   } else
     295             : 
     296             : #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)                        \
     297             :   NS_IMPL_QUERY_CYCLE_COLLECTION(_class)
     298             : 
     299             : #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)              \
     300             :   NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)
     301             : 
     302             : #define NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)                      \
     303             :   NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)                              \
     304             :   NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)
     305             : 
     306             : #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(_class)                        \
     307             :   NS_INTERFACE_MAP_BEGIN(_class)                                               \
     308             :     NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
     309             : 
     310             : #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(_class)              \
     311             :   NS_INTERFACE_MAP_BEGIN(_class)                                               \
     312             :     NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)
     313             : 
     314             : #define NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(_class)  \
     315             :   if (rv == NS_OK) return rv; \
     316             :   nsISupports* foundInterface; \
     317             :   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
     318             : 
     319             : #define NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(_class)            \
     320             :   NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr)    \
     321             :   {                                                                           \
     322             :     NS_PRECONDITION(aInstancePtr, "null out param");                          \
     323             :                                                                               \
     324             :     if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) {       \
     325             :       *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(_class);                \
     326             :       return NS_OK;                                                           \
     327             :     }                                                                         \
     328             :     nsresult rv;
     329             : 
     330             : #define NS_CYCLE_COLLECTION_UPCAST(obj, clazz)                                \
     331             :   NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
     332             : 
     333             : #ifdef DEBUG
     334             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr) _ptr->CheckForRightParticipant()
     335             : #else
     336             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT(_ptr)
     337             : #endif
     338             : 
     339             : // The default implementation of this class template is empty, because it
     340             : // should never be used: see the partial specializations below.
     341             : template<typename T,
     342             :          bool IsXPCOM = mozilla::IsBaseOf<nsISupports, T>::value>
     343             : struct DowncastCCParticipantImpl
     344             : {
     345             : };
     346             : 
     347             : // Specialization for XPCOM CC participants
     348             : template<typename T>
     349             : struct DowncastCCParticipantImpl<T, true>
     350             : {
     351       13099 :   static T* Run(void* aPtr)
     352             :   {
     353       13099 :     nsISupports* s = static_cast<nsISupports*>(aPtr);
     354       13099 :     MOZ_ASSERT(NS_CYCLE_COLLECTION_CLASSNAME(T)::CheckForRightISupports(s),
     355             :                "not the nsISupports pointer we expect");
     356       13099 :     T* rval =  NS_CYCLE_COLLECTION_CLASSNAME(T)::Downcast(s);
     357       13099 :     NS_CHECK_FOR_RIGHT_PARTICIPANT(rval);
     358       13099 :     return rval;
     359             :   }
     360             : };
     361             : 
     362             : // Specialization for native CC participants
     363             : template<typename T>
     364             : struct DowncastCCParticipantImpl<T, false>
     365             : {
     366        1140 :   static T* Run(void* aPtr) { return static_cast<T*>(aPtr); }
     367             : };
     368             : 
     369             : template<typename T>
     370             : T*
     371       14239 : DowncastCCParticipant(void* aPtr)
     372             : {
     373       14239 :   return DowncastCCParticipantImpl<T>::Run(aPtr);
     374             : }
     375             : 
     376             : ///////////////////////////////////////////////////////////////////////////////
     377             : // Helpers for implementing CanSkip methods
     378             : ///////////////////////////////////////////////////////////////////////////////
     379             : 
     380             : // See documentation for nsCycleCollectionParticipant::CanSkip for documentation
     381             : // about this method.
     382             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(_class)                        \
     383             :   NS_IMETHODIMP_(bool)                                                         \
     384             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipReal(void *p,                  \
     385             :                                                      bool aRemovingAllowed)    \
     386             :   {                                                                            \
     387             :     _class *tmp = DowncastCCParticipant<_class >(p);
     388             : 
     389             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END                                  \
     390             :     (void)tmp;                                                                 \
     391             :     return false;                                                              \
     392             :   }
     393             : 
     394             : // See documentation for nsCycleCollectionParticipant::CanSkipInCC for
     395             : // documentation about this method.
     396             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(_class)                  \
     397             :   NS_IMETHODIMP_(bool)                                                         \
     398             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipInCCReal(void *p)              \
     399             :   {                                                                            \
     400             :     _class *tmp = DowncastCCParticipant<_class >(p);
     401             : 
     402             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END                            \
     403             :     (void)tmp;                                                                 \
     404             :     return false;                                                              \
     405             :   }
     406             : 
     407             : // See documentation for nsCycleCollectionParticipant::CanSkipThis for
     408             : // documentation about this method.
     409             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(_class)                   \
     410             :   NS_IMETHODIMP_(bool)                                                         \
     411             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipThisReal(void *p)              \
     412             :   {                                                                            \
     413             :     _class *tmp = DowncastCCParticipant<_class >(p);
     414             : 
     415             : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END                             \
     416             :     (void)tmp;                                                                 \
     417             :     return false;                                                              \
     418             :   }
     419             : 
     420             : ///////////////////////////////////////////////////////////////////////////////
     421             : // Helpers for implementing nsCycleCollectionParticipant::Unlink
     422             : //
     423             : // You need to use NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED if you want
     424             : // the base class Unlink version to be called before your own implementation.
     425             : // You can use NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED if you want the
     426             : // base class Unlink to get called after your own implementation.  You should
     427             : // never use them together.
     428             : ///////////////////////////////////////////////////////////////////////////////
     429             : 
     430             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                          \
     431             :   NS_IMETHODIMP_(void)                                                         \
     432             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p)                       \
     433             :   {                                                                            \
     434             :     _class *tmp = DowncastCCParticipant<_class >(p);
     435             : 
     436             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class)   \
     437             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                \
     438             :     nsISupports *s = static_cast<nsISupports*>(p);                             \
     439             :     NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s);
     440             : 
     441             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_HELPER(_field)                        \
     442             :   ImplCycleCollectionUnlink(tmp->_field);
     443             : 
     444             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK(...)                                   \
     445             :   MOZ_FOR_EACH(NS_IMPL_CYCLE_COLLECTION_UNLINK_HELPER, (), (__VA_ARGS__))
     446             : 
     447             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                    \
     448             :     (void)tmp;                                                                 \
     449             :   }
     450             : 
     451             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(_base_class)             \
     452             :     nsISupports *s = static_cast<nsISupports*>(p);                             \
     453             :     NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s);                     \
     454             :     (void)tmp;                                                                 \
     455             :   }
     456             : 
     457             : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class)                              \
     458             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                \
     459             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     460             : 
     461             : 
     462             : ///////////////////////////////////////////////////////////////////////////////
     463             : // Helpers for implementing nsCycleCollectionParticipant::Traverse
     464             : ///////////////////////////////////////////////////////////////////////////////
     465             : 
     466             : #define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, _refcnt)                     \
     467             :     cb.DescribeRefCountedNode(_refcnt, #_class);
     468             : 
     469             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class)               \
     470             :   NS_IMETHODIMP                                                                \
     471             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::TraverseNative                        \
     472             :                          (void *p, nsCycleCollectionTraversalCallback &cb)     \
     473             :   {                                                                            \
     474             :     _class *tmp = DowncastCCParticipant<_class >(p);
     475             : 
     476             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                        \
     477             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class)                     \
     478             :   NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, tmp->mRefCnt.get())
     479             : 
     480             : // Base class' CC participant should return NS_SUCCESS_INTERRUPTED_TRAVERSE
     481             : // from Traverse if it wants derived classes to not traverse anything from
     482             : // their CC participant.
     483             : 
     484             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \
     485             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class)                     \
     486             :     nsISupports *s = static_cast<nsISupports*>(p);                             \
     487             :     if (NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::TraverseNative(s, cb)      \
     488             :         == NS_SUCCESS_INTERRUPTED_TRAVERSE) {                                  \
     489             :       return NS_SUCCESS_INTERRUPTED_TRAVERSE;                                  \
     490             :     }
     491             : 
     492             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_HELPER(_field)                       \
     493             :   ImplCycleCollectionTraverse(cb, tmp->_field, #_field, 0);
     494             : 
     495             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE(...)                                 \
     496             :   MOZ_FOR_EACH(NS_IMPL_CYCLE_COLLECTION_TRAVERSE_HELPER, (), (__VA_ARGS__))
     497             : 
     498             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field)                       \
     499             :   CycleCollectionNoteChild(cb, tmp->_field, #_field);
     500             : 
     501             : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                                  \
     502             :     (void)tmp;                                                                 \
     503             :     return NS_OK;                                                              \
     504             :   }
     505             : 
     506             : ///////////////////////////////////////////////////////////////////////////////
     507             : // Helpers for implementing nsScriptObjectTracer::Trace
     508             : ///////////////////////////////////////////////////////////////////////////////
     509             : 
     510             : #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)                                 \
     511             :   void                                                                               \
     512             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p,                              \
     513             :                                                const TraceCallbacks &aCallbacks,     \
     514             :                                                void *aClosure)                       \
     515             :   {                                                                                  \
     516             :     _class *tmp = DowncastCCParticipant<_class >(p);
     517             : 
     518             : #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(_class, _base_class)    \
     519             :   NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class)                                 \
     520             :     nsISupports *s = static_cast<nsISupports*>(p);                             \
     521             :     NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Trace(s, aCallbacks, aClosure);
     522             : 
     523             : #define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field)              \
     524             :   aCallbacks.Trace(&tmp->_field, #_field, aClosure);
     525             : 
     526             : // NB: The (void)tmp; hack in the TRACE_END macro exists to support
     527             : // implementations that don't need to do anything in their Trace method.
     528             : // Without this hack, some compilers warn about the unused tmp local.
     529             : #define NS_IMPL_CYCLE_COLLECTION_TRACE_END                                     \
     530             :       (void)tmp;                                                               \
     531             :   }
     532             : 
     533             : ///////////////////////////////////////////////////////////////////////////////
     534             : // Helpers for implementing a concrete nsCycleCollectionParticipant
     535             : ///////////////////////////////////////////////////////////////////////////////
     536             : 
     537             : // If a class defines a participant, then QIing an instance of that class to
     538             : // nsXPCOMCycleCollectionParticipant should produce that participant.
     539             : #ifdef DEBUG
     540             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_BASE                                    \
     541             :     virtual void CheckForRightParticipant()
     542             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_DERIVED                                 \
     543             :     virtual void CheckForRightParticipant() override
     544             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_BODY(_class)                            \
     545             :     {                                                                          \
     546             :       nsXPCOMCycleCollectionParticipant *p;                                    \
     547             :       CallQueryInterface(this, &p);                                            \
     548             :       MOZ_ASSERT(p == &NS_CYCLE_COLLECTION_INNERNAME,                          \
     549             :                  #_class " should QI to its own CC participant");              \
     550             :     }
     551             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)                            \
     552             :     NS_CHECK_FOR_RIGHT_PARTICIPANT_BASE                                        \
     553             :     NS_CHECK_FOR_RIGHT_PARTICIPANT_BODY(_class)
     554             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)                  \
     555             :     NS_CHECK_FOR_RIGHT_PARTICIPANT_DERIVED                                     \
     556             :     NS_CHECK_FOR_RIGHT_PARTICIPANT_BODY(_class)
     557             : #else
     558             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)
     559             : #define NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)
     560             : #endif
     561             : 
     562             : #define NS_DECL_CYCLE_COLLECTION_CLASS_NAME_METHOD(_class) \
     563             :   NS_IMETHOD_(const char*) ClassName() override { return #_class; };
     564             : 
     565             : 
     566             : #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)           \
     567             : public:                                                                        \
     568             :   NS_IMETHOD TraverseNative(void *p, nsCycleCollectionTraversalCallback &cb)   \
     569             :     override;                                                                  \
     570             :   NS_DECL_CYCLE_COLLECTION_CLASS_NAME_METHOD(_class)                           \
     571             :   NS_IMETHOD_(void) DeleteCycleCollectable(void *p) override                   \
     572             :   {                                                                            \
     573             :     DowncastCCParticipant<_class>(p)->DeleteCycleCollectable();                \
     574             :   }                                                                            \
     575             :   static _class* Downcast(nsISupports* s)                                      \
     576             :   {                                                                            \
     577             :     return static_cast<_class*>(static_cast<_base*>(s));                       \
     578             :   }                                                                            \
     579             :   static nsISupports* Upcast(_class *p)                                        \
     580             :   {                                                                            \
     581             :     return NS_ISUPPORTS_CAST(_base*, p);                                       \
     582             :   }                                                                            \
     583             :   template<typename T>                                                         \
     584             :   friend nsISupports*                                                          \
     585             :   ToSupports(T* p, NS_CYCLE_COLLECTION_INNERCLASS* dummy);
     586             : 
     587             : #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                     \
     588             :   NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base)                 \
     589             :   NS_IMETHOD_(void) Unlink(void *p) override;
     590             : 
     591             : #define NS_PARTICIPANT_AS(type, participant)                                   \
     592             :   const_cast<type*>(reinterpret_cast<const type*>(participant))
     593             : 
     594             : #define NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                 \
     595             :   static constexpr nsXPCOMCycleCollectionParticipant* GetParticipant()         \
     596             :   {                                                                            \
     597             :     return &_class::NS_CYCLE_COLLECTION_INNERNAME;                             \
     598             :   }
     599             : 
     600             : /**
     601             :  * We use this macro to force that classes that inherit from a ccable class and
     602             :  * declare their own participant declare themselves as inherited cc classes.
     603             :  * To avoid possibly unnecessary vtables we only do this checking in debug
     604             :  * builds.
     605             :  */
     606             : #ifdef DEBUG
     607             : #define NOT_INHERITED_CANT_OVERRIDE virtual void BaseCycleCollectable() final {}
     608             : #else
     609             : #define NOT_INHERITED_CANT_OVERRIDE
     610             : #endif
     611             : 
     612             : #define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base)                \
     613             : class NS_CYCLE_COLLECTION_INNERCLASS                                           \
     614             :  : public nsXPCOMCycleCollectionParticipant                                    \
     615             : {                                                                              \
     616             : public:                                                                        \
     617             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)       \
     618             :     : nsXPCOMCycleCollectionParticipant(aSkip) {}                              \
     619             : private:                                                                       \
     620             :   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                           \
     621             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
     622             : };                                                                             \
     623             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)                                    \
     624             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;           \
     625             :   NOT_INHERITED_CANT_OVERRIDE
     626             : 
     627             : #define NS_DECL_CYCLE_COLLECTION_CLASS(_class)                                 \
     628             :   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _class)
     629             : 
     630             : // Cycle collector helper for ambiguous classes that can sometimes be skipped.
     631             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _base)        \
     632             : class NS_CYCLE_COLLECTION_INNERCLASS                                             \
     633             :  : public nsXPCOMCycleCollectionParticipant                                      \
     634             : {                                                                                \
     635             : public:                                                                          \
     636             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = true)          \
     637             :     /* Ignore aSkip: we always want skippability. */                             \
     638             :   : nsXPCOMCycleCollectionParticipant(true) {}                                   \
     639             : private:                                                                         \
     640             :   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                             \
     641             :   NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed) override;        \
     642             :   NS_IMETHOD_(bool) CanSkipInCCReal(void *p) override;                           \
     643             :   NS_IMETHOD_(bool) CanSkipThisReal(void *p) override;                           \
     644             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                         \
     645             : };                                                                               \
     646             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)                                      \
     647             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;             \
     648             : NOT_INHERITED_CANT_OVERRIDE
     649             : 
     650             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(_class)                       \
     651             :         NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _class)
     652             : 
     653             : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base)          \
     654             : class NS_CYCLE_COLLECTION_INNERCLASS                                                   \
     655             :  : public nsXPCOMCycleCollectionParticipant                                            \
     656             : {                                                                                      \
     657             : public:                                                                                \
     658             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)               \
     659             :   : nsXPCOMCycleCollectionParticipant(aSkip) {}                                        \
     660             : private:                                                                               \
     661             :   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                                   \
     662             :   NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure) override;  \
     663             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                               \
     664             : };                                                                                     \
     665             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)                                            \
     666             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
     667             : NOT_INHERITED_CANT_OVERRIDE
     668             : 
     669             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base)   \
     670             : class NS_CYCLE_COLLECTION_INNERCLASS                                                      \
     671             :  : public nsXPCOMCycleCollectionParticipant                                               \
     672             : {                                                                                         \
     673             : public:                                                                                   \
     674             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = true)                   \
     675             :     /* Ignore aSkip: we always want skippability. */                                      \
     676             :   : nsXPCOMCycleCollectionParticipant(true) {}                                            \
     677             : private:                                                                                  \
     678             :   NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base)                                      \
     679             :   NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure) override;     \
     680             :   NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed) override;                 \
     681             :   NS_IMETHOD_(bool) CanSkipInCCReal(void *p) override;                                    \
     682             :   NS_IMETHOD_(bool) CanSkipThisReal(void *p) override;                                    \
     683             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                                  \
     684             : };                                                                                        \
     685             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL(_class)                                               \
     686             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME; \
     687             : NOT_INHERITED_CANT_OVERRIDE
     688             : 
     689             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(_class)  \
     690             :   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
     691             : 
     692             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(_class,       \
     693             :                                                                          _base_class)  \
     694             : class NS_CYCLE_COLLECTION_INNERCLASS                                                   \
     695             :  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                                   \
     696             : {                                                                                      \
     697             : public:                                                                                \
     698             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = true)                \
     699             :     /* Ignore aSkip: we always want skippability. */                                   \
     700             :     : NS_CYCLE_COLLECTION_CLASSNAME(_base_class) (true) {}                             \
     701             : private:                                                                               \
     702             :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)                   \
     703             :   NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure) override;  \
     704             :   NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed) override;              \
     705             :   NS_IMETHOD_(bool) CanSkipInCCReal(void *p) override;                                 \
     706             :   NS_IMETHOD_(bool) CanSkipThisReal(void *p) override;                                 \
     707             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                               \
     708             : }; \
     709             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)  \
     710             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     711             : 
     712             : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class)  \
     713             :   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
     714             : 
     715             : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class,        \
     716             :                                                                 _base_class)   \
     717             : public:                                                                        \
     718             :   NS_IMETHOD TraverseNative(void *p, nsCycleCollectionTraversalCallback &cb)   \
     719             :     override;                                                                  \
     720             :   NS_DECL_CYCLE_COLLECTION_CLASS_NAME_METHOD(_class)                           \
     721             :   static _class* Downcast(nsISupports* s)                                      \
     722             :   {                                                                            \
     723             :     return static_cast<_class*>(static_cast<_base_class*>(                     \
     724             :       NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s)));               \
     725             :   }
     726             : 
     727             : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)     \
     728             :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
     729             :   NS_IMETHOD_(void) Unlink(void *p) override;
     730             : 
     731             : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class)          \
     732             : class NS_CYCLE_COLLECTION_INNERCLASS                                           \
     733             :  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
     734             : {                                                                              \
     735             : public:                                                                        \
     736             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)       \
     737             :     : NS_CYCLE_COLLECTION_CLASSNAME(_base_class) (aSkip) {}                    \
     738             : private:                                                                       \
     739             :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)           \
     740             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
     741             : };                                                                             \
     742             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)                          \
     743             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     744             : 
     745             : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class,             \
     746             :                                                            _base_class)        \
     747             : class NS_CYCLE_COLLECTION_INNERCLASS                                           \
     748             :  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                           \
     749             : {                                                                              \
     750             : public:                                                                        \
     751             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)       \
     752             :     : NS_CYCLE_COLLECTION_CLASSNAME(_base_class) (aSkip) {}                    \
     753             : private:                                                                       \
     754             :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
     755             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                       \
     756             : };                                                                             \
     757             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)                          \
     758             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     759             : 
     760             : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(_class,                 \
     761             :                                                                _base_class)            \
     762             : class NS_CYCLE_COLLECTION_INNERCLASS                                                   \
     763             :  : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class)                                   \
     764             : {                                                                                      \
     765             : public:                                                                                \
     766             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)               \
     767             :     : NS_CYCLE_COLLECTION_CLASSNAME(_base_class) (aSkip) {}                            \
     768             : private:                                                                               \
     769             :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class)                   \
     770             :   NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure)            \
     771             :     override;                                                                          \
     772             :   NS_IMPL_GET_XPCOM_CYCLE_COLLECTION_PARTICIPANT(_class)                               \
     773             : };                                                                                     \
     774             : NS_CHECK_FOR_RIGHT_PARTICIPANT_IMPL_INHERITED(_class)                                  \
     775             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     776             : 
     777             : // Cycle collector participant declarations.
     778             : 
     779             : #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                     \
     780             :   public:                                                                      \
     781             :     NS_IMETHOD_(void) Root(void *n) override;                                  \
     782             :     NS_IMETHOD_(void) Unlink(void *n) override;                                \
     783             :     NS_IMETHOD_(void) Unroot(void *n) override;                                \
     784             :     NS_IMETHOD TraverseNative(void *n, nsCycleCollectionTraversalCallback &cb) \
     785             :       override;                                                                \
     786             :     NS_DECL_CYCLE_COLLECTION_CLASS_NAME_METHOD(_class)                         \
     787             :     NS_IMETHOD_(void) DeleteCycleCollectable(void *n) override                 \
     788             :     {                                                                          \
     789             :       DowncastCCParticipant<_class>(n)->DeleteCycleCollectable();              \
     790             :     }                                                                          \
     791             :     static _class* Downcast(void* s)                                           \
     792             :     {                                                                          \
     793             :       return DowncastCCParticipant<_class>(s);                                 \
     794             :     }                                                                          \
     795             :     static void* Upcast(_class *p)                                             \
     796             :     {                                                                          \
     797             :       return static_cast<void*>(p);                                            \
     798             :     }
     799             : 
     800             : #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class)                          \
     801             :   void DeleteCycleCollectable(void)                                            \
     802             :   {                                                                            \
     803             :     delete this;                                                               \
     804             :   }                                                                            \
     805             :   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
     806             :    : public nsCycleCollectionParticipant                                       \
     807             :   {                                                                            \
     808             : public:                                                                        \
     809             :   constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)       \
     810             :     : nsCycleCollectionParticipant(aSkip) {}                                   \
     811             : private:                                                                       \
     812             :     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                         \
     813             :     static constexpr nsCycleCollectionParticipant* GetParticipant()            \
     814             :     {                                                                          \
     815             :       return &_class::NS_CYCLE_COLLECTION_INNERNAME;                           \
     816             :     }                                                                          \
     817             :   };                                                                           \
     818             :   static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     819             : 
     820             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS(_class)                \
     821             :   void DeleteCycleCollectable(void)                                            \
     822             :   {                                                                            \
     823             :     delete this;                                                               \
     824             :   }                                                                            \
     825             :   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
     826             :    : public nsCycleCollectionParticipant                                       \
     827             :   {                                                                            \
     828             :   public:                                                                      \
     829             :     constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = true)      \
     830             :       /* Ignore aSkip: we always want skippability. */                         \
     831             :     : nsCycleCollectionParticipant(true) {}                                    \
     832             :   private:                                                                     \
     833             :     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                         \
     834             :     NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed) override;    \
     835             :     NS_IMETHOD_(bool) CanSkipInCCReal(void *p) override;                       \
     836             :     NS_IMETHOD_(bool) CanSkipThisReal(void *p) override;                       \
     837             :     static nsCycleCollectionParticipant* GetParticipant()                      \
     838             :     {                                                                          \
     839             :       return &_class::NS_CYCLE_COLLECTION_INNERNAME;                           \
     840             :     }                                                                          \
     841             :   };                                                                           \
     842             :   static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     843             : 
     844             : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS_WITH_CUSTOM_DELETE(_class) \
     845             : class NS_CYCLE_COLLECTION_INNERCLASS                                           \
     846             :  : public nsCycleCollectionParticipant                                         \
     847             : {                                                                              \
     848             : public:                                                                        \
     849             :   constexpr NS_CYCLE_COLLECTION_INNERCLASS ()                                  \
     850             :   : nsCycleCollectionParticipant(true) {}                                      \
     851             : private:                                                                       \
     852             :   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                           \
     853             :   NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed) override;      \
     854             :   NS_IMETHOD_(bool) CanSkipInCCReal(void *p) override;                         \
     855             :   NS_IMETHOD_(bool) CanSkipThisReal(void *p) override;                         \
     856             :   static nsCycleCollectionParticipant* GetParticipant()                        \
     857             :   {                                                                            \
     858             :     return &_class::NS_CYCLE_COLLECTION_INNERNAME;                             \
     859             :   }                                                                            \
     860             : };                                                                             \
     861             : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     862             : 
     863             : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class)            \
     864             :   void DeleteCycleCollectable(void)                                            \
     865             :   {                                                                            \
     866             :     delete this;                                                               \
     867             :   }                                                                            \
     868             :   class NS_CYCLE_COLLECTION_INNERCLASS                                         \
     869             :    : public nsScriptObjectTracer                                               \
     870             :   {                                                                            \
     871             :   public:                                                                      \
     872             :     constexpr explicit NS_CYCLE_COLLECTION_INNERCLASS (bool aSkip = false)     \
     873             :       : nsScriptObjectTracer(aSkip) {}                                         \
     874             :   private:                                                                     \
     875             :     NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY(_class)                         \
     876             :     NS_IMETHOD_(void) Trace(void *p, const TraceCallbacks &cb, void *closure)  \
     877             :       override;                                                                \
     878             :     static constexpr nsScriptObjectTracer* GetParticipant()                    \
     879             :     {                                                                          \
     880             :       return &_class::NS_CYCLE_COLLECTION_INNERNAME;                           \
     881             :     }                                                                          \
     882             :   };                                                                           \
     883             :   static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
     884             : 
     885             : #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function)           \
     886             :   NS_IMETHODIMP_(void)                                                         \
     887             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p)                         \
     888             :   {                                                                            \
     889             :     _class *tmp = static_cast<_class*>(p);                                     \
     890             :     tmp->_root_function();                                                     \
     891             :   }
     892             : 
     893             : #define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function)       \
     894             :   NS_IMETHODIMP_(void)                                                         \
     895             :   NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p)                       \
     896             :   {                                                                            \
     897             :     _class *tmp = static_cast<_class*>(p);                                     \
     898             :     tmp->_unroot_function();                                                   \
     899             :   }
     900             : 
     901             : #define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
     902             :  _class::NS_CYCLE_COLLECTION_INNERCLASS _class::NS_CYCLE_COLLECTION_INNERNAME;
     903             : 
     904             : // NB: This is not something you usually want to use.  It is here to allow
     905             : // adding things to the CC graph to help debugging via CC logs, but it does not
     906             : // traverse or unlink anything, so it is useless for anything else.
     907             : #define NS_IMPL_CYCLE_COLLECTION_0(_class)                                     \
     908             :   NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                       \
     909             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                \
     910             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                          \
     911             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                              \
     912             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     913             : 
     914             : #define NS_IMPL_CYCLE_COLLECTION(_class, ...)                                  \
     915             :   NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                       \
     916             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class)                                \
     917             :   NS_IMPL_CYCLE_COLLECTION_UNLINK(__VA_ARGS__)                                 \
     918             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                          \
     919             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class)                              \
     920             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__)                               \
     921             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     922             : 
     923             : // If you are looking for NS_IMPL_CYCLE_COLLECTION_INHERITED_0(_class, _base)
     924             : // you should instead not declare any cycle collected stuff in _class, so it
     925             : // will just inherit the CC declarations from _base.
     926             : 
     927             : #define NS_IMPL_CYCLE_COLLECTION_INHERITED(_class, _base, ...)                 \
     928             :   NS_IMPL_CYCLE_COLLECTION_CLASS(_class)                                       \
     929             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base)               \
     930             :   NS_IMPL_CYCLE_COLLECTION_UNLINK(__VA_ARGS__)                                 \
     931             :   NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                          \
     932             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base)             \
     933             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(__VA_ARGS__)                               \
     934             :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     935             : 
     936             : #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME CycleCollectionNoteEdgeName
     937             : 
     938             : #endif // nsCycleCollectionParticipant_h__

Generated by: LCOV version 1.13