Bug 941805 - Use helper thread pool in all runtimes in a process, r=billm.

This commit is contained in:
Brian Hackett 2014-05-29 13:06:23 -06:00
Родитель 4b8339eede
Коммит 4e0b65ef88
22 изменённых файлов: 39 добавлений и 120 удалений

Просмотреть файл

@ -621,7 +621,7 @@ class ThreadLocalJSRuntime
nsresult Init()
{
mRuntime = JS_NewRuntime(sRuntimeHeapSize, JS_NO_HELPER_THREADS);
mRuntime = JS_NewRuntime(sRuntimeHeapSize);
NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY);
/*

Просмотреть файл

@ -781,8 +781,6 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
}
}
JS_SetIsWorkerRuntime(aRuntime);
JS_SetNativeStackQuota(aRuntime, WORKER_CONTEXT_NATIVE_STACK_LIMIT);
// Security policy:
@ -842,8 +840,7 @@ public:
// call to JS_SetGCParameter inside CreateJSContextForWorker.
WorkerJSRuntime(JSRuntime* aParentRuntime, WorkerPrivate* aWorkerPrivate)
: CycleCollectedJSRuntime(aParentRuntime,
WORKER_DEFAULT_RUNTIME_HEAPSIZE,
JS_NO_HELPER_THREADS),
WORKER_DEFAULT_RUNTIME_HEAPSIZE),
mWorkerPrivate(aWorkerPrivate)
{
}

Просмотреть файл

@ -1577,7 +1577,7 @@ WorkerThreadCount(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
#ifdef JS_THREADSAFE
args.rval().setInt32(cx->runtime()->useHelperThreads() ? WorkerThreadState().threadCount : 0);
args.rval().setInt32(WorkerThreadState().threadCount);
#else
args.rval().setInt32(0);
#endif

Просмотреть файл

@ -62,7 +62,7 @@ int
main (int argc, const char **argv)
{
if (!JS_Init()) return 1;
JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024, JS_USE_HELPER_THREADS));
JSRuntime *runtime = checkPtr(JS_NewRuntime(1024 * 1024));
JS_SetGCParameter(runtime, JSGC_MAX_BYTES, 0xffffffff);
JS_SetNativeStackQuota(runtime, 5000000);

Просмотреть файл

@ -1977,21 +1977,6 @@ CheckScriptSize(JSContext *cx, JSScript* script)
uint32_t numLocalsAndArgs = NumLocalsAndArgs(script);
if (cx->runtime()->isWorkerRuntime()) {
// DOM Workers don't have off thread compilation enabled. Since workers
// don't block the browser's event loop, allow them to compile larger
// scripts.
JS_ASSERT(!cx->runtime()->canUseParallelIonCompilation());
if (script->length() > MAX_DOM_WORKER_SCRIPT_SIZE ||
numLocalsAndArgs > MAX_DOM_WORKER_LOCALS_AND_ARGS)
{
return Method_CantCompile;
}
return Method_Compiled;
}
if (script->length() > MAX_MAIN_THREAD_SCRIPT_SIZE ||
numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS)
{

Просмотреть файл

@ -21,11 +21,6 @@ static const uint32_t MAX_OFF_THREAD_SCRIPT_SIZE = 100 * 1000;
static const uint32_t MAX_MAIN_THREAD_SCRIPT_SIZE = 2 * 1000;
static const uint32_t MAX_MAIN_THREAD_LOCALS_AND_ARGS = 256;
// DOM Worker runtimes don't have off thread compilation, but can also compile
// larger scripts since this doesn't stall the main thread.
static const uint32_t MAX_DOM_WORKER_SCRIPT_SIZE = 16 * 1000;
static const uint32_t MAX_DOM_WORKER_LOCALS_AND_ARGS = 2048;
// Possible register allocators which may be used.
enum IonRegisterAllocator {
RegisterAllocator_LSRA,

Просмотреть файл

@ -52,7 +52,7 @@ BEGIN_TEST(testGCOutOfMemory)
}
virtual JSRuntime * createRuntime() {
JSRuntime *rt = JS_NewRuntime(768 * 1024, JS_USE_HELPER_THREADS);
JSRuntime *rt = JS_NewRuntime(768 * 1024);
if (!rt)
return nullptr;
setNativeStackQuota(rt);

Просмотреть файл

@ -17,7 +17,7 @@ BEGIN_TEST(testOOM)
virtual JSRuntime * createRuntime()
{
JSRuntime *rt = JS_NewRuntime(0, JS_USE_HELPER_THREADS);
JSRuntime *rt = JS_NewRuntime(0);
if (!rt)
return nullptr;
JS_SetGCParameter(rt, JSGC_MAX_BYTES, (uint32_t)-1);
@ -54,7 +54,7 @@ BEGIN_TEST(testNewRuntime)
JSRuntime *rt;
START_OOM_TEST("new runtime");
rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS);
rt = JS_NewRuntime(8L * 1024 * 1024);
if (rt)
OOM_TEST_FINISHED;
END_OOM_TEST;

Просмотреть файл

@ -281,7 +281,7 @@ class JSAPITest
}
virtual JSRuntime * createRuntime() {
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_USE_HELPER_THREADS);
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024);
if (!rt)
return nullptr;
setNativeStackQuota(rt);

Просмотреть файл

@ -633,7 +633,7 @@ JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
#endif
JS_PUBLIC_API(JSRuntime *)
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads, JSRuntime *parentRuntime)
JS_NewRuntime(uint32_t maxbytes, JSRuntime *parentRuntime)
{
MOZ_ASSERT(jsInitState == Running,
"must call JS_Init prior to creating any JSRuntimes");
@ -644,7 +644,7 @@ JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads, JSRuntime
// for the main runtime in the process.
JS_ASSERT_IF(parentRuntime, !parentRuntime->parentRuntime);
JSRuntime *rt = js_new<JSRuntime>(parentRuntime, useHelperThreads);
JSRuntime *rt = js_new<JSRuntime>(parentRuntime);
if (!rt)
return nullptr;

Просмотреть файл

@ -1247,12 +1247,6 @@ JS_IsBuiltinFunctionConstructor(JSFunction *fun);
* See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
*/
typedef enum JSUseHelperThreads
{
JS_NO_HELPER_THREADS,
JS_USE_HELPER_THREADS
} JSUseHelperThreads;
/**
* Initialize SpiderMonkey, returning true only if initialization succeeded.
* Once this method has succeeded, it is safe to call JS_NewRuntime and other
@ -1290,8 +1284,7 @@ extern JS_PUBLIC_API(void)
JS_ShutDown(void);
extern JS_PUBLIC_API(JSRuntime *)
JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads,
JSRuntime *parentRuntime = nullptr);
JS_NewRuntime(uint32_t maxbytes, JSRuntime *parentRuntime = nullptr);
extern JS_PUBLIC_API(void)
JS_DestroyRuntime(JSRuntime *rt);

Просмотреть файл

@ -285,7 +285,6 @@ struct ThreadSafeContext : ContextFriendFields,
const JS::AsmJSCacheOps &asmJSCacheOps() { return runtime_->asmJSCacheOps; }
PropertyName *emptyString() { return runtime_->emptyString; }
FreeOp *defaultFreeOp() { return runtime_->defaultFreeOp(); }
bool useHelperThreads() { return runtime_->useHelperThreads(); }
void *runtimeAddressForJit() { return runtime_; }
void *stackLimitAddress(StackKind kind) { return &runtime_->mainThread.nativeStackLimit[kind]; }
void *stackLimitAddressForJitCode(StackKind kind);

Просмотреть файл

@ -74,12 +74,6 @@ JS_GetAnonymousString(JSRuntime *rt)
return rt->commonNames->anonymous;
}
JS_FRIEND_API(void)
JS_SetIsWorkerRuntime(JSRuntime *rt)
{
rt->setIsWorkerRuntime();
}
JS_FRIEND_API(JSObject *)
JS_FindCompilationScope(JSContext *cx, HandleObject objArg)
{

Просмотреть файл

@ -50,9 +50,6 @@ JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
extern JS_FRIEND_API(JSString *)
JS_GetAnonymousString(JSRuntime *rt);
extern JS_FRIEND_API(void)
JS_SetIsWorkerRuntime(JSRuntime *rt);
extern JS_FRIEND_API(JSObject *)
JS_FindCompilationScope(JSContext *cx, JS::HandleObject obj);

Просмотреть файл

@ -2348,11 +2348,6 @@ js::GetCPUCount()
bool
GCHelperState::init()
{
if (!rt->useHelperThreads()) {
backgroundAllocation = false;
return true;
}
#ifdef JS_THREADSAFE
if (!(done = PR_NewCondVar(rt->gc.lock)))
return false;
@ -2360,6 +2355,8 @@ GCHelperState::init()
backgroundAllocation = (GetCPUCount() >= 2);
WorkerThreadState().ensureInitialized();
#else
backgroundAllocation = false;
#endif /* JS_THREADSAFE */
return true;
@ -2368,7 +2365,7 @@ GCHelperState::init()
void
GCHelperState::finish()
{
if (!rt->useHelperThreads() || !rt->gc.lock) {
if (!rt->gc.lock) {
JS_ASSERT(state_ == IDLE);
return;
}
@ -2495,8 +2492,6 @@ GCHelperState::work()
void
GCHelperState::startBackgroundSweep(bool shouldShrink)
{
JS_ASSERT(rt->useHelperThreads());
#ifdef JS_THREADSAFE
AutoLockWorkerThreadState workerLock;
AutoLockGC lock(rt);
@ -2512,8 +2507,6 @@ GCHelperState::startBackgroundSweep(bool shouldShrink)
void
GCHelperState::startBackgroundShrink()
{
JS_ASSERT(rt->useHelperThreads());
#ifdef JS_THREADSAFE
switch (state()) {
case IDLE:
@ -2538,11 +2531,6 @@ GCHelperState::startBackgroundShrink()
void
GCHelperState::waitBackgroundSweepEnd()
{
if (!rt->useHelperThreads()) {
JS_ASSERT(state_ == IDLE);
return;
}
#ifdef JS_THREADSAFE
AutoLockGC lock(rt);
while (state() == SWEEPING)
@ -2555,11 +2543,6 @@ GCHelperState::waitBackgroundSweepEnd()
void
GCHelperState::waitBackgroundSweepOrAllocEnd()
{
if (!rt->useHelperThreads()) {
JS_ASSERT(state_ == IDLE);
return;
}
#ifdef JS_THREADSAFE
AutoLockGC lock(rt);
if (state() == ALLOCATING)
@ -2575,8 +2558,6 @@ GCHelperState::waitBackgroundSweepOrAllocEnd()
inline void
GCHelperState::startBackgroundAllocationIfIdle()
{
JS_ASSERT(rt->useHelperThreads());
#ifdef JS_THREADSAFE
if (state_ == IDLE)
startBackgroundThread(ALLOCATING);
@ -4003,7 +3984,7 @@ GCRuntime::beginSweepPhase(bool lastGC)
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP);
#ifdef JS_THREADSAFE
sweepOnBackgroundThread = !lastGC && rt->useHelperThreads();
sweepOnBackgroundThread = !lastGC;
#endif
#ifdef DEBUG
@ -4991,10 +4972,11 @@ JS::ShrinkGCBuffers(JSRuntime *rt)
AutoLockGC lock(rt);
JS_ASSERT(!rt->isHeapBusy());
if (!rt->useHelperThreads())
ExpireChunksAndArenas(rt, true);
else
rt->gc.startBackgroundShrink();
#ifdef JS_THREADSAFE
rt->gc.startBackgroundShrink();
#else
ExpireChunksAndArenas(rt, true);
#endif
}
void

Просмотреть файл

@ -2887,9 +2887,7 @@ WorkerMain(void *arg)
{
WorkerInput *input = (WorkerInput *) arg;
JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L,
JS_USE_HELPER_THREADS,
input->runtime);
JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L, input->runtime);
if (!rt) {
js_delete(input);
return;
@ -6284,7 +6282,7 @@ main(int argc, char **argv, char **envp)
return 1;
/* Use the same parameters as the browser in xpcjsruntime.cpp. */
rt = JS_NewRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS);
rt = JS_NewRuntime(32L * 1024L * 1024L);
if (!rt)
return 1;

Просмотреть файл

@ -120,7 +120,7 @@ static const JSWrapObjectCallbacks DefaultWrapObjectCallbacks = {
nullptr
};
JSRuntime::JSRuntime(JSRuntime *parentRuntime, JSUseHelperThreads useHelperThreads)
JSRuntime::JSRuntime(JSRuntime *parentRuntime)
: JS::shadow::Runtime(
#ifdef JSGC_GENERATIONAL
&gc.storeBuffer
@ -223,10 +223,8 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime, JSUseHelperThreads useHelperThrea
defaultJSContextCallback(nullptr),
ctypesActivityCallback(nullptr),
forkJoinWarmup(0),
useHelperThreads_(useHelperThreads),
parallelIonCompilationEnabled_(true),
parallelParsingEnabled_(true),
isWorkerRuntime_(false),
#ifdef DEBUG
enteredPolicy(nullptr),
#endif

Просмотреть файл

@ -1269,7 +1269,7 @@ struct JSRuntime : public JS::shadow::Runtime,
return liveRuntimesCount > 0;
}
JSRuntime(JSRuntime *parentRuntime, JSUseHelperThreads useHelperThreads);
JSRuntime(JSRuntime *parentRuntime);
~JSRuntime();
bool init(uint32_t maxbytes);
@ -1335,50 +1335,33 @@ struct JSRuntime : public JS::shadow::Runtime,
private:
JS::RuntimeOptions options_;
JSUseHelperThreads useHelperThreads_;
// Settings for how helper threads can be used.
bool parallelIonCompilationEnabled_;
bool parallelParsingEnabled_;
// True iff this is a DOM Worker runtime.
bool isWorkerRuntime_;
public:
// This controls whether the JSRuntime is allowed to create any helper
// threads at all. This means both specific threads (background GC thread)
// and the general JS worker thread pool.
bool useHelperThreads() const {
#ifdef JS_THREADSAFE
return useHelperThreads_ == JS_USE_HELPER_THREADS;
#else
return false;
#endif
}
// Note: these values may be toggled dynamically (in response to about:config
// prefs changing).
void setParallelIonCompilationEnabled(bool value) {
parallelIonCompilationEnabled_ = value;
}
bool canUseParallelIonCompilation() const {
return useHelperThreads() &&
parallelIonCompilationEnabled_;
#ifdef JS_THREADSAFE
return parallelIonCompilationEnabled_;
#else
return false;
#endif
}
void setParallelParsingEnabled(bool value) {
parallelParsingEnabled_ = value;
}
bool canUseParallelParsing() const {
return useHelperThreads() &&
parallelParsingEnabled_;
}
void setIsWorkerRuntime() {
isWorkerRuntime_ = true;
}
bool isWorkerRuntime() const {
return isWorkerRuntime_;
#ifdef JS_THREADSAFE
return parallelParsingEnabled_;
#else
return false;
#endif
}
const JS::RuntimeOptions &options() const {

Просмотреть файл

@ -3045,7 +3045,7 @@ static const JSWrapObjectCallbacks WrapObjectCallbacks = {
};
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
: CycleCollectedJSRuntime(nullptr, 32L * 1024L * 1024L, JS_USE_HELPER_THREADS),
: CycleCollectedJSRuntime(nullptr, 32L * 1024L * 1024L),
mJSContextStack(new XPCJSContextStack(MOZ_THIS_IN_INITIALIZER_LIST())),
mCallContext(nullptr),
mAutoRoots(nullptr),

Просмотреть файл

@ -544,7 +544,7 @@ private:
nsresult Init()
{
mRuntime = JS_NewRuntime(sRuntimeHeapSize, JS_NO_HELPER_THREADS);
mRuntime = JS_NewRuntime(sRuntimeHeapSize);
NS_ENSURE_TRUE(mRuntime, NS_ERROR_OUT_OF_MEMORY);
/*

Просмотреть файл

@ -466,8 +466,7 @@ NoteJSChildGrayWrapperShim(void* aData, void* aThing)
static const JSZoneParticipant sJSZoneCycleCollectorGlobal;
CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
uint32_t aMaxbytes,
JSUseHelperThreads aUseHelperThreads)
uint32_t aMaxbytes)
: mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal)
, mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal)
, mJSRuntime(nullptr)
@ -477,7 +476,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
{
mozilla::dom::InitScriptSettings();
mJSRuntime = JS_NewRuntime(aMaxbytes, aUseHelperThreads, aParentRuntime);
mJSRuntime = JS_NewRuntime(aMaxbytes, aParentRuntime);
if (!mJSRuntime) {
MOZ_CRASH();
}

Просмотреть файл

@ -114,8 +114,7 @@ class CycleCollectedJSRuntime
friend class IncrementalFinalizeRunnable;
protected:
CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
uint32_t aMaxbytes,
JSUseHelperThreads aUseHelperThreads);
uint32_t aMaxbytes);
virtual ~CycleCollectedJSRuntime();
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;