Hi List, This is to let you know about some changes to cycle collection macros, which are currently on mozilla-inbound. In short, declaring your classes to the CC just got much simpler, and in a majority of cases a single macro will be able to do all your CC goop for you (see below, "Helper macros"). We plan to update the documentation, but I wanted to let people know about this early to avoid bad surprises when trying to land patches.
For details, see bug 806279. Unlinking fields ================ There is now a unique macro to declare a field to unlink: NS_IMPL_CYCLE_COLLECTION_UNLINK It replaces the following macros: NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY The NS_IMPL_CYCLE_COLLECTION_UNLINK macro takes only one argument: the field to unlink. Example: NS_IMPL_CYCLE_COLLECTION_UNLINK(mSomeMember) Traversing fields ================= There is now a unique (*) macro to declare a field to traverse: NS_IMPL_CYCLE_COLLECTION_TRAVERSE It replaces the following macros: NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER The NS_IMPL_CYCLE_COLLECTION_TRAVERSE macro takes only one argument: the field to traverse. Example: NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSomeMember) (*) : The above is not entirely true: the NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR macro remains. However, it only is very rarely used. We purposefully did not unify it with the rest, to avoid making it easy to accidentally declare raw pointers to the CC. See: https://bugzilla.mozilla.org/show_bug.cgi?id=806279#c28 Fields having nsISupports as an ambiguous base ============================================== For fields whose type is a CC class, this is handled automatically. So the only issue is with fields that have nsISupports as an ambiguous base, and whose types are not CC classes themselves. For those classes, you must provide an overloaded ToSupports function. It should be provided in the same header that declares the class in question. Note that the ToSupports approach is already in use in the new DOM bindings. We're just generalizing its usage here. Example: nsDocument.cpp fails to compile as it tried to traverse a field which is a pointer to nsHTMLCSSStyleSheet, which is not a CC class and has nsISupports as an ambiguous base. The solution is to add the following code to nsHTMLCSSStyleSheet.h: inline nsISupports* ToSupports(nsHTMLCSSStyleSheet* aPointer) { return static_cast<nsIStyleSheet*>(aPointer); } Helper macros ============= We already had helper macros that offered to do all the CC goop automatically: NS_IMPL_CYCLE_COLLECTION_<number of fields> NS_IMPL_CYCLE_COLLECTION_INHERITED_<number of fields> NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_<number of fields> However, they used to only be able to declare plain refpointers-to-isupports fields, not array fields, not native fields and not ambiguous-isupports fields. Now they are able to declare all of that, which makes them usable for probably a wide majority of cases. For example, you can replace existing CC goop like this, NS_IMPL_CYCLE_COLLECTION_CLASS(CanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCanvasElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CanvasRenderingContext2D) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCanvasElement, nsINode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END By just this: NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(CanvasRenderingContext2D, mCanvasElement) You couldn't do it before because of the _AMBIGUOUS. A possibly useful regex ======================= In case you need to adapt a large patch, here is the regex that we used to do the bulk of the porting. Some unusual cases had to be done manually though. See bug 807437. perl -i -pe 'BEGIN{undef $/;} s/CYCLE_COLLECTION_(UNLINK|TRAVERSE)_(NSCOMPTR|NSCOMPTR_AMBIGUOUS|NSCOMARRAY|NATIVE_PTR|NATIVE_MEMBER|NSTARRAY|NSTARRAY_OF_NSCOMPTR|NSTARRAY_MEMBER)\(([^,)]+).*?\)/CYCLE_COLLECTION_\1\(\3\)/gs' Cheers, Benoit _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform