зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d738f7dcea
Коммит
f054d767fb
|
@ -1850,7 +1850,7 @@ js_DestroyScriptsToGC(JSContext *cx, JSCompartment *comp)
|
||||||
while ((script = *listp) != NULL) {
|
while ((script = *listp) != NULL) {
|
||||||
*listp = script->u.nextToGC;
|
*listp = script->u.nextToGC;
|
||||||
script->u.nextToGC = NULL;
|
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 *script = NULL;
|
||||||
JSScript **bucket = EvalCacheHash(cx, linearStr);
|
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);
|
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
|
* 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).
|
* 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) &&
|
cx->runtime->atomState.evalAtom) &&
|
||||||
Execute(cx, scopeobj, script, callerFrame, JSFRAME_EVAL, vp);
|
Execute(cx, scopeobj, script, callerFrame, JSFRAME_EVAL, vp);
|
||||||
|
|
||||||
|
MUST_FLOW_LABEL(destroy);
|
||||||
|
js_CallDestroyScriptHook(cx, script);
|
||||||
|
|
||||||
script->u.nextToGC = *bucket;
|
script->u.nextToGC = *bucket;
|
||||||
*bucket = script;
|
*bucket = script;
|
||||||
#ifdef CHECK_SCRIPT_OWNER
|
#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)
|
js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
|
||||||
{
|
{
|
||||||
JSDestroyScriptHook hook;
|
JSDestroyScriptHook hook;
|
||||||
|
@ -1569,6 +1569,7 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
|
||||||
hook = cx->debugHooks->destroyScriptHook;
|
hook = cx->debugHooks->destroyScriptHook;
|
||||||
if (hook)
|
if (hook)
|
||||||
hook(cx, script, cx->debugHooks->destroyScriptHookData);
|
hook(cx, script, cx->debugHooks->destroyScriptHookData);
|
||||||
|
JS_ClearScriptTraps(cx, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1581,9 +1582,6 @@ DestroyScript(JSContext *cx, JSScript *script)
|
||||||
JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
|
JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
js_CallDestroyScriptHook(cx, script);
|
|
||||||
JS_ClearScriptTraps(cx, script);
|
|
||||||
|
|
||||||
if (script->principals)
|
if (script->principals)
|
||||||
JSPRINCIPALS_DROP(cx, script->principals);
|
JSPRINCIPALS_DROP(cx, script->principals);
|
||||||
|
|
||||||
|
@ -1646,11 +1644,20 @@ void
|
||||||
js_DestroyScript(JSContext *cx, JSScript *script)
|
js_DestroyScript(JSContext *cx, JSScript *script)
|
||||||
{
|
{
|
||||||
JS_ASSERT(!cx->runtime->gcRunning);
|
JS_ASSERT(!cx->runtime->gcRunning);
|
||||||
|
js_CallDestroyScriptHook(cx, script);
|
||||||
DestroyScript(cx, script);
|
DestroyScript(cx, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js_DestroyScriptFromGC(JSContext *cx, JSScript *script)
|
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);
|
JS_ASSERT(cx->runtime->gcRunning);
|
||||||
DestroyScript(cx, script);
|
DestroyScript(cx, script);
|
||||||
|
|
|
@ -649,7 +649,7 @@ js_SweepScriptFilenames(JSRuntime *rt);
|
||||||
extern JS_FRIEND_API(void)
|
extern JS_FRIEND_API(void)
|
||||||
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
|
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
|
||||||
|
|
||||||
extern JS_FRIEND_API(void)
|
extern void
|
||||||
js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
|
js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -659,13 +659,18 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
|
||||||
extern void
|
extern void
|
||||||
js_DestroyScript(JSContext *cx, JSScript *script);
|
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
|
extern void
|
||||||
js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
|
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
|
extern void
|
||||||
js_TraceScript(JSTracer *trc, JSScript *script);
|
js_TraceScript(JSTracer *trc, JSScript *script);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче