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
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. */