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);
|
unsigned chunkIndex = jit->chunkIndex(pc);
|
||||||
ChunkDescriptor &desc = jit->chunkDescriptor(chunkIndex);
|
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)
|
if (desc.chunk)
|
||||||
return Compile_Okay;
|
return Compile_Okay;
|
||||||
|
|
||||||
|
@ -1306,23 +1306,7 @@ JITScript::destroyChunk(FreeOp *fop, unsigned chunkIndex, bool resetUses)
|
|||||||
argsCheckPool = NULL;
|
argsCheckPool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeEntry = NULL;
|
disableScriptEntry();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 =
|
const js::mjit::JITScript *JSScript::JITScriptHandle::UNJITTABLE =
|
||||||
reinterpret_cast<js::mjit::JITScript *>(1);
|
reinterpret_cast<js::mjit::JITScript *>(1);
|
||||||
|
|
||||||
|
@ -779,6 +779,13 @@ struct JITScript
|
|||||||
*/
|
*/
|
||||||
JSC::ExecutablePool *shimPool;
|
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
|
#ifdef JS_MONOIC
|
||||||
/* Inline cache at function entry for checking this/argument types. */
|
/* Inline cache at function entry for checking this/argument types. */
|
||||||
JSC::CodeLocationLabel argsCheckStub;
|
JSC::CodeLocationLabel argsCheckStub;
|
||||||
@ -829,6 +836,8 @@ struct JITScript
|
|||||||
|
|
||||||
void trace(JSTracer *trc);
|
void trace(JSTracer *trc);
|
||||||
void purgeCaches();
|
void purgeCaches();
|
||||||
|
|
||||||
|
void disableScriptEntry();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -40,6 +40,10 @@
|
|||||||
#include "vm/RegExpObject-inl.h"
|
#include "vm/RegExpObject-inl.h"
|
||||||
#include "vm/String-inl.h"
|
#include "vm/String-inl.h"
|
||||||
|
|
||||||
|
#ifdef JS_ION
|
||||||
|
#include "ion/Ion.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
# include "jswin.h"
|
# include "jswin.h"
|
||||||
#endif
|
#endif
|
||||||
@ -780,8 +784,25 @@ stubs::Interrupt(VMFrame &f, jsbytecode *pc)
|
|||||||
void JS_FASTCALL
|
void JS_FASTCALL
|
||||||
stubs::RecompileForInline(VMFrame &f)
|
stubs::RecompileForInline(VMFrame &f)
|
||||||
{
|
{
|
||||||
|
JSScript *script = f.script();
|
||||||
|
|
||||||
ExpandInlineFrames(f.cx->compartment);
|
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);
|
f.jit()->destroyChunk(f.cx->runtime->defaultFreeOp(), f.chunkIndex(), /* resetUses = */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user