1. Andrew Sutherland
  2. jsprobes-patches

Commits

Andrew Sutherland  committed 066f8e6

JSRuntime changes nuked lock constructs

Most of these changes are the same as the changes made to jsworkers.cpp,
which makes sense because it appears a lot of the code is just copied and
pasted from there.

  • Participants
  • Parent commits b683d2f
  • Branches default

Comments (0)

Files changed (1)

File js-runtime-fixups

View file
  • Ignore whitespace
 # HG changeset patch
-# Parent 9851298587333738e41d22f88b6142f747d1976a
+# Parent 3e29c3f42797922e4c1f46e1a810a755c3afe7bd
 
 diff --git a/js/src/jsprobemgr.cpp b/js/src/jsprobemgr.cpp
 --- a/js/src/jsprobemgr.cpp
 +++ b/js/src/jsprobemgr.cpp
-@@ -763,38 +763,61 @@ public:
+@@ -56,6 +56,16 @@
+ /* TODO: remove this include, since it doesn't exist in Android NDK */
+ #include <algorithm>
  
-     virtual Result process(JSContext *cx) =0;
-     virtual ~Event() { }
++class AutoLock
++{
++  private:
++    PRLock *lock;
++
++  public:
++    AutoLock(PRLock *lock) : lock(lock) { PR_Lock(lock); }
++    ~AutoLock() { PR_Unlock(lock); }
++};
++
+ namespace js {
+ namespace probes {
+ 
+@@ -675,7 +685,7 @@
+ {
+ protected:
+     Queue<T, SystemAllocPolicy> queue;
+-    JSLock *lock;
++    PRLock *lock;
+     PRCondVar *condvar;
+     bool closed;
+ 
+@@ -691,25 +701,25 @@
+ 
+     ~ThreadSafeQueue() {
+         if (condvar)
+-            JS_DESTROY_CONDVAR(condvar);
++            PR_DestroyCondVar(condvar);
+         if (lock)
+-            JS_DESTROY_LOCK(lock);
++            PR_DestroyLock(lock);
+     }
+ 
+     bool initThreadSafeQueue() {
+         JS_ASSERT(!lock);
+         JS_ASSERT(!condvar);
+-        return (lock = JS_NEW_LOCK()) && (condvar = JS_NEW_CONDVAR(lock));
++        return (lock = PR_NewLock()) && (condvar = PR_NewCondVar(lock));
+     }
+ 
+-    virtual JSLock *getLock() { return lock; }
++    virtual PRLock *getLock() { return lock; }
+ 
+     bool post(T t) {
+         AutoLock hold(lock);
+         if (closed)
+             return false;
+         if (queue.empty())
+-            JS_NOTIFY_ALL_CONDVAR(condvar);
++            PR_NotifyAllCondVar(condvar);
+         return queue.push(t);
+     }
+ 
+@@ -717,7 +727,7 @@
+         AutoLock hold(lock);
+         closed = true;
+         //queue.clear();
+-        JS_NOTIFY_ALL_CONDVAR(condvar);
++        PR_NotifyAllCondVar(condvar);
+     }
+ 
+     // The caller must hold the lock.
+@@ -725,7 +735,7 @@
+         while (queue.empty()) {
+             if (shouldStop())
+                 return false;
+-            JS_WAIT_CONDVAR(condvar, JS_NO_TIMEOUT);
++            PR_WaitCondVar(condvar, PR_INTERVAL_NO_TIMEOUT);
+         }
+         *t = queue.pop();
+         busy.append(*t);
+@@ -753,7 +763,7 @@
+ 
+     void wake() {
+         AutoLock hold(lock);
+-        JS_NOTIFY_ALL_CONDVAR(condvar);
++        PR_NotifyAllCondVar(condvar);
+     }
  };
  
+@@ -768,15 +778,29 @@
  class RunScriptEvent : public Event {
  
  private:
      }
  
      virtual Result process(JSContext *cx) {
-         ProbeManager *mgr = static_cast<ProbeManager *>(JS_GetContextPrivate(cx));
-         JS_ASSERT(mgr != NULL);
- 
+@@ -786,10 +810,19 @@
          jsval retval;
          JSAutoRequest req(cx);
  
          return ok;
      }
  };
- 
- class ProbeFireEvent : public Event {
-     ProbePoint mProbe;
-     ProbeDataPtr mPayload;
- 
-@@ -1083,78 +1106,99 @@ ProbeManager::~ProbeManager()
- 
- ProbeManager* ProbeManager::create()
- {
-     return new ProbeManager();
- }
+@@ -1088,7 +1121,7 @@
  
  bool ProbeManager::start()
  {
      HandlerDescList dummyList = HandlerDescList();
  
  #ifdef PR_LOGGING
-     gProbeManagerLog = PR_NewLogModule("ProbeManager");
- #endif
- 
+@@ -1098,14 +1131,18 @@
      registry = std::vector<HandlerDescList>((int)ProbePoint_Final, dummyList);
      masterOrders = std::vector<PickOrder*>((int)ProbePoint_Final, NULL);
  
      if (!handlerCx)
          return false;
  
-     JS_SetOptions(handlerCx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
-     JS_SetVersion(handlerCx, JSVERSION_LATEST);
-     JS_SetErrorReporter(handlerCx, js::probes::reportError);
-     /* stuff this here so events can mess with handler vector */
-     JS_SetContextPrivate(handlerCx, static_cast<void *>(this));
+@@ -1117,7 +1154,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;
  
-     JS_SetOptions(adminCx, JSOPTION_VAROBJFIX | JSOPTION_METHODJIT);
+@@ -1125,31 +1162,45 @@
      JS_SetVersion(adminCx, JSVERSION_LATEST);
      JS_SetErrorReporter(adminCx, js::probes::reportError);
  
-     JS_SetContextThread(handlerCx);
+-    JS_SetContextThread(handlerCx);
      /* scope + auto request used to cover side exits */
      {
          JSAutoRequest req(handlerCx);
              return NULL;
          }
      }
-     JS_ClearContextThread(handlerCx);
+-    JS_ClearContextThread(handlerCx);
 +    JS_ClearRuntimeThread(handlerRt);
  
 -    /* set global object in other context, set thread affinity */
-+    /* create a global object for the admin context too */
-     JS_SetContextThread(adminCx);
+-    JS_SetContextThread(adminCx);
 -    JS_BeginRequest(adminCx);
 -    JS_SetGlobalObject(adminCx, global);
 -    JS_EndRequest(adminCx);
++    /* create a global object for the admin context too */
 +    {
 +        JSAutoRequest req(adminCx);
 +        /* Create the global object in a new compartment. */
  
      m_handlerMap = new HandlerMap(adminCx);
      m_handlerMap->init();
- 
-     /* create queue */
-     JS_ASSERT(!eq);
-     eq = new EventQueue();
-     if (!eq || !eq->initThreadSafeQueue()) {
-@@ -1199,26 +1243,29 @@ void ProbeManager::shutdown()
-     }
- 
-     delete eq;
-     eq = NULL;
- 
+@@ -1204,30 +1255,31 @@
      delete mq;
      mq = NULL;
  
+-    JS_SetContextThread(handlerCx);
 +    JS_SetRuntimeThread(handlerRt);
-     JS_SetContextThread(handlerCx);
      JS_DestroyContext(handlerCx);
 +    JS_DestroyRuntime(handlerRt);
      JS_DestroyContext(adminCx);
 -    /* necessary since this thread just started, but context was
 +    /* necessary since this thread just started, but context/runtime was
         allocated by the "main" thread in ProbeManager::start() */
+-    JS_SetContextThread(handlerCx);
 +    JS_SetRuntimeThread(handlerRt);
-     JS_SetContextThread(handlerCx);
      AutoLock hold(eq->getLock());
  
      Event *event = NULL;
      Event::Result result = Event::ok;
  
      while (eq->take(&event)) {
-         JS_RELEASE_LOCK(eq->getLock());
-@@ -1230,18 +1277,19 @@ bool ProbeManager::doWork()
-         JS_ACQUIRE_LOCK(eq->getLock());
+-        JS_RELEASE_LOCK(eq->getLock());
++        PR_Unlock(eq->getLock());
+         {
+             JSAutoRequest req(handlerCx);
+ 
+             result = event->process(handlerCx);
+         }
+-        JS_ACQUIRE_LOCK(eq->getLock());
++        PR_Lock(eq->getLock());
          eq->drop(event);
  
          delete event;
-         if (result  != Event::ok)
+@@ -1235,8 +1287,8 @@
              break;
      }
  
 -    /* release the context from this thread since it will die now. */
+-    JS_ClearContextThread(handlerCx);
 +    /* release the context/runtime from this thread since it will die now. */
-     JS_ClearContextThread(handlerCx);
 +    JS_ClearRuntimeThread(handlerRt);
      return result == Event::ok;
  }
  
- 
- bool ProbeManager::dispatchEvent(JSContext *cx, ProbePoint probe, ProbeDataPtr data) {
-     HandlerDescList hlist;
-     jsval *argv, *unpackedArgs;
-     jsval rval;
-@@ -1372,60 +1420,65 @@ bool ProbeManager::dispatchEvent(JSConte
-                     goto cleanup;
-                 }
- 
-                 curObj = OBJECT_TO_JSVAL(newObj);
-             }
+@@ -1377,12 +1429,28 @@
          }
      }  
  
      }
  
      cleanup:
-     JS_free(cx, argv);
-     JS_free(cx, unpackedArgs);
-     JS_LeaveLocalRootScope(cx);
- 
-     if (!didFail)
-         return true;
- 
-     JS_ReportError(cx, "ProbeManager::dispatchEvent: encountered error when creating object graph");
+@@ -1397,30 +1465,19 @@
      return false;
  }
  
      }
      return true;
  }
- 
- bool ProbeManager::addProbeHandler(ProbePoint probe, 
-                                    ScriptDescriptor &handlerInfo, 
-                                    ScriptDescriptor &specInfo,
-                                    /* out */ HandlerCookie *cookie)
-@@ -1453,39 +1506,52 @@ bool ProbeManager::addProbeHandler(Probe
-     for (int i = 0; i < ProbePointData[probe].argc; i++) {
-         argnames[i+curOffset] = ProbePointData[probe].args[i].name;
-     }
-     curOffset += ProbePointData[probe].argc;
-     for (int i = 0; i < ProbePointData[GLOBAL_PROBE_ARGS].argc; i++) {
+@@ -1458,29 +1515,42 @@
          argnames[i+curOffset] = ProbePointData[GLOBAL_PROBE_ARGS].args[i].name;
      }
      
      addHandler(handlerDesc);
  
      /* register and return the handler's cookie */
-     if (!m_handlerMap->putNew(newCookie, handlerDesc))
-         return false;
- 
-     *cookie = newCookie;
-     return true;
-@@ -1504,16 +1570,25 @@ bool ProbeManager::removeProbeHandler(Ha
-         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;
+@@ -1509,6 +1579,15 @@
      }
  
      removeHandler(hdesc);
  
      /* return status */
      return true;
- }
- 
- bool ProbeManager::clearProbeHandlers(ProbePoint probe)
- {
-     /* steal handler queue lock */
-@@ -1553,17 +1628,19 @@ bool ProbeManager::fireProbe(ProbePoint 
-     /* are there any handlers registered for this probe id? */
-     if (!hasHandlers(probe))
-         return true;
- 
-     PickOrder order = getPickOrder(probe);
+@@ -1558,7 +1637,9 @@
      void *payloadbuf;
      void *bufp;
  
  
      /* zero the memory for debugging niceness */
      memset(payloadbuf, 0L, order.totalBytes);
-     bufp = payloadbuf; /* cursor */
- 
-     va_list argp;
-     int lastArgn = -1;
-     ProbeValue curArg = ProbeValue(ProbeType_DummyGlobal);
-@@ -1595,17 +1672,17 @@ bool ProbeManager::fireProbe(ProbePoint 
-             }
-             curArg = ProbeValue(ty, &curArgp);
-         }
- 
-         /* transform this argument */
+@@ -1600,7 +1681,7 @@
          ProbeValue tmp = curArg;
          for (PickItem::TransformVec::iterator it = item->transforms.begin();
               it != item->transforms.end(); it++) {
                  PR_LOG(gProbeManagerLog, PR_LOG_ERROR, ("Error when applying transform %d (%s)\n", ProbeFunctionData[*it].transform, ProbeFunctionData[*it].fn_name));
              }
          }
- 
-         /* serialize and shift */
-         tmp.serialize(bufp);
-         bufp = ((char *)bufp) + ProbeTypeData[tmp.ty].bytes;
-     }
 diff --git a/js/src/jsprobemgr.h b/js/src/jsprobemgr.h
 --- a/js/src/jsprobemgr.h
 +++ b/js/src/jsprobemgr.h
-@@ -57,17 +57,22 @@ struct PickOrder;
- struct ScriptDescriptor {
-     const jschar *body;
-     size_t length;
-     const char *filename;
-     uintN lineno;
+@@ -62,7 +62,12 @@
  };
  
  struct HandlerDescriptor {
      ProbePoint probe;
      PickOrder *order;
      HandlerCookie cookie;
- };
- 
- struct Message {
- private:
-     const uint64_t *m_data;
-@@ -108,17 +113,18 @@ public:
- private:
-     typedef HashMap<HandlerCookie, HandlerDescriptor*> HandlerMap;
- 
-     static ProbeManager *s_lastManager;
-     static HandlerCookie s_nextHandlerCookie;
+@@ -113,7 +118,8 @@
      static ScriptCookie s_nextScriptCookie;
  
      PRThread *handlerThread;
      EventQueue *eq;
      MessageQueue *mq;
  
-     /* whether the handler thread is currently executing an async script.
-        this should only get/set from the handler thread, as it is not threadsafe */
-     bool m_scriptRunning; 
-     ScriptCookie m_currentScript;
-     PRInt32 m_pendingScriptCount;
-@@ -130,17 +136,18 @@ private:
- 
-     JSContext *handlerCx;
-     JSContext *adminCx;
-     
-     JSObject *itemBuilderProto;
+@@ -135,7 +141,8 @@
  
      explicit ProbeManager() 
      : handlerThread(NULL)
      , eq(NULL)
      , mq(NULL)
      , m_scriptRunning(false)
-     , m_currentScript(0)
-     , m_pendingScriptCount(0)
-     , m_handlerMap(NULL)
-     , handlerCx(NULL)
-     , adminCx(NULL)
-@@ -182,29 +189,31 @@ public:
-     /* main phases */
-     bool start();
-     void shutdown();
-     bool doWork();
- 
+@@ -187,7 +194,7 @@
      /* main commands */
      bool dispatchEvent(JSContext *cx, ProbePoint probe, ProbeDataPtr data);
  
      bool addProbeHandler(ProbePoint probe, ScriptDescriptor &fdesc, ScriptDescriptor &specInfo, HandlerCookie* handlerCookie);
      bool removeProbeHandler(HandlerCookie cookie);
      bool clearProbeHandlers(ProbePoint probe);
- 
-     /* TODO: this should always be inlined into the Probes::whateverThing function
-      * to avoid an extra function call for each probe */
-     /* TODO: inline everything that this calls, as well (EventQueue.push) */
-     bool fireProbe(ProbePoint probe, ...);
+@@ -199,7 +206,9 @@
  
      /* use these to avoid reentrancy on a different thread (say, by
       * triggering a GC or heap resize event on probe runtime) */
  
      bool isScriptRunning() const { return m_scriptRunning; }
      bool hasPendingScripts() const { return m_pendingScriptCount; }
- 
-     bool hasMessages() const;
-     bool pushMessage(Message *message);
-     Message *popMessage();
- };