<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">Thanks for clarifications!</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Fri, Mar 17, 2017 at 5:52 PM, Carlos Garcia Campos <span dir="ltr"><<a href="mailto:cgarcia@igalia.com" target="_blank">cgarcia@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">El mié, 15-03-2017 a las 14:54 +0900, Yusuke SUZUKI escribió:<br>
> On Fri, Mar 10, 2017 at 9:49 PM, <a href="mailto:tevaum@gmail.com">tevaum@gmail.com</a> <<a href="mailto:tevaum@gmail.com">tevaum@gmail.com</a>><br>
> wrote:<br>
> > Hi. I started implementing a JavaScriptCore GObject binding in [1].<br>
> > This API provides two main objects: JSCContext, representing<br>
> > JSGlobalContextRef, and JSCValue, representing JSValueRef. It's a<br>
> > first patch and does't do any memory management, because I wasn't<br>
> > really aware of how JSC handles JSValueRefs and stuff.<br>
> ><br>
> > Asking on JSC list they replied that JSValues are garbage collected<br>
> > and when you need to keep a reference to it in the heap you should<br>
> > protect them. [2]<br>
> ><br>
><br>
> Yes. JSValues are GC-managed ones. So if it is on machine stack /<br>
> registers, it will be marked and kept alive.<br>
> And once it becomes unreachable, GC automatically collects these<br>
> values.<br>
<br>
</span>Thanks for your help Yusuke, we really need help to understand how<br>
things work in JSC to design our API.<br>
<span class=""><br>
> Note that JSValueRef is actually the value type rather than the<br>
> pointer to something. (Internally, it something the pointer to the<br>
> JSString*, JSObject*.)<br>
> It should be always copied. And it should not be allocated in heap<br>
> usually.<br>
> <br>
> > This is already done by the bindings: JSValueRefs are protected on<br>
> > contruction of JSCValue and unprotected on destruction, but<br>
> > JSCValues were implemented as initially owned and noone's keeping<br>
> > their reference to unref them when needed.<br>
> ><br>
><br>
> I think we should not protect/unprotect in API side automatically.<br>
> And I think we should not represent JSCValue as heap allocated one.<br>
> JSCValue should be represented like gint64 (value type).<br>
<br>
</span>What we really have is not a heap allocated JSValueRef, but a heap<br>
allocated GObject wrapper for a JSValueRef. Similar to what JSValue is<br>
in the Objc API, a NSObject wrapping a JSValueRef. So, for example:<br>
<br>
JSCValue *jsc_boolean_new (JSCContext *, gboolean);<br>
<br>
JSCValue is the wrapper, and this simply calls JSValueMakeBoolean to<br>
create the JSVAlueRef wrapped by this GObject.<br></blockquote><div><br></div><div>OK, so, in that case, JSCValueRef is stored in JSCValue. And JSCValue is allocated in the heap.</div><div>Yeah, right. In that case, we should protect that value.</div><div>I've just looked JSValue.mm & JSValue.h. Yup, they use protect/unprotect to offer such JSValue thing :) </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
In the Objc API values are always protected on construction and<br>
unprotected on destruction. However, it also has API to create managed<br>
values, that I think they are like a weak ref.<br></blockquote><div><br></div><div> [JSValue valueWithJSValueRef:inContext:]?</div><div>It seems that resulted JSValue is autorelease-ed. And they are held in weak map, thus we can internalize JSValues.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> Or if we would like to do that, I think we should separate it from<br>
> the usual JSValue class.<br>
> They are responsibility of API users.<br>
> Consider the following case,<br>
><br>
> std::vector<JSValueRef> vector;<br>
><br>
> In that case, the elements of the vector is allocated in the heap.<br>
> And GC does not know about this heap area.<br>
> So GC does not mark objects in this heap area. In that case, users<br>
> should protect them.<br>
<br>
</span>What we have is something like this:<br>
<br>
typedef struct _JSCValuePrivate {<br>
JSCContext* context;<br>
JSValueRef value;<br>
} JSCValuePrivate;<br>
<br>
And yes, that struct is always heap allocated.<br></blockquote><div><br></div><div>OK, in that case, we should protect/unprotect it.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
> But if you use JSValueRef usually (not holding it in heap), we do not<br>
> need to protect it explicitly. GC will see your stack and registers.<br>
><br>
> I think the above use case is relatively rare: Usually, we create the<br>
> JSValue on the stack and pass it though the registers.<br>
> When we would like to store these values in the heap, we should store<br>
> it in JSArray (js managed object) instead of users' vector or<br>
> something.<br>
><br>
> Protecting and unprotecting are just adding and removing the value to<br>
> the set of the GC root set.<br>
<br>
</span>So, I guess that if I create a JSValue that is heap allocated on a<br>
context, and then I unprotect it, forcing a full GC would delete the<br>
JSValue immediately, right?</blockquote><div><br></div><div>Is there any reference to the managed value in registers / stack(it includes x64 red zone)? (even such registers are not used)</div><div>I guess GC marks it alive because of this.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I think I tried this for testing when we<br>
started to work on this API and didn't work for me, that's why I'm<br>
asking.<br>
<div class="HOEnZb"><div class="h5"><br>
> It is not free, it adds and drops the cell to and from the hash set.<br>
> This is similar to V8's Persistent<>.<br>
> <br>
> > So in the current state, we are leaking JSCValues and, as JSCValues<br>
> > protect JSValueRefs, memory is never freed.<br>
> ><br>
> > JavaScriptCore doesn't have any API to directly free JSValueRefs,<br>
> > so JSCValues needs to be destructed to unprotect JSValueRefs.<br>
> ><br>
> > My thought is to Adopt JSCValues when they are created using a<br>
> > private API in the JSCContext (jscContextAdoptJSCValue(<wbr>JSCValue*)<br>
> > ?). As JSCValues have a JSCContext reference, we can call<br>
> > jscContextAdoptJSCValue in JSCValue's constructed callback. With<br>
> > this private API, JSCContext will get a JSCValue reference and add<br>
> > it to a HashMap that will map the JSValueRef to the JSCValue. When<br>
> > added to the HashMap, JSCValue will be owned by the context and<br>
> > will be freed when the context is unrefed.<br>
> ><br>
> > What do you think about this idea?<br>
> ><br>
> > [1] <a href="https://bugs.webkit.org/show_bug.cgi?id=164061" rel="noreferrer" target="_blank">https://bugs.webkit.org/show_<wbr>bug.cgi?id=164061</a><br>
> > [2] <a href="https://lists.webkit.org/pipermail/jsc-dev/2016-November/000084" rel="noreferrer" target="_blank">https://lists.webkit.org/<wbr>pipermail/jsc-dev/2016-<wbr>November/000084</a><br>
> > .html<br>
> ><br>
> > ______________________________<wbr>_________________<br>
> > webkit-gtk mailing list<br>
> > <a href="mailto:webkit-gtk@lists.webkit.org">webkit-gtk@lists.webkit.org</a><br>
> > <a href="https://lists.webkit.org/mailman/listinfo/webkit-gtk" rel="noreferrer" target="_blank">https://lists.webkit.org/<wbr>mailman/listinfo/webkit-gtk</a><br>
> ><br>
><br>
> ______________________________<wbr>_________________<br>
> webkit-gtk mailing list<br>
> <a href="mailto:webkit-gtk@lists.webkit.org">webkit-gtk@lists.webkit.org</a><br>
> <a href="https://lists.webkit.org/mailman/listinfo/webkit-gtk" rel="noreferrer" target="_blank">https://lists.webkit.org/<wbr>mailman/listinfo/webkit-gtk</a><br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Carlos Garcia Campos<br>
<a href="http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3" rel="noreferrer" target="_blank">http://pgp.rediris.es:11371/<wbr>pks/lookup?op=get&search=<wbr>0xF3D322D0EC4582C3</a></font></span></blockquote></div><br></div></div>