зеркало из https://github.com/mozilla/gecko-dev.git
Bug 907777 - Add preference for off thread parsing, coalesce with preference for off thread Ion compilation, r=billm.
This commit is contained in:
Родитель
6495e92bc1
Коммит
e6289f59db
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче