mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 773655 - Don't destroy JM code before Ion compilation. r=bhackett
This commit is contained in:
parent
b63445b8d8
commit
a1826885c6
@ -1008,6 +1008,19 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
unsigned chunkIndex = jit->chunkIndex(pc);
|
||||
ChunkDescriptor &desc = jit->chunkDescriptor(chunkIndex);
|
||||
|
||||
if (jit->mustDestroyEntryChunk) {
|
||||
// We kept this chunk around so that Ion can get info from its caches.
|
||||
// If we end up here, we decided not to use Ion so we can destroy the
|
||||
// chunk now.
|
||||
JS_ASSERT(jit->nchunks == 1);
|
||||
jit->mustDestroyEntryChunk = false;
|
||||
|
||||
if (desc.chunk) {
|
||||
jit->destroyChunk(cx->runtime->defaultFreeOp(), chunkIndex, /* resetUses = */ false);
|
||||
return Compile_Skipped;
|
||||
}
|
||||
}
|
||||
|
||||
if (desc.chunk)
|
||||
return Compile_Okay;
|
||||
|
||||
|
@ -1306,23 +1306,7 @@ JITScript::destroyChunk(FreeOp *fop, unsigned chunkIndex, bool resetUses)
|
||||
argsCheckPool = NULL;
|
||||
}
|
||||
|
||||
invokeEntry = NULL;
|
||||
fastEntry = NULL;
|
||||
argsCheckEntry = NULL;
|
||||
arityCheckEntry = NULL;
|
||||
|
||||
// Fixup any ICs still referring to this chunk.
|
||||
while (!JS_CLIST_IS_EMPTY(&callers)) {
|
||||
JS_STATIC_ASSERT(offsetof(ic::CallICInfo, links) == 0);
|
||||
ic::CallICInfo *ic = (ic::CallICInfo *) callers.next;
|
||||
|
||||
uint8_t *start = (uint8_t *)ic->funGuard.executableAddress();
|
||||
JSC::RepatchBuffer repatch(JSC::JITCode(start - 32, 64));
|
||||
|
||||
repatch.repatch(ic->funGuard, NULL);
|
||||
repatch.relink(ic->funJump, ic->slowPathStart);
|
||||
ic->purgeGuardedObject();
|
||||
}
|
||||
disableScriptEntry();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1346,6 +1330,28 @@ JITScript::purgeCaches()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JITScript::disableScriptEntry()
|
||||
{
|
||||
invokeEntry = NULL;
|
||||
fastEntry = NULL;
|
||||
argsCheckEntry = NULL;
|
||||
arityCheckEntry = NULL;
|
||||
|
||||
// Fixup any ICs still referring to this script.
|
||||
while (!JS_CLIST_IS_EMPTY(&callers)) {
|
||||
JS_STATIC_ASSERT(offsetof(ic::CallICInfo, links) == 0);
|
||||
ic::CallICInfo *ic = (ic::CallICInfo *) callers.next;
|
||||
|
||||
uint8_t *start = (uint8_t *)ic->funGuard.executableAddress();
|
||||
JSC::RepatchBuffer repatch(JSC::JITCode(start - 32, 64));
|
||||
|
||||
repatch.repatch(ic->funGuard, NULL);
|
||||
repatch.relink(ic->funJump, ic->slowPathStart);
|
||||
ic->purgeGuardedObject();
|
||||
}
|
||||
}
|
||||
|
||||
const js::mjit::JITScript *JSScript::JITScriptHandle::UNJITTABLE =
|
||||
reinterpret_cast<js::mjit::JITScript *>(1);
|
||||
|
||||
|
@ -779,6 +779,13 @@ struct JITScript
|
||||
*/
|
||||
JSC::ExecutablePool *shimPool;
|
||||
|
||||
/*
|
||||
* If set, we decided to keep the JITChunk so that Ion can access its caches.
|
||||
* The chunk has to be destroyed the next time the script runs in JM.
|
||||
* Note that this flag implies nchunks == 1.
|
||||
*/
|
||||
bool mustDestroyEntryChunk;
|
||||
|
||||
#ifdef JS_MONOIC
|
||||
/* Inline cache at function entry for checking this/argument types. */
|
||||
JSC::CodeLocationLabel argsCheckStub;
|
||||
@ -829,6 +836,8 @@ struct JITScript
|
||||
|
||||
void trace(JSTracer *trc);
|
||||
void purgeCaches();
|
||||
|
||||
void disableScriptEntry();
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include "vm/RegExpObject-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
#ifdef JS_ION
|
||||
#include "ion/Ion.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "jswin.h"
|
||||
#endif
|
||||
@ -780,8 +784,25 @@ stubs::Interrupt(VMFrame &f, jsbytecode *pc)
|
||||
void JS_FASTCALL
|
||||
stubs::RecompileForInline(VMFrame &f)
|
||||
{
|
||||
JSScript *script = f.script();
|
||||
|
||||
ExpandInlineFrames(f.cx->compartment);
|
||||
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), f.script());
|
||||
Recompiler::clearStackReferences(f.cx->runtime->defaultFreeOp(), script);
|
||||
|
||||
#ifdef JS_ION
|
||||
if (ion::IsEnabled(f.cx) && f.jit()->nchunks == 1 &&
|
||||
script->canIonCompile() && !script->hasIonScript())
|
||||
{
|
||||
// After returning to the interpreter, IonMonkey will try to compile
|
||||
// this script. Don't destroy the JITChunk immediately so that Ion
|
||||
// still has access to its ICs.
|
||||
JS_ASSERT(!f.jit()->mustDestroyEntryChunk);
|
||||
f.jit()->mustDestroyEntryChunk = true;
|
||||
f.jit()->disableScriptEntry();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user