mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Move JIT handles in scripts to a separate structure, bug 758613. r=dvander
This commit is contained in:
parent
c6997d5d56
commit
0c72d188da
@ -2130,8 +2130,7 @@ TypeCompartment::nukeTypes(FreeOp *fop)
|
||||
|
||||
for (gc::CellIter i(compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->hasJITCode())
|
||||
mjit::ReleaseScriptCode(fop, script);
|
||||
mjit::ReleaseScriptCode(fop, script);
|
||||
}
|
||||
#endif /* JS_METHODJIT */
|
||||
|
||||
|
@ -1942,7 +1942,7 @@ void
|
||||
JSScript::recompileForStepMode(FreeOp *fop)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
if (hasJITCode()) {
|
||||
if (hasJITInfo()) {
|
||||
mjit::Recompiler::clearStackReferences(fop, this);
|
||||
mjit::ReleaseScriptCode(fop, this);
|
||||
}
|
||||
@ -2206,7 +2206,7 @@ JSScript::applySpeculationFailed(JSContext *cx, JSScript *script_)
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
if (script->hasJITCode()) {
|
||||
if (script->hasJITInfo()) {
|
||||
mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
|
||||
mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
|
||||
}
|
||||
|
@ -379,6 +379,26 @@ struct JSScript : public js::gc::Cell
|
||||
|
||||
static void staticAsserts();
|
||||
};
|
||||
|
||||
// All the possible JITScripts that can simultaneously exist for a script.
|
||||
struct JITScriptSet
|
||||
{
|
||||
JITScriptHandle jitHandleNormal; // JIT info for normal scripts
|
||||
JITScriptHandle jitHandleNormalBarriered; // barriered JIT info for normal scripts
|
||||
JITScriptHandle jitHandleCtor; // JIT info for constructors
|
||||
JITScriptHandle jitHandleCtorBarriered; // barriered JIT info for constructors
|
||||
|
||||
static size_t jitHandleOffset(bool constructing, bool barriers) {
|
||||
return constructing
|
||||
? (barriers
|
||||
? offsetof(JITScriptSet, jitHandleCtorBarriered)
|
||||
: offsetof(JITScriptSet, jitHandleCtor))
|
||||
: (barriers
|
||||
? offsetof(JITScriptSet, jitHandleNormalBarriered)
|
||||
: offsetof(JITScriptSet, jitHandleNormal));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // JS_METHODJIT
|
||||
|
||||
//
|
||||
@ -421,15 +441,11 @@ struct JSScript : public js::gc::Cell
|
||||
/* Persistent type information retained across GCs. */
|
||||
js::types::TypeScript *types;
|
||||
|
||||
public:
|
||||
private:
|
||||
#ifdef JS_METHODJIT
|
||||
JITScriptHandle jitHandleNormal; // JIT info for normal scripts
|
||||
JITScriptHandle jitHandleNormalBarriered; // barriered JIT info for normal scripts
|
||||
JITScriptHandle jitHandleCtor; // JIT info for constructors
|
||||
JITScriptHandle jitHandleCtorBarriered; // barriered JIT info for constructors
|
||||
JITScriptSet *jitInfo;
|
||||
#endif
|
||||
|
||||
private:
|
||||
js::HeapPtrFunction function_;
|
||||
|
||||
// 32-bit fields.
|
||||
@ -449,7 +465,7 @@ struct JSScript : public js::gc::Cell
|
||||
* or has had backedges taken. Reset if the
|
||||
* script's JIT code is forcibly discarded. */
|
||||
|
||||
#if !defined(JS_METHODJIT) && JS_BITS_PER_WORD == 32
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
uint32_t pad32;
|
||||
#endif
|
||||
|
||||
@ -666,27 +682,26 @@ struct JSScript : public js::gc::Cell
|
||||
// accesses jitHandleNormal/jitHandleCtor, via jitHandleOffset().
|
||||
friend class js::mjit::CallCompiler;
|
||||
|
||||
static size_t jitHandleOffset(bool constructing, bool barriers) {
|
||||
return constructing
|
||||
? (barriers ? offsetof(JSScript, jitHandleCtorBarriered) : offsetof(JSScript, jitHandleCtor))
|
||||
: (barriers ? offsetof(JSScript, jitHandleNormalBarriered) : offsetof(JSScript, jitHandleNormal));
|
||||
public:
|
||||
bool hasJITInfo() {
|
||||
return jitInfo != NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
bool hasJITCode() {
|
||||
return jitHandleNormal.isValid()
|
||||
|| jitHandleNormalBarriered.isValid()
|
||||
|| jitHandleCtor.isValid()
|
||||
|| jitHandleCtorBarriered.isValid();
|
||||
}
|
||||
static size_t offsetOfJITInfo() { return offsetof(JSScript, jitInfo); }
|
||||
|
||||
inline bool ensureHasJITInfo(JSContext *cx);
|
||||
inline void destroyJITInfo(js::FreeOp *fop);
|
||||
|
||||
JITScriptHandle *jitHandle(bool constructing, bool barriers) {
|
||||
JS_ASSERT(jitInfo);
|
||||
return constructing
|
||||
? (barriers ? &jitHandleCtorBarriered : &jitHandleCtor)
|
||||
: (barriers ? &jitHandleNormalBarriered : &jitHandleNormal);
|
||||
? (barriers ? &jitInfo->jitHandleCtorBarriered : &jitInfo->jitHandleCtor)
|
||||
: (barriers ? &jitInfo->jitHandleNormalBarriered : &jitInfo->jitHandleNormal);
|
||||
}
|
||||
|
||||
js::mjit::JITScript *getJIT(bool constructing, bool barriers) {
|
||||
if (!jitInfo)
|
||||
return NULL;
|
||||
JITScriptHandle *jith = jitHandle(constructing, barriers);
|
||||
return jith->isValid() ? jith->getValid() : NULL;
|
||||
}
|
||||
|
@ -213,6 +213,24 @@ JSScript::clearNesting()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
inline bool
|
||||
JSScript::ensureHasJITInfo(JSContext *cx)
|
||||
{
|
||||
if (jitInfo)
|
||||
return true;
|
||||
jitInfo = cx->new_<JITScriptSet>();
|
||||
return jitInfo != NULL;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSScript::destroyJITInfo(js::FreeOp *fop)
|
||||
{
|
||||
fop->delete_(jitInfo);
|
||||
jitInfo = NULL;
|
||||
}
|
||||
#endif /* JS_METHODJIT */
|
||||
|
||||
inline void
|
||||
JSScript::writeBarrierPre(JSScript *script)
|
||||
{
|
||||
|
@ -111,6 +111,8 @@ mjit::Compiler::compile()
|
||||
|
||||
CompileStatus status = performCompilation();
|
||||
if (status != Compile_Okay && status != Compile_Retry) {
|
||||
if (!outerScript->ensureHasJITInfo(cx))
|
||||
return Compile_Error;
|
||||
JSScript::JITScriptHandle *jith = outerScript->jitHandle(isConstructing, cx->compartment->needsBarrier());
|
||||
JSScript::ReleaseCode(cx->runtime->defaultFreeOp(), jith);
|
||||
jith->setUnjittable();
|
||||
@ -909,9 +911,11 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
if (!cx->methodJitEnabled)
|
||||
return Compile_Abort;
|
||||
|
||||
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->needsBarrier());
|
||||
if (jith->isUnjittable())
|
||||
return Compile_Abort;
|
||||
if (script->hasJITInfo()) {
|
||||
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->needsBarrier());
|
||||
if (jith->isUnjittable())
|
||||
return Compile_Abort;
|
||||
}
|
||||
|
||||
if (request == CompileRequest_Interpreter &&
|
||||
!cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS) &&
|
||||
@ -931,6 +935,11 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
|
||||
uint64_t gcNumber = cx->runtime->gcNumber;
|
||||
|
||||
if (!script->ensureHasJITInfo(cx))
|
||||
return Compile_Error;
|
||||
|
||||
JSScript::JITScriptHandle *jith = script->jitHandle(construct, cx->compartment->needsBarrier());
|
||||
|
||||
JITScript *jit;
|
||||
if (jith->isEmpty()) {
|
||||
jit = MakeJITScript(cx, script);
|
||||
|
@ -1366,7 +1366,10 @@ JSScript::JITScriptHandle::staticAsserts()
|
||||
size_t
|
||||
JSScript::sizeOfJitScripts(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
size_t n = 0;
|
||||
if (!hasJITInfo())
|
||||
return 0;
|
||||
|
||||
size_t n = mallocSizeOf(jitInfo);
|
||||
for (int constructing = 0; constructing <= 1; constructing++) {
|
||||
for (int barriers = 0; barriers <= 1; barriers++) {
|
||||
JITScript *jit = getJIT((bool) constructing, (bool) barriers);
|
||||
|
@ -872,6 +872,9 @@ CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
inline void
|
||||
ReleaseScriptCode(FreeOp *fop, JSScript *script)
|
||||
{
|
||||
if (!script->hasJITInfo())
|
||||
return;
|
||||
|
||||
for (int constructing = 0; constructing <= 1; constructing++) {
|
||||
for (int barriers = 0; barriers <= 1; barriers++) {
|
||||
JSScript::JITScriptHandle *jith = script->jitHandle((bool) constructing, (bool) barriers);
|
||||
@ -879,6 +882,8 @@ ReleaseScriptCode(FreeOp *fop, JSScript *script)
|
||||
JSScript::ReleaseCode(fop, jith);
|
||||
}
|
||||
}
|
||||
|
||||
script->destroyJITInfo(fop);
|
||||
}
|
||||
|
||||
// Expand all stack frames inlined by the JIT within a compartment.
|
||||
|
@ -571,10 +571,13 @@ class CallCompiler : public BaseCompiler
|
||||
masm.loadPtr(scriptAddr, t0);
|
||||
|
||||
// Test that:
|
||||
// - script->jitHandle{Ctor,Normal}->value is neither NULL nor UNJITTABLE, and
|
||||
// - script->jitHandle{Ctor,Normal}->value->arityCheckEntry is not NULL.
|
||||
//
|
||||
size_t offset = JSScript::jitHandleOffset(callingNew, f.cx->compartment->needsBarrier());
|
||||
// - script->jitInfo is not NULL
|
||||
// - script->jitInfo->jitHandle{Ctor,Normal}->value is neither NULL nor UNJITTABLE, and
|
||||
// - script->jitInfo->jitHandle{Ctor,Normal}->value->arityCheckEntry is not NULL.
|
||||
masm.loadPtr(Address(t0, JSScript::offsetOfJITInfo()), t0);
|
||||
Jump hasNoJitInfo = masm.branchPtr(Assembler::Equal, t0, ImmPtr(NULL));
|
||||
size_t offset = JSScript::JITScriptSet::jitHandleOffset(callingNew,
|
||||
f.cx->compartment->needsBarrier());
|
||||
masm.loadPtr(Address(t0, offset), t0);
|
||||
Jump hasNoJitCode = masm.branchPtr(Assembler::BelowOrEqual, t0,
|
||||
ImmPtr(JSScript::JITScriptHandle::UNJITTABLE));
|
||||
@ -583,6 +586,7 @@ class CallCompiler : public BaseCompiler
|
||||
|
||||
Jump hasCode = masm.branchPtr(Assembler::NotEqual, t0, ImmPtr(0));
|
||||
|
||||
hasNoJitInfo.linkTo(masm.label(), &masm);
|
||||
hasNoJitCode.linkTo(masm.label(), &masm);
|
||||
|
||||
/*
|
||||
|
@ -394,7 +394,7 @@ ClearAllFrames(JSCompartment *compartment)
|
||||
void
|
||||
Recompiler::clearStackReferences(FreeOp *fop, JSScript *script)
|
||||
{
|
||||
JS_ASSERT(script->hasJITCode());
|
||||
JS_ASSERT(script->hasJITInfo());
|
||||
|
||||
JaegerSpew(JSpew_Recompile, "recompiling script (file \"%s\") (line \"%d\") (length \"%d\")\n",
|
||||
script->filename, script->lineno, script->length);
|
||||
|
@ -231,7 +231,7 @@ void
|
||||
BreakpointSite::recompile(FreeOp *fop)
|
||||
{
|
||||
#ifdef JS_METHODJIT
|
||||
if (script->hasJITCode()) {
|
||||
if (script->hasJITInfo()) {
|
||||
mjit::Recompiler::clearStackReferences(fop, script);
|
||||
mjit::ReleaseScriptCode(fop, script);
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ GlobalObject::clear(JSContext *cx)
|
||||
*/
|
||||
for (gc::CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->compileAndGo && script->hasJITCode() && script->hasClearedGlobal()) {
|
||||
if (script->compileAndGo && script->hasJITInfo() && script->hasClearedGlobal()) {
|
||||
mjit::Recompiler::clearStackReferences(cx->runtime->defaultFreeOp(), script);
|
||||
mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user