Subj : Re: JS_GetArrayLength() crashing (garbage collection issue) To : netscape.public.mozilla.jseng From : smaraux Date : Mon Feb 28 2005 02:42 am Brendan Eich wrote in message news:<421F7392.3050606@meer.net>... > > A children is typically added with > > JSObject *localObj = JSConstructObject(...my objectClass...); > > JS_AddRoot(context, &localObj); > > jsval localVal = OBJECT_TO_JSVAL(localObj); > > JS_SetElement(Context, pDataHolder, (jsint) u4Index, &localVal ); > > > > But (I guess that) as it is local, localObj is being deleted, causing > > a bit later a JS_GC call to crash. > > > Don't guess, and don't root unnecessarily. If pDataHolder is rooted or > well-connected, you shouldn't need to root localObj above. Have you > read http://www.mozilla.org/js/spidermonkey/gctips.html yet? > > How is pDataHolder protected from GC? > > /be I have two differents cases (sort of VRML / MPEG4 script). - in both cases list of children is in the attached object private struct. So there is no direct JS link between JS parent and children objects. Is there a cleaner way I could do this ? JSObject* mainArrayObject (JS_NewObject/JS_ConstructObject) + -> private data (struct) + -> JSObject* children (JS_NewArrayObject). + -> equivalent data in VRML way. each child being: JSObject* childObject (JS_NewObject/JS_ConstructObject) + -> private data (struct) + -> equivalent data in VRML way. - Some arrays are kind of "global", they must not be erased before end of script. I declare them as properties, with JS_DefineUCProperty, so that jsval corresponds to the main array object. - some arrays are local then they are not rooted. They must be deleted with their children at each call to GC (equivalent to a function wide variable, GC being called after each function call). Moreover, jsvals/objects defined with JS_DefineUCProperty leads to memoryleaks : destructor of attached object is never called, even at JS_DestroyContext. How can I delete them ? I currently solved my first issue by keeping a reference of jsval to each child object. This allow me to removeRoot on it when children are finalized. This is not very clean, as parent object does not handle children deletion, GC does. If I could avoid calling addRoot on each child, but linking it to its parent, it would be more efficient, but I don't know how to do this. I have read GC Tips, but I did not catch everything. In my case I am not sure I need local roots, as my only rooted values would live as long as the script itself. .