diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index be6562d4a0a4..90012de8a1d6 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -51,11 +51,11 @@ js::DestroyHelperThreadsState() gHelperThreadState = nullptr; } -void +bool js::EnsureHelperThreadsInitialized() { MOZ_ASSERT(gHelperThreadState); - gHelperThreadState->ensureInitialized(); + return gHelperThreadState->ensureInitialized(); } static size_t @@ -453,7 +453,7 @@ static const uint32_t HELPER_STACK_SIZE = kDefaultHelperStackSize; static const uint32_t HELPER_STACK_QUOTA = kDefaultHelperStackQuota; #endif -void +bool GlobalHelperThreadState::ensureInitialized() { MOZ_ASSERT(CanUseExtraThreads()); @@ -462,11 +462,11 @@ GlobalHelperThreadState::ensureInitialized() AutoLockHelperThreadState lock; if (threads) - return; + return true; threads = js_pod_calloc(threadCount); if (!threads) - CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized"); + return false; for (size_t i = 0; i < threadCount; i++) { HelperThread& helper = threads[i]; @@ -474,11 +474,15 @@ GlobalHelperThreadState::ensureInitialized() helper.thread = PR_CreateThread(PR_USER_THREAD, HelperThread::ThreadMain, &helper, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, HELPER_STACK_SIZE); - if (!helper.thread || !helper.threadData->init()) - CrashAtUnhandlableOOM("GlobalHelperThreadState::ensureInitialized"); + if (!helper.thread || !helper.threadData->init()) { + finishThreads(); + return false; + } } resetAsmJSFailureState(); + + return true; } GlobalHelperThreadState::GlobalHelperThreadState() @@ -510,12 +514,7 @@ GlobalHelperThreadState::GlobalHelperThreadState() void GlobalHelperThreadState::finish() { - if (threads) { - MOZ_ASSERT(CanUseExtraThreads()); - for (size_t i = 0; i < threadCount; i++) - threads[i].destroy(); - js_free(threads); - } + finishThreads(); PR_DestroyCondVar(consumerWakeup); PR_DestroyCondVar(producerWakeup); @@ -525,6 +524,19 @@ GlobalHelperThreadState::finish() ionLazyLinkList_.clear(); } +void +GlobalHelperThreadState::finishThreads() +{ + if (!threads) + return; + + MOZ_ASSERT(CanUseExtraThreads()); + for (size_t i = 0; i < threadCount; i++) + threads[i].destroy(); + js_free(threads); + threads = nullptr; +} + void GlobalHelperThreadState::lock() { diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index 368028d590ce..b11160808420 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -103,8 +103,9 @@ class GlobalHelperThreadState GlobalHelperThreadState(); - void ensureInitialized(); + bool ensureInitialized(); void finish(); + void finishThreads(); void lock(); void unlock(); @@ -351,7 +352,7 @@ void DestroyHelperThreadsState(); // Initialize helper threads unless already initialized. -void +bool EnsureHelperThreadsInitialized(); // This allows the JS shell to override GetCPUCount() when passed the diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index 9f46439ec3a4..54e6d09121c1 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -283,10 +283,10 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) if (!regexpStack.init()) return false; - js::TlsPerThreadData.set(&mainThread); + if (CanUseExtraThreads() && !EnsureHelperThreadsInitialized()) + return false; - if (CanUseExtraThreads()) - EnsureHelperThreadsInitialized(); + js::TlsPerThreadData.set(&mainThread); if (!gc.init(maxbytes, maxNurseryBytes)) return false;