Bug 756267 - Move the internal logic to only call script destroy hook if create hook was called from inside the JS engine to JSD, and add a flag for controlling it. r=jorendorff
authorSteve Fink <sfink@mozilla.com>
Fri, 17 Aug 2012 10:23:21 -0700
changeset 108135 85698a1c20cb77aaa9e791beb4ff8212f716d649
parent 108134 d7d6e90e2580486b0d95d6ac76ee2cbb2b6d0868
child 108136 bbb5e18e6c0a8a99e4e0e6b0f7e74b0dd9fda436
push id1490
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 18:29:50 +0000
treeherdermozilla-beta@f335e7dacdc1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs756267
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 756267 - Move the internal logic to only call script destroy hook if create hook was called from inside the JS engine to JSD, and add a flag for controlling it. r=jorendorff
js/jsd/idl/jsdIDebuggerService.idl
js/jsd/jsd_scpt.c
js/jsd/jsdebug.h
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/jsd/idl/jsdIDebuggerService.idl
+++ b/js/jsd/idl/jsdIDebuggerService.idl
@@ -843,17 +843,17 @@ interface jsdIStackFrame : jsdIEphemeral
                  in unsigned long line, out jsdIValue result);
     
 };
 
 /**
  * Script object. In JavaScript engine terms, there's a single script for each
  * function, and one for the top level script.
  */
-[scriptable, uuid(721724e0-7716-4bf4-b48f-92b78d056141)]
+[scriptable, uuid(8ce9b2a2-cc33-48a8-9f47-8696186ed9a5)]
 interface jsdIScript : jsdIEphemeral
 {
     /** Internal use only. */
     [noscript] readonly attribute JSDContext JSDContext;
     /** Internal use only. */
     [noscript] readonly attribute JSDScript  JSDScript;
     
     /**
@@ -879,16 +879,22 @@ interface jsdIScript : jsdIEphemeral
      * script. The context flag FLAG_PROFILE_WHEN_SET decides the logic.
      */
     const unsigned long FLAG_PROFILE = 0x01;
     /**
      * Determines whether or not to ignore breakpoints, etc. in this script.
      * The context flag JSD_DEBUG_WHEN_SET decides the logic.
      */
     const unsigned long FLAG_DEBUG   = 0x02;
+    /**
+     * Determines whether to invoke the onScriptDestroy callback for this
+     * script. The default is for this to be true if the onScriptCreated
+     * callback was invoked for this script.
+     */
+    const unsigned long FLAG_CALL_DESTROY_HOOK = 0x04;
     
     /**
      * FLAG_* attributes from above, OR'd together.
      */
     attribute unsigned long flags;
 
     /**
      * Filename given for this script when it was compiled.
--- a/js/jsd/jsd_scpt.c
+++ b/js/jsd/jsd_scpt.c
@@ -657,16 +657,18 @@ jsd_NewScriptHookProc(
     _dumpJSDScript(jsdc, jsdscript, "***NEW Script: ");
     _dumpJSDScriptList( jsdc );
     JSD_UNLOCK_SCRIPTS(jsdc);
 #endif /* JSD_DUMP */
 
     /* local in case jsdc->scriptHook gets cleared on another thread */
     JSD_LOCK();
     hook = jsdc->scriptHook;
+    if( hook )
+        jsdscript->flags = jsdscript->flags | JSD_SCRIPT_CALL_DESTROY_HOOK_BIT;
     hookData = jsdc->scriptHookData;
     JSD_UNLOCK();
 
     if( hook )
         hook(jsdc, jsdscript, JS_TRUE, hookData);
 }
 
 void
@@ -695,17 +697,17 @@ jsd_DestroyScriptHookProc(
 #ifdef JSD_DUMP
     JSD_LOCK_SCRIPTS(jsdc);
     _dumpJSDScript(jsdc, jsdscript, "***DESTROY Script: ");
     JSD_UNLOCK_SCRIPTS(jsdc);
 #endif /* JSD_DUMP */
 
     /* local in case hook gets cleared on another thread */
     JSD_LOCK();
-    hook = jsdc->scriptHook;
+    hook = (jsdscript->flags & JSD_SCRIPT_CALL_DESTROY_HOOK_BIT) ? jsdc->scriptHook : NULL;
     hookData = jsdc->scriptHookData;
     JSD_UNLOCK();
 
     if( hook )
         hook(jsdc, jsdscript, JS_FALSE, hookData);
 
     JSD_LOCK_SCRIPTS(jsdc);
     JS_HashTableRemove(jsdc->scriptsTable, (void *)script);
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -366,16 +366,22 @@ JSD_GetJSFunction(JSDContext* jsdc, JSDS
 * script.  The context flag JSD_PROFILE_WHEN_SET decides the logic.
 */
 #define JSD_SCRIPT_PROFILE_BIT 0x01
 /*
 * Determines whether or not to ignore breakpoints, etc. in this script.
 * The context flag JSD_DEBUG_WHEN_SET decides the logic.
 */
 #define JSD_SCRIPT_DEBUG_BIT   0x02
+/*
+ * Determines whether to invoke the onScriptDestroy callback for this
+ * script. The default is for this to be true if the onScriptCreated
+ * callback was invoked for this script.
+ */
+#define JSD_SCRIPT_CALL_DESTROY_HOOK_BIT 0x04
 
 extern JSD_PUBLIC_API(uint32_t)
 JSD_GetScriptFlags(JSDContext *jsdc, JSDScript* jsdscript);
 
 extern JSD_PUBLIC_API(void)
 JSD_SetScriptFlags(JSDContext *jsdc, JSDScript* jsdscript, uint32_t flags);
 
 /*
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1757,35 +1757,29 @@ JSScript::enclosingScriptsCompiledSucces
         }
     }
     return true;
 }
 
 JS_FRIEND_API(void)
 js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
 {
-    JS_ASSERT(!script->callDestroyHook);
     JS_ASSERT(!script->isActiveEval);
     if (JSNewScriptHook hook = cx->runtime->debugHooks.newScriptHook) {
         AutoKeepAtoms keep(cx->runtime);
         hook(cx, script->filename, script->lineno, script, fun,
              cx->runtime->debugHooks.newScriptHookData);
     }
-    script->callDestroyHook = true;
 }
 
 void
 js::CallDestroyScriptHook(FreeOp *fop, JSScript *script)
 {
-    if (!script->callDestroyHook)
-        return;
-
     if (JSDestroyScriptHook hook = fop->runtime()->debugHooks.destroyScriptHook)
         hook(fop, script, fop->runtime()->debugHooks.destroyScriptHookData);
-    script->callDestroyHook = false;
     script->clearTraps(fop);
 }
 
 void
 JSScript::finalize(FreeOp *fop)
 {
     // NOTE: this JSScript may be partially initialized at this point.  E.g. we
     // may have created it and partially initialized it with
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -462,17 +462,16 @@ struct JSScript : public js::gc::Cell
     bool            hasSingletons:1;  /* script has singleton objects */
     bool            isActiveEval:1;   /* script came from eval(), and is still active */
     bool            isCachedEval:1;   /* script came from eval(), and is in eval cache */
     bool            uninlineable:1;   /* script is considered uninlineable by analysis */
 #ifdef JS_METHODJIT
     bool            debugMode:1;      /* script was compiled in debug mode */
     bool            failedBoundsCheck:1; /* script has had hoisted bounds checks fail */
 #endif
-    bool            callDestroyHook:1;/* need to call destroy hook */
     bool            isGenerator:1;    /* is a generator */
     bool            isGeneratorExp:1; /* is a generator expression */
     bool            hasScriptCounts:1;/* script has an entry in
                                          JSCompartment::scriptCountsMap */
     bool            hasDebugScript:1; /* script has an entry in
                                          JSCompartment::debugScriptMap */
   private:
     /* See comments below. */