[webkit-gtk] JavaScriptCore GObject Bindings - Memory Management

Yusuke SUZUKI utatane.tea at gmail.com
Tue Mar 14 22:54:08 PDT 2017


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.

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).

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.
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.
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
> <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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-gtk/attachments/20170315/979953c5/attachment.html>


More information about the webkit-gtk mailing list