зеркало из https://github.com/mozilla/gecko-dev.git
Backout merge (a=backout)
This commit is contained in:
Коммит
6b611606ab
|
@ -2284,7 +2284,7 @@ JSContext::updateJITEnabled()
|
|||
# endif
|
||||
;
|
||||
#ifdef JS_TRACER
|
||||
profilingEnabled = (options & JSOPTION_PROFILING) && traceJitEnabled;
|
||||
profilingEnabled = (options & JSOPTION_PROFILING) && traceJitEnabled && methodJitEnabled;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -749,10 +749,6 @@ InvokeSessionGuard::start(JSContext *cx, const Value &calleev, const Value &this
|
|||
#ifdef JS_TRACER
|
||||
if (TRACE_RECORDER(cx))
|
||||
AbortRecording(cx, "attempt to reenter VM while recording");
|
||||
#ifdef JS_METHODJIT
|
||||
if (TRACE_PROFILER(cx))
|
||||
AbortProfiling(cx);
|
||||
#endif
|
||||
LeaveTrace(cx);
|
||||
#endif
|
||||
|
||||
|
@ -2341,21 +2337,11 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
|
||||
/* Check for too deep of a native thread stack. */
|
||||
#ifdef JS_TRACER
|
||||
#ifdef JS_METHODJIT
|
||||
JS_CHECK_RECURSION(cx, do {
|
||||
if (TRACE_RECORDER(cx))
|
||||
AbortRecording(cx, "too much recursion");
|
||||
if (TRACE_PROFILER(cx))
|
||||
AbortProfiling(cx);
|
||||
return JS_FALSE;
|
||||
} while (0););
|
||||
#else
|
||||
JS_CHECK_RECURSION(cx, do {
|
||||
if (TRACE_RECORDER(cx))
|
||||
AbortRecording(cx, "too much recursion");
|
||||
return JS_FALSE;
|
||||
} while (0););
|
||||
#endif
|
||||
#else
|
||||
JS_CHECK_RECURSION(cx, return JS_FALSE);
|
||||
#endif
|
||||
|
@ -2418,15 +2404,9 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
MonitorResult r = MonitorLoopEdge(cx, inlineCallCount); \
|
||||
if (r == MONITOR_RECORDING) { \
|
||||
JS_ASSERT(TRACE_RECORDER(cx)); \
|
||||
JS_ASSERT(!TRACE_PROFILER(cx)); \
|
||||
MONITOR_BRANCH_TRACEVIS; \
|
||||
ENABLE_INTERRUPTS(); \
|
||||
CLEAR_LEAVE_ON_TRACE_POINT(); \
|
||||
} else if (r == MONITOR_PROFILING) { \
|
||||
JS_ASSERT(TRACE_PROFILER(cx)); \
|
||||
JS_ASSERT(!TRACE_RECORDER(cx)); \
|
||||
ENABLE_INTERRUPTS(); \
|
||||
CLEAR_LEAVE_ON_TRACE_POINT(); \
|
||||
} \
|
||||
RESTORE_INTERP_VARS(); \
|
||||
JS_ASSERT_IF(cx->throwing, r == MONITOR_ERROR); \
|
||||
|
@ -2460,7 +2440,6 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
# define LEAVE_ON_SAFE_POINT() \
|
||||
do { \
|
||||
JS_ASSERT_IF(leaveOnSafePoint, !TRACE_RECORDER(cx)); \
|
||||
JS_ASSERT_IF(leaveOnSafePoint, !TRACE_PROFILER(cx)); \
|
||||
if (leaveOnSafePoint && !regs.fp->hasImacropc() && \
|
||||
script->maybeNativeCodeForPC(regs.fp->isConstructing(), regs.pc)) { \
|
||||
JS_ASSERT(!TRACE_RECORDER(cx)); \
|
||||
|
@ -2572,20 +2551,11 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
*/
|
||||
if (interpMode == JSINTERP_RECORD) {
|
||||
JS_ASSERT(TRACE_RECORDER(cx));
|
||||
JS_ASSERT(!TRACE_PROFILER(cx));
|
||||
ENABLE_INTERRUPTS();
|
||||
#ifdef JS_METHODJIT
|
||||
} else if (interpMode == JSINTERP_PROFILE) {
|
||||
JS_ASSERT(TRACE_PROFILER(cx));
|
||||
JS_ASSERT(!TRACE_RECORDER(cx));
|
||||
ENABLE_INTERRUPTS();
|
||||
#endif
|
||||
} else if (TRACE_RECORDER(cx)) {
|
||||
AbortRecording(cx, "attempt to reenter interpreter while recording");
|
||||
#ifdef JS_METHODJIT
|
||||
} else if (TRACE_PROFILER(cx)) {
|
||||
AbortProfiling(cx);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (regs.fp->hasImacropc())
|
||||
|
@ -2660,10 +2630,6 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
#ifdef JS_TRACER
|
||||
if (TRACE_RECORDER(cx))
|
||||
AbortRecording(cx, "interrupt hook");
|
||||
#ifdef JS_METHODJIT
|
||||
if (TRACE_PROFILER(cx))
|
||||
AbortProfiling(cx);
|
||||
#endif
|
||||
#endif
|
||||
Value rval;
|
||||
switch (hook(cx, script, regs.pc, Jsvalify(&rval),
|
||||
|
@ -2688,7 +2654,6 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
#ifdef JS_TRACER
|
||||
#ifdef JS_METHODJIT
|
||||
if (LoopProfile *prof = TRACE_PROFILER(cx)) {
|
||||
JS_ASSERT(!TRACE_RECORDER(cx));
|
||||
LoopProfile::ProfileAction act = prof->profileOperation(cx, op);
|
||||
switch (act) {
|
||||
case LoopProfile::ProfComplete:
|
||||
|
@ -2702,7 +2667,6 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||
}
|
||||
#endif
|
||||
if (TraceRecorder* tr = TRACE_RECORDER(cx)) {
|
||||
JS_ASSERT(!TRACE_PROFILER(cx));
|
||||
AbortableRecordingStatus status = tr->monitorRecording(op);
|
||||
JS_ASSERT_IF(cx->throwing, status == ARECORD_ERROR);
|
||||
|
||||
|
|
|
@ -2412,7 +2412,6 @@ TraceMonitor::outOfMemory() const
|
|||
AbortableRecordingStatus
|
||||
TraceRecorder::finishSuccessfully()
|
||||
{
|
||||
JS_ASSERT(!traceMonitor->profile);
|
||||
JS_ASSERT(traceMonitor->recorder == this);
|
||||
JS_ASSERT(fragment->lastIns && fragment->code());
|
||||
|
||||
|
@ -2438,7 +2437,6 @@ TraceRecorder::finishSuccessfully()
|
|||
JS_REQUIRES_STACK TraceRecorder::AbortResult
|
||||
TraceRecorder::finishAbort(const char* reason)
|
||||
{
|
||||
JS_ASSERT(!traceMonitor->profile);
|
||||
JS_ASSERT(traceMonitor->recorder == this);
|
||||
JS_ASSERT(!fragment->code());
|
||||
|
||||
|
@ -2709,7 +2707,6 @@ TraceMonitor::flush()
|
|||
{
|
||||
/* flush should only be called after all recorders have been aborted. */
|
||||
JS_ASSERT(!recorder);
|
||||
JS_ASSERT(!profile);
|
||||
AUDIT(cacheFlushed);
|
||||
|
||||
// recover profiling data from expiring Fragments
|
||||
|
@ -4403,10 +4400,6 @@ ResetJITImpl(JSContext* cx)
|
|||
JS_ASSERT_NOT_ON_TRACE(cx);
|
||||
AbortRecording(cx, "flush cache");
|
||||
}
|
||||
#if JS_METHODJIT
|
||||
if (tm->profile)
|
||||
AbortProfiling(cx);
|
||||
#endif
|
||||
if (ProhibitFlush(cx)) {
|
||||
debug_only_print0(LC_TMTracer, "Deferring JIT flush due to deep bail.\n");
|
||||
tm->needFlush = JS_TRUE;
|
||||
|
@ -5505,7 +5498,6 @@ TraceRecorder::startRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* f,
|
|||
bool speculate)
|
||||
{
|
||||
TraceMonitor *tm = &JS_TRACE_MONITOR(cx);
|
||||
JS_ASSERT(!tm->profile);
|
||||
JS_ASSERT(!tm->needFlush);
|
||||
JS_ASSERT_IF(cx->fp()->hasImacropc(), f->root != f);
|
||||
|
||||
|
@ -6400,9 +6392,6 @@ static JS_ALWAYS_INLINE VMSideExit*
|
|||
ExecuteTrace(JSContext* cx, Fragment* f, TracerState& state)
|
||||
{
|
||||
JS_ASSERT(!cx->bailExit);
|
||||
#ifdef JS_METHODJIT
|
||||
JS_ASSERT(!TRACE_PROFILER(cx));
|
||||
#endif
|
||||
union { NIns *code; GuardRecord* (FASTCALL *func)(TracerState*); } u;
|
||||
u.code = f->code();
|
||||
GuardRecord* rec;
|
||||
|
@ -6470,8 +6459,7 @@ ExecuteTree(JSContext* cx, TreeFragment* f, uintN& inlineCallCount,
|
|||
#endif
|
||||
JS_ASSERT(f->root == f && f->code());
|
||||
TraceMonitor* tm = &JS_TRACE_MONITOR(cx);
|
||||
JS_ASSERT(!tm->profile);
|
||||
|
||||
|
||||
if (!ScopeChainCheck(cx, f) || !cx->stack().ensureEnoughSpaceToEnterTrace() ||
|
||||
inlineCallCount + f->maxCallDepth > JS_MAX_INLINE_CALL_COUNT) {
|
||||
*lrp = NULL;
|
||||
|
@ -6935,7 +6923,7 @@ TraceRecorder::assertInsideLoop()
|
|||
}
|
||||
|
||||
JS_REQUIRES_STACK MonitorResult
|
||||
RecordLoopEdge(JSContext* cx, uintN& inlineCallCount, bool execOK)
|
||||
RecordLoopEdge(JSContext* cx, uintN& inlineCallCount)
|
||||
{
|
||||
#ifdef MOZ_TRACEVIS
|
||||
TraceVisStateObj tvso(cx, S_MONITOR);
|
||||
|
@ -6943,8 +6931,6 @@ RecordLoopEdge(JSContext* cx, uintN& inlineCallCount, bool execOK)
|
|||
|
||||
TraceMonitor* tm = &JS_TRACE_MONITOR(cx);
|
||||
|
||||
JS_ASSERT(!tm->profile);
|
||||
|
||||
/* Is the recorder currently active? */
|
||||
if (tm->recorder) {
|
||||
tm->recorder->assertInsideLoop();
|
||||
|
@ -7060,9 +7046,6 @@ RecordLoopEdge(JSContext* cx, uintN& inlineCallCount, bool execOK)
|
|||
return MONITOR_NOT_RECORDING;
|
||||
}
|
||||
|
||||
if (!execOK)
|
||||
return MONITOR_NOT_RECORDING;
|
||||
|
||||
VMSideExit* lr = NULL;
|
||||
VMSideExit* innermostNestedGuard = NULL;
|
||||
|
||||
|
@ -7157,7 +7140,6 @@ TraceRecorder::monitorRecording(JSOp op)
|
|||
TraceMonitor &localtm = JS_TRACE_MONITOR(cx);
|
||||
debug_only_stmt( JSContext *localcx = cx; )
|
||||
assertInsideLoop();
|
||||
JS_ASSERT(!localtm.profile);
|
||||
|
||||
/* Process needFlush requests now. */
|
||||
if (localtm.needFlush) {
|
||||
|
@ -7643,7 +7625,6 @@ void
|
|||
FinishJIT(TraceMonitor *tm)
|
||||
{
|
||||
JS_ASSERT(!tm->recorder);
|
||||
JS_ASSERT(!tm->profile);
|
||||
|
||||
#ifdef JS_JIT_SPEW
|
||||
if (jitstats.recorderStarted) {
|
||||
|
@ -16226,7 +16207,6 @@ RecordTracePoint(JSContext* cx, uintN& inlineCallCount, bool* blacklist, bool ex
|
|||
jsbytecode* pc = cx->regs->pc;
|
||||
|
||||
JS_ASSERT(!TRACE_RECORDER(cx));
|
||||
JS_ASSERT(!tm->profile);
|
||||
|
||||
JSObject* globalObj = cx->fp()->scopeChain().getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
|
@ -16328,15 +16308,13 @@ RecordTracePoint(JSContext* cx, uintN& inlineCallCount, bool* blacklist, bool ex
|
|||
return TPA_RanStuff;
|
||||
}
|
||||
|
||||
LoopProfile::LoopProfile(JSStackFrame *entryfp, jsbytecode *top, jsbytecode *bottom)
|
||||
: script(entryfp->script()),
|
||||
entryfp(entryfp),
|
||||
LoopProfile::LoopProfile(JSScript *script, jsbytecode *top, jsbytecode *bottom)
|
||||
: script(script),
|
||||
top(top),
|
||||
bottom(bottom),
|
||||
hits(0),
|
||||
profiled(false),
|
||||
traceOK(false),
|
||||
execOK(false),
|
||||
numAllOps(0),
|
||||
numSelfOps(0),
|
||||
numSelfOpsMult(0),
|
||||
|
@ -16359,21 +16337,20 @@ LoopProfile::profileLoopEdge(JSContext* cx, uintN& inlineCallCount)
|
|||
decide(cx);
|
||||
} else {
|
||||
/* Record an inner loop invocation. */
|
||||
JSStackFrame *fp = cx->fp();
|
||||
JSScript *script = cx->fp()->script();
|
||||
jsbytecode *pc = cx->regs->pc;
|
||||
bool found = false;
|
||||
|
||||
/* We started with the most deeply nested one first, since it gets hit most often.*/
|
||||
for (int i = int(numInnerLoops)-1; i >= 0; i--) {
|
||||
if (innerLoops[i].entryfp == fp && innerLoops[i].top == pc) {
|
||||
if (innerLoops[i].script == script && innerLoops[i].top == pc) {
|
||||
innerLoops[i].iters++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && numInnerLoops < PROFILE_MAX_INNER_LOOPS)
|
||||
innerLoops[numInnerLoops++] = InnerLoop(fp, pc, NULL);
|
||||
innerLoops[numInnerLoops++] = InnerLoop(script, pc, NULL);
|
||||
}
|
||||
|
||||
return MONITOR_NOT_RECORDING;
|
||||
|
@ -16410,32 +16387,32 @@ LookupOrAddProfile(JSContext *cx, TraceMonitor *tm, void** traceData, uintN *tra
|
|||
* This ensures that no flush has happened in between.
|
||||
*/
|
||||
|
||||
if (traceData) {
|
||||
if (*traceData && *traceEpoch == tm->flushEpoch) {
|
||||
prof = (LoopProfile *)*traceData;
|
||||
} else {
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
jsbytecode* bottom = GetLoopBottom(cx);
|
||||
if (!bottom)
|
||||
return NULL;
|
||||
prof = new (*tm->dataAlloc) LoopProfile(cx->fp(), pc, bottom);
|
||||
*traceData = prof;
|
||||
*traceEpoch = tm->flushEpoch;
|
||||
tm->loopProfiles->put(pc, prof);
|
||||
}
|
||||
#if JS_MONOIC
|
||||
if (*traceData && *traceEpoch == tm->flushEpoch) {
|
||||
prof = (LoopProfile *)*traceData;
|
||||
} else {
|
||||
LoopProfileMap &table = *tm->loopProfiles;
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
if (LoopProfileMap::AddPtr p = table.lookupForAdd(pc)) {
|
||||
prof = p->value;
|
||||
} else {
|
||||
jsbytecode* bottom = GetLoopBottom(cx);
|
||||
if (!bottom)
|
||||
return NULL;
|
||||
prof = new (*tm->dataAlloc) LoopProfile(cx->fp(), pc, bottom);
|
||||
table.add(p, pc, prof);
|
||||
}
|
||||
jsbytecode* bottom = GetLoopBottom(cx);
|
||||
if (!bottom)
|
||||
return NULL;
|
||||
prof = new (*tm->dataAlloc) LoopProfile(cx->fp()->script(), pc, bottom);
|
||||
*traceData = prof;
|
||||
*traceEpoch = tm->flushEpoch;
|
||||
tm->loopProfiles->put(pc, prof);
|
||||
}
|
||||
#else
|
||||
LoopProfileMap &table = *tm->loopProfiles;
|
||||
jsbytecode* pc = cx->regs->pc;
|
||||
if (LoopProfileMap::AddPtr p = table.lookupForAdd(pc)) {
|
||||
prof = p->value;
|
||||
} else {
|
||||
jsbytecode* bottom = GetLoopBottom(cx);
|
||||
if (!bottom)
|
||||
return NULL;
|
||||
prof = new (*tm->dataAlloc) LoopProfile(cx->fp()->script(), pc, bottom);
|
||||
table.add(p, pc, prof);
|
||||
}
|
||||
#endif
|
||||
|
||||
return prof;
|
||||
}
|
||||
|
@ -16476,10 +16453,9 @@ MonitorTracePoint(JSContext *cx, uintN& inlineCallCount, bool* blacklist,
|
|||
}
|
||||
}
|
||||
|
||||
debug_only_printf(LC_TMProfiler, "Profiling at line %d from methodjit\n",
|
||||
debug_only_printf(LC_TMProfiler, "Profiling at line %d\n",
|
||||
js_FramePCToLineNumber(cx, cx->fp()));
|
||||
|
||||
prof->entryfp = cx->fp();
|
||||
tm->profile = prof;
|
||||
|
||||
if (!Interpret(cx, cx->fp(), inlineCallCount, JSINTERP_PROFILE))
|
||||
|
@ -16491,14 +16467,16 @@ MonitorTracePoint(JSContext *cx, uintN& inlineCallCount, bool* blacklist,
|
|||
}
|
||||
|
||||
/*
|
||||
* Returns true if pc is within the given loop. Also returns true if
|
||||
* we are in some function called by the loop.
|
||||
* Returns true if pc is within the given loop.
|
||||
* If we're in a different script, then we must have come from
|
||||
* a call instruction within the loop (since we check if we're within
|
||||
* the loop before each instruction) so we're still in the loop.
|
||||
*/
|
||||
template<class T>
|
||||
static inline bool
|
||||
PCWithinLoop(JSStackFrame *fp, jsbytecode *pc, T& loop)
|
||||
PCWithinLoop(JSScript *script, jsbytecode *pc, T& loop)
|
||||
{
|
||||
return fp > loop.entryfp || (fp == loop.entryfp && pc >= loop.top && pc <= loop.bottom);
|
||||
return script != loop.script || (pc >= loop.top && pc <= loop.bottom);
|
||||
}
|
||||
|
||||
LoopProfile::ProfileAction
|
||||
|
@ -16512,19 +16490,18 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
|
|||
}
|
||||
|
||||
jsbytecode *pc = cx->regs->pc;
|
||||
JSStackFrame *fp = cx->fp();
|
||||
JSScript *script = fp->script();
|
||||
JSScript *script = cx->fp()->maybeScript();
|
||||
|
||||
if (!PCWithinLoop(fp, pc, *this)) {
|
||||
if (!PCWithinLoop(script, pc, *this)) {
|
||||
debug_only_printf(LC_TMProfiler, "Profiling complete (loop exit) at %d (line %u)\n",
|
||||
(int)(cx->regs->pc - script->code),
|
||||
(int)(cx->regs->pc - cx->fp()->script()->code),
|
||||
js_FramePCToLineNumber(cx, cx->fp()));
|
||||
tm->profile->decide(cx);
|
||||
tm->profile = NULL;
|
||||
return ProfComplete;
|
||||
}
|
||||
|
||||
while (loopStackDepth > 0 && !PCWithinLoop(fp, pc, loopStack[loopStackDepth-1])) {
|
||||
while (loopStackDepth > 0 && !PCWithinLoop(script, pc, loopStack[loopStackDepth-1])) {
|
||||
debug_only_print0(LC_TMProfiler, "Profiler: Exiting inner loop\n");
|
||||
loopStackDepth--;
|
||||
}
|
||||
|
@ -16539,7 +16516,7 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
|
|||
}
|
||||
|
||||
debug_only_print0(LC_TMProfiler, "Profiler: Entering inner loop\n");
|
||||
loopStack[loopStackDepth++] = InnerLoop(fp, pc, GetLoopBottom(cx));
|
||||
loopStack[loopStackDepth++] = InnerLoop(script, pc, GetLoopBottom(cx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16601,7 +16578,7 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
|
|||
}
|
||||
|
||||
if (op == JSOP_CALLPROP && loopStackDepth == 0)
|
||||
branchMultiplier *= mjit::GetCallTargetCount(script, cx->regs->pc);
|
||||
branchMultiplier *= mjit::GetCallTargetCount(cx->fp()->script(), cx->regs->pc);
|
||||
|
||||
if (op == JSOP_TABLESWITCH) {
|
||||
jsint low = GET_JUMP_OFFSET(pc + JUMP_OFFSET_LEN);
|
||||
|
@ -16635,7 +16612,7 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
|
|||
}
|
||||
|
||||
/* Check if we're exiting the loop being profiled. */
|
||||
JSOp testOp = js_GetOpcode(cx, script, testPC);
|
||||
JSOp testOp = js_GetOpcode(cx, cx->fp()->script(), testPC);
|
||||
if (testOp == JSOP_IFEQ || testOp == JSOP_IFNE || testOp == JSOP_GOTO
|
||||
|| testOp == JSOP_AND || testOp == JSOP_OR)
|
||||
{
|
||||
|
@ -16683,15 +16660,6 @@ LoopProfile::profileOperation(JSContext* cx, JSOp op)
|
|||
} else {
|
||||
stackClear();
|
||||
}
|
||||
|
||||
if (count(OP_RECURSIVE) || count(OP_EVAL)) {
|
||||
debug_only_printf(LC_TMProfiler, "Profiling complete (early exit) at %d (line %u)\n",
|
||||
(int)(cx->regs->pc - script->code),
|
||||
js_FramePCToLineNumber(cx, cx->fp()));
|
||||
tm->profile->decide(cx);
|
||||
tm->profile = NULL;
|
||||
return ProfComplete;
|
||||
}
|
||||
|
||||
return ProfContinue;
|
||||
}
|
||||
|
@ -16727,7 +16695,7 @@ LoopProfile::isCompilationExpensive(JSContext *cx, uintN depth)
|
|||
return true;
|
||||
|
||||
/* Is the code too branchy? */
|
||||
if (numSelfOpsMult > numSelfOps*100000)
|
||||
if (numSelfOpsMult >= numSelfOps*100000)
|
||||
return true;
|
||||
|
||||
/* Ensure that inner loops aren't too expensive. */
|
||||
|
@ -16802,24 +16770,20 @@ LoopProfile::decide(JSContext *cx)
|
|||
#endif
|
||||
|
||||
traceOK = false;
|
||||
/*
|
||||
* The first two cases are "early exits"; if these change, need
|
||||
* to change profileOperation too.
|
||||
*/
|
||||
if (count(OP_RECURSIVE)) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: recursive\n");
|
||||
/* don't trace */
|
||||
} else if (count(OP_EVAL)) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: eval\n");
|
||||
/* don't trace */
|
||||
} else if (numInnerLoops > 3) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: >3 inner loops\n");
|
||||
/* don't trace */
|
||||
} else if (shortLoop) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: short\n");
|
||||
/* don't trace */
|
||||
} else if (maybeShortLoop && numInnerLoops < 2) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: maybe short\n");
|
||||
/* don't trace */
|
||||
} else if (isCompilationExpensive(cx, 4)) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: expensive\n");
|
||||
/* don't trace */
|
||||
} else if (isCompilationUnprofitable(cx, 4)) {
|
||||
debug_only_print0(LC_TMProfiler, "NOTRACE: unprofitable\n");
|
||||
/* don't trace */
|
||||
} else {
|
||||
uintN goodOps = 0;
|
||||
|
||||
|
@ -16874,34 +16838,11 @@ LoopProfile::decide(JSContext *cx)
|
|||
JS_REQUIRES_STACK MonitorResult
|
||||
MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount)
|
||||
{
|
||||
if (!cx->profilingEnabled || TRACE_RECORDER(cx))
|
||||
return RecordLoopEdge(cx, inlineCallCount, true);
|
||||
|
||||
TraceMonitor *tm = &JS_TRACE_MONITOR(cx);
|
||||
|
||||
if (tm->profile)
|
||||
return tm->profile->profileLoopEdge(cx, inlineCallCount);
|
||||
|
||||
LoopProfile *prof = LookupOrAddProfile(cx, tm, NULL, NULL);
|
||||
if (!prof)
|
||||
return MONITOR_NOT_RECORDING;
|
||||
|
||||
if (prof->hits++ < PROFILE_HOTLOOP)
|
||||
return MONITOR_NOT_RECORDING;
|
||||
|
||||
if (prof->profiled) {
|
||||
if (prof->traceOK)
|
||||
return RecordLoopEdge(cx, inlineCallCount, prof->execOK);
|
||||
return MONITOR_NOT_RECORDING;
|
||||
}
|
||||
|
||||
debug_only_printf(LC_TMProfiler, "Profiling at line %d from interpreter\n",
|
||||
js_FramePCToLineNumber(cx, cx->fp()));
|
||||
|
||||
prof->entryfp = cx->fp();
|
||||
tm->profile = prof;
|
||||
|
||||
return MONITOR_PROFILING;
|
||||
else
|
||||
return RecordLoopEdge(cx, inlineCallCount);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16909,10 +16850,8 @@ AbortProfiling(JSContext *cx)
|
|||
{
|
||||
debug_only_print0(LC_TMProfiler, "Profiling complete (aborted)\n");
|
||||
TraceMonitor *tm = &JS_TRACE_MONITOR(cx);
|
||||
tm->profile->profiled = true;
|
||||
tm->profile->traceOK = false;
|
||||
tm->profile->execOK = false;
|
||||
Blacklist(tm->profile->top);
|
||||
tm->profile->numSelfOps = MAX_PROFILE_OPS;
|
||||
tm->profile->decide(cx);
|
||||
tm->profile = NULL;
|
||||
}
|
||||
|
||||
|
@ -16921,7 +16860,7 @@ AbortProfiling(JSContext *cx)
|
|||
JS_REQUIRES_STACK MonitorResult
|
||||
MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount)
|
||||
{
|
||||
return RecordLoopEdge(cx, inlineCallCount, true);
|
||||
return RecordLoopEdge(cx, inlineCallCount);
|
||||
}
|
||||
|
||||
#endif /* JS_METHODJIT */
|
||||
|
|
|
@ -640,7 +640,6 @@ VMFragment::toTreeFragment()
|
|||
|
||||
enum MonitorResult {
|
||||
MONITOR_RECORDING,
|
||||
MONITOR_PROFILING,
|
||||
MONITOR_NOT_RECORDING,
|
||||
MONITOR_ERROR
|
||||
};
|
||||
|
@ -673,9 +672,6 @@ public:
|
|||
/* The script in which the loop header lives. */
|
||||
JSScript *script;
|
||||
|
||||
/* The stack frame where we started profiling. Only valid while profiling! */
|
||||
JSStackFrame *entryfp;
|
||||
|
||||
/* The bytecode locations of the loop header and the back edge. */
|
||||
jsbytecode *top, *bottom;
|
||||
|
||||
|
@ -731,14 +727,13 @@ public:
|
|||
* and how many iterations we execute it.
|
||||
*/
|
||||
struct InnerLoop {
|
||||
JSStackFrame *entryfp;
|
||||
JSScript *script;
|
||||
jsbytecode *top, *bottom;
|
||||
uintN iters;
|
||||
|
||||
InnerLoop() {}
|
||||
InnerLoop(JSStackFrame *entryfp, jsbytecode *top, jsbytecode *bottom)
|
||||
: entryfp(entryfp), script(entryfp->script()), top(top), bottom(bottom), iters(0) {}
|
||||
InnerLoop(JSScript *script, jsbytecode *top, jsbytecode *bottom)
|
||||
: script(script), top(top), bottom(bottom), iters(0) {}
|
||||
};
|
||||
|
||||
/* These two variables track all the inner loops seen while profiling (up to a limit). */
|
||||
|
@ -788,7 +783,7 @@ public:
|
|||
return StackValue(false);
|
||||
}
|
||||
|
||||
LoopProfile(JSStackFrame *entryfp, jsbytecode *top, jsbytecode *bottom);
|
||||
LoopProfile(JSScript *script, jsbytecode *top, jsbytecode *bottom);
|
||||
|
||||
enum ProfileAction {
|
||||
ProfContinue,
|
||||
|
@ -1565,7 +1560,7 @@ class TraceRecorder
|
|||
friend class DetermineTypesVisitor;
|
||||
friend class RecursiveSlotMap;
|
||||
friend class UpRecursiveSlotMap;
|
||||
friend MonitorResult RecordLoopEdge(JSContext*, uintN&, bool);
|
||||
friend MonitorResult RecordLoopEdge(JSContext*, uintN&);
|
||||
friend TracePointAction RecordTracePoint(JSContext*, uintN &inlineCallCount,
|
||||
bool *blacklist);
|
||||
friend AbortResult AbortRecording(JSContext*, const char*);
|
||||
|
|
Загрузка…
Ссылка в новой задаче