Bug 534120. When jsd is paused unhook as much as we can, so we don't interfere with the jit. r=timeless, jorendorff.
--- 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)
*/