diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index e33a10ffefd..bcd75cc8234 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -434,8 +434,26 @@ js::EnqueuePendingParseTasksAfterGC(JSRuntime* rt) HelperThreadState().notifyAll(GlobalHelperThreadState::PRODUCER); } -static const uint32_t HELPER_STACK_SIZE = 512 * 1024; -static const uint32_t HELPER_STACK_QUOTA = 450 * 1024; +static const uint32_t kDefaultHelperStackSize = 512 * 1024; +static const uint32_t kDefaultHelperStackQuota = 450 * 1024; + +// TSan enforces a minimum stack size that's just slightly larger than our +// default helper stack size. It does this to store blobs of TSan-specific +// data on each thread's stack. Unfortunately, that means that even though +// we'll actually receive a larger stack than we requested, the effective +// usable space of that stack is significantly less than what we expect. +// To offset TSan stealing our stack space from underneath us, double the +// default. +// +// Note that we don't need this for ASan/MOZ_ASAN because ASan doesn't +// require all the thread-specific state that TSan does. +#if defined(MOZ_TSAN) +static const uint32_t HELPER_STACK_SIZE = 2 * kDefaultHelperStackSize; +static const uint32_t HELPER_STACK_QUOTA = 2 * kDefaultHelperStackQuota; +#else +static const uint32_t HELPER_STACK_SIZE = kDefaultHelperStackSize; +static const uint32_t HELPER_STACK_QUOTA = kDefaultHelperStackQuota; +#endif void GlobalHelperThreadState::ensureInitialized()