[quickjs-devel] Re: how to make an object survive gc...

  • From: Ondřej Jirman <deibeemoocheuguhumoh@xxxxxx>
  • To: quickjs-devel@xxxxxxxxxxxxx
  • Date: Sun, 15 Sep 2019 17:03:57 +0200

Hi,

On Sun, Sep 15, 2019 at 04:37:01PM +0200, Mario Gliewe wrote:

Hi,

I didn't dive deeper into the garbage collector yet..

I stumbled over the need to create a native object, which will not be
necessarily directly referenced by the globalThis of a context. So it
wont be marked on the MARK phase of the gc when just using globalThis as
a starting point.

Is it sufficient to just have a JSValue instance somewhere holding the
object, or will i have to manually ref() the object in some kind to
prevent the object becoming destroyed on gc()?

You just need to keep JSValue ref somewhere private in C code (see JS_DupValue
for how to make a ref). You can keep it in per context private data for example
(see JS_SetContextOpaque). Before destroying the context, you'd just need to
unref your object. This way it will not be collected by gc.

gc_mark is meant for breaking cycles and should be used to mark JSValues that
are referenced by your C class object's private data. You should never mark the
class object itself with gc_mark.

I noticed that in the gc_mark() of a timer (in quickjs-libc), the
callback function inside the JSOSTimer struct is explicitly mark()ed,
but how did the gc got to ask the timer object itself in the first place?

function a() {
        let t = setTimer(cb, 100);
        // t is unrefed here, when gc runs it will try to collect t and call
        // gc_mark on it, if another ref is not held from C code, it will
        // be freed (that's why C code holds the ref to the timer object too
        // in the private data, so that timer is not cancelled immediately in
        // this case)
}

regards,
        o.

greets maG




Other related posts: