Backout 1b55728f51ad (bug 633016) due to leaking jsdScript objects
authorSteve Fink <sfink@mozilla.com>
Thu, 10 Feb 2011 14:33:10 -0800
changeset 62407 0c7b2e76db077b6e56adc25101c369077c3c19f4
parent 62406 2d60ba7e95a18c18f6b4149e16fc85844abd44a7
child 62408 bc906595cef3b3e19e948b96f8399c861c0b6cb7
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs633016
milestone2.0b12pre
backs out1b55728f51ad6428b1d3ee631eef5f98354b82fc
Backout 1b55728f51ad (bug 633016) due to leaking jsdScript objects
js/src/jsobj.cpp
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1244,33 +1244,19 @@ EvalKernel(JSContext *cx, uintN argc, Va
      * haven't wrapped that yet, do so now, before we make a copy of it for
      * the eval code to use.
      */
     if (evalType == DIRECT_EVAL && !caller->computeThis(cx))
         return false;
 
     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).
      */
     JSStackFrame *callerFrame = (staticLevel != 0) ? caller : NULL;
     if (!script) {
         uintN lineno;
         const char *filename = js_ComputeFilename(cx, caller, principals, &lineno);
@@ -1289,19 +1275,16 @@ EvalKernel(JSContext *cx, uintN argc, Va
     /*
      * Belt-and-braces: check that the lesser of eval's principals and the
      * caller's principals has access to scopeobj.
      */
     JSBool ok = js_CheckPrincipalsAccess(cx, scopeobj, principals,
                                          cx->runtime->atomState.evalAtom) &&
                 Execute(cx, scopeobj, script, callerFrame, JSFRAME_EVAL, vp);
 
-destroy:
-    js_CallDestroyScriptHook(cx, script);
-
     script->u.nextToGC = *bucket;
     *bucket = script;
 #ifdef CHECK_SCRIPT_OWNER
     script->owner = NULL;
 #endif
 
     return ok;
 }
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1556,37 +1556,39 @@ js_CallNewScriptHook(JSContext *cx, JSSc
     hook = cx->debugHooks->newScriptHook;
     if (hook) {
         AutoKeepAtoms keep(cx->runtime);
         hook(cx, script->filename, script->lineno, script, fun,
              cx->debugHooks->newScriptHookData);
     }
 }
 
-void
+JS_FRIEND_API(void)
 js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
 {
     JSDestroyScriptHook hook;
 
     hook = cx->debugHooks->destroyScriptHook;
     if (hook)
         hook(cx, script, cx->debugHooks->destroyScriptHookData);
-    JS_ClearScriptTraps(cx, script);
 }
 
 static void
 DestroyScript(JSContext *cx, JSScript *script)
 {
 #ifdef DEBUG
     if (script->isEmpty())
         JS_RUNTIME_UNMETER(cx->runtime, liveEmptyScripts);
     else
         JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
 #endif
 
+    js_CallDestroyScriptHook(cx, script);
+    JS_ClearScriptTraps(cx, script);
+
     if (script->principals)
         JSPRINCIPALS_DROP(cx, script->principals);
 
     if (JS_GSN_CACHE(cx).code == script->code)
         JS_PURGE_GSN_CACHE(cx);
 
     /*
      * Worry about purging the property cache and any compiled traces related
@@ -1639,17 +1641,16 @@ DestroyScript(JSContext *cx, JSScript *s
 
     cx->free(script);
 }
 
 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);
     DestroyScript(cx, script);
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -644,17 +644,17 @@ js_SweepScriptFilenames(JSRuntime *rt);
  * New-script-hook calling is factored from js_NewScriptFromCG so that it
  * and callers of js_XDRScript can share this code.  In the case of callers
  * of js_XDRScript, the hook should be invoked only after successful decode
  * of any owning function (the fun parameter) or script object (null fun).
  */
 extern JS_FRIEND_API(void)
 js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
 
-extern void
+extern JS_FRIEND_API(void)
 js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
 
 /*
  * The function must be used only outside the GC for a script that was run
  * only on the current thread.
  */
 extern void
 js_DestroyScript(JSContext *cx, JSScript *script);