Bug 714050 - Add support for optional JS helper threads (r=luke)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 16 Oct 2012 11:57:09 -0700
changeset 110597 3f603fdf63564ea2b9eb1b5ed1ebf98263b990fb
parent 110596 557cfb0bdc396835d11d6d1f62316fbd92df96cf
child 110598 08302471419d5635e79c4d8b0adba82af11d7998
push id23700
push userryanvm@gmail.com
push dateThu, 18 Oct 2012 02:10:26 +0000
treeherdermozilla-central@5142bbd4da12 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs714050
milestone19.0a1
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 714050 - Add support for optional JS helper threads (r=luke)
dom/indexedDB/IDBObjectStore.cpp
dom/workers/RuntimeService.cpp
gfx/skia/src/xml/SkJS.cpp
js/src/jsapi-tests/testGCOutOfMemory.cpp
js/src/jsapi-tests/testOOM.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/shell/js.cpp
js/xpconnect/src/XPCJSRuntime.cpp
netwerk/base/src/ProxyAutoConfig.cpp
startupcache/test/TestStartupCache.cpp
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -492,17 +492,17 @@ class ThreadLocalJSRuntime
   ThreadLocalJSRuntime()
   : mRuntime(NULL), mContext(NULL), mGlobal(NULL)
   {
       MOZ_COUNT_CTOR(ThreadLocalJSRuntime);
   }
 
   nsresult Init()
   {
-    mRuntime = JS_NewRuntime(sRuntimeHeapSize);
+    mRuntime = JS_NewRuntime(sRuntimeHeapSize, JS_NO_HELPER_THREADS);
     NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY);
 
     mContext = JS_NewContext(mRuntime, 0);
     NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY);
 
     JSAutoRequest ar(mContext);
 
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, NULL);
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -378,17 +378,17 @@ ContentSecurityPolicyAllows(JSContext* a
 JSContext*
 CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate)
 {
   aWorkerPrivate->AssertIsOnWorkerThread();
   NS_ASSERTION(!aWorkerPrivate->GetJSContext(), "Already has a context!");
 
   // The number passed here doesn't matter, we're about to change it in the call
   // to JS_SetGCParameter.
-  JSRuntime* runtime = JS_NewRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE);
+  JSRuntime* runtime = JS_NewRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE, JS_NO_HELPER_THREADS);
   if (!runtime) {
     NS_WARNING("Could not create new runtime!");
     return nullptr;
   }
 
   // This is the real place where we set the max memory for the runtime.
   JS_SetGCParameter(runtime, JSGC_MAX_BYTES,
                     aWorkerPrivate->GetJSRuntimeHeapSize());
--- a/gfx/skia/src/xml/SkJS.cpp
+++ b/gfx/skia/src/xml/SkJS.cpp
@@ -154,17 +154,17 @@ JSClass global_class = {
     "global", JSCLASS_NEW_RESOLVE,
     JS_PropertyStub,  JS_PropertyStub,
     JS_PropertyStub,  JS_PropertyStub,
     global_enumerate, (JSResolveOp) global_resolve,
     JS_ConvertStub,   JS_FinalizeStub
 };
 
 SkJS::SkJS(void* hwnd) : SkOSWindow(hwnd) {
-    if ((fRuntime = JS_NewRuntime(0x100000)) == NULL) {
+    if ((fRuntime = JS_NewRuntime(0x100000, JS_NO_HELPER_THREADS)) == NULL) {
         SkASSERT(0);
         return;
     }
     if ((fContext = JS_NewContext(fRuntime, 0x1000)) == NULL) {
         SkASSERT(0);
         return;
     }
     ;
--- a/js/src/jsapi-tests/testGCOutOfMemory.cpp
+++ b/js/src/jsapi-tests/testGCOutOfMemory.cpp
@@ -45,16 +45,16 @@ BEGIN_TEST(testGCOutOfMemory)
          "        array.push({});"
          "    }"
          "})();", root.address());
     CHECK_EQUAL(errorCount, 1);
     return true;
 }
 
 virtual JSRuntime * createRuntime() {
-    return JS_NewRuntime(512 * 1024);
+    return JS_NewRuntime(512 * 1024, JS_USE_HELPER_THREADS);
 }
 
 virtual void destroyRuntime() {
     JS_DestroyRuntime(rt);
 }
 
 END_TEST(testGCOutOfMemory)
--- a/js/src/jsapi-tests/testOOM.cpp
+++ b/js/src/jsapi-tests/testOOM.cpp
@@ -13,13 +13,13 @@ BEGIN_TEST(testOOM)
     JS_SetProperty(cx, global, "rootme", &tmp);
     mozilla::DebugOnly<const jschar *> s = JS_GetStringCharsZ(cx, jsstr);
     JS_ASSERT(s[0] == '9' && s[1] == '\0');
     return true;
 }
 
 virtual JSRuntime * createRuntime()
 {
-    JSRuntime *rt = JS_NewRuntime(0);
+    JSRuntime *rt = JS_NewRuntime(0, JS_USE_HELPER_THREADS);
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, (uint32_t)-1);
     return rt;
 }
 END_TEST(testOOM)
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -249,17 +249,17 @@ class JSAPITest
         fflush(stdout);
         JS_SET_RVAL(cx, vp, JSVAL_VOID);
         return JS_TRUE;
     }
 
     bool definePrint();
 
     virtual JSRuntime * createRuntime() {
-        JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024);
+        JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS);
         if (!rt)
             return NULL;
 
         const size_t MAX_STACK_SIZE =
 /* Assume we can't use more than 5e5 bytes of C stack by default. */
 #if (defined(DEBUG) && defined(__SUNPRO_CC))  || defined(JS_CPU_SPARC)
             /*
              * Sun compiler uses a larger stack space for js::Interpret() with
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -711,17 +711,17 @@ JS_FRIEND_API(void) LeaveAssertNoGCScope
 JS_FRIEND_API(bool) InNoGCScope() { return false; }
 JS_FRIEND_API(bool) NeedRelaxedRootChecks() { return false; }
 #endif
 
 } /* namespace JS */
 
 static const JSSecurityCallbacks NullSecurityCallbacks = { };
 
-JSRuntime::JSRuntime()
+JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
   : atomsCompartment(NULL),
 #ifdef JS_THREADSAFE
     ownerThread_(NULL),
 #endif
     tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     execAlloc_(NULL),
     bumpAlloc_(NULL),
@@ -858,17 +858,18 @@ JSRuntime::JSRuntime()
 #endif
     inOOMReport(0),
     jitHardening(false),
     ionTop(NULL),
     ionJSContext(NULL),
     ionStackLimit(0),
     ionActivation(NULL),
     ionPcScriptCache(NULL),
-    ionReturnOverride_(MagicValue(JS_ARG_POISON))
+    ionReturnOverride_(MagicValue(JS_ARG_POISON)),
+    useHelperThreads_(useHelperThreads)
 {
     /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
     JS_INIT_CLIST(&contextList);
     JS_INIT_CLIST(&debuggerList);
     JS_INIT_CLIST(&onNewGlobalObjectWatchers);
 
     PodZero(&debugHooks);
     PodZero(&atomState);
@@ -1055,17 +1056,17 @@ JS_FRIEND_API(void)
 JSRuntime::assertValidThread() const
 {
     JS_ASSERT(ownerThread_ == PR_GetCurrentThread());
     JS_ASSERT(this == JS::TlsRuntime.get());
 }
 #endif  /* JS_THREADSAFE */
 
 JS_PUBLIC_API(JSRuntime *)
-JS_NewRuntime(uint32_t maxbytes)
+JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads)
 {
     if (!js_NewRuntimeWasCalled) {
 #ifdef DEBUG
         /*
          * This code asserts that the numbers associated with the error names
          * in jsmsg.def are monotonically increasing.  It uses values for the
          * error names enumerated in jscntxt.c.  It's not a compile-time check
          * but it's better than nothing.
@@ -1093,17 +1094,17 @@ JS_NewRuntime(uint32_t maxbytes)
         InitMemorySubsystem();
 
         if (!JS::TlsRuntime.init())
             return NULL;
 
         js_NewRuntimeWasCalled = JS_TRUE;
     }
 
-    JSRuntime *rt = js_new<JSRuntime>();
+    JSRuntime *rt = js_new<JSRuntime>(useHelperThreads);
     if (!rt)
         return NULL;
 
 #if defined(JS_METHODJIT) && defined(JS_ION)
     if (!ion::InitializeIon())
         return NULL;
 #endif
 
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2921,18 +2921,24 @@ JS_IsBuiltinFunctionConstructor(JSFuncti
  * single-threaded fashion, otherwise the behavior of the library is undefined.
  * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
  */
 #define JS_NewRuntime       JS_Init
 #define JS_DestroyRuntime   JS_Finish
 #define JS_LockRuntime      JS_Lock
 #define JS_UnlockRuntime    JS_Unlock
 
+typedef enum JSUseHelperThreads
+{
+    JS_NO_HELPER_THREADS,
+    JS_USE_HELPER_THREADS
+} JSUseHelperThreads;
+
 extern JS_PUBLIC_API(JSRuntime *)
-JS_NewRuntime(uint32_t maxbytes);
+JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads);
 
 /* Deprecated. */
 #define JS_CommenceRuntimeShutDown(rt) ((void) 0)
 
 extern JS_PUBLIC_API(void)
 JS_DestroyRuntime(JSRuntime *rt);
 
 extern JS_PUBLIC_API(void)
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -976,17 +976,17 @@ struct JSRuntime : js::RuntimeFriendFiel
         ionReturnOverride_ = js::MagicValue(JS_ARG_POISON);
         return v;
     }
     void setIonReturnOverride(const js::Value &v) {
         JS_ASSERT(!hasIonReturnOverride());
         ionReturnOverride_ = v;
     }
 
-    JSRuntime();
+    JSRuntime(JSUseHelperThreads useHelperThreads);
     ~JSRuntime();
 
     bool init(uint32_t maxbytes);
 
     JSRuntime *thisFromCtor() { return this; }
 
     /*
      * Call the system malloc while checking for GC memory pressure and
@@ -1093,16 +1093,27 @@ struct JSRuntime : js::RuntimeFriendFiel
 
     void setJitHardening(bool enabled);
     bool getJitHardening() const {
         return jitHardening;
     }
 
     void sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, JS::RuntimeSizes *runtime);
     size_t sizeOfExplicitNonHeap();
+
+  private:
+    JSUseHelperThreads useHelperThreads_;
+  public:
+    bool useHelperThreads() const {
+#ifdef JS_THREADSAFE
+        return useHelperThreads_ == JS_USE_HELPER_THREADS;
+#else
+        return false;
+#endif
+    }
 };
 
 /* Common macros to access thread-local caches in JSRuntime. */
 #define JS_KEEP_ATOMS(rt)   (rt)->gcKeepAtoms++;
 #define JS_UNKEEP_ATOMS(rt) (rt)->gcKeepAtoms--;
 
 namespace js {
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4939,17 +4939,17 @@ main(int argc, char **argv, char **envp)
 #ifdef XP_WIN
     // Set the timer calibration delay count to 0 so we get high
     // resolution right away, which we need for precise benchmarking.
     extern int CALIBRATION_DELAY_COUNT;
     CALIBRATION_DELAY_COUNT = 0;
 #endif
 
     /* Use the same parameters as the browser in xpcjsruntime.cpp. */
-    rt = JS_NewRuntime(32L * 1024L * 1024L);
+    rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS);
     if (!rt)
         return 1;
 
     JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
 
     JS_SetTrustedPrincipals(rt, &shellTrustedPrincipals);
     JS_SetSecurityCallbacks(rt, &securityCallbacks);
 
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2279,17 +2279,17 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     Preferences::AddBoolVarCache(&gExperimentalBindingsEnabled,
                                  "dom.experimental_bindings",
                                  false);
 
 
     // these jsids filled in later when we have a JSContext to work with.
     mStrIDs[0] = JSID_VOID;
 
-    mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L); // pref ?
+    mJSRuntime = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS); // pref ?
     if (!mJSRuntime)
         NS_RUNTIMEABORT("JS_NewRuntime failed.");
 
     // Unconstrain the runtime's threshold on nominal heap size, to avoid
     // triggering GC too often if operating continuously near an arbitrary
     // finite threshold (0xffffffff is infinity for uint32_t parameters).
     // This leaves the maximum-JS_malloc-bytes threshold still in effect
     // to cause period, and we hope hygienic, last-ditch GCs from within
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -516,17 +516,17 @@ private:
   JSRuntimeWrapper()
     : mRuntime(nullptr), mContext(nullptr), mGlobal(nullptr), mOK(false)
   {
       MOZ_COUNT_CTOR(JSRuntimeWrapper);
   }
 
   nsresult Init()
   {
-    mRuntime = JS_NewRuntime(sRuntimeHeapSize);
+    mRuntime = JS_NewRuntime(sRuntimeHeapSize, JS_NO_HELPER_THREADS);
     NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY);
 
     mContext = JS_NewContext(mRuntime, 0);
     NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY);
 
     JSAutoRequest ar(mContext);
 
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr);
--- a/startupcache/test/TestStartupCache.cpp
+++ b/startupcache/test/TestStartupCache.cpp
@@ -283,17 +283,17 @@ TestEarlyShutdown() {
   }
  
   return NS_OK;
 }
 
 bool
 SetupJS(JSContext **cxp)
 {
-  JSRuntime *rt = JS_NewRuntime(32 * 1024 * 1024);
+  JSRuntime *rt = JS_NewRuntime(32 * 1024 * 1024, JS_NO_HELPER_THREADS);
   if (!rt)
     return false;
   JSContext *cx = JS_NewContext(rt, 8192);
   if (!cx)
     return false;
   *cxp = cx;
   return true;
 }