[webkit-gtk] JavaScriptCore GObject Bindings - Memory Management

Yusuke SUZUKI utatane.tea at gmail.com
Fri Mar 17 06:58:27 PDT 2017


Thanks for clarifications!

On Fri, Mar 17, 2017 at 5:52 PM, Carlos Garcia Campos <cgarcia at igalia.com>
wrote:

> El mié, 15-03-2017 a las 14:54 +0900, Yusuke SUZUKI escribió:
> > On Fri, Mar 10, 2017 at 9:49 PM, tevaum at gmail.com <tevaum at gmail.com>
> > wrote:
> > > Hi. I started implementing a JavaScriptCore GObject binding in [1].
> > > This API provides two main objects: JSCContext, representing
> > > JSGlobalContextRef, and JSCValue, representing JSValueRef. It's a
> > > first patch and does't do any memory management, because I wasn't
> > > really aware of how JSC handles JSValueRefs and stuff.
> > >
> > > Asking on JSC list they replied that JSValues are garbage collected
> > > and when you need to keep a reference to it in the heap you should
> > > protect them. [2]
> > >
> >
> > Yes. JSValues are GC-managed ones. So if it is on machine stack /
> > registers, it will be marked and kept alive.
> > And once it becomes unreachable, GC automatically collects these
> > values.
>
> Thanks for your help Yusuke, we really need help to understand how
> things work in JSC to design our API.
>
> > Note that JSValueRef is actually the value type rather than the
> > pointer to something. (Internally, it something the pointer to the
> > JSString*, JSObject*.)
> > It should be always copied. And it should not be allocated in heap
> > usually.
> >
> > > This is already done by the bindings: JSValueRefs are protected on
> > > contruction of JSCValue and unprotected on destruction, but
> > > JSCValues were implemented as initially owned and noone's keeping
> > > their reference to unref them when needed.
> > >
> >
> > I think we should not protect/unprotect in API side automatically.
> > And I think we should not represent JSCValue as heap allocated one.
> > JSCValue should be represented like gint64 (value type).
>
> What we really have is not a heap allocated JSValueRef, but a heap
> allocated GObject wrapper for a JSValueRef. Similar to what JSValue is
> in the Objc API, a NSObject wrapping a JSValueRef. So, for example:
>
> JSCValue *jsc_boolean_new (JSCContext *, gboolean);
>
> JSCValue is the wrapper, and this simply calls JSValueMakeBoolean to
> create the JSVAlueRef wrapped by this GObject.
>

OK, so, in that case, JSCValueRef is stored in JSCValue. And JSCValue is
allocated in the heap.
Yeah, right. In that case, we should protect that value.
I've just looked JSValue.mm & JSValue.h. Yup, they use protect/unprotect to
offer such JSValue thing :)


>
> In the Objc API values are always protected on construction and
> unprotected on destruction. However, it also has API to create managed
> values, that I think they are like a weak ref.
>

 [JSValue valueWithJSValueRef:inContext:]?
It seems that resulted JSValue is autorelease-ed. And they are held in weak
map, thus we can internalize JSValues.


>
> > Or if we would like to do that, I think we should separate it from
> > the usual JSValue class.
> > They are responsibility of API users.
> > Consider the following case,
> >
> > std::vector<JSValueRef> vector;
> >
> > In that case, the elements of the vector is allocated in the heap.
> > And GC does not know about this heap area.
> > So GC does not mark objects in this heap area. In that case, users
> > should protect them.
>
> What we have is something like this:
>
> typedef struct _JSCValuePrivate {
>     JSCContext* context;
>     JSValueRef value;
> } JSCValuePrivate;
>
> And yes, that struct is always heap allocated.
>

OK, in that case, we should protect/unprotect it.


>
> > But if you use JSValueRef usually (not holding it in heap), we do not
> > need to protect it explicitly. GC will see your stack and registers.
> >
> > I think the above use case is relatively rare: Usually, we create the
> > JSValue on the stack and pass it though the registers.
> > When we would like to store these values in the heap, we should store
> > it in JSArray (js managed object) instead of users' vector or
> > something.
> >
> > Protecting and unprotecting are just adding and removing the value to
> > the set of the GC root set.
>
> So, I guess that if I create a JSValue that is heap allocated on a
> context, and then I unprotect it, forcing a full GC would delete the
> JSValue immediately, right?


Is there any reference to the managed value in registers / stack(it
includes x64 red zone)? (even such registers are not used)
I guess GC marks it alive because of this.


> I think I tried this for testing when we
> started to work on this API and didn't work for me, that's why I'm
> asking.
>
> > It is not free, it adds and drops the cell to and from the hash set.
> > This is similar to V8's Persistent<>.
> >
> > > So in the current state, we are leaking JSCValues and, as JSCValues
> > > protect JSValueRefs, memory is never freed.
> > >
> > > JavaScriptCore doesn't have any API to directly free JSValueRefs,
> > > so JSCValues needs to be destructed to unprotect JSValueRefs.
> > >
> > > My thought is to Adopt JSCValues when they are created using a
> > > private API in the JSCContext (jscContextAdoptJSCValue(JSCValue*)
> > > ?). As JSCValues have a JSCContext reference, we can call
> > > jscContextAdoptJSCValue in JSCValue's constructed callback. With
> > > this private API, JSCContext will get a JSCValue reference and add
> > > it to a HashMap that will map the JSValueRef to the JSCValue. When
> > > added to the HashMap, JSCValue will be owned by the context and
> > > will be freed when the context is unrefed.
> > >
> > > What do you think about this idea?
> > >
> > > [1] https://bugs.webkit.org/show_bug.cgi?id=164061
> > > [2] https://lists.webkit.org/pipermail/jsc-dev/2016-November/000084
> > > .html
> > >
> > > _______________________________________________
> > > webkit-gtk mailing list
> > > webkit-gtk at lists.webkit.org
> > > https://lists.webkit.org/mailman/listinfo/webkit-gtk
> > >
> >
> > _______________________________________________
> > webkit-gtk mailing list
> > webkit-gtk at lists.webkit.org
> > https://lists.webkit.org/mailman/listinfo/webkit-gtk
> --
> Carlos Garcia Campos
> http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-gtk/attachments/20170317/9a3e04fe/attachment.html>


More information about the webkit-gtk mailing list