mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[INFER] Reset use count when recompiling, bug 650163.
This commit is contained in:
parent
42a0a50b2d
commit
769796394d
@ -146,9 +146,6 @@ JSCompartment::init(JSContext *cx)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (!backEdgeTable.init())
|
||||
return false;
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
if (!(jaegerCompartment = rt->new_<mjit::JaegerCompartment>()))
|
||||
return false;
|
||||
@ -652,21 +649,3 @@ JSCompartment::allocMathCache(JSContext *cx)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return mathCache;
|
||||
}
|
||||
|
||||
size_t
|
||||
JSCompartment::backEdgeCount(jsbytecode *pc) const
|
||||
{
|
||||
if (BackEdgeMap::Ptr p = backEdgeTable.lookup(pc))
|
||||
return p->value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
JSCompartment::incBackEdgeCount(jsbytecode *pc)
|
||||
{
|
||||
if (BackEdgeMap::Ptr p = backEdgeTable.lookupWithDefault(pc, 0))
|
||||
return ++p->value;
|
||||
return 1; /* oom not reported by backEdgeTable, so ignore. */
|
||||
}
|
||||
|
||||
|
@ -509,21 +509,11 @@ struct JS_FRIEND_API(JSCompartment) {
|
||||
|
||||
js::MathCache *allocMathCache(JSContext *cx);
|
||||
|
||||
typedef js::HashMap<jsbytecode*,
|
||||
size_t,
|
||||
js::DefaultHasher<jsbytecode*>,
|
||||
js::SystemAllocPolicy> BackEdgeMap;
|
||||
|
||||
BackEdgeMap backEdgeTable;
|
||||
|
||||
JSCompartment *thisForCtor() { return this; }
|
||||
public:
|
||||
js::MathCache *getMathCache(JSContext *cx) {
|
||||
return mathCache ? mathCache : allocMathCache(cx);
|
||||
}
|
||||
|
||||
size_t backEdgeCount(jsbytecode *pc) const;
|
||||
size_t incBackEdgeCount(jsbytecode *pc);
|
||||
};
|
||||
|
||||
#define JS_SCRIPTS_TO_GC(cx) ((cx)->compartment->scriptsToGC)
|
||||
|
@ -1968,34 +1968,6 @@ TypeCompartment::dynamicPush(JSContext *cx, JSScript *script, uint32 offset, jst
|
||||
*/
|
||||
if (script->fun && !script->fun->getType()->unknownProperties())
|
||||
ObjectStateChange(cx, script->fun->getType(), false);
|
||||
|
||||
/*
|
||||
* If we unexpectedly read a hole out of an array, mark all array reads in
|
||||
* the script as undefined. :FIXME: bug 650163 remove hack.
|
||||
*/
|
||||
if (script->hasAnalysis() && script->analysis(cx)->ranInference() &&
|
||||
JSOp(*pc) == JSOP_GETELEM && type == TYPE_UNDEFINED) {
|
||||
analyze::ScriptAnalysis *analysis = script->analysis(cx);
|
||||
unsigned offset = 0;
|
||||
while (offset < script->length) {
|
||||
if (JSOp(script->code[offset]) == JSOP_GETELEM && analysis->maybeCode(offset)) {
|
||||
TypeSet *pushed = analysis->pushedTypes(offset, 0);
|
||||
if (!pushed->hasType(TYPE_UNDEFINED)) {
|
||||
pushed->addType(cx, TYPE_UNDEFINED);
|
||||
TypeResult *result = (TypeResult *) cx->calloc_(sizeof(TypeResult));
|
||||
if (!result) {
|
||||
setPendingNukeTypes(cx);
|
||||
return;
|
||||
}
|
||||
result->offset = offset;
|
||||
result->type = TYPE_UNDEFINED;
|
||||
result->next = script->typeResults;
|
||||
script->typeResults = result;
|
||||
}
|
||||
}
|
||||
offset += analyze::GetBytecodeLength(pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -421,9 +421,11 @@ struct JSScript {
|
||||
uint32 length; /* length of code vector */
|
||||
|
||||
private:
|
||||
uint16 version; /* JS version under which script was compiled */
|
||||
size_t useCount_; /* Number of times the script has been called
|
||||
* or has had backedges taken. Reset if the
|
||||
* script's JIT code is forcibly discarded. */
|
||||
|
||||
size_t callCount_; /* Number of times the script has been called. */
|
||||
uint16 version; /* JS version under which script was compiled */
|
||||
|
||||
public:
|
||||
uint16 nfixed; /* number of slots besides stack operands in
|
||||
@ -633,9 +635,10 @@ struct JSScript {
|
||||
return constructing ? jitCtor : jitNormal;
|
||||
}
|
||||
|
||||
size_t callCount() const { return callCount_; }
|
||||
size_t incCallCount() { return ++callCount_; }
|
||||
size_t *addressOfCallCount() { return &callCount_; }
|
||||
size_t useCount() const { return useCount_; }
|
||||
size_t incUseCount() { return ++useCount_; }
|
||||
size_t *addressOfUseCount() { return &useCount_; }
|
||||
void resetUseCount() { useCount_ = 0; }
|
||||
|
||||
JITScriptStatus getJITStatus(bool constructing) {
|
||||
void *addr = constructing ? jitArityCheckCtor : jitArityCheckNormal;
|
||||
|
@ -88,7 +88,7 @@ static const char *OpcodeNames[] = {
|
||||
* Number of times a script must be called or had a backedge before we try to
|
||||
* inline its calls.
|
||||
*/
|
||||
static const size_t CALLS_BACKEDGES_BEFORE_INLINING = 10000;
|
||||
static const size_t USES_BEFORE_INLINING = 10000;
|
||||
|
||||
mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructing)
|
||||
: BaseCompiler(cx),
|
||||
@ -138,14 +138,9 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructi
|
||||
if (cx->typeInferenceEnabled())
|
||||
addTraceHints = false;
|
||||
|
||||
/*
|
||||
* Note: we use callCount_ to count both calls and backedges in scripts
|
||||
* after they have been compiled and we are checking to recompile a version
|
||||
* with inline calls. :FIXME: should remove compartment->incBackEdgeCount
|
||||
* and do the same when deciding to initially compile.
|
||||
*/
|
||||
/* Once a script starts getting really hot we will inline calls in it. */
|
||||
if (!debugMode() && cx->typeInferenceEnabled() &&
|
||||
(outerScript->callCount() >= CALLS_BACKEDGES_BEFORE_INLINING ||
|
||||
(outerScript->useCount() >= USES_BEFORE_INLINING ||
|
||||
cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS))) {
|
||||
inlining_ = true;
|
||||
}
|
||||
@ -1121,9 +1116,8 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
|
||||
jitTraceICs[i].slowTraceHint = stubCode.locationOf(traceICs[i].slowTraceHint.get());
|
||||
#ifdef JS_TRACER
|
||||
uint32 hotloop = GetHotloop(cx);
|
||||
uint32 prevCount = cx->compartment->backEdgeCount(traceICs[i].jumpTarget);
|
||||
jitTraceICs[i].loopCounterStart = hotloop;
|
||||
jitTraceICs[i].loopCounter = hotloop < prevCount ? 1 : hotloop - prevCount;
|
||||
jitTraceICs[i].loopCounter = hotloop;
|
||||
#endif
|
||||
|
||||
stubCode.patch(traceICs[i].addrLabel, &jitTraceICs[i]);
|
||||
@ -3129,17 +3123,17 @@ mjit::Compiler::recompileCheckHelper()
|
||||
if (inlining() || debugMode() || !analysis->hasFunctionCalls() || !cx->typeInferenceEnabled())
|
||||
return;
|
||||
|
||||
size_t *addr = script->addressOfCallCount();
|
||||
size_t *addr = script->addressOfUseCount();
|
||||
masm.add32(Imm32(1), AbsoluteAddress(addr));
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_ARM)
|
||||
Jump jump = masm.branch32(Assembler::GreaterThanOrEqual, AbsoluteAddress(addr),
|
||||
Imm32(CALLS_BACKEDGES_BEFORE_INLINING));
|
||||
Imm32(USES_BEFORE_INLINING));
|
||||
#else
|
||||
/* Handle processors that can't load from absolute addresses. */
|
||||
RegisterID reg = frame.allocReg();
|
||||
masm.move(ImmPtr(addr), reg);
|
||||
Jump jump = masm.branch32(Assembler::GreaterThanOrEqual, Address(reg, 0),
|
||||
Imm32(CALLS_BACKEDGES_BEFORE_INLINING));
|
||||
Imm32(USES_BEFORE_INLINING));
|
||||
frame.freeReg(reg);
|
||||
#endif
|
||||
stubcc.linkExit(jump, Uses(0));
|
||||
|
@ -50,11 +50,11 @@ enum CompileRequest
|
||||
CompileRequest_JIT
|
||||
};
|
||||
|
||||
/* Number of times a script must be called before we run it in the methodjit. */
|
||||
static const size_t CALLS_BEFORE_COMPILE = 16;
|
||||
|
||||
/* Number of loop back-edges we execute in the interpreter before methodjitting. */
|
||||
static const size_t BACKEDGES_BEFORE_COMPILE = 16;
|
||||
/*
|
||||
* Number of times a script must be called or have back edges taken before we
|
||||
* run it in the methodjit.
|
||||
*/
|
||||
static const size_t USES_BEFORE_COMPILE = 16;
|
||||
|
||||
static inline CompileStatus
|
||||
CanMethodJIT(JSContext *cx, JSScript *script, StackFrame *fp, CompileRequest request)
|
||||
@ -67,7 +67,7 @@ CanMethodJIT(JSContext *cx, JSScript *script, StackFrame *fp, CompileRequest req
|
||||
if (request == CompileRequest_Interpreter &&
|
||||
status == JITScript_None &&
|
||||
!cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS) &&
|
||||
script->incCallCount() <= CALLS_BEFORE_COMPILE)
|
||||
script->incUseCount() <= USES_BEFORE_COMPILE)
|
||||
{
|
||||
return Compile_Skipped;
|
||||
}
|
||||
@ -90,7 +90,7 @@ CanMethodJITAtBranch(JSContext *cx, JSScript *script, StackFrame *fp, jsbytecode
|
||||
return Compile_Abort;
|
||||
if (status == JITScript_None &&
|
||||
!cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS) &&
|
||||
cx->compartment->incBackEdgeCount(pc) <= BACKEDGES_BEFORE_COMPILE)
|
||||
script->incUseCount() <= USES_BEFORE_COMPILE)
|
||||
{
|
||||
return Compile_Skipped;
|
||||
}
|
||||
|
@ -718,6 +718,9 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void *
|
||||
js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VMFrame &f);
|
||||
|
||||
__declspec(naked) void JaegerInterpoline() {
|
||||
__asm {
|
||||
/* Align the stack to 16 bytes. */
|
||||
|
@ -52,6 +52,8 @@
|
||||
#include "jscntxtinlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
|
||||
#include "MethodJIT-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::mjit;
|
||||
|
||||
@ -325,7 +327,7 @@ Recompiler::Recompiler(JSContext *cx, JSScript *script)
|
||||
* redirect that entryncode to the interpoline.
|
||||
*/
|
||||
void
|
||||
Recompiler::recompile()
|
||||
Recompiler::recompile(bool resetUses)
|
||||
{
|
||||
JS_ASSERT(script->hasJITCode());
|
||||
|
||||
@ -418,6 +420,14 @@ Recompiler::recompile()
|
||||
ReleaseScriptCode(cx, script, false);
|
||||
}
|
||||
|
||||
if (resetUses) {
|
||||
/*
|
||||
* Wait for the script to get warm again before doing another compile,
|
||||
* unless we are recompiling *because* the script got hot.
|
||||
*/
|
||||
script->resetUseCount();
|
||||
}
|
||||
|
||||
cx->compartment->types.recompilations++;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ class Recompiler {
|
||||
public:
|
||||
Recompiler(JSContext *cx, JSScript *script);
|
||||
|
||||
void recompile();
|
||||
void recompile(bool resetUses = true);
|
||||
|
||||
static void
|
||||
expandInlineFrames(JSContext *cx, StackFrame *fp, mjit::CallSite *inlined,
|
||||
|
@ -1302,7 +1302,7 @@ stubs::RecompileForInline(VMFrame &f)
|
||||
{
|
||||
ExpandInlineFrames(f.cx, true);
|
||||
Recompiler recompiler(f.cx, f.script());
|
||||
recompiler.recompile();
|
||||
recompiler.recompile(/* resetUses */ false);
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
|
Loading…
Reference in New Issue
Block a user