Commits

Andrew Sutherland committed 25d8075

blog post workingness snapshot

  • Participants
  • Parent commits b7a73b7

Comments (0)

Files changed (5)

File fix-wrong-gc-rooting

-# HG changeset patch
-# Parent 0d692b8bfd1fc97013b021203d922a12d4736c9c
-
-diff --git a/js/src/jsprobemgr.cpp b/js/src/jsprobemgr.cpp
---- a/js/src/jsprobemgr.cpp
-+++ b/js/src/jsprobemgr.cpp
-@@ -856,6 +856,28 @@
-     }
- };
- 
-+class RemoveProbeEvent : public Event {
-+    HandlerDescriptor *mHandleDescriptor;
-+
-+private:
-+    RemoveProbeEvent(HandlerDescriptor *hdesc) 
-+        : mHandleDescriptor(hdesc) { }
-+
-+public:
-+    static Event *create(HandlerDescriptor *hdesc) {
-+        return new RemoveProbeEvent(hdesc);
-+    }
-+
-+    virtual Result process(JSContext *cx) {
-+        ProbeManager *mgr = static_cast<ProbeManager *>(JS_GetContextPrivate(cx));
-+        JS_ASSERT(mgr != NULL);
-+
-+        mgr->dispatchProbeRemoval(cx, mHandleDescriptor);
-+        mHandleDescriptor = 0;
-+        return ok;
-+    }
-+};
-+
- class EventQueue : public ThreadSafeQueue<Event *> {
- public:
-     ~EventQueue() { JS_ASSERT(queue.empty()); }
-@@ -1447,8 +1469,8 @@
-             /* this should not happen because we try and compile it on add */
-             if (!desc.handlerFun)
-                 continue;
--            JSObject *handlerFunObj = JS_GetFunctionObject(desc.handlerFun);
--            JS_AddNamedObjectRoot(cx, &handlerFunObj, "probe");
-+            desc.handlerFunObj = JS_GetFunctionObject(desc.handlerFun);
-+            JS_AddNamedObjectRoot(cx, &desc.handlerFunObj, "probe");
-         }
-         JS_CallFunction(cx, globalObj, desc.handlerFun, argc, argv, &rval);
-     }
-@@ -1564,35 +1586,58 @@
- bool ProbeManager::removeProbeHandler(HandlerCookie cookie)
- {
-     HandlerDescriptor *hdesc;
-+    {
-+        /* steal handler queue lock */
-+        AutoLock hold(eq->getLock());
-+        JSAutoRequest req(adminCx);
- 
--    /* steal handler queue lock */
--    AutoLock hold(eq->getLock());
--    JSAutoRequest req(adminCx);
-+        /* look up handler by cookie, remove if it exists */
-+        if (HandlerMap::Ptr p = m_handlerMap->lookup(cookie)) {
-+            hdesc = p->value;
-+            m_handlerMap->remove(p);
-+        } else {
-+            PR_LOG(gProbeManagerLog, PR_LOG_ERROR, ("ProbeManager: Tried to remove handler with bad cookie: %d\n", cookie));
-+            return false;
-+        }
- 
--    /* look up handler by cookie, remove if it exists */
--    if (HandlerMap::Ptr p = m_handlerMap->lookup(cookie)) {
--        hdesc = p->value;
--        m_handlerMap->remove(p);
--    } else {
--        PR_LOG(gProbeManagerLog, PR_LOG_ERROR, ("ProbeManager: Tried to remove handler with bad cookie: %d\n", cookie));
-+        removeHandler(hdesc);
-+        /* TODO: post a cleanup message to the processing thread so it can remove
-+           the root:
-+        JS_RemoveObjectRoot(adminCx, &hdesc->handlerFunObj);
-+        */
-+
-+        /* null out the allocations made on this thread */
-+        JS_free(adminCx, hdesc->argnames);
-+        JS_free(adminCx, const_cast<jschar *>(hdesc->handlerDef.body));
-+        JS_free(adminCx, const_cast<char *>(hdesc->handlerDef.filename));
-+        hdesc->argnames = 0;
-+        hdesc->handlerDef.body = 0;
-+        hdesc->handlerDef.filename = 0;
-+    }
-+
-+    /* create an event for cleanup that must happen on the processing thread */
-+    Event *event = RemoveProbeEvent::create(hdesc);
-+    if (!eq->post(event)) {
-+        delete event;
-+        JS_ReportOutOfMemory(adminCx);
-         return false;
-     }
- 
--    removeHandler(hdesc);
--    /* TODO: post a cleanup message to the processing thread so it can remove
--       the root:
--    JSObject *handlerFunObj = JS_GetFunctionObject(hdesc->handlerFun);
--    JS_RemoveObjectRoot(adminCx, &handlerFunObj);
--    */
--
--    JS_free(adminCx, hdesc->argnames);
--    JS_free(adminCx, const_cast<jschar *>(hdesc->handlerDef.body));
--    JS_free(adminCx, const_cast<char *>(hdesc->handlerDef.filename));
--
--    /* return status */
-     return true;
- }
- 
-+bool ProbeManager::dispatchProbeRemoval(JSContext *cx,
-+                                        HandlerDescriptor *hdesc) {
-+    JS_RemoveObjectRoot(cx, &hdesc->handlerFunObj);
-+    hdesc->handlerFun = 0;
-+
-+    delete hdesc;
-+
-+    return true;
-+}
-+
-+/* XXX this method's removal semantics are not safe, but no one calls it
-+   either */
- bool ProbeManager::clearProbeHandlers(ProbePoint probe)
- {
-     /* steal handler queue lock */
-diff --git a/js/src/jsprobemgr.h b/js/src/jsprobemgr.h
---- a/js/src/jsprobemgr.h
-+++ b/js/src/jsprobemgr.h
-@@ -64,6 +64,8 @@
- struct HandlerDescriptor {
-     /* created on the processing thread the first time it is used */
-     JSFunction *handlerFun;
-+    /* function object for the handler that can serve as a GC root */
-+    JSObject   *handlerFunObj;
-     /* the script info to be used to compile handlerFun */
-     ScriptDescriptor handlerDef;
-     uintN argc;
-@@ -197,6 +199,7 @@
-     bool runScriptOnce(const ScriptDescriptor &fdesc, ScriptCookie *scriptCookie);
-     bool addProbeHandler(ProbePoint probe, ScriptDescriptor &fdesc, ScriptDescriptor &specInfo, HandlerCookie* handlerCookie);
-     bool removeProbeHandler(HandlerCookie cookie);
-+    bool dispatchProbeRemoval(JSContext *cx, HandlerDescriptor *hdesc);
-     bool clearProbeHandlers(ProbePoint probe);
- 
-     /* TODO: this should always be inlined into the Probes::whateverThing function

File jetpack-scriptcontext-problem-snafu

-# HG changeset patch
-# Parent 9af83a523235c7ec4adfd6d7e75815c5f419521c
-
-diff --git a/toolkit/components/probes/ProbeService.cpp b/toolkit/components/probes/ProbeService.cpp
---- a/toolkit/components/probes/ProbeService.cpp
-+++ b/toolkit/components/probes/ProbeService.cpp
-@@ -83,7 +83,7 @@
- 
- private:
-     typedef nsInterfaceHashtable<nsUint32HashKey, nsIProbeMessageListener> ListenerMap;
--    typedef nsInterfaceHashtable<nsUint32HashKey, nsIScriptContext> ContextMap;
-+    typedef nsInterfaceHashtable<nsUint32HashKey, nsISupports> ContextMap;
- 
-     bool mHasShutdown;
-     nsCOMPtr<nsITimer> mDrainTimer;
-@@ -242,8 +242,15 @@
- 
-     /* lookup listener for this scriptcookie */
-     nsCOMPtr<nsIProbeMessageListener> listener = mListeners.Get(cookie);
--    nsCOMPtr<nsIScriptContext> scriptCx = mListenerContexts.Get(cookie);
--    JSContext *cx = (JSContext *) scriptCx->GetNativeContext();
-+    nsCOMPtr<nsISupports> supportsCx = mListenerContexts.Get(cookie);
-+    nsCOMPtr<nsIScriptContext> scriptCx = do_QueryInterface(supportsCx);
-+    JSContext *cx;
-+    if (scriptCx) {
-+        cx = (JSContext *) scriptCx->GetNativeContext();
-+    }
-+    else {
-+        nsCOMPtr<ns
-+    }
- 
-     /* unpack message, using cx */
-     ScriptCookie outCookie;
-@@ -395,9 +402,10 @@
-     if (!mManager->runScriptOnce(codeDesc, &codeCookie))
-         return NS_ERROR_FAILURE;
- 
--    nsIScriptContext *scriptCx = GetScriptContextFromJSContext(cx);
--    if (!scriptCx)
--        return NS_ERROR_FAILURE;
-+    if (!(JS_GetOptions(cx) & JSOPTION_PRIVATE_IS_NSISUPPORTS))
-+        return NS_ERROR_UNEXPECTED;
-+    nsISupports *supportsCx =
-+        static_cast<nsISupports *>(JS_GetContextPrivate(cx));
- 
-     mListeners.Put(codeCookie, listener);
-     mListenerContexts.Put(codeCookie, scriptCx);

File js-run-probes

 # HG changeset patch
-# Parent a543a29c8529ca75719d1572a2c19eabf816ef85
+# Parent 78e429f3ec6891c2a39a8672532a5850bc8863fb
 
 diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp
 --- a/js/src/jsinterp.cpp
 diff --git a/js/src/jsprobedefs.cpp b/js/src/jsprobedefs.cpp
 --- a/js/src/jsprobedefs.cpp
 +++ b/js/src/jsprobedefs.cpp
-@@ -238,6 +238,26 @@
+@@ -238,6 +238,34 @@
      return true;
  }
  
 +}
 +
 +bool
++env_threadId(JSRuntime *rt, ProbeValue *arg)
++{
++    JS_ASSERT(arg->ty == ProbeType_DummyGlobal);
++    PROBE_VALUE_SET(arg, intptr_t, (intptr_t)PR_GetCurrentThread());
++    return true;
++}
++
++bool
 +context_to_compartment(JSRuntime *rt, ProbeValue *arg)
 +{
 +    JS_ASSERT(arg);
 diff --git a/js/src/jsprobedefs.h b/js/src/jsprobedefs.h
 --- a/js/src/jsprobedefs.h
 +++ b/js/src/jsprobedefs.h
-@@ -158,6 +158,8 @@
+@@ -158,6 +158,9 @@
  bool compartment_gcLastBytes(JSRuntime *rt, ProbeValue *val);
  bool compartment_id(JSRuntime *rt, ProbeValue *val);
  bool env_currentTimeMS(JSRuntime *rt, ProbeValue *val);
 +bool env_currentTimeUS(JSRuntime *rt, ProbeValue *val);
++bool env_threadId(JSRuntime *rt, ProbeValue *val);
 +bool context_to_compartment(JSRuntime *rt, ProbeValue *val);
  
  js::Value deserialize_size_t(JSContext *cx, ProbeValue val);
 diff --git a/js/src/jsprobes.tbl b/js/src/jsprobes.tbl
 --- a/js/src/jsprobes.tbl
 +++ b/js/src/jsprobes.tbl
-@@ -205,6 +205,8 @@
+@@ -205,6 +205,10 @@
  PROBE_TRANS(compartment_gcLastBytes,       gcLastBytes,        9,  JSCompartmentPtr,    size_t)
  PROBE_TRANS(compartment_id,                id,                10,  JSCompartmentPtr,    intptr_t)
  PROBE_TRANS(env_currentTimeMS,             currentTimeMS,     11,  DummyGlobal,         double)
 +PROBE_TRANS(env_currentTimeUS,             currentTimeUS,     12,  DummyGlobal,         double)
-+PROBE_TRANS(context_to_compartment,        compartment,       13,  JSContextPtr,        JSCompartmentPtr)
++PROBE_TRANS(env_threadId,                  threadId,          13,  DummyGlobal,
++     intptr_t)
++PROBE_TRANS(context_to_compartment,        compartment,       14,  JSContextPtr,        JSCompartmentPtr)
  
  /* teardown PROBE_POINT helpers */
  #undef _NO_ARGS

File js-runtime-fixups

 # HG changeset patch
-# Parent 3e29c3f42797922e4c1f46e1a810a755c3afe7bd
+# Parent 897717105735a2735498e89381eb00ff2ff3d80b
 
 diff --git a/js/src/jsprobemgr.cpp b/js/src/jsprobemgr.cpp
 --- a/js/src/jsprobemgr.cpp
          return ok;
      }
  };
-@@ -1088,7 +1121,7 @@
+@@ -823,6 +856,28 @@
+     }
+ };
+ 
++class RemoveProbeEvent : public Event {
++    HandlerDescriptor *mHandleDescriptor;
++
++private:
++    RemoveProbeEvent(HandlerDescriptor *hdesc) 
++        : mHandleDescriptor(hdesc) { }
++
++public:
++    static Event *create(HandlerDescriptor *hdesc) {
++        return new RemoveProbeEvent(hdesc);
++    }
++
++    virtual Result process(JSContext *cx) {
++        ProbeManager *mgr = static_cast<ProbeManager *>(JS_GetContextPrivate(cx));
++        JS_ASSERT(mgr != NULL);
++
++        mgr->dispatchProbeRemoval(cx, mHandleDescriptor);
++        mHandleDescriptor = 0;
++        return ok;
++    }
++};
++
+ class EventQueue : public ThreadSafeQueue<Event *> {
+ public:
+     ~EventQueue() { JS_ASSERT(queue.empty()); }
+@@ -1088,7 +1143,7 @@
  
  bool ProbeManager::start()
  {
      HandlerDescList dummyList = HandlerDescList();
  
  #ifdef PR_LOGGING
-@@ -1098,14 +1131,18 @@
+@@ -1098,14 +1153,18 @@
      registry = std::vector<HandlerDescList>((int)ProbePoint_Final, dummyList);
      masterOrders = std::vector<PickOrder*>((int)ProbePoint_Final, NULL);
  
      if (!handlerCx)
          return false;
  
-@@ -1117,7 +1154,7 @@
+@@ -1117,7 +1176,7 @@
  
      /* create admin context -- this is only used by the main thread,
         and is used to allocate new JSScripts and JSFunctions */
      if (!adminCx)
          return false;
  
-@@ -1125,31 +1162,45 @@
+@@ -1125,31 +1184,45 @@
      JS_SetVersion(adminCx, JSVERSION_LATEST);
      JS_SetErrorReporter(adminCx, js::probes::reportError);
  
  
      m_handlerMap = new HandlerMap(adminCx);
      m_handlerMap->init();
-@@ -1204,30 +1255,31 @@
+@@ -1204,30 +1277,31 @@
      delete mq;
      mq = NULL;
  
          eq->drop(event);
  
          delete event;
-@@ -1235,8 +1287,8 @@
+@@ -1235,8 +1309,8 @@
              break;
      }
  
      return result == Event::ok;
  }
  
-@@ -1377,12 +1429,28 @@
+@@ -1377,12 +1451,28 @@
          }
      }  
  
 +            /* this should not happen because we try and compile it on add */
 +            if (!desc.handlerFun)
 +                continue;
-+            JSObject *handlerFunObj = JS_GetFunctionObject(desc.handlerFun);
-+            JS_AddNamedObjectRoot(cx, &handlerFunObj, "probe");
++            desc.handlerFunObj = JS_GetFunctionObject(desc.handlerFun);
++            JS_AddNamedObjectRoot(cx, &desc.handlerFunObj, "probe");
 +        }
 +        JS_CallFunction(cx, globalObj, desc.handlerFun, argc, argv, &rval);
      }
  
      cleanup:
-@@ -1397,30 +1465,19 @@
+@@ -1397,30 +1487,19 @@
      return false;
  }
  
      }
      return true;
  }
-@@ -1458,29 +1515,42 @@
+@@ -1458,29 +1537,42 @@
          argnames[i+curOffset] = ProbePointData[GLOBAL_PROBE_ARGS].args[i].name;
      }
      
      addHandler(handlerDesc);
  
      /* register and return the handler's cookie */
-@@ -1509,6 +1579,15 @@
+@@ -1494,26 +1586,58 @@
+ bool ProbeManager::removeProbeHandler(HandlerCookie cookie)
+ {
+     HandlerDescriptor *hdesc;
++    {
++        /* steal handler queue lock */
++        AutoLock hold(eq->getLock());
++        JSAutoRequest req(adminCx);
+ 
+-    /* steal handler queue lock */
+-    AutoLock hold(eq->getLock());
+-    JSAutoRequest req(adminCx);
++        /* look up handler by cookie, remove if it exists */
++        if (HandlerMap::Ptr p = m_handlerMap->lookup(cookie)) {
++            hdesc = p->value;
++            m_handlerMap->remove(p);
++        } else {
++            PR_LOG(gProbeManagerLog, PR_LOG_ERROR, ("ProbeManager: Tried to remove handler with bad cookie: %d\n", cookie));
++            return false;
++        }
+ 
+-    /* look up handler by cookie, remove if it exists */
+-    if (HandlerMap::Ptr p = m_handlerMap->lookup(cookie)) {
+-        hdesc = p->value;
+-        m_handlerMap->remove(p);
+-    } else {
+-        PR_LOG(gProbeManagerLog, PR_LOG_ERROR, ("ProbeManager: Tried to remove handler with bad cookie: %d\n", cookie));
++        removeHandler(hdesc);
++        /* TODO: post a cleanup message to the processing thread so it can remove
++           the root:
++        JS_RemoveObjectRoot(adminCx, &hdesc->handlerFunObj);
++        */
++
++        /* null out the allocations made on this thread */
++        JS_free(adminCx, hdesc->argnames);
++        JS_free(adminCx, const_cast<jschar *>(hdesc->handlerDef.body));
++        JS_free(adminCx, const_cast<char *>(hdesc->handlerDef.filename));
++        hdesc->argnames = 0;
++        hdesc->handlerDef.body = 0;
++        hdesc->handlerDef.filename = 0;
++    }
++
++    /* create an event for cleanup that must happen on the processing thread */
++    Event *event = RemoveProbeEvent::create(hdesc);
++    if (!eq->post(event)) {
++        delete event;
++        JS_ReportOutOfMemory(adminCx);
+         return false;
      }
  
-     removeHandler(hdesc);
-+    /* TODO: post a cleanup message to the processing thread so it can remove
-+       the root:
-+    JSObject *handlerFunObj = JS_GetFunctionObject(hdesc->handlerFun);
-+    JS_RemoveObjectRoot(adminCx, &handlerFunObj);
-+    */
+-    removeHandler(hdesc);
+-
+-    /* return status */
+     return true;
+ }
+ 
++bool ProbeManager::dispatchProbeRemoval(JSContext *cx,
++                                        HandlerDescriptor *hdesc) {
++    JS_RemoveObjectRoot(cx, &hdesc->handlerFunObj);
++    hdesc->handlerFun = 0;
 +
-+    JS_free(adminCx, hdesc->argnames);
-+    JS_free(adminCx, const_cast<jschar *>(hdesc->handlerDef.body));
-+    JS_free(adminCx, const_cast<char *>(hdesc->handlerDef.filename));
- 
-     /* return status */
-     return true;
-@@ -1558,7 +1637,9 @@
++    delete hdesc;
++
++    return true;
++}
++
++/* XXX this method's removal semantics are not safe, but no one calls it
++   either */
+ bool ProbeManager::clearProbeHandlers(ProbePoint probe)
+ {
+     /* steal handler queue lock */
+@@ -1558,7 +1682,9 @@
      void *payloadbuf;
      void *bufp;
  
  
      /* zero the memory for debugging niceness */
      memset(payloadbuf, 0L, order.totalBytes);
-@@ -1600,7 +1681,7 @@
+@@ -1600,7 +1726,7 @@
          ProbeValue tmp = curArg;
          for (PickItem::TransformVec::iterator it = item->transforms.begin();
               it != item->transforms.end(); it++) {
 diff --git a/js/src/jsprobemgr.h b/js/src/jsprobemgr.h
 --- a/js/src/jsprobemgr.h
 +++ b/js/src/jsprobemgr.h
-@@ -62,7 +62,12 @@
+@@ -62,7 +62,14 @@
  };
  
  struct HandlerDescriptor {
 +    /* created on the processing thread the first time it is used */
      JSFunction *handlerFun;
++    /* function object for the handler that can serve as a GC root */
++    JSObject   *handlerFunObj;
 +    /* the script info to be used to compile handlerFun */
 +    ScriptDescriptor handlerDef;
 +    uintN argc;
      ProbePoint probe;
      PickOrder *order;
      HandlerCookie cookie;
-@@ -113,7 +118,8 @@
+@@ -113,7 +120,8 @@
      static ScriptCookie s_nextScriptCookie;
  
      PRThread *handlerThread;
      EventQueue *eq;
      MessageQueue *mq;
  
-@@ -135,7 +141,8 @@
+@@ -135,7 +143,8 @@
  
      explicit ProbeManager() 
      : handlerThread(NULL)
      , eq(NULL)
      , mq(NULL)
      , m_scriptRunning(false)
-@@ -187,7 +194,7 @@
+@@ -187,9 +196,10 @@
      /* main commands */
      bool dispatchEvent(JSContext *cx, ProbePoint probe, ProbeDataPtr data);
  
 +    bool runScriptOnce(const ScriptDescriptor &fdesc, ScriptCookie *scriptCookie);
      bool addProbeHandler(ProbePoint probe, ScriptDescriptor &fdesc, ScriptDescriptor &specInfo, HandlerCookie* handlerCookie);
      bool removeProbeHandler(HandlerCookie cookie);
++    bool dispatchProbeRemoval(JSContext *cx, HandlerDescriptor *hdesc);
      bool clearProbeHandlers(ProbePoint probe);
-@@ -199,7 +206,9 @@
+ 
+     /* TODO: this should always be inlined into the Probes::whateverThing function
+@@ -199,7 +209,9 @@
  
      /* use these to avoid reentrancy on a different thread (say, by
       * triggering a GC or heap resize event on probe runtime) */
 js-run-probes
 provide-all-compartment-ptrs
 jetpack-scriptcontext-naked-jscontext
-fix-wrong-gc-rooting
-jetpack-scriptcontext-problem-snafu