зеркало из https://github.com/mozilla/gecko-dev.git
Bug 823884: Make call uninlineable when aborting during inlining, r=nbp
This commit is contained in:
Родитель
e4b89b0500
Коммит
b3a11b3d2a
|
@ -1135,7 +1135,7 @@ AttachFinishedCompilations(JSContext *cx)
|
|||
static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
|
||||
|
||||
template <typename CompileContext>
|
||||
static bool
|
||||
static AbortReason
|
||||
IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing,
|
||||
CompileContext &compileContext)
|
||||
{
|
||||
|
@ -1149,31 +1149,31 @@ IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *o
|
|||
|
||||
LifoAlloc *alloc = cx->new_<LifoAlloc>(BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
|
||||
if (!alloc)
|
||||
return false;
|
||||
return AbortReason_Alloc;
|
||||
|
||||
AutoDestroyAllocator autoDestroy(alloc);
|
||||
|
||||
TempAllocator *temp = alloc->new_<TempAllocator>(alloc);
|
||||
if (!temp)
|
||||
return false;
|
||||
return AbortReason_Alloc;
|
||||
|
||||
IonContext ictx(cx, cx->compartment, temp);
|
||||
|
||||
if (!cx->compartment->ensureIonCompartmentExists(cx))
|
||||
return false;
|
||||
return AbortReason_Alloc;
|
||||
|
||||
MIRGraph *graph = alloc->new_<MIRGraph>(temp);
|
||||
ExecutionMode executionMode = compileContext.executionMode();
|
||||
CompileInfo *info = alloc->new_<CompileInfo>(script, fun, osrPc, constructing,
|
||||
executionMode);
|
||||
if (!info)
|
||||
return false;
|
||||
return AbortReason_Alloc;
|
||||
|
||||
types::AutoEnterTypeInference enter(cx, true);
|
||||
TypeInferenceOracle oracle;
|
||||
|
||||
if (!oracle.init(cx, script))
|
||||
return false;
|
||||
return AbortReason_Disable;
|
||||
|
||||
AutoFlushCache afc("IonCompile");
|
||||
|
||||
|
@ -1185,10 +1185,10 @@ IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *o
|
|||
IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &oracle, info);
|
||||
if (!compileContext.compile(builder, graph, autoDestroy)) {
|
||||
IonSpew(IonSpew_Abort, "IM Compilation failed.");
|
||||
return false;
|
||||
return builder->abortReason();
|
||||
}
|
||||
|
||||
return true;
|
||||
return AbortReason_NoAbort;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1245,16 +1245,27 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
|
|||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
MethodStatus
|
||||
TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing)
|
||||
{
|
||||
SequentialCompileContext compileContext;
|
||||
if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) {
|
||||
|
||||
AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
|
||||
|
||||
if (reason == AbortReason_Alloc)
|
||||
return Method_Skipped;
|
||||
|
||||
if (reason == AbortReason_Inlining)
|
||||
return Method_Skipped;
|
||||
|
||||
if (reason == AbortReason_Disable) {
|
||||
if (!cx->isExceptionPending())
|
||||
ForbidCompilation(cx, script);
|
||||
return false;
|
||||
return Method_CantCompile;
|
||||
}
|
||||
return true;
|
||||
|
||||
JS_ASSERT(reason == AbortReason_NoAbort);
|
||||
return Method_Compiled;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1370,10 +1381,12 @@ Compile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrP
|
|||
}
|
||||
|
||||
SequentialCompileContext compileContext;
|
||||
if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext))
|
||||
|
||||
AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
|
||||
if (reason == AbortReason_Disable)
|
||||
return Method_CantCompile;
|
||||
|
||||
// Compilation succeeded, but we invalidated right away.
|
||||
// Compilation succeeded or we invalidated right away or an inlining/alloc abort
|
||||
return script->hasIonScript() ? Method_Compiled : Method_Skipped;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,6 +211,13 @@ enum MethodStatus
|
|||
Method_Compiled
|
||||
};
|
||||
|
||||
enum AbortReason {
|
||||
AbortReason_Alloc,
|
||||
AbortReason_Inlining,
|
||||
AbortReason_Disable,
|
||||
AbortReason_NoAbort
|
||||
};
|
||||
|
||||
// An Ion context is needed to enter into either an Ion method or an instance
|
||||
// of the Ion compiler. It points to a temporary allocator and the active
|
||||
// JSContext, either of which may be NULL, and the active compartment, which
|
||||
|
@ -296,7 +303,7 @@ class CodeGenerator;
|
|||
CodeGenerator *CompileBackEnd(MIRGenerator *mir);
|
||||
void AttachFinishedCompilations(JSContext *cx);
|
||||
void FinishOffThreadBuilder(IonBuilder *builder);
|
||||
bool TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
|
||||
MethodStatus TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
|
||||
|
||||
static inline bool IsEnabled(JSContext *cx)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
|
|||
backgroundCodegen_(NULL),
|
||||
recompileInfo(cx->compartment->types.compiledInfo),
|
||||
cx(cx),
|
||||
abortReason_(AbortReason_Disable),
|
||||
loopDepth_(loopDepth),
|
||||
callerResumePoint_(NULL),
|
||||
callerBuilder_(NULL),
|
||||
|
@ -360,6 +361,7 @@ IonBuilder::build()
|
|||
return false;
|
||||
|
||||
JS_ASSERT(loopDepth_ == 0);
|
||||
abortReason_ = AbortReason_NoAbort;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3172,8 +3174,16 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32_t argc, bool construc
|
|||
}
|
||||
|
||||
// Build the graph.
|
||||
if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv))
|
||||
if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv)) {
|
||||
JS_ASSERT(calleeScript->hasAnalysis());
|
||||
|
||||
// Inlining the callee failed. Disable inlining the function
|
||||
if (inlineBuilder.abortReason_ == AbortReason_Disable)
|
||||
calleeScript->analysis()->setIonUninlineable();
|
||||
|
||||
abortReason_ = AbortReason_Inlining;
|
||||
return false;
|
||||
}
|
||||
|
||||
MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();
|
||||
|
||||
|
|
|
@ -492,8 +492,11 @@ class IonBuilder : public MIRGenerator
|
|||
CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
|
||||
void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }
|
||||
|
||||
AbortReason abortReason() { return abortReason_; }
|
||||
|
||||
private:
|
||||
JSContext *cx;
|
||||
AbortReason abortReason_;
|
||||
|
||||
jsbytecode *pc;
|
||||
MBasicBlock *current;
|
||||
|
|
|
@ -888,6 +888,7 @@ class ScriptAnalysis
|
|||
bool failed() const { return hadFailure; }
|
||||
bool ionInlineable() const { return isIonInlineable; }
|
||||
bool ionInlineable(uint32_t argc) const { return isIonInlineable && argc == script_->function()->nargs; }
|
||||
void setIonUninlineable() { isIonInlineable = false; }
|
||||
bool jaegerInlineable() const { return isJaegerInlineable; }
|
||||
bool jaegerInlineable(uint32_t argc) const { return isJaegerInlineable && argc == script_->function()->nargs; }
|
||||
bool jaegerCompileable() { return isJaegerCompileable; }
|
||||
|
|
|
@ -839,7 +839,10 @@ stubs::TriggerIonCompile(VMFrame &f)
|
|||
osrPC = NULL;
|
||||
|
||||
RootedFunction scriptFunction(f.cx, script->function());
|
||||
if (!ion::TestIonCompile(f.cx, script, scriptFunction, osrPC, f.fp()->isConstructing())) {
|
||||
ion::MethodStatus compileStatus =
|
||||
ion::TestIonCompile(f.cx, script, scriptFunction, osrPC, f.fp()->isConstructing());
|
||||
|
||||
if (compileStatus != ion::Method_Compiled) {
|
||||
if (f.cx->isExceptionPending())
|
||||
THROW();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче