1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * The Mozilla Foundation.
19 : * Portions created by the Initial Developer are Copyright (C) 2006
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #ifndef nsCycleCollectionParticipant_h__
39 : #define nsCycleCollectionParticipant_h__
40 :
41 : #include "nsISupports.h"
42 :
43 : // NOTE: If you use header files to define DEBUG_CC, you must do so here
44 : // *and* in nsCycleCollector.h
45 : //#define DEBUG_CC
46 :
47 : #define NS_CYCLECOLLECTIONPARTICIPANT_IID \
48 : { \
49 : 0x9674489b, \
50 : 0x1f6f, \
51 : 0x4550, \
52 : { 0xa7, 0x30, 0xcc, 0xae, 0xdd, 0x10, 0x4c, 0xf9 } \
53 : }
54 :
55 : /**
56 : * Special IID to get at the base nsISupports for a class. Usually this is the
57 : * canonical nsISupports pointer, but in the case of tearoffs for example it is
58 : * the base nsISupports pointer of the tearoff. This allow the cycle collector
59 : * to have separate nsCycleCollectionParticipant's for tearoffs or aggregated
60 : * classes.
61 : */
62 : #define NS_CYCLECOLLECTIONISUPPORTS_IID \
63 : { \
64 : 0xc61eac14, \
65 : 0x5f7a, \
66 : 0x4481, \
67 : { 0x96, 0x5e, 0x7e, 0xaa, 0x6e, 0xff, 0xa8, 0x5f } \
68 : }
69 :
70 : /**
71 : * Just holds the IID so NS_GET_IID works.
72 : */
73 : class nsCycleCollectionISupports
74 : {
75 : public:
76 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONISUPPORTS_IID)
77 : };
78 :
79 : NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports,
80 : NS_CYCLECOLLECTIONISUPPORTS_IID)
81 :
82 : class nsCycleCollectionParticipant;
83 :
84 : class NS_NO_VTABLE nsCycleCollectionTraversalCallback
85 : {
86 : public:
87 : // You must call DescribeRefCountedNode() with an accurate
88 : // refcount, otherwise cycle collection will fail, and probably crash.
89 : // If the callback cares about objsz or objname, it should
90 : // put WANT_DEBUG_INFO in mFlags.
91 : NS_IMETHOD_(void) DescribeRefCountedNode(nsrefcnt refcount,
92 : size_t objsz,
93 : const char *objname) = 0;
94 : NS_IMETHOD_(void) DescribeGCedNode(bool ismarked,
95 : size_t objsz,
96 : const char *objname) = 0;
97 : NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root) = 0;
98 : NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void *root,
99 : nsCycleCollectionParticipant* helper) = 0;
100 : NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void *child) = 0;
101 : NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) = 0;
102 : NS_IMETHOD_(void) NoteNativeChild(void *child,
103 : nsCycleCollectionParticipant *helper) = 0;
104 :
105 : // Give a name to the edge associated with the next call to
106 : // NoteScriptChild, NoteXPCOMChild, or NoteNativeChild.
107 : // Callbacks who care about this should set WANT_DEBUG_INFO in the
108 : // flags.
109 : NS_IMETHOD_(void) NoteNextEdgeName(const char* name) = 0;
110 :
111 : NS_IMETHOD_(void) NoteWeakMapping(void *map, void *key, void *val) = 0;
112 :
113 : enum {
114 : // Values for flags:
115 :
116 : // Caller should pass useful objsz and objname to
117 : // DescribeRefCountedNode and DescribeGCedNode and should call
118 : // NoteNextEdgeName.
119 : WANT_DEBUG_INFO = (1<<0),
120 :
121 : // Caller should not skip objects that we know will be
122 : // uncollectable.
123 : WANT_ALL_TRACES = (1<<1)
124 : };
125 : PRUint32 Flags() const { return mFlags; }
126 4188235 : bool WantDebugInfo() const { return (mFlags & WANT_DEBUG_INFO) != 0; }
127 2205138 : bool WantAllTraces() const { return (mFlags & WANT_ALL_TRACES) != 0; }
128 : protected:
129 27561 : nsCycleCollectionTraversalCallback() : mFlags(0) {}
130 :
131 : PRUint32 mFlags;
132 : };
133 :
134 : class NS_NO_VTABLE nsCycleCollectionParticipant
135 : {
136 : public:
137 20436 : nsCycleCollectionParticipant() : mMightSkip(false) {}
138 398208 : nsCycleCollectionParticipant(bool aSkip) : mMightSkip(aSkip) {}
139 :
140 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
141 :
142 : NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
143 :
144 : NS_IMETHOD Root(void *p) = 0;
145 : NS_IMETHOD Unlink(void *p) = 0;
146 : NS_IMETHOD Unroot(void *p) = 0;
147 :
148 : // If CanSkip returns true, p is removed from the purple buffer during
149 : // a call to nsCycleCollector_forgetSkippable().
150 : // Note, calling CanSkip may remove objects from the purple buffer!
151 : // If aRemovingAllowed is true, p can be removed from the purple buffer.
152 388578 : bool CanSkip(void *p, bool aRemovingAllowed)
153 : {
154 388578 : return mMightSkip ? CanSkipReal(p, aRemovingAllowed) : false;
155 : }
156 :
157 : // If CanSkipInCC returns true, p is skipped when selecting roots for the
158 : // cycle collector graph.
159 : // Note, calling CanSkipInCC may remove other objects from the purple buffer!
160 115052 : bool CanSkipInCC(void *p)
161 : {
162 115052 : return mMightSkip ? CanSkipInCCReal(p) : false;
163 : }
164 :
165 : // If CanSkipThis returns true, p is not added to the graph.
166 : // This method is called during cycle collection, so don't
167 : // change the state of any objects!
168 373691 : bool CanSkipThis(void *p)
169 : {
170 373691 : return mMightSkip ? CanSkipThisReal(p) : false;
171 : }
172 : protected:
173 0 : NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed)
174 : {
175 0 : NS_ASSERTION(false, "Forgot to implement CanSkipReal?");
176 0 : return false;
177 : }
178 0 : NS_IMETHOD_(bool) CanSkipInCCReal(void *p)
179 : {
180 0 : NS_ASSERTION(false, "Forgot to implement CanSkipInCCReal?");
181 0 : return false;
182 : }
183 0 : NS_IMETHOD_(bool) CanSkipThisReal(void *p)
184 : {
185 0 : NS_ASSERTION(false, "Forgot to implement CanSkipThisReal?");
186 0 : return false;
187 : }
188 :
189 : bool mMightSkip;
190 : };
191 :
192 : NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
193 : NS_CYCLECOLLECTIONPARTICIPANT_IID)
194 :
195 : #undef IMETHOD_VISIBILITY
196 : #define IMETHOD_VISIBILITY NS_COM_GLUE
197 :
198 : typedef void
199 : (* TraceCallback)(PRUint32 langID, void *p, const char *name, void *closure);
200 :
201 : class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
202 : {
203 : public:
204 : nsScriptObjectTracer() : nsCycleCollectionParticipant(false) {}
205 398208 : nsScriptObjectTracer(bool aSkip) : nsCycleCollectionParticipant(aSkip) {}
206 :
207 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
208 : void NS_COM_GLUE TraverseScriptObjects(void *p,
209 : nsCycleCollectionTraversalCallback &cb);
210 : };
211 :
212 : class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
213 : : public nsScriptObjectTracer
214 : {
215 : public:
216 341112 : nsXPCOMCycleCollectionParticipant()
217 341112 : : nsScriptObjectTracer(false) {}
218 57096 : nsXPCOMCycleCollectionParticipant(bool aSkip)
219 57096 : : nsScriptObjectTracer(aSkip) {}
220 :
221 : NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
222 :
223 : NS_IMETHOD Root(void *p);
224 : NS_IMETHOD Unlink(void *p);
225 : NS_IMETHOD Unroot(void *p);
226 :
227 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);
228 :
229 : NS_IMETHOD_(void) UnmarkIfPurple(nsISupports *p);
230 :
231 : bool CheckForRightISupports(nsISupports *s);
232 : };
233 :
234 : #undef IMETHOD_VISIBILITY
235 : #define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
236 :
237 : ///////////////////////////////////////////////////////////////////////////////
238 : // Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
239 : ///////////////////////////////////////////////////////////////////////////////
240 :
241 : #define NS_CYCLE_COLLECTION_INNERCLASS \
242 : cycleCollection
243 :
244 : #define NS_CYCLE_COLLECTION_CLASSNAME(_class) \
245 : _class::NS_CYCLE_COLLECTION_INNERCLASS
246 :
247 : #define NS_CYCLE_COLLECTION_INNERNAME \
248 : _cycleCollectorGlobal
249 :
250 : #define NS_CYCLE_COLLECTION_NAME(_class) \
251 : _class::NS_CYCLE_COLLECTION_INNERNAME
252 :
253 : #define NS_IMPL_QUERY_CYCLE_COLLECTION(_class) \
254 : if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
255 : *aInstancePtr = & NS_CYCLE_COLLECTION_NAME(_class); \
256 : return NS_OK; \
257 : } else
258 :
259 : #define NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class) \
260 : if ( aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ) { \
261 : *aInstancePtr = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this); \
262 : return NS_OK; \
263 : } else
264 :
265 : #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class) \
266 : NS_IMPL_QUERY_CYCLE_COLLECTION(_class)
267 :
268 : #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class) \
269 : NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)
270 :
271 : #define NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class) \
272 : NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class) \
273 : NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)
274 :
275 : #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(_class) \
276 : NS_INTERFACE_MAP_BEGIN(_class) \
277 : NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
278 :
279 : #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(_class) \
280 : NS_INTERFACE_MAP_BEGIN(_class) \
281 : NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)
282 :
283 : #define NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(_class) \
284 : if (rv == NS_OK) return rv; \
285 : nsISupports* foundInterface; \
286 : NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
287 :
288 : #define NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(_class) \
289 : NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
290 : { \
291 : NS_PRECONDITION(aInstancePtr, "null out param"); \
292 : \
293 : if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
294 : *aInstancePtr = &NS_CYCLE_COLLECTION_NAME(_class); \
295 : return NS_OK; \
296 : } \
297 : nsresult rv;
298 :
299 : #define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \
300 : NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
301 :
302 : ///////////////////////////////////////////////////////////////////////////////
303 : // Helpers for implementing CanSkip methods
304 : ///////////////////////////////////////////////////////////////////////////////
305 :
306 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(_class) \
307 : NS_IMETHODIMP_(bool) \
308 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipReal(void *p, \
309 : bool aRemovingAllowed) \
310 : { \
311 : nsISupports *s = static_cast<nsISupports*>(p); \
312 : NS_ASSERTION(CheckForRightISupports(s), \
313 : "not the nsISupports pointer we expect"); \
314 : _class *tmp = Downcast(s);
315 :
316 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END \
317 : (void)tmp; \
318 : return false; \
319 : }
320 :
321 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(_class) \
322 : NS_IMETHODIMP_(bool) \
323 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipInCCReal(void *p) \
324 : { \
325 : nsISupports *s = static_cast<nsISupports*>(p); \
326 : NS_ASSERTION(CheckForRightISupports(s), \
327 : "not the nsISupports pointer we expect"); \
328 : _class *tmp = Downcast(s);
329 :
330 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END \
331 : (void)tmp; \
332 : return false; \
333 : }
334 :
335 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(_class) \
336 : NS_IMETHODIMP_(bool) \
337 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::CanSkipThisReal(void *p) \
338 : { \
339 : nsISupports *s = static_cast<nsISupports*>(p); \
340 : NS_ASSERTION(CheckForRightISupports(s), \
341 : "not the nsISupports pointer we expect"); \
342 : _class *tmp = Downcast(s);
343 :
344 : #define NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END \
345 : (void)tmp; \
346 : return false; \
347 : }
348 :
349 : ///////////////////////////////////////////////////////////////////////////////
350 : // Helpers for implementing nsCycleCollectionParticipant::Unlink
351 : ///////////////////////////////////////////////////////////////////////////////
352 :
353 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
354 : NS_IMETHODIMP \
355 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
356 : { \
357 : nsISupports *s = static_cast<nsISupports*>(p); \
358 : NS_ASSERTION(CheckForRightISupports(s), \
359 : "not the nsISupports pointer we expect"); \
360 : _class *tmp = Downcast(s);
361 :
362 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class) \
363 : NS_IMETHODIMP \
364 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
365 : { \
366 : nsISupports *s = static_cast<nsISupports*>(p); \
367 : NS_ASSERTION(CheckForRightISupports(s), \
368 : "not the nsISupports pointer we expect"); \
369 : _class *tmp = static_cast<_class*>(Downcast(s)); \
370 : NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s);
371 :
372 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(_class) \
373 : NS_IMETHODIMP \
374 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
375 : { \
376 : _class *tmp = static_cast<_class*>(p);
377 :
378 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field) \
379 : tmp->_field = NULL;
380 :
381 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(_field) \
382 : tmp->_field.Clear();
383 :
384 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(_field) \
385 : tmp->_field.Clear();
386 :
387 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
388 : return NS_OK; \
389 : }
390 :
391 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
392 : NS_IMETHODIMP \
393 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
394 : { \
395 : NS_ASSERTION(CheckForRightISupports(static_cast<nsISupports*>(p)), \
396 : "not the nsISupports pointer we expect"); \
397 : return NS_OK; \
398 : }
399 :
400 : #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(_class) \
401 : NS_IMETHODIMP \
402 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
403 : { \
404 : return NS_OK; \
405 : }
406 :
407 :
408 : ///////////////////////////////////////////////////////////////////////////////
409 : // Helpers for implementing nsCycleCollectionParticipant::Traverse
410 : ///////////////////////////////////////////////////////////////////////////////
411 :
412 : #define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, _refcnt) \
413 : cb.DescribeRefCountedNode(_refcnt, sizeof(_class), #_class);
414 :
415 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \
416 : NS_IMETHODIMP \
417 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
418 : (void *p, \
419 : nsCycleCollectionTraversalCallback &cb) \
420 : { \
421 : nsISupports *s = static_cast<nsISupports*>(p); \
422 : NS_ASSERTION(CheckForRightISupports(s), \
423 : "not the nsISupports pointer we expect"); \
424 : _class *tmp = static_cast<_class*>(Downcast(s));
425 :
426 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
427 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \
428 : NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, tmp->mRefCnt.get())
429 :
430 : // Base class' CC participant should return NS_SUCCESS_INTERRUPTED_TRAVERSE
431 : // from Traverse if it wants derived classes to not traverse anything from
432 : // their CC participant.
433 : #define NS_SUCCESS_INTERRUPTED_TRAVERSE \
434 : NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 2)
435 :
436 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \
437 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(_class) \
438 : if (NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Traverse(s, cb) == \
439 : NS_SUCCESS_INTERRUPTED_TRAVERSE) { \
440 : return NS_SUCCESS_INTERRUPTED_TRAVERSE; \
441 : }
442 :
443 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(_class) \
444 : NS_IMETHODIMP \
445 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
446 : (void *p, \
447 : nsCycleCollectionTraversalCallback &cb) \
448 : { \
449 : _class *tmp = static_cast<_class*>(p); \
450 : NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class, tmp->mRefCnt.get())
451 :
452 : #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name) \
453 : PR_BEGIN_MACRO \
454 : if (NS_UNLIKELY((_cb).WantDebugInfo())) { \
455 : (_cb).NoteNextEdgeName(_name); \
456 : } \
457 : PR_END_MACRO
458 :
459 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field) \
460 : PR_BEGIN_MACRO \
461 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
462 : cb.NoteXPCOMChild(tmp->_field); \
463 : PR_END_MACRO;
464 :
465 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field) \
466 : PR_BEGIN_MACRO \
467 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
468 : cb.NoteXPCOMChild(tmp->_field.get()); \
469 : PR_END_MACRO;
470 :
471 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(_field, _base) \
472 : PR_BEGIN_MACRO \
473 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
474 : cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(_base*, tmp->_field)); \
475 : PR_END_MACRO;
476 :
477 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(_field) \
478 : { \
479 : PRInt32 i; \
480 : for (i = 0; i < tmp->_field.Count(); ++i) { \
481 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field "[i]"); \
482 : cb.NoteXPCOMChild(tmp->_field[i]); \
483 : } \
484 : }
485 :
486 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(_ptr, _ptr_class, _name) \
487 : PR_BEGIN_MACRO \
488 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, _name); \
489 : cb.NoteNativeChild(_ptr, &NS_CYCLE_COLLECTION_NAME(_ptr_class)); \
490 : PR_END_MACRO;
491 :
492 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(_field, _field_class) \
493 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->_field, _field_class, \
494 : #_field)
495 :
496 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(_array, _element_class, \
497 : _name) \
498 : { \
499 : PRUint32 i, length = (_array).Length(); \
500 : for (i = 0; i < length; ++i) \
501 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR((_array)[i], \
502 : _element_class, \
503 : _name "[i]"); \
504 : }
505 :
506 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(_field) \
507 : { \
508 : PRUint32 i, length = tmp->_field.Length(); \
509 : for (i = 0; i < length; ++i) { \
510 : NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field "[i]"); \
511 : cb.NoteXPCOMChild(tmp->_field[i].get()); \
512 : } \
513 : }
514 :
515 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(_field, \
516 : _element_class) \
517 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(tmp->_field, _element_class, \
518 : #_field)
519 :
520 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
521 : TraverseScriptObjects(p, cb);
522 :
523 : #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
524 : return NS_OK; \
525 : }
526 :
527 : ///////////////////////////////////////////////////////////////////////////////
528 : // Helpers for implementing nsScriptObjectTracer::Trace
529 : ///////////////////////////////////////////////////////////////////////////////
530 :
531 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \
532 : void \
533 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
534 : TraceCallback aCallback, \
535 : void *aClosure) \
536 : { \
537 : nsISupports *s = static_cast<nsISupports*>(p); \
538 : NS_ASSERTION(CheckForRightISupports(s), \
539 : "not the nsISupports pointer we expect"); \
540 : _class *tmp = Downcast(s);
541 :
542 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(_class, _base_class) \
543 : void \
544 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
545 : TraceCallback aCallback, \
546 : void *aClosure) \
547 : { \
548 : nsISupports *s = static_cast<nsISupports*>(p); \
549 : NS_ASSERTION(CheckForRightISupports(s), \
550 : "not the nsISupports pointer we expect"); \
551 : _class *tmp = static_cast<_class*>(Downcast(s)); \
552 : NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Trace(s, \
553 : aCallback, \
554 : aClosure);
555 :
556 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class) \
557 : void \
558 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
559 : TraceCallback aCallback, \
560 : void *aClosure) \
561 : { \
562 : _class *tmp = static_cast<_class*>(p);
563 :
564 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, _object, _name) \
565 : if (_object) \
566 : aCallback(_langID, _object, _name, aClosure);
567 :
568 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(_langID, _field) \
569 : NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, tmp->_field, #_field)
570 :
571 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(_object, _name) \
572 : NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT, \
573 : _object, _name)
574 :
575 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field) \
576 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->_field, #_field)
577 :
578 : // NB: The (void)tmp; hack in the TRACE_END macro exists to support
579 : // implementations that don't need to do anything in their Trace method.
580 : // Without this hack, some compilers warn about the unused tmp local.
581 : #define NS_IMPL_CYCLE_COLLECTION_TRACE_END \
582 : (void)tmp; \
583 : }
584 :
585 : ///////////////////////////////////////////////////////////////////////////////
586 : // Helpers for implementing a concrete nsCycleCollectionParticipant
587 : ///////////////////////////////////////////////////////////////////////////////
588 :
589 : #define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE \
590 : static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
591 :
592 : #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
593 : public: \
594 : NS_IMETHOD Traverse(void *p, \
595 : nsCycleCollectionTraversalCallback &cb); \
596 : NS_IMETHOD_(void) UnmarkIfPurple(nsISupports *s) \
597 : { \
598 : Downcast(s)->UnmarkIfPurple(); \
599 : } \
600 : static _class* Downcast(nsISupports* s) \
601 : { \
602 : return static_cast<_class*>(static_cast<_base*>(s)); \
603 : } \
604 : static nsISupports* Upcast(_class *p) \
605 : { \
606 : return NS_ISUPPORTS_CAST(_base*, p); \
607 : }
608 :
609 : #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
610 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
611 : NS_IMETHOD Unlink(void *p);
612 :
613 : #define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base) \
614 : class NS_CYCLE_COLLECTION_INNERCLASS \
615 : : public nsXPCOMCycleCollectionParticipant \
616 : { \
617 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
618 : }; \
619 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
620 :
621 : #define NS_DECL_CYCLE_COLLECTION_CLASS(_class) \
622 : NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _class)
623 :
624 : // Cycle collector helper for ambiguous classes that can sometimes be skipped.
625 : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _base) \
626 : class NS_CYCLE_COLLECTION_INNERCLASS \
627 : : public nsXPCOMCycleCollectionParticipant \
628 : { \
629 : public: \
630 : NS_CYCLE_COLLECTION_INNERCLASS () : nsXPCOMCycleCollectionParticipant(true) {} \
631 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
632 : protected: \
633 : NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \
634 : NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \
635 : NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
636 : }; \
637 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
638 :
639 : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(_class) \
640 : NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(_class, _class)
641 :
642 : // Cycle collector helper for classes that don't want to unlink anything.
643 : // Note: if this is used a lot it might make sense to have a base class that
644 : // doesn't do anything in Root/Unlink/Unroot.
645 : #define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class) \
646 : class NS_CYCLE_COLLECTION_INNERCLASS \
647 : : public nsXPCOMCycleCollectionParticipant \
648 : { \
649 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class) \
650 : NS_IMETHOD Root(void *p) \
651 : { \
652 : return NS_OK; \
653 : } \
654 : NS_IMETHOD Unlink(void *p) \
655 : { \
656 : return NS_OK; \
657 : } \
658 : NS_IMETHOD Unroot(void *p) \
659 : { \
660 : return NS_OK; \
661 : } \
662 : }; \
663 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
664 :
665 : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base) \
666 : class NS_CYCLE_COLLECTION_INNERCLASS \
667 : : public nsXPCOMCycleCollectionParticipant \
668 : { \
669 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
670 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
671 : }; \
672 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
673 :
674 : #define NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base) \
675 : class NS_CYCLE_COLLECTION_INNERCLASS \
676 : : public nsXPCOMCycleCollectionParticipant \
677 : { \
678 : public: \
679 : NS_CYCLE_COLLECTION_INNERCLASS () : nsXPCOMCycleCollectionParticipant(true) {} \
680 : NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
681 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
682 : protected: \
683 : NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \
684 : NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \
685 : NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
686 : }; \
687 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
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 : NS_CYCLE_COLLECTION_INNERCLASS () \
699 : : NS_CYCLE_COLLECTION_CLASSNAME(_base_class)() \
700 : { \
701 : mMightSkip = true; \
702 : } \
703 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
704 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
705 : protected: \
706 : NS_IMETHOD_(bool) CanSkipReal(void *p, bool aRemovingAllowed); \
707 : NS_IMETHOD_(bool) CanSkipInCCReal(void *p); \
708 : NS_IMETHOD_(bool) CanSkipThisReal(void *p); \
709 : }; \
710 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
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 Traverse(void *p, \
719 : nsCycleCollectionTraversalCallback &cb); \
720 : static _class* Downcast(nsISupports* s) \
721 : { \
722 : return static_cast<_class*>(static_cast<_base_class*>( \
723 : NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s))); \
724 : }
725 :
726 : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
727 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
728 : NS_IMETHOD Unlink(void *p);
729 :
730 : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class) \
731 : class NS_CYCLE_COLLECTION_INNERCLASS \
732 : : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
733 : { \
734 : public: \
735 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
736 : }; \
737 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
738 :
739 : #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class, \
740 : _base_class) \
741 : class NS_CYCLE_COLLECTION_INNERCLASS \
742 : : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
743 : { \
744 : public: \
745 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY_NO_UNLINK(_class, _base_class) \
746 : }; \
747 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
748 :
749 : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(_class, \
750 : _base_class) \
751 : class NS_CYCLE_COLLECTION_INNERCLASS \
752 : : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
753 : { \
754 : public: \
755 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
756 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_BODY(_class, _base_class) \
757 : }; \
758 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
759 :
760 : /**
761 : * This implements a stub UnmarkIfPurple function for classes that want to be
762 : * traversed but whose AddRef/Release functions don't add/remove them to/from
763 : * the purple buffer. If you're just using NS_DECL_CYCLE_COLLECTING_ISUPPORTS
764 : * then you don't need this.
765 : */
766 : #define NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(_class) \
767 : NS_IMETHODIMP_(void) UnmarkIfPurple() \
768 : { \
769 : } \
770 :
771 : #define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
772 : NS_CYCLE_COLLECTION_CLASSNAME(_class) NS_CYCLE_COLLECTION_NAME(_class);
773 :
774 : #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
775 : public: \
776 : NS_IMETHOD Root(void *n); \
777 : NS_IMETHOD Unlink(void *n); \
778 : NS_IMETHOD Unroot(void *n); \
779 : NS_IMETHOD Traverse(void *n, \
780 : nsCycleCollectionTraversalCallback &cb);
781 :
782 : #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
783 : class NS_CYCLE_COLLECTION_INNERCLASS \
784 : : public nsCycleCollectionParticipant \
785 : { \
786 : NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
787 : }; \
788 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
789 :
790 : #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class) \
791 : class NS_CYCLE_COLLECTION_INNERCLASS \
792 : : public nsScriptObjectTracer \
793 : { \
794 : NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
795 : NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
796 : }; \
797 : NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
798 :
799 : #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
800 : NS_IMETHODIMP \
801 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Root(void *p) \
802 : { \
803 : _class *tmp = static_cast<_class*>(p); \
804 : tmp->_root_function(); \
805 : return NS_OK; \
806 : }
807 :
808 : #define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function) \
809 : NS_IMETHODIMP \
810 : NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p) \
811 : { \
812 : _class *tmp = static_cast<_class*>(p); \
813 : tmp->_unroot_function(); \
814 : return NS_OK; \
815 : }
816 :
817 : #define NS_IMPL_CYCLE_COLLECTION_0(_class) \
818 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
819 : NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
820 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
821 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
822 :
823 : #define NS_IMPL_CYCLE_COLLECTION_1(_class, _f) \
824 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
825 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
826 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f) \
827 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
828 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
829 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f) \
830 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
831 :
832 : #define NS_IMPL_CYCLE_COLLECTION_2(_class, _f1, _f2) \
833 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
834 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
835 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
836 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
837 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
838 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
839 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
840 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
841 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
842 :
843 : #define NS_IMPL_CYCLE_COLLECTION_3(_class, _f1, _f2, _f3) \
844 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
845 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
846 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
847 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
848 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
849 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
850 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
851 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
852 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
853 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
854 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
855 :
856 : #define NS_IMPL_CYCLE_COLLECTION_4(_class, _f1, _f2, _f3, _f4) \
857 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
858 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
859 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
860 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
861 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
862 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f4) \
863 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
864 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
865 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
866 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
867 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
868 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f4) \
869 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
870 :
871 : #define NS_IMPL_CYCLE_COLLECTION_5(_class, _f1, _f2, _f3, _f4, _f5) \
872 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
873 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
874 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
875 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
876 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
877 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f4) \
878 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f5) \
879 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
880 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
881 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
882 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
883 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
884 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f4) \
885 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f5) \
886 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
887 :
888 : #define NS_IMPL_CYCLE_COLLECTION_6(_class, _f1, _f2, _f3, _f4, _f5, _f6) \
889 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
890 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
891 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
892 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
893 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
894 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f4) \
895 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f5) \
896 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f6) \
897 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
898 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
899 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
900 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
901 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
902 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f4) \
903 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f5) \
904 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f6) \
905 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
906 :
907 : #define NS_IMPL_CYCLE_COLLECTION_7(_class, _f1, _f2, _f3, _f4, _f5, _f6, _f7) \
908 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
909 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
910 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
911 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
912 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
913 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f4) \
914 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f5) \
915 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f6) \
916 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f7) \
917 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
918 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
919 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
920 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
921 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
922 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f4) \
923 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f5) \
924 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f6) \
925 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f7) \
926 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
927 :
928 : #define NS_IMPL_CYCLE_COLLECTION_8(_class, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8) \
929 : NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
930 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
931 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
932 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
933 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
934 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f4) \
935 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f5) \
936 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f6) \
937 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f7) \
938 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f8) \
939 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
940 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
941 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
942 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
943 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
944 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f4) \
945 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f5) \
946 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f6) \
947 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f7) \
948 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f8) \
949 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
950 :
951 : #endif // nsCycleCollectionParticipant_h__
|