|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 // This header will be included by headers that define refpointer and array classes |
|
7 // in order to specialize CC helpers such as ImplCycleCollectionTraverse for them. |
|
8 |
|
9 #ifndef nsCycleCollectionNoteChild_h__ |
|
10 #define nsCycleCollectionNoteChild_h__ |
|
11 |
|
12 #include "nsCycleCollectionTraversalCallback.h" |
|
13 #include "mozilla/Likely.h" |
|
14 #include "mozilla/TypeTraits.h" |
|
15 |
|
16 enum { |
|
17 CycleCollectionEdgeNameArrayFlag = 1 |
|
18 }; |
|
19 |
|
20 // Just a helper for appending "[i]". Didn't want to pull in string headers here. |
|
21 void |
|
22 CycleCollectionNoteEdgeNameImpl(nsCycleCollectionTraversalCallback& aCallback, |
|
23 const char* aName, |
|
24 uint32_t aFlags = 0); |
|
25 |
|
26 // Should be inlined so that in the no-debug-info case this is just a simple if(). |
|
27 MOZ_ALWAYS_INLINE void |
|
28 CycleCollectionNoteEdgeName(nsCycleCollectionTraversalCallback& aCallback, |
|
29 const char* aName, |
|
30 uint32_t aFlags = 0) |
|
31 { |
|
32 if (MOZ_UNLIKELY(aCallback.WantDebugInfo())) { |
|
33 CycleCollectionNoteEdgeNameImpl(aCallback, aName, aFlags); |
|
34 } |
|
35 } |
|
36 |
|
37 #define NS_CYCLE_COLLECTION_INNERCLASS \ |
|
38 cycleCollection |
|
39 |
|
40 #define NS_CYCLE_COLLECTION_INNERNAME \ |
|
41 _cycleCollectorGlobal |
|
42 |
|
43 #define NS_CYCLE_COLLECTION_PARTICIPANT(_class) \ |
|
44 _class::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant() |
|
45 |
|
46 template <typename T> |
|
47 nsISupports* ToSupports(T* p, typename T::NS_CYCLE_COLLECTION_INNERCLASS* dummy = 0) |
|
48 { |
|
49 return T::NS_CYCLE_COLLECTION_INNERCLASS::Upcast(p); |
|
50 } |
|
51 |
|
52 // The default implementation of this class template is empty, because it |
|
53 // should never be used: see the partial specializations below. |
|
54 template <typename T, |
|
55 bool IsXPCOM = mozilla::IsBaseOf<nsISupports, T>::value> |
|
56 struct CycleCollectionNoteChildImpl |
|
57 { |
|
58 }; |
|
59 |
|
60 template <typename T> |
|
61 struct CycleCollectionNoteChildImpl<T, true> |
|
62 { |
|
63 static void Run(nsCycleCollectionTraversalCallback& aCallback, T* aChild) |
|
64 { |
|
65 aCallback.NoteXPCOMChild(ToSupports(aChild)); |
|
66 } |
|
67 }; |
|
68 |
|
69 template <typename T> |
|
70 struct CycleCollectionNoteChildImpl<T, false> |
|
71 { |
|
72 static void Run(nsCycleCollectionTraversalCallback& aCallback, T* aChild) |
|
73 { |
|
74 aCallback.NoteNativeChild(aChild, NS_CYCLE_COLLECTION_PARTICIPANT(T)); |
|
75 } |
|
76 }; |
|
77 |
|
78 template <typename T> |
|
79 inline void CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback, |
|
80 T* aChild, |
|
81 const char* aName, |
|
82 uint32_t aFlags = 0) |
|
83 { |
|
84 CycleCollectionNoteEdgeName(aCallback, aName, aFlags); |
|
85 CycleCollectionNoteChildImpl<T>::Run(aCallback, aChild); |
|
86 } |
|
87 |
|
88 #endif // nsCycleCollectionNoteChild_h__ |