Re: How do I trace objects on the heap with JS 59

Steve Fink <[email protected]> Thu, 9 Aug 2018 10:46:54 -0700
Newsgroups gmane.comp.mozilla.devel.jseng
Message-ID <[email protected]>
On 08/09/2018 01:40 AM, Miles wrote:
> Hi,
> 
> I'm currently trying to update my embedding from a very old version (1.8.5) to 59. I have lots of objects which I used to root using JS_AddObjectRoot.
> These are stored on heap structures.
> I'm trying to understand how to do the rooting in 59.
> 
> In the GC rooting guide on MDN at https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/GC_Rooting_Guide#GC_things_on_the_heap it says:
> 
> GC thing pointers on the heap must be wrapped in a JS::Heap<T>. The only exception to this is if they are added as roots with the JS_Add<T>Root() functions or JS::PersistentRooted class, but don't do this unless it's really necessary.  JS::Heap<T> pointers must also continue to be traced in the normal way, which is not covered here.
> 
> OK, so I need to use JS::Heap<JSObject *> and these need to be traced but how to do it isn't covered in the guide... Please can someone point me to some documentation/reference which says how to do it. I can't find any information anywhere...
> 
> Alternatively it looks like I could use the JS::PersistentRooted class to do what I want but it specifically says not to do this unless it's really necessary. Why is that then? Is it some sort of performance issue?

The exact equivalent of JS_Add*Root is JS::PersistentRooted. It is 
discouraged because it is ridiculously easy to keep things alive 
forever. For example, if the referent of a PersistentRooted field 
creates a cycle with its container, then nothing in or reachable from 
that cycle will ever be freed up. And since global objects are reachable 
from pretty much everything, that means that if your structure is 
reachable from any JS object, you'll have a cycle.

You want such fields to be traced, not rooted. That generally means that 
you define a trace() method on your structures that calls JS::TraceEdge 
on each of your Heap<T> fields. That is enough to put your structure in 
a Rooted<yourstruct> on the stack, btw, if you happen to want to.

The exact signature of trace() is

     void trace(JSTracer* trc, const char* name);

Actually, this spurred me to update the MDN documentation to include 
tracing: 
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/GC_Rooting_Guide#GC_things_on_the_heap