зеркало из https://github.com/mozilla/gecko-dev.git
Bug 820583 - Use a larger script size limit when compiling off thread, r=dvander.
This commit is contained in:
Родитель
944e9bba9f
Коммит
b42b809fbc
|
@ -1198,6 +1198,28 @@ IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *o
|
||||||
return abortReason;
|
return abortReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
OffThreadCompilationEnabled(JSContext *cx)
|
||||||
|
{
|
||||||
|
return js_IonOptions.parallelCompilation
|
||||||
|
&& cx->runtime->useHelperThreads()
|
||||||
|
&& cx->runtime->helperThreadCount() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
OffThreadCompilationAvailable(JSContext *cx)
|
||||||
|
{
|
||||||
|
// Even if off thread compilation is enabled, compilation must still occur
|
||||||
|
// on the main thread in some cases. Do not compile off thread during an
|
||||||
|
// incremental GC, as this may trip incremental read barriers. Also skip
|
||||||
|
// off thread compilation if script execution is being profiled, as
|
||||||
|
// CodeGenerator::maybeCreateScriptCounts will not attach script profiles
|
||||||
|
// when running off thread.
|
||||||
|
return OffThreadCompilationEnabled(cx)
|
||||||
|
&& cx->runtime->gcIncrementalState == gc::NO_INCREMENTAL
|
||||||
|
&& !cx->runtime->profilingScripts;
|
||||||
|
}
|
||||||
|
|
||||||
AbortReason
|
AbortReason
|
||||||
SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
|
SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
|
||||||
AutoDestroyAllocator &autoDestroy)
|
AutoDestroyAllocator &autoDestroy)
|
||||||
|
@ -1214,16 +1236,8 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
|
||||||
}
|
}
|
||||||
builder->clearForBackEnd();
|
builder->clearForBackEnd();
|
||||||
|
|
||||||
// Try to compile the script off thread, if possible. Compilation cannot be
|
// If possible, compile the script off thread.
|
||||||
// performed off thread during an incremental GC, as doing so may trip
|
if (OffThreadCompilationAvailable(cx)) {
|
||||||
// incremental read barriers. Also skip off thread compilation if script
|
|
||||||
// execution is being profiled, as CodeGenerator::maybeCreateScriptCounts
|
|
||||||
// will not attach script profiles when running off thread.
|
|
||||||
if (js_IonOptions.parallelCompilation &&
|
|
||||||
OffThreadCompilationAvailable(cx) &&
|
|
||||||
cx->runtime->gcIncrementalState == gc::NO_INCREMENTAL &&
|
|
||||||
!cx->runtime->profilingScripts)
|
|
||||||
{
|
|
||||||
builder->script()->ion = ION_COMPILING_SCRIPT;
|
builder->script()->ion = ION_COMPILING_SCRIPT;
|
||||||
|
|
||||||
if (!StartOffThreadIonCompile(cx, builder)) {
|
if (!StartOffThreadIonCompile(cx, builder)) {
|
||||||
|
@ -1332,27 +1346,47 @@ CheckScript(UnrootedScript script)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static MethodStatus
|
||||||
CheckScriptSize(UnrootedScript script)
|
CheckScriptSize(JSContext *cx, UnrootedScript script)
|
||||||
{
|
{
|
||||||
if (!js_IonOptions.limitScriptSize)
|
if (!js_IonOptions.limitScriptSize)
|
||||||
return true;
|
return Method_Compiled;
|
||||||
|
|
||||||
static const uint32_t MAX_SCRIPT_SIZE = 2000;
|
// Longer scripts can only be compiled off thread, as these compilations
|
||||||
|
// can be expensive and stall the main thread for too long.
|
||||||
|
static const uint32_t MAX_MAIN_THREAD_SCRIPT_SIZE = 2000;
|
||||||
|
static const uint32_t MAX_OFF_THREAD_SCRIPT_SIZE = 20000;
|
||||||
static const uint32_t MAX_LOCALS_AND_ARGS = 256;
|
static const uint32_t MAX_LOCALS_AND_ARGS = 256;
|
||||||
|
|
||||||
if (script->length > MAX_SCRIPT_SIZE) {
|
if (script->length > MAX_OFF_THREAD_SCRIPT_SIZE) {
|
||||||
IonSpew(IonSpew_Abort, "Script too large (%u bytes)", script->length);
|
IonSpew(IonSpew_Abort, "Script too large (%u bytes)", script->length);
|
||||||
return false;
|
return Method_CantCompile;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (script->length > MAX_MAIN_THREAD_SCRIPT_SIZE) {
|
||||||
|
if (OffThreadCompilationEnabled(cx)) {
|
||||||
|
// 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
|
||||||
|
// occurring with profiling should reflect those without), but do
|
||||||
|
// not forbid compilation so that the script may be compiled later.
|
||||||
|
if (!OffThreadCompilationAvailable(cx) && !cx->runtime->profilingScripts) {
|
||||||
|
IonSpew(IonSpew_Abort, "Script too large for main thread, skipping (%u bytes)", script->length);
|
||||||
|
return Method_Skipped;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IonSpew(IonSpew_Abort, "Script too large (%u bytes)", script->length);
|
||||||
|
return Method_CantCompile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t numLocalsAndArgs = analyze::TotalSlots(script);
|
uint32_t numLocalsAndArgs = analyze::TotalSlots(script);
|
||||||
if (numLocalsAndArgs > MAX_LOCALS_AND_ARGS) {
|
if (numLocalsAndArgs > MAX_LOCALS_AND_ARGS) {
|
||||||
IonSpew(IonSpew_Abort, "Too many locals and arguments (%u)", numLocalsAndArgs);
|
IonSpew(IonSpew_Abort, "Too many locals and arguments (%u)", numLocalsAndArgs);
|
||||||
return false;
|
return Method_CantCompile;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return Method_Compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodStatus
|
static MethodStatus
|
||||||
|
@ -1366,11 +1400,17 @@ Compile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrP
|
||||||
return Method_CantCompile;
|
return Method_CantCompile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CheckScript(script) || !CheckScriptSize(script)) {
|
if (!CheckScript(script)) {
|
||||||
IonSpew(IonSpew_Abort, "Aborted compilation of %s:%d", script->filename, script->lineno);
|
IonSpew(IonSpew_Abort, "Aborted compilation of %s:%d", script->filename, script->lineno);
|
||||||
return Method_CantCompile;
|
return Method_CantCompile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodStatus status = CheckScriptSize(cx, script);
|
||||||
|
if (status != Method_Compiled) {
|
||||||
|
IonSpew(IonSpew_Abort, "Aborted compilation of %s:%d", script->filename, script->lineno);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
if (script->ion) {
|
if (script->ion) {
|
||||||
if (!script->ion->method())
|
if (!script->ion->method())
|
||||||
return Method_CantCompile;
|
return Method_CantCompile;
|
||||||
|
|
|
@ -19,12 +19,6 @@ using mozilla::DebugOnly;
|
||||||
|
|
||||||
#ifdef JS_PARALLEL_COMPILATION
|
#ifdef JS_PARALLEL_COMPILATION
|
||||||
|
|
||||||
bool
|
|
||||||
js::OffThreadCompilationAvailable(JSContext *cx)
|
|
||||||
{
|
|
||||||
return cx->runtime->useHelperThreads() && cx->runtime->helperThreadCount() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder)
|
js::StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder)
|
||||||
{
|
{
|
||||||
|
@ -360,10 +354,4 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
js::OffThreadCompilationAvailable(JSContext *cx)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* JS_PARALLEL_COMPILATION */
|
#endif /* JS_PARALLEL_COMPILATION */
|
||||||
|
|
|
@ -120,10 +120,6 @@ StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder);
|
||||||
void
|
void
|
||||||
CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script);
|
CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script);
|
||||||
|
|
||||||
/* Return true iff off-thread compilation is possible. */
|
|
||||||
bool
|
|
||||||
OffThreadCompilationAvailable(JSContext *cx);
|
|
||||||
|
|
||||||
class AutoLockWorkerThreadState
|
class AutoLockWorkerThreadState
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче