diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 891eef85819..700481e2e8e 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -70,7 +70,7 @@ #ifdef DEBUG static struct { uint64 recorderStarted, recorderAborted, traceCompleted, sideExitIntoInterpreter, - blacklisted, typeMapMismatchAtEntry, returnToDifferentLoopHeader, traceTriggered, + typeMapMismatchAtEntry, returnToDifferentLoopHeader, traceTriggered, globalShapeMismatchAtEntry, typeMapTrashed, slotDemoted, slotPromoted, unstableLoopVariable; } stat = { 0LL, }; #define AUDIT(x) (stat.x++) @@ -1048,9 +1048,7 @@ js_DeleteRecorder(JSContext* cx) tm->recorder = NULL; } -#define HOTLOOP1 10 -#define HOTLOOP2 13 -#define HOTLOOP3 37 +#define HOTLOOP 10 bool js_LoopEdge(JSContext* cx) @@ -1082,63 +1080,58 @@ js_LoopEdge(JSContext* cx) Fragment* f = tm->fragmento->getLoop(cx->fp->regs->pc); if (!f->code()) { - int hits = ++f->hits(); - if (!f->isBlacklisted() && hits >= HOTLOOP1) { - if (hits == HOTLOOP1 || hits == HOTLOOP2 || hits == HOTLOOP3) { - AUDIT(recorderStarted); - f->calldepth = 0; - /* allocate space to store the LIR for this tree */ - if (!f->lirbuf) { - f->lirbuf = new (&gc) LirBuffer(tm->fragmento, builtins); -#ifdef DEBUG - f->lirbuf->names = new (&gc) LirNameMap(&gc, builtins, tm->fragmento->labels); + if (++f->hits() >= HOTLOOP) { + AUDIT(recorderStarted); + f->calldepth = 0; + /* allocate space to store the LIR for this tree */ + if (!f->lirbuf) { + f->lirbuf = new (&gc) LirBuffer(tm->fragmento, builtins); +#ifdef DEBUG + f->lirbuf->names = new (&gc) LirNameMap(&gc, builtins, tm->fragmento->labels); #endif - } - /* create the tree anchor structure */ - VMFragmentInfo* fi = (VMFragmentInfo*)f->vmprivate; - if (!fi) { - /* setup the VM-private FragmentInfo structure for this fragment */ - fi = new VMFragmentInfo(); // TODO: deallocate when fragment dies - f->vmprivate = fi; - - /* create the list of global properties we want to intern */ - int internableGlobals = findInternableGlobals(cx, cx->fp, NULL); - if (internableGlobals < 0) - return false; - fi->gslots = (uint16*)malloc(sizeof(uint16) * internableGlobals); - if ((fi->ngslots = findInternableGlobals(cx, cx->fp, fi->gslots)) < 0) - return false; - fi->globalShape = OBJ_SCOPE(JS_GetGlobalForObject(cx, - cx->fp->scopeChain))->shape; - - /* determine the native frame layout at the entry point */ - unsigned entryNativeFrameSlots = nativeFrameSlots(fi->ngslots, - cx->fp, cx->fp, *cx->fp->regs); - fi->entryNativeFrameSlots = entryNativeFrameSlots; - fi->nativeStackBase = (entryNativeFrameSlots - - (cx->fp->regs->sp - cx->fp->spbase)) * sizeof(double); - fi->maxNativeFrameSlots = entryNativeFrameSlots; - fi->maxCallDepth = 0; - } - - /* capture the entry type map if we don't have one yet (or we threw it away) */ - if (!fi->typeMap) { - fi->typeMap = (uint8*)malloc(fi->entryNativeFrameSlots * sizeof(uint8)); - uint8* m = fi->typeMap; - - /* remember the coerced type of each active slot in the type map */ - FORALL_SLOTS_IN_PENDING_FRAMES(cx, fi->ngslots, fi->gslots, cx->fp, cx->fp, - *m++ = getCoercedType(*vp) - ); - } - - tm->recorder = new (&gc) TraceRecorder(cx, f, fi->typeMap); - - /* start recording if no exception during construction */ - return !cx->throwing; } - if (hits > HOTLOOP3) - f->blacklist(); + /* create the tree anchor structure */ + VMFragmentInfo* fi = (VMFragmentInfo*)f->vmprivate; + if (!fi) { + /* setup the VM-private FragmentInfo structure for this fragment */ + fi = new VMFragmentInfo(); // TODO: deallocate when fragment dies + f->vmprivate = fi; + + /* create the list of global properties we want to intern */ + int internableGlobals = findInternableGlobals(cx, cx->fp, NULL); + if (internableGlobals < 0) + return false; + fi->gslots = (uint16*)malloc(sizeof(uint16) * internableGlobals); + if ((fi->ngslots = findInternableGlobals(cx, cx->fp, fi->gslots)) < 0) + return false; + fi->globalShape = OBJ_SCOPE(JS_GetGlobalForObject(cx, + cx->fp->scopeChain))->shape; + + /* determine the native frame layout at the entry point */ + unsigned entryNativeFrameSlots = nativeFrameSlots(fi->ngslots, + cx->fp, cx->fp, *cx->fp->regs); + fi->entryNativeFrameSlots = entryNativeFrameSlots; + fi->nativeStackBase = (entryNativeFrameSlots - + (cx->fp->regs->sp - cx->fp->spbase)) * sizeof(double); + fi->maxNativeFrameSlots = entryNativeFrameSlots; + fi->maxCallDepth = 0; + } + + /* capture the entry type map if we don't have one yet (or we threw it away) */ + if (!fi->typeMap) { + fi->typeMap = (uint8*)malloc(fi->entryNativeFrameSlots * sizeof(uint8)); + uint8* m = fi->typeMap; + + /* remember the coerced type of each active slot in the type map */ + FORALL_SLOTS_IN_PENDING_FRAMES(cx, fi->ngslots, fi->gslots, cx->fp, cx->fp, + *m++ = getCoercedType(*vp) + ); + } + + tm->recorder = new (&gc) TraceRecorder(cx, f, fi->typeMap); + + /* start recording if no exception during construction */ + return !cx->throwing; } return false; } @@ -1235,9 +1228,9 @@ js_DestroyJIT(JSContext* cx) "unstable loop variable(%llu)\n", stat.recorderStarted, stat.recorderAborted, stat.traceCompleted, stat.returnToDifferentLoopHeader, stat.typeMapTrashed, stat.slotDemoted, stat.slotPromoted, stat.unstableLoopVariable); - printf("monitor: triggered(%llu), exits (%llu), blacklisted(%llu), type mismatch(%llu), " + printf("monitor: triggered(%llu), exits (%llu), type mismatch(%llu), " "global mismatch(%llu)\n", stat.traceTriggered, stat.sideExitIntoInterpreter, - stat.blacklisted, stat.typeMapMismatchAtEntry, stat.globalShapeMismatchAtEntry); + stat.typeMapMismatchAtEntry, stat.globalShapeMismatchAtEntry); #endif }