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

James Stortz <[email protected]> Sat, 18 Aug 2018 13:16:48 -0400
Newsgroups gmane.comp.mozilla.devel.jseng
Message-ID <CAE0WHd9UBi+Lz3Y5CsfvUOMNJfzgkpwZRCCuB1ZpKT64H=3tDA@mail.gmail.com>
On Thu, Aug 16, 2018 at 10:33 AM, Miles <[email protected]> wrote:

> What does calling JS::TraceEdge do? Does it
> 1. Ensure that jsobject is kept up to date to refer to the correct
> (JSObject *) pointer
> or
> 2. Root the object to stop GC on it.
>
> Or perhaps it is both?
>
> Basically, how can I do my two 'normal' and 'special' use cases using
> tracing? Can I somehow store the JSObject pointer in a structure but still
> allow it to go out of scope as normal for my 'normal' case and also prevent
> GC in some circumstances for my 'special' case. Is it possible?
>
> I *think* this is the same question that James is asking...
>


Miles, did anybody help answer this? (Sometimes I get these emails delayed,
but I thought I'd try to help in some small way, since I was able to get
mine working, as far as I can tell.)

Yes, I have the same questions, and I believe our understanding is correct.
My advice is this: "You have to know when it is ok to keep the [heap]
object alive." For example, say if you had an event/request object, and
wanted to keep it alive so the backend can do work, and then return control
to the JS. Upon returning control to JS, you would be ok to free it from
the heap/destroy private, as once the object is rooted again [on the stack]
it would be treated as per usual, and able to GC.

If your special case is as straight-forward as that, then that'll work. If
not, you should try to work it out so you can know exactly when it needs to
be alive. My case was more complicated, but I was able to do that, and I
tested by calling `JS_GC(cx)` in the middle of my program, and it did
indeed GC those objects.

I like how you are using `TraceOp` on your `JSClass`, but unfortunately I
don't know how that works. I think it just adds/removes the tracer
automatically, whereas I used
`JS_AddExtraGCRootsTracer`/`JS_RemoveExtraRootsTracer`, as well as a
`FinalizeOp`. That means, elsewhere in my program, I would NULL the
`JS::Heap<>` and remove it's tracer, and that allowed FinalizeOp to delete
the private, and complete GC as per usual.

I think your approach would be cleaner, but similar using `TraceOp` ...?

Good luck and Regards,
James