Bug 907777 - Add preference for off thread parsing, coalesce with preference for off thread Ion compilation, r=billm.

This commit is contained in:
Brian Hackett 2013-08-22 07:22:33 -06:00
Родитель 6495e92bc1
Коммит e6289f59db
14 изменённых файлов: 72 добавлений и 43 удалений

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

@ -698,6 +698,7 @@ static const char js_baselinejit_eager_str[] = JS_OPTIONS_DOT_STR "baselinejit.
static const char js_ion_content_str[] = JS_OPTIONS_DOT_STR "ion.content";
static const char js_ion_chrome_str[] = JS_OPTIONS_DOT_STR "ion.chrome";
static const char js_ion_eager_str[] = JS_OPTIONS_DOT_STR "ion.unsafe_eager_compilation";
static const char js_parallel_parsing_str[] = JS_OPTIONS_DOT_STR "parallel_parsing";
static const char js_ion_parallel_compilation_str[] = JS_OPTIONS_DOT_STR "ion.parallel_compilation";
int
@ -739,6 +740,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
js_ion_content_str);
bool useIonEager = Preferences::GetBool(js_ion_eager_str);
bool useAsmJS = Preferences::GetBool(js_asmjs_content_str);
bool parallelParsing = Preferences::GetBool(js_parallel_parsing_str);
bool parallelIonCompilation = Preferences::GetBool(js_ion_parallel_compilation_str);
nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
if (xr) {
@ -793,7 +795,8 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
::JS_SetOptions(context->mContext, newDefaultJSOptions & JSOPTION_MASK);
::JS_SetParallelCompilationEnabled(context->mContext, parallelIonCompilation);
::JS_SetParallelParsingEnabled(context->mContext, parallelParsing);
::JS_SetParallelIonCompilationEnabled(context->mContext, parallelIonCompilation);
::JS_SetGlobalCompilerOption(context->mContext, JSCOMPILER_BASELINE_USECOUNT_TRIGGER,
(useBaselineJITEager ? 0 : -1));

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

@ -4819,7 +4819,7 @@ ParallelCompilationEnabled(ExclusiveContext *cx)
if (!cx->isJSContext())
return cx->workerThreadState()->numThreads > 1;
return OffThreadCompilationEnabled(cx->asJSContext());
return OffThreadIonCompilationEnabled(cx->asJSContext()->runtime());
}
// State of compilation as tracked and updated by the main thread.

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

@ -1592,7 +1592,7 @@ OffThreadCompilationAvailable(JSContext *cx)
// Also skip off thread compilation if the SPS profiler is enabled, as it
// stores strings in the spsProfiler data structure, which is not protected
// by a lock.
return OffThreadCompilationEnabled(cx)
return OffThreadIonCompilationEnabled(cx->runtime())
&& cx->runtime()->gcIncrementalState == gc::NO_INCREMENTAL
&& !cx->runtime()->profilingScripts
&& !cx->runtime()->spsProfiler.enabled();
@ -1773,7 +1773,7 @@ CheckScriptSize(JSContext *cx, JSScript* script)
if (script->length > MAX_MAIN_THREAD_SCRIPT_SIZE ||
numLocalsAndArgs > MAX_MAIN_THREAD_LOCALS_AND_ARGS)
{
if (OffThreadCompilationEnabled(cx)) {
if (OffThreadIonCompilationEnabled(cx->runtime())) {
// Even if off thread compilation is enabled, there are cases where
// compilation must still occur on the main thread. Don't compile
// in these cases (except when profiling scripts, as compilations

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

@ -93,11 +93,6 @@ struct IonOptions
// Default: true
bool eaa;
// Toggles whether compilation occurs off the main thread.
//
// Default: true iff there are at least two CPUs available
bool parallelCompilation;
#ifdef CHECK_OSIPOINT_REGISTERS
// Emit extra code to verify live regs at the start of a VM call
// are not modified before its OsiPoint.
@ -204,8 +199,6 @@ struct IonOptions
eagerCompilation = true;
usesBeforeCompile = 0;
baselineUsesBeforeCompile = 0;
parallelCompilation = false;
}
IonOptions()
@ -221,7 +214,6 @@ struct IonOptions
checkRangeAnalysis(false),
uce(true),
eaa(true),
parallelCompilation(false),
#ifdef CHECK_OSIPOINT_REGISTERS
checkOsiPointRegisters(false),
#endif

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

@ -9038,9 +9038,6 @@ IonBuilder::addShapeGuard(MDefinition *obj, Shape *const shape, BailoutKind bail
types::StackTypeSet *
IonBuilder::cloneTypeSet(types::StackTypeSet *types)
{
if (!js_IonOptions.parallelCompilation)
return types;
// Clone a type set so that it can be stored into the MIR and accessed
// during off thread compilation. This is necessary because main thread
// updates to type sets can race with reads in the compiler backend, and

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

@ -8,6 +8,8 @@
#include "jit/IonSpewer.h"
#include "jsworkers.h"
#include "jit/Ion.h"
#ifndef ION_SPEW_DIR
@ -79,7 +81,7 @@ ion::EnableIonDebugLogging()
void
ion::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
{
if (!js_IonOptions.parallelCompilation) {
if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime)) {
ionspewer.beginFunction(graph, func);
} else {
if (func) {
@ -96,21 +98,21 @@ ion::IonSpewNewFunction(MIRGraph *graph, HandleScript func)
void
ion::IonSpewPass(const char *pass)
{
if (!js_IonOptions.parallelCompilation)
if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
ionspewer.spewPass(pass);
}
void
ion::IonSpewPass(const char *pass, LinearScanAllocator *ra)
{
if (!js_IonOptions.parallelCompilation)
if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
ionspewer.spewPass(pass, ra);
}
void
ion::IonSpewEndFunction()
{
if (!js_IonOptions.parallelCompilation)
if (!OffThreadIonCompilationEnabled(GetIonContext()->runtime))
ionspewer.endFunction();
}

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

@ -11,6 +11,8 @@
#include <limits.h>
#include "jsworkers.h"
#include "jit/IonAllocPolicy.h"
#include "jit/Registers.h"
#include "jit/RegisterSets.h"
@ -269,8 +271,8 @@ class Label : public LabelBase
#ifdef DEBUG
// Note: the condition is a hack to silence this assert when OOM testing,
// see bug 756614.
if (!js_IonOptions.parallelCompilation)
JS_ASSERT_IF(MaybeGetIonContext() && !GetIonContext()->runtime->hadOutOfMemory, !used());
if (MaybeGetIonContext() && !OffThreadIonCompilationEnabled(GetIonContext()->runtime))
JS_ASSERT_IF(!GetIonContext()->runtime->hadOutOfMemory, !used());
#endif
}
};

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

@ -4839,10 +4839,13 @@ JS::Compile(JSContext *cx, HandleObject obj, CompileOptions options, const char
JS_PUBLIC_API(bool)
JS::CanCompileOffThread(JSContext *cx, const CompileOptions &options)
{
#if defined(JS_THREADSAFE) && defined(JS_ION)
#ifdef JS_WORKER_THREADS
if (!cx->runtime()->useHelperThreads() || !cx->runtime()->helperThreadCount())
return false;
if (!cx->runtime()->useHelperThreadsForParsing())
return false;
// Off thread compilation can't occur during incremental collections on the
// atoms compartment, to avoid triggering barriers. Outside the atoms
// compartment, the compilation will use a new zone which doesn't require
@ -4880,7 +4883,7 @@ JS::CompileOffThread(JSContext *cx, Handle<JSObject*> obj, CompileOptions option
const jschar *chars, size_t length,
OffThreadCompileCallback callback, void *callbackData)
{
#if defined(JS_THREADSAFE) && defined(JS_ION)
#ifdef JS_WORKER_THREADS
JS_ASSERT(CanCompileOffThread(cx, options));
return StartOffThreadParseScript(cx, options, chars, length, obj, callback, callbackData);
#else
@ -4891,7 +4894,7 @@ JS::CompileOffThread(JSContext *cx, Handle<JSObject*> obj, CompileOptions option
JS_PUBLIC_API(void)
JS::FinishOffThreadScript(JSRuntime *rt, JSScript *script)
{
#if defined(JS_THREADSAFE) && defined(JS_ION)
#ifdef JS_WORKER_THREADS
JS_ASSERT(CurrentThreadCanAccessRuntime(rt));
rt->workerThreadState->finishParseTaskForScript(rt, script);
#else
@ -6636,10 +6639,18 @@ JS_ScheduleGC(JSContext *cx, uint32_t count)
#endif
JS_PUBLIC_API(void)
JS_SetParallelCompilationEnabled(JSContext *cx, bool enabled)
JS_SetParallelParsingEnabled(JSContext *cx, bool enabled)
{
#ifdef JS_ION
ion::js_IonOptions.parallelCompilation = enabled;
cx->runtime()->setCanUseHelperThreadsForParsing(enabled);
#endif
}
JS_PUBLIC_API(void)
JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled)
{
#ifdef JS_ION
cx->runtime()->setCanUseHelperThreadsForIonCompilation(enabled);
#endif
}
@ -6661,11 +6672,6 @@ JS_SetGlobalCompilerOption(JSContext *cx, JSCompilerOption opt, uint32_t value)
ion::js_IonOptions.usesBeforeCompile = value;
ion::js_IonOptions.eagerCompilation = (value == 0);
break;
case JSCOMPILER_PJS_ENABLE:
if (value == uint32_t(-1))
value = uint32_t(defaultValues.parallelCompilation);
ion::js_IonOptions.parallelCompilation = bool(value);
break;
}
#endif
}

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

@ -5196,12 +5196,14 @@ JS_ScheduleGC(JSContext *cx, uint32_t count);
#endif
extern JS_PUBLIC_API(void)
JS_SetParallelCompilationEnabled(JSContext *cx, bool enabled);
JS_SetParallelParsingEnabled(JSContext *cx, bool enabled);
extern JS_PUBLIC_API(void)
JS_SetParallelIonCompilationEnabled(JSContext *cx, bool enabled);
typedef enum JSCompilerOption {
JSCOMPILER_BASELINE_USECOUNT_TRIGGER,
JSCOMPILER_ION_USECOUNT_TRIGGER,
JSCOMPILER_PJS_ENABLE
JSCOMPILER_ION_USECOUNT_TRIGGER
} JSCompilerOption;
extern JS_PUBLIC_API(void)

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

@ -186,12 +186,12 @@ struct WorkerThread
#endif /* JS_THREADSAFE && JS_ION */
inline bool
OffThreadCompilationEnabled(JSContext *cx)
OffThreadIonCompilationEnabled(JSRuntime *rt)
{
#ifdef JS_WORKER_THREADS
return ion::js_IonOptions.parallelCompilation
&& cx->runtime()->useHelperThreads()
&& cx->runtime()->helperThreadCount() != 0;
return rt->useHelperThreads()
&& rt->helperThreadCount() != 0
&& rt->useHelperThreadsForIonCompilation();
#else
return false;
#endif

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

@ -5151,19 +5151,23 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
ion::js_IonOptions.compileTryCatch = true;
#ifdef JS_THREADSAFE
bool parallelCompilation = false;
if (const char *str = op->getStringOption("ion-parallel-compile")) {
if (strcmp(str, "on") == 0) {
if (cx->runtime()->helperThreadCount() == 0) {
fprintf(stderr, "Parallel compilation not available without helper threads");
return EXIT_FAILURE;
}
ion::js_IonOptions.parallelCompilation = true;
} else if (strcmp(str, "off") == 0) {
ion::js_IonOptions.parallelCompilation = false;
} else {
parallelCompilation = true;
} else if (strcmp(str, "off") != 0) {
return OptionFailure("ion-parallel-compile", str);
}
}
/*
* Note: In shell builds, parallel compilation is only enabled with an
* explicit option.
*/
cx->runtime()->setCanUseHelperThreadsForIonCompilation(parallelCompilation);
#endif /* JS_THREADSAFE */
#endif /* JS_ION */

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

@ -269,7 +269,9 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
parallelWarmup(0),
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
useHelperThreads_(useHelperThreads),
requestedHelperThreadCount(-1)
requestedHelperThreadCount(-1),
useHelperThreadsForIonCompilation_(true),
useHelperThreadsForParsing_(true)
#ifdef DEBUG
, enteredPolicy(NULL)
#endif

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

@ -1576,6 +1576,10 @@ struct JSRuntime : public JS::shadow::Runtime,
JSUseHelperThreads useHelperThreads_;
int32_t requestedHelperThreadCount;
// Settings for how helper threads can be used.
bool useHelperThreadsForIonCompilation_;
bool useHelperThreadsForParsing_;
public:
bool useHelperThreads() const {
@ -1601,6 +1605,20 @@ struct JSRuntime : public JS::shadow::Runtime,
#endif
}
void setCanUseHelperThreadsForIonCompilation(bool value) {
useHelperThreadsForIonCompilation_ = value;
}
bool useHelperThreadsForIonCompilation() const {
return useHelperThreadsForIonCompilation_;
}
void setCanUseHelperThreadsForParsing(bool value) {
useHelperThreadsForParsing_ = value;
}
bool useHelperThreadsForParsing() const {
return useHelperThreadsForParsing_;
}
#ifdef DEBUG
public:
js::AutoEnterPolicy *enteredPolicy;

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

@ -821,6 +821,7 @@ pref("javascript.options.baselinejit.chrome", true);
pref("javascript.options.ion.content", true);
pref("javascript.options.ion.chrome", false);
pref("javascript.options.asmjs", true);
pref("javascript.options.parallel_parsing", true);
pref("javascript.options.ion.parallel_compilation", true);
pref("javascript.options.jit_hardening", true);
pref("javascript.options.typeinference.content", true);