Subj : Re: JS_ASSERT in js_MarkScriptFilename() To : Edward Chan From : Brendan Eich Date : Fri Feb 20 2004 08:04 pm Edward Chan wrote: >Sorry for my previous post. Regarding (2) and (3), I now understand what the >mark and sweep is doing. But I'm still not sure about (1). > > sfe->mark is overlaid on he->value, which is set to NULL by the actual argument passed to JS_HashTableRawAdd. The assertion is just checking that NULL == 0 (== JS_FALSE). >And I'm still not sure when the script objects (that js engine is creating) >are unrooted. > Not every live object must be rooted. Every live object must be reachable from one or more roots. Also, the engine makes script data structures (JSScripts), which are not objects (JSObjects), and not owned by objects. A JSScript is a manually allocated data structure. If you use the JS API to make one, it's up to you to call JS_DestoryScript on it. If you hand off ownership of one that you create to a script object, then you must not call JS_DestroyScript -- the script object's finalizer will do that for you when the object is GC'd. > Because unless "all" the script objects are unrooted at the >end (whatever "end" means, perhaps JS_DestroyScript?), the second one is >unrooted the ScriptFilenameEntry in the script_filename_table will be >unmarked and deleted. So when the other scripts try to mark it, it will be >accessing deleted memory. Am I starting to understand the way gc is >working, or am I still way off? > > You're still off. The GC works in two phases. The mark phase does no "unrooting", so nothing changes then. The sweep phase is collecting only garbage, so what it destroys should not be reachable from any root, or from any other live data structure. >Sorry for all this confusion. > You don't need to call JS_NewScriptObject, JS_AddRoot, or JS_RemoveRoot. Again, JS_ExecuteScript protects its script parameter by rooting it from cx->fp->script (a root-by-definition that the GC scans). When you see the script->filename still valid for the last time, is the GC running? Is this the same GC run that then finds that script's filename member pointing at freed memory later (during the sweep phase)? You can test the rt->gcNumber member to see which GC occurrence is running. /be .