Cleanup recorder activation, use a single hot loop threshold (10).

This commit is contained in:
Andreas Gal 2008-07-17 13:42:58 -07:00
parent d12de2bcc6
commit 3df09fb85c

View File

@ -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
}