Bug 905544 - Fix assertion failure in threadsafe builds with --disable-ion, r=billm.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 22 Aug 2013 18:02:28 -0600
changeset 143988 d74b077b663c87eb53de2ef2c132ecdb970699fb
parent 143987 eefc5a5ed6c9105b1118407c75dea250c07954f6
child 143989 2aea1fd9522d94bb4a1fcc789ecf1245811925bb
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbillm
bugs905544
milestone26.0a1
Bug 905544 - Fix assertion failure in threadsafe builds with --disable-ion, r=billm.
js/src/jscntxtinlines.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -347,17 +347,17 @@ ExclusiveContext::maybePause() const
         AutoLockWorkerThreadState lock(*runtime_->workerThreadState);
         workerThread->pause();
     }
 #endif
 }
 
 class AutoLockForExclusiveAccess
 {
-#ifdef JS_THREADSAFE
+#ifdef JS_WORKER_THREADS
     JSRuntime *runtime;
 
     void init(JSRuntime *rt) {
         runtime = rt;
         if (runtime->numExclusiveThreads) {
             PR_Lock(runtime->exclusiveAccessLock);
 #ifdef DEBUG
             runtime->exclusiveAccessOwner = PR_GetCurrentThread();
@@ -384,29 +384,29 @@ class AutoLockForExclusiveAccess
             runtime->exclusiveAccessOwner = NULL;
 #endif
             PR_Unlock(runtime->exclusiveAccessLock);
         } else {
             JS_ASSERT(runtime->mainThreadHasExclusiveAccess);
             runtime->mainThreadHasExclusiveAccess = false;
         }
     }
-#else // JS_THREADSAFE
+#else // JS_WORKER_THREADS
   public:
     AutoLockForExclusiveAccess(ExclusiveContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
     AutoLockForExclusiveAccess(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
     ~AutoLockForExclusiveAccess() {
         // An empty destructor is needed to avoid warnings from clang about
         // unused local variables of this type.
     }
-#endif // JS_THREADSAFE
+#endif // JS_WORKER_THREADS
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 inline LifoAlloc &
 ExclusiveContext::typeLifoAlloc()
 {
     return zone()->types.typeLifoAlloc;
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -101,16 +101,18 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     interrupt(0),
     handlingSignal(false),
     operationCallback(NULL),
 #ifdef JS_THREADSAFE
     operationCallbackLock(NULL),
 #ifdef DEBUG
     operationCallbackOwner(NULL),
 #endif
+#endif
+#ifdef JS_WORKER_THREADS
     exclusiveAccessLock(NULL),
     exclusiveAccessOwner(NULL),
     mainThreadHasExclusiveAccess(false),
     exclusiveThreadsPaused(false),
     numExclusiveThreads(0),
 #endif
     systemZone(NULL),
     numCompartments(0),
@@ -311,17 +313,19 @@ bool
 JSRuntime::init(uint32_t maxbytes)
 {
 #ifdef JS_THREADSAFE
     ownerThread_ = PR_GetCurrentThread();
 
     operationCallbackLock = PR_NewLock();
     if (!operationCallbackLock)
         return false;
+#endif
 
+#ifdef JS_WORKER_THREADS
     exclusiveAccessLock = PR_NewLock();
     if (!exclusiveAccessLock)
         return false;
 #endif
 
     if (!mainThread.init())
         return false;
 
@@ -388,37 +392,38 @@ JSRuntime::init(uint32_t maxbytes)
 #endif
     return true;
 }
 
 JSRuntime::~JSRuntime()
 {
     mainThread.removeFromThreadList();
 
-#ifdef JS_THREADSAFE
-# ifdef JS_ION
+#ifdef JS_WORKER_THREADS
     if (workerThreadState)
         js_delete(workerThreadState);
-# endif
-    sourceCompressorThread.finish();
-
-    JS_ASSERT(!operationCallbackOwner);
-    if (operationCallbackLock)
-        PR_DestroyLock(operationCallbackLock);
 
     JS_ASSERT(!exclusiveAccessOwner);
     if (exclusiveAccessLock)
         PR_DestroyLock(exclusiveAccessLock);
 
     JS_ASSERT(!numExclusiveThreads);
 
     // Avoid bogus asserts during teardown.
     exclusiveThreadsPaused = true;
 #endif
 
+#ifdef JS_THREADSAFE
+    sourceCompressorThread.finish();
+
+    JS_ASSERT(!operationCallbackOwner);
+    if (operationCallbackLock)
+        PR_DestroyLock(operationCallbackLock);
+#endif
+
     /*
      * Even though all objects in the compartment are dead, we may have keep
      * some filenames around because of gcKeepAtoms.
      */
     FreeScriptData(this);
 
 #ifdef DEBUG
     /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
@@ -722,17 +727,17 @@ JSRuntime::onOutOfMemory(void *p, size_t
 
 bool
 JSRuntime::activeGCInAtomsZone()
 {
     Zone *zone = atomsCompartment_->zone();
     return zone->needsBarrier() || zone->isGCScheduled() || zone->wasGCStarted();
 }
 
-#ifdef JS_THREADSAFE
+#ifdef JS_WORKER_THREADS
 
 void
 JSRuntime::setUsedByExclusiveThread(Zone *zone)
 {
     JS_ASSERT(!zone->usedByExclusiveThread);
     zone->usedByExclusiveThread = true;
     numExclusiveThreads++;
 }
@@ -740,16 +745,20 @@ JSRuntime::setUsedByExclusiveThread(Zone
 void
 JSRuntime::clearUsedByExclusiveThread(Zone *zone)
 {
     JS_ASSERT(zone->usedByExclusiveThread);
     zone->usedByExclusiveThread = false;
     numExclusiveThreads--;
 }
 
+#endif // JS_WORKER_THREADS
+
+#ifdef JS_THREADSAFE
+
 bool
 js::CurrentThreadCanAccessRuntime(JSRuntime *rt)
 {
     DebugOnly<PerThreadData *> pt = js::TlsPerThreadData.get();
     JS_ASSERT(pt && pt->associatedWith(rt));
     return rt->ownerThread_ == PR_GetCurrentThread() || InExclusiveParallelSection();
 }
 
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -749,16 +749,23 @@ struct JSRuntime : public JS::shadow::Ru
 #if defined(JS_THREADSAFE) && defined(DEBUG)
         return operationCallbackOwner == PR_GetCurrentThread();
 #else
         return true;
 #endif
     }
 
 #ifdef JS_THREADSAFE
+
+    js::SourceCompressorThread sourceCompressorThread;
+
+# ifdef JS_ION
+    js::WorkerThreadState *workerThreadState;
+# define JS_WORKER_THREADS
+
   private:
     /*
      * Lock taken when using per-runtime or per-zone data that could otherwise
      * be accessed simultaneously by both the main thread and another thread
      * with an ExclusiveContext.
      *
      * Locking this only occurs if there is actually a thread other than the
      * main thread with an ExclusiveContext which could access such data.
@@ -774,30 +781,31 @@ struct JSRuntime : public JS::shadow::Ru
     friend class js::AutoLockForExclusiveAccess;
     friend class js::AutoPauseWorkersForGC;
     friend class js::ThreadDataIter;
 
   public:
     void setUsedByExclusiveThread(JS::Zone *zone);
     void clearUsedByExclusiveThread(JS::Zone *zone);
 
+# endif // JS_ION
 #endif // JS_THREADSAFE
 
     bool currentThreadHasExclusiveAccess() {
-#if defined(JS_THREADSAFE) && defined(DEBUG)
+#if defined(JS_WORKER_THREADS) && defined(DEBUG)
         return (!numExclusiveThreads && mainThreadHasExclusiveAccess) ||
             exclusiveThreadsPaused ||
             exclusiveAccessOwner == PR_GetCurrentThread();
 #else
         return true;
 #endif
     }
 
     bool exclusiveThreadsPresent() const {
-#ifdef JS_THREADSAFE
+#ifdef JS_WORKER_THREADS
         return numExclusiveThreads > 0;
 #else
         return false;
 #endif
     }
 
     /* Embedders can use this zone however they wish. */
     JS::Zone            *systemZone;
@@ -1311,25 +1319,16 @@ struct JSRuntime : public JS::shadow::Ru
     // performing interrupt checks in loops.
   private:
     bool signalHandlersInstalled_;
   public:
     bool signalHandlersInstalled() const {
         return signalHandlersInstalled_;
     }
 
-#ifdef JS_THREADSAFE
-# ifdef JS_ION
-    js::WorkerThreadState *workerThreadState;
-# define JS_WORKER_THREADS
-# endif
-
-    js::SourceCompressorThread sourceCompressorThread;
-#endif
-
   private:
     js::FreeOp          defaultFreeOp_;
 
   public:
     js::FreeOp *defaultFreeOp() {
         return &defaultFreeOp_;
     }