diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 1841de0b4179..28b47f268f82 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -1444,40 +1444,43 @@ js_AttemptToExtendTree(JSContext* cx, GuardRecord* lr, Fragment* f) return false; } +static bool +js_ContinueRecording(JSContext* cx, TraceRecorder* r, jsbytecode* oldpc) +{ +#ifdef JS_THREADSAFE + if (OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->title.ownercx != cx) { +#ifdef DEBUG + printf("Global object not owned by this context.\n"); +#endif + return false; /* we stay away from shared global objects */ + } +#endif + if (r->isLoopHeader(cx)) { /* did we hit the start point? */ + AUDIT(traceCompleted); + r->closeLoop(JS_TRACE_MONITOR(cx).fragmento); + js_DeleteRecorder(cx); + return false; /* done recording */ + } + if (++r->backEdgeCount >= MAX_XJUMPS) { + AUDIT(returnToDifferentLoopHeader); + debug_only(printf("loop edge %d -> %d, header %d\n", + oldpc - cx->fp->script->code, + cx->fp->regs->pc - cx->fp->script->code, + (jsbytecode*)r->getFragment()->root->ip - cx->fp->script->code)); + js_AbortRecording(cx, oldpc, "Loop edge does not return to header"); + return false; /* done recording */ + } + return true; /* keep recording (attempting to unroll inner loop) */ +} + bool js_LoopEdge(JSContext* cx, jsbytecode* oldpc, uintN& inlineCallCount) { JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx); /* is the recorder currently active? */ - if (tm->recorder) { - TraceRecorder* r = tm->recorder; -#ifdef JS_THREADSAFE - /* XXX should this test not be earlier, to avoid even recording? */ - if (OBJ_SCOPE(JS_GetGlobalForObject(cx, cx->fp->scopeChain))->title.ownercx != cx) { -#ifdef DEBUG - printf("Global object not owned by this context.\n"); -#endif - return false; /* we stay away from shared global objects */ - } -#endif - if (r->isLoopHeader(cx)) { /* did we hit the start point? */ - AUDIT(traceCompleted); - r->closeLoop(JS_TRACE_MONITOR(cx).fragmento); - js_DeleteRecorder(cx); - return false; /* done recording */ - } - if (++r->backEdgeCount >= MAX_XJUMPS) { - AUDIT(returnToDifferentLoopHeader); - debug_only(printf("loop edge %d -> %d, header %d\n", - oldpc - cx->fp->script->code, - cx->fp->regs->pc - cx->fp->script->code, - (jsbytecode*)r->getFragment()->root->ip - cx->fp->script->code)); - js_AbortRecording(cx, oldpc, "Loop edge does not return to header"); - return false; /* done recording */ - } - return true; /* keep recording (attempting to unroll inner loop) */ - } + if (tm->recorder) + return js_ContinueRecording(cx, tm->recorder, oldpc); Fragment* f = tm->fragmento->getLoop(cx->fp->regs->pc); if (!f->code()) {