Subj : Re: JS_ASSERT in js_MarkScriptFilename() To : Edward Chan From : Brendan Eich Date : Fri Feb 20 2004 12:17 am Edward Chan wrote: >Ok, some more info. After some debugging, I'm getting closer to >understanding what's going on. > >This is what I'm seeing, > >I'm in the process of doing a gc. While enumerating gcRootsHash, > >JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_marker, cx); > >it has found a JSScript object that it is marking. However, when it gets to >js_MarkScript(), script->filename is bad. > >The reason it is bad is because a previous gc, has removed it from >script_filename_table, and freed it. > > Then the script(s) that referenced that filename were not visible the GC activated on that thread's runtime, which says that the pattern of Compile/Execute/DestroyScript you showed can' be all that is going on. >So I have a few questions: > >When filename is removed from script_filename_table, and freed, do you null >out script->filename for all the script objects that are pointing to that >address in memory that was just freed? It seems like this is not the case. > >But shouldn't it be? > > On the contrary: garbage collection means marking live objects reachable from other objects, ultimately from members of the root set. There is no means of "nulling" out otherwise-dangling reference, and no purpose -- the GC is broken if it collects something that live objects still reference. >But if so, how do you know which script objects are pointing to that >filename? I don't see where this is being maintained. > > You are thinking of some kind of weak reference system, with notification when the strong references all go away to clear intermediate weak delegates. The script filename table entries are garbage collected using mark&sweep. The mark phase starts from GC roots and should reach all live scripts. Any scripts not marked will not have their script filename table entries marked, so those entries may be collected if they are not marked via other scripts from the same file. Again, you have to find the unrooted script. Reminder: JS_ExecuteScript roots the executing script from cx->fp->script. /be .