Bug 534120. When jsd is paused unhook as much as we can, so we don't interfere with the jit. r=timeless, jorendorff.
authorBoris Zbarsky <bzbarsky@mit.edu>
Sat, 12 Dec 2009 13:35:04 -0800
changeset 35647 119c8036630f15cb4c9bbc051fa9a59e25e742c8
parent 35646 a59c83eda97b21d137aa9c941477189462e53fc8
child 35648 e12ccfe8c5a7cceace95fba2c7c8c467e0d6f43f
push id10660
push userbzbarsky@mozilla.com
push dateSat, 12 Dec 2009 21:38:18 +0000
treeherdermozilla-central@119c8036630f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstimeless, jorendorff
bugs534120
milestone1.9.3a1pre
Bug 534120. When jsd is paused unhook as much as we can, so we don't interfere with the jit. r=timeless, jorendorff.
js/jsd/jsd.h
js/jsd/jsd_high.c
js/jsd/jsd_xpc.cpp
js/jsd/jsdebug.c
js/jsd/jsdebug.h
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -343,16 +343,22 @@ jsd_DebuggerOnForUser(JSRuntime*        
                       void*              user);
 extern JSDContext*
 jsd_DebuggerOn(void);
 
 extern void
 jsd_DebuggerOff(JSDContext* jsdc);
 
 extern void
+jsd_DebuggerPause(JSDContext* jsdc, JSBool forceAllHooksOff);
+
+extern void
+jsd_DebuggerUnpause(JSDContext* jsdc);
+
+extern void
 jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user);
 
 extern JSDContext*
 jsd_JSDContextForJSContext(JSContext* context);
 
 extern void*
 jsd_SetContextPrivate(JSDContext* jsdc, void *data);
 
--- a/js/jsd/jsd_high.c
+++ b/js/jsd/jsd_high.c
@@ -198,25 +198,29 @@ jsd_DebuggerOnForUser(JSRuntime*        
 {
     JSDContext* jsdc;
     JSContext* iter = NULL;
 
     jsdc = _newJSDContext(jsrt, callbacks, user);
     if( ! jsdc )
         return NULL;
 
-    /* set hooks here */
+    /*
+     * Set hooks here.  The new/destroy script hooks are on even when
+     * the debugger is paused.  The destroy hook so we'll clean up
+     * internal data structures when scripts are destroyed, and the
+     * newscript hook for backwards compatibility for now.  We'd like
+     * to stop doing that.
+     */
     JS_SetNewScriptHookProc(jsdc->jsrt, jsd_NewScriptHookProc, jsdc);
     JS_SetDestroyScriptHookProc(jsdc->jsrt, jsd_DestroyScriptHookProc, jsdc);
-    JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
-    JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
-    JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
-    JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
-    JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
-    JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
+    jsd_DebuggerUnpause(jsdc);
+    if (!(jsdc->flags & JSD_DISABLE_OBJECT_TRACE)) {
+        JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
+    }
 #ifdef LIVEWIRE
     LWDBG_SetNewScriptHookProc(jsd_NewScriptHookProc, jsdc);
 #endif
     if( jsdc->userCallbacks.setContext )
         jsdc->userCallbacks.setContext(jsdc, jsdc->user);
     return jsdc;
 }
 
@@ -226,25 +230,23 @@ jsd_DebuggerOn(void)
     JS_ASSERT(_jsrt);
     JS_ASSERT(_validateUserCallbacks(&_callbacks));
     return jsd_DebuggerOnForUser(_jsrt, &_callbacks, _user);
 }
 
 void
 jsd_DebuggerOff(JSDContext* jsdc)
 {
+    jsd_DebuggerPause(jsdc, JS_TRUE);
     /* clear hooks here */
     JS_SetNewScriptHookProc(jsdc->jsrt, NULL, NULL);
     JS_SetDestroyScriptHookProc(jsdc->jsrt, NULL, NULL);
-    JS_SetDebuggerHandler(jsdc->jsrt, NULL, NULL);
-    JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
-    JS_SetCallHook(jsdc->jsrt, NULL, NULL);
+    /* Have to unset these too, since jsd_DebuggerPause only unsets
+       them conditionally */
     JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
-    JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
-    JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
 #ifdef LIVEWIRE
     LWDBG_SetNewScriptHookProc(NULL,NULL);
 #endif
 
     /* clean up */
     JSD_LockScriptSubsystem(jsdc);
     jsd_DestroyScriptManager(jsdc);
     JSD_UnlockScriptSubsystem(jsdc);
@@ -252,16 +254,40 @@ jsd_DebuggerOff(JSDContext* jsdc)
     
     _destroyJSDContext(jsdc);
 
     if( jsdc->userCallbacks.setContext )
         jsdc->userCallbacks.setContext(NULL, jsdc->user);
 }
 
 void
+jsd_DebuggerPause(JSDContext* jsdc, JSBool forceAllHooksOff)
+{
+    JS_SetDebuggerHandler(jsdc->jsrt, NULL, NULL);
+    if (forceAllHooksOff ||
+        (!(jsdc->flags & JSD_COLLECT_PROFILE_DATA) &&
+         (jsdc->flags & JSD_DISABLE_OBJECT_TRACE))) {
+        JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
+        JS_SetCallHook(jsdc->jsrt, NULL, NULL);
+    }
+    JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
+    JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
+}
+
+void
+jsd_DebuggerUnpause(JSDContext* jsdc)
+{
+    JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
+    JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
+    JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
+    JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
+    JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
+}
+
+void
 jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user)
 {
     _jsrt = jsrt;
     _user = user;
 
 #ifdef JSD_HAS_DANGEROUS_THREAD
     _dangerousThread = JSD_CURRENT_THREAD();
 #endif
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -2651,16 +2651,17 @@ jsdService::Pause(PRUint32 *_rval)
     if (++mPauseLevel == 1) {
         JSD_SetErrorReporter (mCx, NULL, NULL);
         JSD_ClearThrowHook (mCx);
         JSD_ClearInterruptHook (mCx);
         JSD_ClearDebuggerHook (mCx);
         JSD_ClearDebugBreakHook (mCx);
         JSD_ClearTopLevelHook (mCx);
         JSD_ClearFunctionHook (mCx);
+        JSD_DebuggerPause (mCx);
     }
 
     if (_rval)
         *_rval = mPauseLevel;
 
     return NS_OK;
 }
 
@@ -2672,16 +2673,17 @@ jsdService::UnPause(PRUint32 *_rval)
 
     if (mPauseLevel == 0)
         return NS_ERROR_NOT_AVAILABLE;
 
     /* check mOn before we muck with this stuff, it's possible the debugger
      * was turned off while we were paused.
      */
     if (--mPauseLevel == 0 && mOn) {
+        JSD_DebuggerUnpause (mCx);
         if (mErrorHook)
             JSD_SetErrorReporter (mCx, jsds_ErrorHookProc, NULL);
         if (mThrowHook)
             JSD_SetThrowHook (mCx, jsds_ExecutionHookProc, NULL);
         if (mInterruptHook)
             JSD_SetInterruptHook (mCx, jsds_ExecutionHookProc, NULL);
         if (mDebuggerHook)
             JSD_SetDebuggerHook (mCx, jsds_ExecutionHookProc, NULL);
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -60,16 +60,29 @@ JSD_DebuggerOn(void)
 
 JSD_PUBLIC_API(void)
 JSD_DebuggerOff(JSDContext* jsdc)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsd_DebuggerOff(jsdc);
 }
 
+JSD_PUBLIC_API(void)
+JSD_DebuggerPause(JSDContext* jsdc)
+{
+    JSD_ASSERT_VALID_CONTEXT(jsdc);
+    jsd_DebuggerPause(jsdc, JS_FALSE);
+}
+
+JSD_PUBLIC_API(void)
+JSD_DebuggerUnpause(JSDContext* jsdc)
+{
+    JSD_ASSERT_VALID_CONTEXT(jsdc);
+    jsd_DebuggerUnpause(jsdc);
+}
 
 JSD_PUBLIC_API(uintN)
 JSD_GetMajorVersion(void)
 {
     return JSD_MAJOR_VERSION;
 }
 
 JSD_PUBLIC_API(uintN)
@@ -118,17 +131,35 @@ JSD_ClearAllProfileData(JSDContext *jsdc
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsd_ClearAllProfileData(jsdc);    
 }
 
 JSD_PUBLIC_API(void)
 JSD_SetContextFlags(JSDContext *jsdc, uint32 flags)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
+    uint32 oldFlags = jsdc->flags;
     jsdc->flags = flags;
+    if ((flags & JSD_COLLECT_PROFILE_DATA) ||
+        !(flags & JSD_DISABLE_OBJECT_TRACE)) {
+        // Need to reenable our call hooks now
+        JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
+        JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
+    }
+    if ((oldFlags ^ flags) & JSD_DISABLE_OBJECT_TRACE) {
+        // Changing our JSD_DISABLE_OBJECT_TRACE flag
+        if (!(flags & JSD_DISABLE_OBJECT_TRACE)) {
+            // Need to reenable our object hooks now
+            if (jsd_InitObjectManager(jsdc))
+                JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
+        } else {
+            jsd_DestroyObjectManager(jsdc);
+            JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
+        }
+    }
 }
 
 JSD_PUBLIC_API(uint32)
 JSD_GetContextFlags(JSDContext *jsdc)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     return jsdc->flags;
 }
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -146,16 +146,28 @@ JSD_DebuggerOnForUser(JSRuntime*        
 
 /*
 * Shutdown JSD for this JSDContext
 */
 extern JSD_PUBLIC_API(void)
 JSD_DebuggerOff(JSDContext* jsdc);
 
 /*
+ * Pause JSD for this JSDContext
+ */
+extern JSD_PUBLIC_API(void)
+JSD_DebuggerPause(JSDContext* jsdc);
+
+/*
+ * Unpause JSD for this JSDContext
+ */
+extern JSD_PUBLIC_API(void)
+JSD_DebuggerUnpause(JSDContext* jsdc);
+
+/*
 * Get the Major Version (initial JSD release used major version = 1)
 */
 extern JSD_PUBLIC_API(uintN)
 JSD_GetMajorVersion(void);
 
 /*
 * Get the Minor Version (initial JSD release used minor version = 0)
 */