diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index b9bcb097d7b0..95a258da79c9 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -98,6 +98,12 @@ JSCompartment::JSCompartment(JSRuntime *rt) JSCompartment::~JSCompartment() { + /* + * Even though all objects in the compartment are dead, we may have keep + * some filenames around because of gcKeepAtoms. + */ + FreeScriptFilenames(this); + #ifdef JS_METHODJIT Foreground::delete_(jaegerCompartment_); #endif diff --git a/js/src/jsexn.cpp b/js/src/jsexn.cpp index 95a50473eab7..15ae495b2200 100644 --- a/js/src/jsexn.cpp +++ b/js/src/jsexn.cpp @@ -463,7 +463,7 @@ exn_trace(JSTracer *trc, JSObject *obj) if (elem->funName) MarkString(trc, &elem->funName, "stack trace function name"); if (IS_GC_MARKING_TRACER(trc) && elem->filename) - js_MarkScriptFilename(elem->filename); + MarkScriptFilename(elem->filename); vcount += elem->argc; } vp = GetStackTraceValueBuffer(priv); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 232038af67ac..7ee955296a9e 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3252,7 +3252,7 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind) * script's filename. See bug 323267. */ for (GCCompartmentsIter c(rt); !c.done(); c.next()) - js_SweepScriptFilenames(c); + SweepScriptFilenames(c); /* * This removes compartments from rt->compartment, so we do it last to make diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 4f42e46d8160..84bc3d2e869b 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -886,8 +886,6 @@ SaveScriptFilename(JSContext *cx, const char *filename) return sfe->filename; } -} /* namespace js */ - /* * Back up from a saved filename by its offset within its hash table entry. */ @@ -895,14 +893,14 @@ SaveScriptFilename(JSContext *cx, const char *filename) ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename))) void -js_MarkScriptFilename(const char *filename) +MarkScriptFilename(const char *filename) { ScriptFilenameEntry *sfe = FILENAME_TO_SFE(filename); sfe->marked = true; } void -js_SweepScriptFilenames(JSCompartment *comp) +SweepScriptFilenames(JSCompartment *comp) { ScriptFilenameTable &table = comp->scriptFilenameTable; for (ScriptFilenameTable::Enum e(table); !e.empty(); e.popFront()) { @@ -916,6 +914,18 @@ js_SweepScriptFilenames(JSCompartment *comp) } } +void +FreeScriptFilenames(JSCompartment *comp) +{ + ScriptFilenameTable &table = comp->scriptFilenameTable; + for (ScriptFilenameTable::Enum e(table); !e.empty(); e.popFront()) + Foreground::free_(e.front()); + + table.clear(); +} + +} /* namespace js */ + /* * JSScript data structures memory alignment: * @@ -1888,7 +1898,7 @@ JSScript::markChildren(JSTracer *trc) MarkObject(trc, &globalObject, "object"); if (IS_GC_MARKING_TRACER(trc) && filename) - js_MarkScriptFilename(filename); + MarkScriptFilename(filename); bindings.trace(trc); diff --git a/js/src/jsscript.h b/js/src/jsscript.h index deccce65b90a..a0a7e5778f5b 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -793,12 +793,6 @@ StackDepth(JSScript *script) return script->nslots - script->nfixed; } -extern void -js_MarkScriptFilename(const char *filename); - -extern void -js_SweepScriptFilenames(JSCompartment *comp); - /* * New-script-hook calling is factored from NewScriptFromEmitter so that it * and callers of XDRScript can share this code. In the case of callers @@ -813,6 +807,15 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script); namespace js { +extern void +MarkScriptFilename(const char *filename); + +extern void +SweepScriptFilenames(JSCompartment *comp); + +extern void +FreeScriptFilenames(JSCompartment *comp); + struct ScriptOpcodeCountsPair { JSScript *script;