/gecko_api/include/nsCycleCollectionParticipant.h

http://firefox-mac-pdf.googlecode.com/ · C Header · 675 lines · 493 code · 101 blank · 81 comment · 8 complexity · 9170c9dc2e0073ea857658faa9c68b88 MD5 · raw file

  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. #ifndef nsCycleCollectionParticipant_h__
  38. #define nsCycleCollectionParticipant_h__
  39. #include "nsISupports.h"
  40. // NOTE: If you use header files to define DEBUG_CC, you must do so here
  41. // *and* in nsCycleCollector.h
  42. //#define DEBUG_CC
  43. #ifdef DEBUG_CC
  44. #define IF_DEBUG_CC_PARAM(_p) , _p
  45. #define IF_DEBUG_CC_ONLY_PARAM(_p) _p
  46. #else
  47. #define IF_DEBUG_CC_PARAM(_p)
  48. #define IF_DEBUG_CC_ONLY_PARAM(_p)
  49. #endif
  50. #define NS_CYCLECOLLECTIONPARTICIPANT_IID \
  51. { \
  52. 0x9674489b, \
  53. 0x1f6f, \
  54. 0x4550, \
  55. { 0xa7, 0x30, 0xcc, 0xae, 0xdd, 0x10, 0x4c, 0xf9 } \
  56. }
  57. /**
  58. * Special IID to get at the base nsISupports for a class. Usually this is the
  59. * canonical nsISupports pointer, but in the case of tearoffs for example it is
  60. * the base nsISupports pointer of the tearoff. This allow the cycle collector
  61. * to have separate nsCycleCollectionParticipant's for tearoffs or aggregated
  62. * classes.
  63. */
  64. #define NS_CYCLECOLLECTIONISUPPORTS_IID \
  65. { \
  66. 0xc61eac14, \
  67. 0x5f7a, \
  68. 0x4481, \
  69. { 0x96, 0x5e, 0x7e, 0xaa, 0x6e, 0xff, 0xa8, 0x5f } \
  70. }
  71. /**
  72. * Just holds the IID so NS_GET_IID works.
  73. */
  74. class nsCycleCollectionISupports
  75. {
  76. public:
  77. NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONISUPPORTS_IID)
  78. };
  79. NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionISupports,
  80. NS_CYCLECOLLECTIONISUPPORTS_IID)
  81. class nsCycleCollectionParticipant;
  82. enum CCNodeType { RefCounted, GCMarked, GCUnmarked };
  83. class NS_NO_VTABLE nsCycleCollectionTraversalCallback
  84. {
  85. public:
  86. // If type is RefCounted you must call DescribeNode() with an accurate
  87. // refcount, otherwise cycle collection will fail, and probably crash.
  88. // If type is not refcounted then the refcount will be ignored.
  89. #ifdef DEBUG_CC
  90. NS_IMETHOD_(void) DescribeNode(CCNodeType type,
  91. nsrefcnt refcount,
  92. size_t objsz,
  93. const char *objname) = 0;
  94. #else
  95. NS_IMETHOD_(void) DescribeNode(CCNodeType type,
  96. nsrefcnt refcount) = 0;
  97. #endif
  98. NS_IMETHOD_(void) NoteXPCOMRoot(nsISupports *root) = 0;
  99. NS_IMETHOD_(void) NoteRoot(PRUint32 langID, void *root,
  100. nsCycleCollectionParticipant* helper) = 0;
  101. NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void *child) = 0;
  102. NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child) = 0;
  103. NS_IMETHOD_(void) NoteNativeChild(void *child,
  104. nsCycleCollectionParticipant *helper) = 0;
  105. #ifdef DEBUG_CC
  106. // Give a name to the edge associated with the next call to
  107. // NoteScriptChild, NoteXPCOMChild, or NoteNativeChild.
  108. NS_IMETHOD_(void) NoteNextEdgeName(const char* name) = 0;
  109. #endif
  110. };
  111. class NS_NO_VTABLE nsCycleCollectionParticipant
  112. {
  113. public:
  114. NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
  115. NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
  116. NS_IMETHOD RootAndUnlinkJSObjects(void *p) = 0;
  117. NS_IMETHOD Unlink(void *p) = 0;
  118. NS_IMETHOD Unroot(void *p) = 0;
  119. };
  120. NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
  121. NS_CYCLECOLLECTIONPARTICIPANT_IID)
  122. #undef IMETHOD_VISIBILITY
  123. #define IMETHOD_VISIBILITY NS_COM_GLUE
  124. typedef void
  125. (* PR_CALLBACK TraceCallback)(PRUint32 langID, void *p, void *closure);
  126. class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
  127. {
  128. public:
  129. NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
  130. void NS_COM_GLUE TraverseScriptObjects(void *p,
  131. nsCycleCollectionTraversalCallback &cb);
  132. };
  133. class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
  134. : public nsScriptObjectTracer
  135. {
  136. public:
  137. NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
  138. NS_IMETHOD RootAndUnlinkJSObjects(void *p);
  139. NS_IMETHOD Unlink(void *p);
  140. NS_IMETHOD Unroot(void *p);
  141. NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);
  142. NS_IMETHOD_(void) UnmarkPurple(nsISupports *p);
  143. PRBool CheckForRightISupports(nsISupports *s);
  144. };
  145. #undef IMETHOD_VISIBILITY
  146. #define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
  147. ///////////////////////////////////////////////////////////////////////////////
  148. // Helpers for implementing a QI to nsXPCOMCycleCollectionParticipant
  149. ///////////////////////////////////////////////////////////////////////////////
  150. #define NS_CYCLE_COLLECTION_INNERCLASS \
  151. cycleCollection
  152. #define NS_CYCLE_COLLECTION_CLASSNAME(_class) \
  153. _class::NS_CYCLE_COLLECTION_INNERCLASS
  154. #define NS_CYCLE_COLLECTION_INNERNAME \
  155. _cycleCollectorGlobal
  156. #define NS_CYCLE_COLLECTION_NAME(_class) \
  157. _class::NS_CYCLE_COLLECTION_INNERNAME
  158. #define NS_IMPL_QUERY_CYCLE_COLLECTION(_class) \
  159. if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
  160. *aInstancePtr = & NS_CYCLE_COLLECTION_NAME(_class); \
  161. return NS_OK; \
  162. } else
  163. #define NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class) \
  164. if ( aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ) \
  165. foundInterface = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this); \
  166. else
  167. #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class) \
  168. NS_IMPL_QUERY_CYCLE_COLLECTION(_class)
  169. #define NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class) \
  170. NS_IMPL_QUERY_CYCLE_COLLECTION_ISUPPORTS(_class)
  171. #define NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class) \
  172. NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class) \
  173. NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION_ISUPPORTS(_class)
  174. #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(_class) \
  175. NS_INTERFACE_MAP_BEGIN(_class) \
  176. NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
  177. #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(_class) \
  178. NS_INTERFACE_MAP_BEGIN(_class) \
  179. NS_INTERFACE_MAP_ENTRY_CYCLE_COLLECTION(_class)
  180. #define NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(_class) \
  181. if (rv == NS_OK) return rv; \
  182. nsISupports* foundInterface; \
  183. NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class)
  184. #define NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(_class) \
  185. NS_IMETHODIMP _class::QueryInterface(REFNSIID aIID, void** aInstancePtr) \
  186. { \
  187. NS_PRECONDITION(aInstancePtr, "null out param"); \
  188. \
  189. if ( aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant)) ) { \
  190. *aInstancePtr = &NS_CYCLE_COLLECTION_NAME(_class); \
  191. return NS_OK; \
  192. } \
  193. nsresult rv;
  194. #define NS_CYCLE_COLLECTION_UPCAST(obj, clazz) \
  195. NS_CYCLE_COLLECTION_CLASSNAME(clazz)::Upcast(obj)
  196. ///////////////////////////////////////////////////////////////////////////////
  197. // Helpers for implementing nsCycleCollectionParticipant::RootAndUnlinkJSObjects
  198. ///////////////////////////////////////////////////////////////////////////////
  199. #define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(_class) \
  200. NS_IMETHODIMP \
  201. NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
  202. { \
  203. nsISupports *s = static_cast<nsISupports*>(p); \
  204. NS_ASSERTION(CheckForRightISupports(s), \
  205. "not the nsISupports pointer we expect"); \
  206. nsXPCOMCycleCollectionParticipant::RootAndUnlinkJSObjects(s); \
  207. _class *tmp = Downcast(s);
  208. #define NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN_NATIVE(_class, _root_function) \
  209. NS_IMETHODIMP \
  210. NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
  211. { \
  212. _class *tmp = static_cast<_class*>(p); \
  213. tmp->_root_function();
  214. #define NS_IMPL_CYCLE_COLLECTION_ROOT_END \
  215. return NS_OK; \
  216. }
  217. ///////////////////////////////////////////////////////////////////////////////
  218. // Helpers for implementing nsCycleCollectionParticipant::Unlink
  219. ///////////////////////////////////////////////////////////////////////////////
  220. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
  221. NS_IMETHODIMP \
  222. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
  223. { \
  224. nsISupports *s = static_cast<nsISupports*>(p); \
  225. NS_ASSERTION(CheckForRightISupports(s), \
  226. "not the nsISupports pointer we expect"); \
  227. _class *tmp = Downcast(s);
  228. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base_class) \
  229. NS_IMETHODIMP \
  230. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
  231. { \
  232. nsISupports *s = static_cast<nsISupports*>(p); \
  233. NS_ASSERTION(CheckForRightISupports(s), \
  234. "not the nsISupports pointer we expect"); \
  235. _class *tmp = static_cast<_class*>(Downcast(s)); \
  236. NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Unlink(s);
  237. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(_class) \
  238. NS_IMETHODIMP \
  239. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
  240. { \
  241. _class *tmp = static_cast<_class*>(p);
  242. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field) \
  243. tmp->_field = NULL;
  244. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(_field) \
  245. tmp->_field.Clear();
  246. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(_field) \
  247. tmp->_field.Clear();
  248. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
  249. return NS_OK; \
  250. }
  251. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
  252. NS_IMETHODIMP \
  253. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
  254. { \
  255. NS_ASSERTION(CheckForRightISupports(static_cast<nsISupports*>(p)), \
  256. "not the nsISupports pointer we expect"); \
  257. return NS_OK; \
  258. }
  259. #define NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(_class) \
  260. NS_IMETHODIMP \
  261. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unlink(void *p) \
  262. { \
  263. return NS_OK; \
  264. }
  265. ///////////////////////////////////////////////////////////////////////////////
  266. // Helpers for implementing nsCycleCollectionParticipant::Traverse
  267. ///////////////////////////////////////////////////////////////////////////////
  268. #ifdef DEBUG_CC
  269. #define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class) \
  270. cb.DescribeNode(RefCounted, tmp->mRefCnt.get(), sizeof(_class), #_class);
  271. #else
  272. #define NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class) \
  273. cb.DescribeNode(RefCounted, tmp->mRefCnt.get());
  274. #endif
  275. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
  276. NS_IMETHODIMP \
  277. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
  278. (void *p, \
  279. nsCycleCollectionTraversalCallback &cb) \
  280. { \
  281. nsISupports *s = static_cast<nsISupports*>(p); \
  282. NS_ASSERTION(CheckForRightISupports(s), \
  283. "not the nsISupports pointer we expect"); \
  284. _class *tmp = Downcast(s); \
  285. NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
  286. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base_class) \
  287. NS_IMETHODIMP \
  288. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
  289. (void *p, \
  290. nsCycleCollectionTraversalCallback &cb) \
  291. { \
  292. nsISupports *s = static_cast<nsISupports*>(p); \
  293. NS_ASSERTION(CheckForRightISupports(s), \
  294. "not the nsISupports pointer we expect"); \
  295. _class *tmp = static_cast<_class*>(Downcast(s)); \
  296. NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Traverse(s, cb);
  297. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(_class) \
  298. NS_IMETHODIMP \
  299. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Traverse \
  300. (void *p, \
  301. nsCycleCollectionTraversalCallback &cb) \
  302. { \
  303. _class *tmp = static_cast<_class*>(p); \
  304. NS_IMPL_CYCLE_COLLECTION_DESCRIBE(_class)
  305. #ifdef DEBUG_CC
  306. #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name) \
  307. PR_BEGIN_MACRO (_cb).NoteNextEdgeName(_name); PR_END_MACRO
  308. #else
  309. #define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(_cb, _name) \
  310. PR_BEGIN_MACRO PR_END_MACRO
  311. #endif
  312. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(_field) \
  313. PR_BEGIN_MACRO \
  314. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
  315. cb.NoteXPCOMChild(tmp->_field); \
  316. PR_END_MACRO;
  317. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field) \
  318. PR_BEGIN_MACRO \
  319. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
  320. cb.NoteXPCOMChild(tmp->_field.get()); \
  321. PR_END_MACRO;
  322. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(_field, _base) \
  323. PR_BEGIN_MACRO \
  324. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field); \
  325. cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(_base*, tmp->_field)); \
  326. PR_END_MACRO;
  327. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(_field) \
  328. { \
  329. PRInt32 i; \
  330. for (i = 0; i < tmp->_field.Count(); ++i) { \
  331. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, #_field "[i]"); \
  332. cb.NoteXPCOMChild(tmp->_field[i]); \
  333. } \
  334. }
  335. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(_ptr, _ptr_class, _name) \
  336. PR_BEGIN_MACRO \
  337. NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, _name); \
  338. cb.NoteNativeChild(_ptr, &NS_CYCLE_COLLECTION_NAME(_ptr_class)); \
  339. PR_END_MACRO;
  340. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(_field, _field_class) \
  341. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->_field, _field_class, \
  342. #_field)
  343. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(_array, _element_class, \
  344. _name) \
  345. { \
  346. PRUint32 i, length = (_array).Length(); \
  347. for (i = 0; i < length; ++i) \
  348. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR((_array)[i], \
  349. _element_class, \
  350. _name "[i]"); \
  351. }
  352. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(_field, \
  353. _element_class) \
  354. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(tmp->_field, _element_class, \
  355. #_field)
  356. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
  357. TraverseScriptObjects(tmp, cb);
  358. #define NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
  359. return NS_OK; \
  360. }
  361. ///////////////////////////////////////////////////////////////////////////////
  362. // Helpers for implementing nsScriptObjectTracer::Trace
  363. ///////////////////////////////////////////////////////////////////////////////
  364. #define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \
  365. void \
  366. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
  367. TraceCallback aCallback, \
  368. void *aClosure) \
  369. { \
  370. nsISupports *s = static_cast<nsISupports*>(p); \
  371. NS_ASSERTION(CheckForRightISupports(s), \
  372. "not the nsISupports pointer we expect"); \
  373. _class *tmp = Downcast(s);
  374. #define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class) \
  375. void \
  376. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
  377. TraceCallback aCallback, \
  378. void *aClosure) \
  379. { \
  380. _class *tmp = static_cast<_class*>(p);
  381. #define NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, _object) \
  382. if (_object) \
  383. aCallback(_langID, _object, aClosure);
  384. #define NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(_langID, _field) \
  385. NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(_langID, tmp->_field)
  386. #define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(_object) \
  387. NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(nsIProgrammingLanguage::JAVASCRIPT, \
  388. _object)
  389. #define NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(_field) \
  390. NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->_field)
  391. #define NS_IMPL_CYCLE_COLLECTION_TRACE_END \
  392. }
  393. ///////////////////////////////////////////////////////////////////////////////
  394. // Helpers for implementing a concrete nsCycleCollectionParticipant
  395. ///////////////////////////////////////////////////////////////////////////////
  396. #define NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE \
  397. static NS_CYCLE_COLLECTION_INNERCLASS NS_CYCLE_COLLECTION_INNERNAME;
  398. #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
  399. public: \
  400. NS_IMETHOD Traverse(void *p, \
  401. nsCycleCollectionTraversalCallback &cb); \
  402. NS_IMETHOD_(void) UnmarkPurple(nsISupports *s) \
  403. { \
  404. Downcast(s)->UnmarkPurple(); \
  405. } \
  406. static _class* Downcast(nsISupports* s) \
  407. { \
  408. return static_cast<_class*>(static_cast<_base*>(s)); \
  409. } \
  410. static nsISupports* Upcast(_class *p) \
  411. { \
  412. return NS_ISUPPORTS_CAST(_base*, p); \
  413. }
  414. #define NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
  415. NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _base) \
  416. NS_IMETHOD Unlink(void *p);
  417. #define NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _base) \
  418. class NS_CYCLE_COLLECTION_INNERCLASS \
  419. : public nsXPCOMCycleCollectionParticipant \
  420. { \
  421. NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
  422. }; \
  423. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  424. #define NS_DECL_CYCLE_COLLECTION_CLASS(_class) \
  425. NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(_class, _class)
  426. // Cycle collector helper for classes that don't want to unlink anything.
  427. // Note: if this is used a lot it might make sense to have a base class that
  428. // doesn't do anything in RootAndUnlinkJSObjects/Unlink/Unroot.
  429. #define NS_DECL_CYCLE_COLLECTION_CLASS_NO_UNLINK(_class) \
  430. class NS_CYCLE_COLLECTION_INNERCLASS \
  431. : public nsXPCOMCycleCollectionParticipant \
  432. { \
  433. NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(_class, _class) \
  434. NS_IMETHOD RootAndUnlinkJSObjects(void *p) \
  435. { \
  436. return NS_OK; \
  437. } \
  438. NS_IMETHOD Unlink(void *p) \
  439. { \
  440. return NS_OK; \
  441. } \
  442. NS_IMETHOD Unroot(void *p) \
  443. { \
  444. return NS_OK; \
  445. } \
  446. }; \
  447. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  448. #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _base) \
  449. class NS_CYCLE_COLLECTION_INNERCLASS \
  450. : public nsXPCOMCycleCollectionParticipant \
  451. { \
  452. NS_IMETHOD RootAndUnlinkJSObjects(void *p); \
  453. NS_DECL_CYCLE_COLLECTION_CLASS_BODY(_class, _base) \
  454. NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
  455. }; \
  456. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  457. #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(_class) \
  458. NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(_class, _class)
  459. #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(_class, _base_class) \
  460. class NS_CYCLE_COLLECTION_INNERCLASS \
  461. : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
  462. { \
  463. public: \
  464. NS_IMETHOD Unlink(void *p); \
  465. NS_IMETHOD Traverse(void *p, \
  466. nsCycleCollectionTraversalCallback &cb); \
  467. static _class* Downcast(nsISupports* s) \
  468. { \
  469. return static_cast<_class*>(static_cast<_base_class*>( \
  470. NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s))); \
  471. } \
  472. }; \
  473. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  474. #define NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(_class, \
  475. _base_class) \
  476. class NS_CYCLE_COLLECTION_INNERCLASS \
  477. : public NS_CYCLE_COLLECTION_CLASSNAME(_base_class) \
  478. { \
  479. public: \
  480. NS_IMETHOD Traverse(void *p, \
  481. nsCycleCollectionTraversalCallback &cb); \
  482. static _class* Downcast(nsISupports* s) \
  483. { \
  484. return static_cast<_class*>(static_cast<_base_class*>( \
  485. NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Downcast(s))); \
  486. } \
  487. }; \
  488. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  489. /**
  490. * This implements a stub UnmarkPurple function for classes that want to be
  491. * traversed but whose AddRef/Release functions don't add/remove them to/from
  492. * the purple buffer. If you're just using NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  493. * then you don't need this.
  494. */
  495. #define NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(_class) \
  496. NS_IMETHODIMP_(void) UnmarkPurple() \
  497. { \
  498. } \
  499. #define NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
  500. NS_CYCLE_COLLECTION_CLASSNAME(_class) NS_CYCLE_COLLECTION_NAME(_class);
  501. #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
  502. public: \
  503. NS_IMETHOD RootAndUnlinkJSObjects(void *n); \
  504. NS_IMETHOD Unlink(void *n); \
  505. NS_IMETHOD Unroot(void *n); \
  506. NS_IMETHOD Traverse(void *n, \
  507. nsCycleCollectionTraversalCallback &cb);
  508. #define NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(_class) \
  509. class NS_CYCLE_COLLECTION_INNERCLASS \
  510. : public nsCycleCollectionParticipant \
  511. { \
  512. NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
  513. }; \
  514. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  515. #define NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(_class) \
  516. class NS_CYCLE_COLLECTION_INNERCLASS \
  517. : public nsScriptObjectTracer \
  518. { \
  519. NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS_BODY \
  520. NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure); \
  521. }; \
  522. NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
  523. #define NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(_class, _root_function) \
  524. NS_IMETHODIMP \
  525. NS_CYCLE_COLLECTION_CLASSNAME(_class)::RootAndUnlinkJSObjects(void *p) \
  526. { \
  527. _class *tmp = static_cast<_class*>(p); \
  528. tmp->_root_function(); \
  529. return NS_OK; \
  530. }
  531. #define NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(_class, _unroot_function) \
  532. NS_IMETHODIMP \
  533. NS_CYCLE_COLLECTION_CLASSNAME(_class)::Unroot(void *p) \
  534. { \
  535. _class *tmp = static_cast<_class*>(p); \
  536. tmp->_unroot_function(); \
  537. return NS_OK; \
  538. }
  539. #define NS_IMPL_CYCLE_COLLECTION_0(_class) \
  540. NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
  541. NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_class) \
  542. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
  543. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  544. #define NS_IMPL_CYCLE_COLLECTION_1(_class, _f) \
  545. NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
  546. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
  547. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f) \
  548. NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
  549. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
  550. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f) \
  551. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  552. #define NS_IMPL_CYCLE_COLLECTION_2(_class, _f1, _f2) \
  553. NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
  554. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
  555. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
  556. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
  557. NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
  558. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
  559. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
  560. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
  561. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  562. #define NS_IMPL_CYCLE_COLLECTION_3(_class, _f1, _f2, _f3) \
  563. NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
  564. NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
  565. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f1) \
  566. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f2) \
  567. NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_f3) \
  568. NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
  569. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
  570. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f1) \
  571. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f2) \
  572. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_f3) \
  573. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
  574. #endif // nsCycleCollectionParticipant_h__