mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[INFER] Don't discard JIT code for the topmost frame while recompiling, bug 647424.
This commit is contained in:
parent
54470b0628
commit
55790989cb
@ -89,14 +89,12 @@ static const char *OpcodeNames[] = {
|
||||
*/
|
||||
static const size_t CALLS_BACKEDGES_BEFORE_INLINING = 10000;
|
||||
|
||||
mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript,
|
||||
bool isConstructing, bool isEval, JSObject *globalObj,
|
||||
mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructing,
|
||||
const Vector<PatchableFrame> *patchFrames, bool recompiling)
|
||||
: BaseCompiler(cx),
|
||||
outerScript(outerScript),
|
||||
isConstructing(isConstructing),
|
||||
isEval(isEval),
|
||||
globalObj(globalObj),
|
||||
globalObj(outerScript->global),
|
||||
patchFrames(patchFrames),
|
||||
savedTraps(NULL),
|
||||
frame(cx, *this, masm, stubcc),
|
||||
@ -345,7 +343,7 @@ mjit::Compiler::performCompilation(JITScript **jitp)
|
||||
if (!script->jitNormal) {
|
||||
CompileStatus status = Compile_Retry;
|
||||
while (status == Compile_Retry) {
|
||||
mjit::Compiler cc(cx, script, isConstructing, false, globalObj, NULL, true);
|
||||
mjit::Compiler cc(cx, script, isConstructing, NULL, true);
|
||||
status = cc.compile();
|
||||
}
|
||||
if (status != Compile_Okay) {
|
||||
@ -450,8 +448,7 @@ mjit::TryCompile(JSContext *cx, JSStackFrame *fp)
|
||||
// before giving up.
|
||||
CompileStatus status = Compile_Retry;
|
||||
for (unsigned i = 0; status == Compile_Retry && i < 5; i++) {
|
||||
Compiler cc(cx, fp->script(), fp->isConstructing(), fp->isEvalFrame(),
|
||||
fp->scopeChain().getGlobal(), NULL, fp->script()->inlineParents);
|
||||
Compiler cc(cx, fp->script(), fp->isConstructing(), NULL, fp->script()->inlineParents);
|
||||
status = cc.compile();
|
||||
}
|
||||
|
||||
@ -2961,30 +2958,22 @@ mjit::Compiler::emitReturn(FrameEntry *fe)
|
||||
* even on the entry frame. To avoid double-putting, EnterMethodJIT clears
|
||||
* out the entry frame's activation objects.
|
||||
*/
|
||||
if (script->fun) {
|
||||
if (script->fun->isHeavyweight()) {
|
||||
/* There will always be a call object. */
|
||||
prepareStubCall(Uses(fe ? 1 : 0));
|
||||
INLINE_STUBCALL(stubs::PutActivationObjects);
|
||||
} else {
|
||||
/* if (hasCallObj() || hasArgsObj()) */
|
||||
Jump putObjs = masm.branchTest32(Assembler::NonZero,
|
||||
Address(JSFrameReg, JSStackFrame::offsetOfFlags()),
|
||||
Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ));
|
||||
stubcc.linkExit(putObjs, Uses(frame.frameSlots()));
|
||||
|
||||
stubcc.leave();
|
||||
OOL_STUBCALL(stubs::PutActivationObjects);
|
||||
|
||||
emitReturnValue(&stubcc.masm, fe);
|
||||
emitFinalReturn(stubcc.masm);
|
||||
}
|
||||
if (script->fun && script->fun->isHeavyweight()) {
|
||||
/* There will always be a call object. */
|
||||
prepareStubCall(Uses(fe ? 1 : 0));
|
||||
INLINE_STUBCALL(stubs::PutActivationObjects);
|
||||
} else {
|
||||
if (isEval && script->strictModeCode) {
|
||||
/* There will always be a call object. */
|
||||
prepareStubCall(Uses(fe ? 1 : 0));
|
||||
INLINE_STUBCALL(stubs::PutActivationObjects);
|
||||
}
|
||||
/* if (hasCallObj() || hasArgsObj()) */
|
||||
Jump putObjs = masm.branchTest32(Assembler::NonZero,
|
||||
Address(JSFrameReg, JSStackFrame::offsetOfFlags()),
|
||||
Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ));
|
||||
stubcc.linkExit(putObjs, Uses(frame.frameSlots()));
|
||||
|
||||
stubcc.leave();
|
||||
OOL_STUBCALL(stubs::PutActivationObjects);
|
||||
|
||||
emitReturnValue(&stubcc.masm, fe);
|
||||
emitFinalReturn(stubcc.masm);
|
||||
}
|
||||
|
||||
emitReturnValue(&masm, fe);
|
||||
|
@ -354,7 +354,6 @@ class Compiler : public BaseCompiler
|
||||
|
||||
JSScript *outerScript;
|
||||
bool isConstructing;
|
||||
bool isEval;
|
||||
|
||||
JSObject *globalObj;
|
||||
|
||||
@ -453,8 +452,7 @@ class Compiler : public BaseCompiler
|
||||
// follows interpreter usage in JSOP_LENGTH.
|
||||
enum { LengthAtomIndex = uint32(-2) };
|
||||
|
||||
Compiler(JSContext *cx, JSScript *outerScript, bool isConstructing, bool isEval,
|
||||
JSObject *globalObj,
|
||||
Compiler(JSContext *cx, JSScript *outerScript, bool isConstructing,
|
||||
const Vector<PatchableFrame> *patchFrames, bool recompiling);
|
||||
~Compiler();
|
||||
|
||||
|
@ -511,26 +511,29 @@ Recompiler::recompile()
|
||||
ReleaseScriptCode(cx, script, true);
|
||||
ReleaseScriptCode(cx, script, false);
|
||||
|
||||
if (normalFrames.length() &&
|
||||
!recompile(normalFrames, normalPatches, normalSites, normalNatives)) {
|
||||
/*
|
||||
* Regenerate the code if there are JIT frames on the stack, if this script
|
||||
* has inline parents and thus always needs JIT code, or if it is a newly
|
||||
* pushed frame by e.g. the interpreter. :XXX: it would be nice if we could
|
||||
* ensure that compiling a script does not then trigger its recompilation.
|
||||
*/
|
||||
JSStackFrame *top = (cx->fp() && cx->fp()->isScriptFrame()) ? cx->fp() : NULL;
|
||||
bool keepNormal = !normalFrames.empty() || script->inlineParents ||
|
||||
(top && top->script() == script && !top->isConstructing());
|
||||
bool keepCtor = !ctorFrames.empty() ||
|
||||
(top && top->script() == script && top->isConstructing());
|
||||
|
||||
if (keepNormal && !recompile(script, false,
|
||||
normalFrames, normalPatches, normalSites, normalNatives)) {
|
||||
return false;
|
||||
}
|
||||
if (keepCtor && !recompile(script, true,
|
||||
ctorFrames, ctorPatches, ctorSites, ctorNatives)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctorFrames.length() &&
|
||||
!recompile(ctorFrames, ctorPatches, ctorSites, ctorNatives)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure that scripts with inline parents still have JIT code. */
|
||||
if (script->inlineParents && !script->jitNormal) {
|
||||
CompileStatus status = Compile_Retry;
|
||||
while (status == Compile_Retry) {
|
||||
mjit::Compiler cc(cx, script, false, false, script->global, NULL, true);
|
||||
status = cc.compile();
|
||||
}
|
||||
if (status != Compile_Okay)
|
||||
return false;
|
||||
}
|
||||
JS_ASSERT_IF(keepNormal, script->jitNormal);
|
||||
JS_ASSERT_IF(keepCtor, script->jitCtor);
|
||||
|
||||
cx->compartment->types.recompilations++;
|
||||
|
||||
@ -568,18 +571,17 @@ Recompiler::cleanup(JITScript *jit, Vector<CallSite> *sites)
|
||||
}
|
||||
|
||||
bool
|
||||
Recompiler::recompile(Vector<PatchableFrame> &frames, Vector<PatchableAddress> &patches, Vector<CallSite> &sites,
|
||||
Recompiler::recompile(JSScript *script, bool isConstructing,
|
||||
Vector<PatchableFrame> &frames,
|
||||
Vector<PatchableAddress> &patches, Vector<CallSite> &sites,
|
||||
Vector<PatchableNative> &natives)
|
||||
{
|
||||
JSStackFrame *fp = frames[0].fp;
|
||||
|
||||
JaegerSpew(JSpew_Recompile, "On stack recompilation, %u patches, %u natives\n",
|
||||
patches.length(), natives.length());
|
||||
JaegerSpew(JSpew_Recompile, "On stack recompilation, %u frames, %u patches, %u natives\n",
|
||||
frames.length(), patches.length(), natives.length());
|
||||
|
||||
CompileStatus status = Compile_Retry;
|
||||
while (status == Compile_Retry) {
|
||||
Compiler cc(cx, fp->script(), fp->isConstructing(), fp->isEvalFrame(),
|
||||
fp->scopeChain().getGlobal(), &frames, true);
|
||||
Compiler cc(cx, script, isConstructing, &frames, true);
|
||||
if (!cc.loadOldTraps(sites))
|
||||
return false;
|
||||
status = cc.compile();
|
||||
@ -587,7 +589,7 @@ Recompiler::recompile(Vector<PatchableFrame> &frames, Vector<PatchableAddress> &
|
||||
if (status != Compile_Okay)
|
||||
return false;
|
||||
|
||||
JITScript *jit = script->getJIT(fp->isConstructing());
|
||||
JITScript *jit = script->getJIT(isConstructing);
|
||||
|
||||
/* Perform the earlier scanned patches */
|
||||
for (uint32 i = 0; i < patches.length(); i++)
|
||||
|
@ -116,7 +116,8 @@ private:
|
||||
static void applyPatch(JITScript *jit, PatchableAddress& toPatch);
|
||||
PatchableNative stealNative(JITScript *jit, jsbytecode *pc);
|
||||
void patchNative(JITScript *jit, PatchableNative &native);
|
||||
bool recompile(Vector<PatchableFrame> &frames,
|
||||
bool recompile(JSScript *script, bool isConstructing,
|
||||
Vector<PatchableFrame> &frames,
|
||||
Vector<PatchableAddress> &patches, Vector<CallSite> &sites,
|
||||
Vector<PatchableNative> &natives);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user