Bug 942984 - Set native stack limit for JS worker threads, r=billm.

This commit is contained in:
Brian Hackett 2013-11-26 19:18:04 -07:00
parent 8998a84de1
commit fe02999862
4 changed files with 39 additions and 3 deletions

View File

@ -429,7 +429,10 @@ js_ReportOverRecursed(JSContext *maybecx)
void
js_ReportOverRecursed(ThreadSafeContext *cx)
{
js_ReportOverRecursed(cx->maybeJSContext());
if (cx->isJSContext())
js_ReportOverRecursed(cx->asJSContext());
else if (cx->isExclusiveContext())
cx->asExclusiveContext()->addPendingOverRecursed();
}
void

View File

@ -399,6 +399,7 @@ class ExclusiveContext : public ThreadSafeContext
// Methods specific to any WorkerThread for the context.
frontend::CompileError &addPendingCompileError();
void addPendingOverRecursed();
};
inline void

View File

@ -9,6 +9,7 @@
#ifdef JS_WORKER_THREADS
#include "mozilla/DebugOnly.h"
#include "jsnativestack.h"
#include "prmjtime.h"
#include "frontend/BytecodeCompiler.h"
@ -22,6 +23,7 @@
using namespace js;
using mozilla::ArrayLength;
using mozilla::DebugOnly;
bool
@ -179,7 +181,8 @@ ParseTask::ParseTask(ExclusiveContext *cx, JSContext *initCx,
JS::OffThreadCompileCallback callback, void *callbackData)
: cx(cx), options(initCx), chars(chars), length(length),
alloc(JSRuntime::TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), scopeChain(scopeChain),
callback(callback), callbackData(callbackData), script(nullptr), errors(cx)
callback(callback), callbackData(callbackData), script(nullptr),
errors(cx), overRecursed(false)
{
JSRuntime *rt = scopeChain->runtimeFromMainThread();
@ -308,6 +311,9 @@ js::WaitForOffThreadParsingToFinish(JSRuntime *rt)
}
}
static const uint32_t WORKER_STACK_SIZE = 512 * 1024;
static const uint32_t WORKER_STACK_QUOTA = 450 * 1024;
bool
WorkerThreadState::init()
{
@ -343,7 +349,7 @@ WorkerThreadState::init()
helper.threadData.ref().addToThreadList();
helper.thread = PR_CreateThread(PR_USER_THREAD,
WorkerThread::ThreadMain, &helper,
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, WORKER_STACK_SIZE);
if (!helper.thread || !helper.threadData.ref().init()) {
for (size_t j = 0; j < numThreads; j++)
threads[j].destroy();
@ -576,6 +582,8 @@ WorkerThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void *toke
AutoCompartment ac(maybecx, parseTask->scopeChain);
for (size_t i = 0; i < parseTask->errors.length(); i++)
parseTask->errors[i]->throwError(maybecx);
if (parseTask->overRecursed)
js_ReportOverRecursed(maybecx);
if (script) {
// The Debugger only needs to be told about the topmost script that was compiled.
@ -729,6 +737,13 @@ ExclusiveContext::addPendingCompileError()
return *error;
}
void
ExclusiveContext::addPendingOverRecursed()
{
if (workerThread()->parseTask)
workerThread()->parseTask->overRecursed = true;
}
void
WorkerThread::handleParseWorkload(WorkerThreadState &state)
{
@ -891,6 +906,16 @@ WorkerThread::threadLoop()
js::TlsPerThreadData.set(threadData.addr());
// Compute the thread's stack limit, for over-recursed checks.
uintptr_t stackLimit = GetNativeStackBase();
#if JS_STACK_GROWTH_DIRECTION > 0
stackLimit += WORKER_STACK_QUOTA;
#else
stackLimit -= WORKER_STACK_QUOTA;
#endif
for (size_t i = 0; i < ArrayLength(threadData.ref().nativeStackLimit); i++)
threadData.ref().nativeStackLimit[i] = stackLimit;
while (true) {
JS_ASSERT(!ionBuilder && !asmData);
@ -982,4 +1007,10 @@ ExclusiveContext::addPendingCompileError()
MOZ_ASSUME_UNREACHABLE("Off thread compilation not available.");
}
void
ExclusiveContext::addPendingOverRecursed()
{
MOZ_ASSUME_UNREACHABLE("Off thread compilation not available.");
}
#endif /* JS_WORKER_THREADS */

View File

@ -353,6 +353,7 @@ struct ParseTask
// Any errors or warnings produced during compilation. These are reported
// when finishing the script.
Vector<frontend::CompileError *> errors;
bool overRecursed;
ParseTask(ExclusiveContext *cx, JSContext *initCx,
const jschar *chars, size_t length, JSObject *scopeChain,