Bug 633016 - Notify debug hooks of script lifetime when pulling script from the eval cache (r=luke)

--HG--
extra : rebase_source : cec97d3ad0bcbad52bda31fb6148ce1e6a1a3b95
This commit is contained in:
Steve Fink 2011-02-11 13:23:18 -08:00
Родитель d738f7dcea
Коммит f054d767fb
4 изменённых файлов: 40 добавлений и 11 удалений

Просмотреть файл

@ -1850,7 +1850,7 @@ js_DestroyScriptsToGC(JSContext *cx, JSCompartment *comp)
while ((script = *listp) != NULL) {
*listp = script->u.nextToGC;
script->u.nextToGC = NULL;
js_DestroyScriptFromGC(cx, script);
js_DestroyCachedScript(cx, script);
}
}
}

Просмотреть файл

@ -1249,9 +1249,23 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
JSScript *script = NULL;
JSScript **bucket = EvalCacheHash(cx, linearStr);
if (evalType == DIRECT_EVAL && caller->isFunctionFrame() && !caller->isEvalFrame())
if (evalType == DIRECT_EVAL && caller->isFunctionFrame() && !caller->isEvalFrame()) {
script = EvalCacheLookup(cx, linearStr, caller, staticLevel, principals, scopeobj, bucket);
/*
* Although the eval cache keeps a script alive from the perspective of
* the JS engine, from a jsdbgapi user's perspective each eval()
* creates and destroys a script. This hides implementation details and
* allows jsdbgapi clients to avoid calling JS_GetScriptObject after a
* script has been returned to the eval cache, which is invalid since
* script->u.object aliases script->u.nextToGC.
*/
if (script) {
js_CallNewScriptHook(cx, script, NULL);
MUST_FLOW_THROUGH("destroy");
}
}
/*
* We can't have a callerFrame (down in js::Execute's terms) if we're in
* global code (or if we're an indirect eval).
@ -1280,6 +1294,9 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
cx->runtime->atomState.evalAtom) &&
Execute(cx, scopeobj, script, callerFrame, JSFRAME_EVAL, vp);
MUST_FLOW_LABEL(destroy);
js_CallDestroyScriptHook(cx, script);
script->u.nextToGC = *bucket;
*bucket = script;
#ifdef CHECK_SCRIPT_OWNER

Просмотреть файл

@ -1561,7 +1561,7 @@ js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
}
}
JS_FRIEND_API(void)
void
js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
{
JSDestroyScriptHook hook;
@ -1569,6 +1569,7 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
hook = cx->debugHooks->destroyScriptHook;
if (hook)
hook(cx, script, cx->debugHooks->destroyScriptHookData);
JS_ClearScriptTraps(cx, script);
}
static void
@ -1581,9 +1582,6 @@ DestroyScript(JSContext *cx, JSScript *script)
JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
#endif
js_CallDestroyScriptHook(cx, script);
JS_ClearScriptTraps(cx, script);
if (script->principals)
JSPRINCIPALS_DROP(cx, script->principals);
@ -1646,11 +1644,20 @@ void
js_DestroyScript(JSContext *cx, JSScript *script)
{
JS_ASSERT(!cx->runtime->gcRunning);
js_CallDestroyScriptHook(cx, script);
DestroyScript(cx, script);
}
void
js_DestroyScriptFromGC(JSContext *cx, JSScript *script)
{
JS_ASSERT(cx->runtime->gcRunning);
js_CallDestroyScriptHook(cx, script);
DestroyScript(cx, script);
}
void
js_DestroyCachedScript(JSContext *cx, JSScript *script)
{
JS_ASSERT(cx->runtime->gcRunning);
DestroyScript(cx, script);

Просмотреть файл

@ -649,7 +649,7 @@ js_SweepScriptFilenames(JSRuntime *rt);
extern JS_FRIEND_API(void)
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
extern JS_FRIEND_API(void)
extern void
js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
/*
@ -659,13 +659,18 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
extern void
js_DestroyScript(JSContext *cx, JSScript *script);
/*
* If data is not null, it indicates that the script could been accessed only
* from that thread.
*/
extern void
js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
/*
* Script objects may be cached and reused, in which case their JSD-visible
* lifetimes may be shorter than their actual lifetimes. Destroy one such
* script for real as part of a GC pass. From JSD's point of view, the script
* is already dead.
*/
extern void
js_DestroyCachedScript(JSContext *cx, JSScript *script);
extern void
js_TraceScript(JSTracer *trc, JSScript *script);