Bug 578159: remove object allocation debug hook. (r=gal, sr=brendan)
authorPaul Biggar <pbiggar@mozilla.com>
Fri, 23 Jul 2010 19:33:49 -0700
changeset 48556 0126fbed203674f70c4c2c15600d8595d41f0ed1
parent 48555 0a242b1501168ef0f40aa903b212e3bd0a8613f9
child 48557 943de0cf6f0acf50fad4e93960a0afc15f86afeb
push idunknown
push userunknown
push dateunknown
reviewersgal, brendan
bugs578159
milestone2.0b2pre
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 578159: remove object allocation debug hook. (r=gal, sr=brendan)
js/jsd/idl/jsdIDebuggerService.idl
js/jsd/jsd.h
js/jsd/jsd_high.c
js/jsd/jsd_obj.c
js/jsd/jsd_step.c
js/jsd/jsd_xpc.cpp
js/jsd/jsdebug.c
js/jsd/jsdebug.h
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsgc.cpp
js/src/jsobjinlines.h
js/src/jsprvtd.h
--- a/js/jsd/idl/jsdIDebuggerService.idl
+++ b/js/jsd/idl/jsdIDebuggerService.idl
@@ -181,21 +181,21 @@ interface jsdIDebuggerService : nsISuppo
      * been TYPE_INTERRUPTED or TYPE_THROW.  TYPE_BREAKPOINT,
      * TYPE_DEBUG_REQUESTED, and TYPE_DEBUGGER_KEYWORD always stop, regardless
      * of this setting, as long as the top frame is not disabled.
      *
      * If HIDE_DISABLED_FRAMES is set, this is effectively set as well.
      */
     const unsigned long MASK_TOP_FRAME_ONLY     = 0x20;
     /**
-     * When this flag is set, object creation will not be tracked.  This will
-     * reduce the performance price you pay by enabling the debugger.
+     * This flag has been retired, do not re-use. It previously provided a hook
+     * for object allocation.
      */
-    const unsigned long DISABLE_OBJECT_TRACE = 0x40;
-    
+    const unsigned long DISABLE_OBJECT_TRACE_RETIRED = 0x40;
+
     /**
      * Debugger service flags.
      */
     attribute unsigned long flags;
     
     /**
      * Major version number of implementation.
      */
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -1040,19 +1040,16 @@ jsd_InitObjectManager(JSDContext* jsdc);
 
 extern void
 jsd_DestroyObjectManager(JSDContext* jsdc);
 
 extern void
 jsd_DestroyObjects(JSDContext* jsdc);
 
 extern void
-jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
-
-extern void
 jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
                  JSStackFrame *fp);
 
 extern JSDObject*
 jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp);
 
 extern JSObject*
 jsd_GetWrappedObject(JSDContext* jsdc, JSDObject* jsdobj);
--- a/js/jsd/jsd_high.c
+++ b/js/jsd/jsd_high.c
@@ -208,19 +208,16 @@ jsd_DebuggerOnForUser(JSRuntime*        
      * 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);
     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;
 }
 
@@ -234,19 +231,16 @@ jsd_DebuggerOn(void)
 
 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);
-    /* Have to unset these too, since jsd_DebuggerPause only unsets
-       them conditionally */
-    JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
 #ifdef LIVEWIRE
     LWDBG_SetNewScriptHookProc(NULL,NULL);
 #endif
 
     /* clean up */
     JSD_LockScriptSubsystem(jsdc);
     jsd_DestroyScriptManager(jsdc);
     JSD_UnlockScriptSubsystem(jsdc);
@@ -257,19 +251,17 @@ jsd_DebuggerOff(JSDContext* 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))) {
+    if (forceAllHooksOff || !(jsdc->flags & JSD_COLLECT_PROFILE_DATA)) {
         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
--- a/js/jsd/jsd_obj.c
+++ b/js/jsd/jsd_obj.c
@@ -123,72 +123,21 @@ static JSDObject*
 
     jsdobj = (JSDObject*) calloc(1, sizeof(JSDObject));
     if (jsdobj)
     {
         JS_INIT_CLIST(&jsdobj->links);
         JS_APPEND_LINK(&jsdobj->links, &jsdc->objectsList);
         jsdobj->obj = obj;
         JS_HashTableAdd(jsdc->objectsTable, obj, jsdobj);
-
-        if (jsdc->flags & JSD_DISABLE_OBJECT_TRACE)
-            return jsdobj;
-        
-        /* walk the stack to find js frame (if any) causing creation */
-        while (NULL != (fp = JS_FrameIterator(cx, &iter)))
-        {
-            if( !JS_IsNativeFrame(cx, fp) )
-            {
-                JSScript* script = JS_GetFrameScript(cx, fp);
-                if( !script )
-                    continue;
-
-                newURL = JS_GetScriptFilename(cx, script);
-                if( newURL )
-                    jsdobj->newURL = jsd_AddAtom(jsdc, newURL);
-
-                pc = JS_GetFramePC(cx, fp);
-                if( pc )
-                    jsdobj->newLineno = JS_PCToLineNumber(cx, script, pc);
-
-                break;
-            }
-        }
     }
     return jsdobj;
 }
 
 void
-jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure)
-{
-    JSDObject* jsdobj;
-    JSDContext* jsdc = (JSDContext*) closure;
-
-    if( ! jsdc || ! jsdc->inited )
-        return;
-
-    JSD_LOCK_OBJECTS(jsdc);
-    if(isNew)
-    {
-        jsdobj = _createJSDObject(jsdc, cx, obj);
-        TRACEOBJ(jsdc, jsdobj, 0);
-    }
-    else
-    {
-        jsdobj = jsd_GetJSDObjectForJSObject(jsdc, obj);
-        if( jsdobj )
-        {
-            TRACEOBJ(jsdc, jsdobj, 1);
-            _destroyJSDObject(jsdc, jsdobj);
-        }
-    }
-    JSD_UNLOCK_OBJECTS(jsdc);
-}
-
-void
 jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
                  JSStackFrame *fp)
 {
     JSDObject* jsdobj;
     JSScript* script;
     JSDScript* jsdscript;
     const char* ctorURL;
     const char* ctorName;
--- a/js/jsd/jsd_step.c
+++ b/js/jsd/jsd_step.c
@@ -114,22 +114,20 @@ JSBool
 {
     JSDScript*        jsdscript;
     JSScript*         jsscript;
     JSBool            hookresult = JS_TRUE;
     
     if (!jsdc || !jsdc->inited)
         return JS_FALSE;
 
-    if (!hook && !(jsdc->flags & JSD_COLLECT_PROFILE_DATA) &&
-        jsdc->flags & JSD_DISABLE_OBJECT_TRACE)
+    if (!hook && !(jsdc->flags & JSD_COLLECT_PROFILE_DATA))
     {
-        /* no hook to call, no profile data needs to be collected, and
-         * the client has object tracing disabled, so there is nothing
-         * to do here.
+        /* no hook to call, no profile data needs to be collected,
+         * so there is nothing to do here.
          */
         return hookresult;
     }
     
     if (before && JS_IsConstructorFrame(cx, fp))
         jsd_Constructing(jsdc, cx, JS_GetFrameThis(cx, fp), fp);
 
     jsscript = JS_GetFrameScript(cx, fp);
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -3275,17 +3275,17 @@ jsdASObserver::Observe (nsISupports *aSu
     rts->GetRuntime (&rt);
     if (NS_FAILED(rv))
         return rv;
 
     rv = jsds->OnForRuntime(rt);
     if (NS_FAILED(rv))
         return rv;
     
-    return jsds->SetFlags(JSD_DISABLE_OBJECT_TRACE);
+    return NS_OK;
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(jsdASObserver)
 NS_DEFINE_NAMED_CID(JSDSERVICE_CID);
 NS_DEFINE_NAMED_CID(JSDASO_CID);
 
 static const mozilla::Module::CIDEntry kJSDCIDs[] = {
     { &kJSDSERVICE_CID, false, NULL, jsdServiceConstructor },
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -133,32 +133,21 @@ JSD_ClearAllProfileData(JSDContext *jsdc
 }
 
 JSD_PUBLIC_API(void)
 JSD_SetContextFlags(JSDContext *jsdc, uint32 flags)
 {
     uint32 oldFlags = jsdc->flags;
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsdc->flags = flags;
-    if ((flags & JSD_COLLECT_PROFILE_DATA) ||
-        !(flags & JSD_DISABLE_OBJECT_TRACE)) {
+    if (flags & JSD_COLLECT_PROFILE_DATA) {
         /* 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 */
-            JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
-        } else {
-            jsd_DestroyObjects(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
@@ -235,21 +235,22 @@ JSD_ClearAllProfileData(JSDContext* jsdc
 * This only applies when the reason for calling the hook would have
 * been JSD_HOOK_INTERRUPTED or JSD_HOOK_THROW.  JSD_HOOK_BREAKPOINT,
 * JSD_HOOK_DEBUG_REQUESTED, and JSD_HOOK_DEBUGGER_KEYWORD always stop,
 * regardless of this setting, as long as the top frame is not disabled.
 *
 * If JSD_HIDE_DISABLED_FRAMES is set, this is effectively set as well.
 */
 #define JSD_MASK_TOP_FRAME_ONLY   0x20
+
 /*
-* When this flag is set, object creation will not be tracked.  This will
-* reduce the performance price you pay by enabling the debugger.
+* 0x40 was formerly used to hook into object creation.
 */
-#define JSD_DISABLE_OBJECT_TRACE  0x40
+#define JSD_DISABLE_OBJECT_TRACE_RETIRED 0x40
+
 
 extern JSD_PUBLIC_API(void)
 JSD_SetContextFlags (JSDContext* jsdc, uint32 flags);
 
 extern JSD_PUBLIC_API(uint32)
 JSD_GetContextFlags (JSDContext* jsdc);     
 
 /*
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1326,18 +1326,17 @@ struct JSRuntime {
 
     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
     JSDebugHooks        globalDebugHooks;
 
 #ifdef JS_TRACER
     /* True if any debug hooks not supported by the JIT are enabled. */
     bool debuggerInhibitsJIT() const {
         return (globalDebugHooks.interruptHook ||
-                globalDebugHooks.callHook ||
-                globalDebugHooks.objectHook);
+                globalDebugHooks.callHook);
     }
 #endif
 
     /* More debugging state, see jsdbgapi.c. */
     JSCList             trapList;
     JSCList             watchPointList;
 
     /* Client opaque pointers */
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -1688,35 +1688,16 @@ JS_SetCallHook(JSRuntime *rt, JSInterpre
     }
     if (hook)
         LeaveTraceRT(rt);
 #endif
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
-JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
-{
-#ifdef JS_TRACER
-    {
-        AutoLockGC lock(rt);
-        bool wasInhibited = rt->debuggerInhibitsJIT();
-#endif
-        rt->globalDebugHooks.objectHook = hook;
-        rt->globalDebugHooks.objectHookData = closure;
-#ifdef JS_TRACER
-        JITInhibitingHookChange(rt, wasInhibited);
-    }
-    if (hook)
-        LeaveTraceRT(rt);
-#endif
-    return JS_TRUE;
-}
-
-JS_PUBLIC_API(JSBool)
 JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
 {
     rt->globalDebugHooks.throwHook = hook;
     rt->globalDebugHooks.throwHookData = closure;
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -386,19 +386,16 @@ JS_SetSourceHandler(JSRuntime *rt, JSSou
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
-JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure);
-
-extern JS_PUBLIC_API(JSBool)
 JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure);
 
 extern JS_PUBLIC_API(JSBool)
 JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
 
 /************************************************************************/
 
 extern JS_PUBLIC_API(size_t)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2509,35 +2509,16 @@ FinalizeObject(JSContext *cx, JSObject *
 }
 
 inline void
 FinalizeFunction(JSContext *cx, JSFunction *fun, unsigned thingKind)
 {
     FinalizeObject(cx, FUN_OBJECT(fun), thingKind);
 }
 
-inline void
-FinalizeHookedObject(JSContext *cx, JSObject *obj, unsigned thingKind)
-{
-    if (!obj->map)
-        return;
-
-    if (cx->debugHooks->objectHook) {
-        cx->debugHooks->objectHook(cx, obj, JS_FALSE,
-                                   cx->debugHooks->objectHookData);
-    }
-    FinalizeObject(cx, obj, thingKind);
-}
-
-inline void
-FinalizeHookedFunction(JSContext *cx, JSFunction *fun, unsigned thingKind)
-{
-    FinalizeHookedObject(cx, FUN_OBJECT(fun), thingKind);
-}
-
 #if JS_HAS_XML_SUPPORT
 inline void
 FinalizeXML(JSContext *cx, JSXML *xml, unsigned thingKind)
 {
     js_FinalizeXML(cx, xml);
 }
 #endif
 
@@ -3026,29 +3007,20 @@ GC(JSContext *cx  GCTIMER_PARAM)
 #endif
 
     /*
      * We finalize iterators before other objects so the iterator can use the
      * object which properties it enumerates over to finalize the enumeration
      * state. We finalize objects before string, double and other GC things
      * things to ensure that object's finalizer can access them even if they
      * will be freed.
-     *
-     * To minimize the number of checks per each to be freed object and
-     * function we use separated list finalizers when a debug hook is
-     * installed.
      */
     JS_ASSERT(!rt->gcEmptyArenaList);
-    if (!cx->debugHooks->objectHook) {
-        FinalizeArenaList<JSObject, FinalizeObject>(cx, FINALIZE_OBJECT);
-        FinalizeArenaList<JSFunction, FinalizeFunction>(cx, FINALIZE_FUNCTION);
-    } else {
-        FinalizeArenaList<JSObject, FinalizeHookedObject>(cx, FINALIZE_OBJECT);
-        FinalizeArenaList<JSFunction, FinalizeHookedFunction>(cx, FINALIZE_FUNCTION);
-    }
+    FinalizeArenaList<JSObject, FinalizeObject>(cx, FINALIZE_OBJECT);
+    FinalizeArenaList<JSFunction, FinalizeFunction>(cx, FINALIZE_FUNCTION);
 #if JS_HAS_XML_SUPPORT
     FinalizeArenaList<JSXML, FinalizeXML>(cx, FINALIZE_XML);
 #endif
     TIMESTAMP(sweepObjectEnd);
 
     /*
      * We sweep the deflated cache before we finalize the strings so the
      * cache can safely use js_IsAboutToBeFinalized..
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -554,28 +554,16 @@ NewNativeClassInstance(JSContext *cx, Cl
         JS_ASSERT(scope->canProvideEmptyScope(&js_ObjectOps, clasp));
         scope = scope->getEmptyScope(cx, clasp);
         JS_UNLOCK_OBJ(cx, proto);
 
         if (!scope) {
             obj = NULL;
         } else {
             obj->map = scope;
-
-            /*
-             * Do not call debug hooks on trace, because we might be in a non-_FAIL
-             * builtin. See bug 481444.
-             */
-            if (cx->debugHooks->objectHook && !JS_ON_TRACE(cx)) {
-                AutoObjectRooter tvr(cx, obj);
-                AutoKeepAtoms keep(cx->runtime);
-                cx->debugHooks->objectHook(cx, obj, JS_TRUE,
-                                           cx->debugHooks->objectHookData);
-                cx->weakRoots.finalizableNewborns[FINALIZE_OBJECT] = obj;
-            }
         }
     }
 
     objectCreationScope.handleCreation(obj);
     return obj;
 }
 
 bool
@@ -670,28 +658,16 @@ NewObjectWithGivenProto(JSContext *cx, C
             obj = NULL;
             goto out;
         }
     } else {
         JS_ASSERT(ops->objectMap->ops == ops);
         obj->map = const_cast<JSObjectMap *>(ops->objectMap);
     }
 
-    /*
-     * Do not call debug hooks on trace, because we might be in a non-_FAIL
-     * builtin. See bug 481444.
-     */
-    if (cx->debugHooks->objectHook && !JS_ON_TRACE(cx)) {
-        AutoObjectRooter tvr(cx, obj);
-        AutoKeepAtoms keep(cx->runtime);
-        cx->debugHooks->objectHook(cx, obj, JS_TRUE,
-                                   cx->debugHooks->objectHookData);
-        cx->weakRoots.finalizableNewborns[FINALIZE_OBJECT] = obj;
-    }
-
 out:
     objectCreationScope.handleCreation(obj);
     return obj;
 }
 
 static inline JSProtoKey
 GetClassProtoKey(js::Class *clasp)
 {
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -258,19 +258,16 @@ typedef void
  *
  * Returning NULL in the 'before' hook will cause the 'after' hook *not* to
  * be called.
  */
 typedef void *
 (* JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before,
                       JSBool *ok, void *closure);
 
-typedef void
-(* JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
-
 typedef JSBool
 (* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report,
                      void *closure);
 
 typedef struct JSDebugHooks {
     JSInterruptHook     interruptHook;
     void                *interruptHookData;
     JSNewScriptHook     newScriptHook;
@@ -280,18 +277,16 @@ typedef struct JSDebugHooks {
     JSDebuggerHandler   debuggerHandler;
     void                *debuggerHandlerData;
     JSSourceHandler     sourceHandler;
     void                *sourceHandlerData;
     JSInterpreterHook   executeHook;
     void                *executeHookData;
     JSInterpreterHook   callHook;
     void                *callHookData;
-    JSObjectHook        objectHook;
-    void                *objectHookData;
     JSThrowHook         throwHook;
     void                *throwHookData;
     JSDebugErrorHook    debugErrorHook;
     void                *debugErrorHookData;
 } JSDebugHooks;
 
 /* JSObjectOps function pointer typedefs. */