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

Reply via email to