mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Add the concept of peer fragments to nanojit. Each loop fragment can have a number of peer fragments, which we can use to have several different specialized variants of a loop (i.e. for different types). The makefile doesn't pick up the change to Fragmento.h, so make sure you clobber by hand or you will end up wasting an hour of your life in gdb (like me.)
This commit is contained in:
parent
10a24ff80c
commit
7b954b5cd7
@ -1729,7 +1729,7 @@ js_ContinueRecording(JSContext* cx, TraceRecorder* r, jsbytecode* oldpc, uintN&
|
||||
}
|
||||
/* does this branch go to an inner loop? */
|
||||
Fragment* f = fragmento->getLoop(cx->fp->regs->pc);
|
||||
if (nesting_enabled && f->code() && !((TreeInfo*)f->vmprivate)->globalSlots.length()) {
|
||||
if (nesting_enabled && f && f->code() && !((TreeInfo*)f->vmprivate)->globalSlots.length()) {
|
||||
JS_ASSERT(f->vmprivate);
|
||||
/* call the inner tree */
|
||||
GuardRecord* lr = js_ExecuteTree(cx, f, inlineCallCount);
|
||||
@ -1945,6 +1945,8 @@ js_LoopEdge(JSContext* cx, jsbytecode* oldpc, uintN& inlineCallCount)
|
||||
f = cacheEntry->fragment;
|
||||
} else {
|
||||
f = tm->fragmento->getLoop(pc);
|
||||
if (!f)
|
||||
f = tm->fragmento->newLoop(pc);
|
||||
cacheEntry->pc = pc;
|
||||
cacheEntry->fragment = f;
|
||||
}
|
||||
|
@ -173,7 +173,14 @@ namespace nanojit
|
||||
|
||||
while (!_frags->isEmpty()) {
|
||||
Fragment *f = _frags->removeLast();
|
||||
f->releaseTreeMem(this);
|
||||
Fragment *peer = f->peer;
|
||||
while (peer) {
|
||||
Fragment *next = peer->peer;
|
||||
peer->releaseTreeMem(this);
|
||||
delete peer;
|
||||
peer = next;
|
||||
}
|
||||
f->releaseTreeMem(this);
|
||||
delete f;
|
||||
}
|
||||
|
||||
@ -194,19 +201,22 @@ namespace nanojit
|
||||
return _core;
|
||||
}
|
||||
|
||||
Fragment* Fragmento::newLoop(const void* ip)
|
||||
{
|
||||
Fragment *f = newFrag(ip);
|
||||
f->peer = _frags->get(ip);
|
||||
_frags->put(ip, f);
|
||||
f->anchor = f;
|
||||
f->root = f;
|
||||
f->kind = LoopTrace;
|
||||
f->mergeCounts = new (_core->gc) BlockHist(_core->gc);
|
||||
verbose_only( addLabel(f, "T", _frags->size()); )
|
||||
return f;
|
||||
}
|
||||
|
||||
Fragment* Fragmento::getLoop(const void* ip)
|
||||
{
|
||||
Fragment* f = _frags->get(ip);
|
||||
if (!f) {
|
||||
f = newFrag(ip);
|
||||
_frags->put(ip, f);
|
||||
f->anchor = f;
|
||||
f->root = f;
|
||||
f->kind = LoopTrace;
|
||||
f->mergeCounts = new (_core->gc) BlockHist(_core->gc);
|
||||
verbose_only( addLabel(f, "T", _frags->size()); )
|
||||
}
|
||||
return f;
|
||||
return _frags->get(ip);
|
||||
}
|
||||
|
||||
#ifdef NJ_VERBOSE
|
||||
@ -385,22 +395,27 @@ namespace nanojit
|
||||
for (int32_t i=0; i<count; i++)
|
||||
{
|
||||
Fragment *f = _frags->at(i);
|
||||
fragstats stat = { 0,0,0,0,0 };
|
||||
dumpFragStats(f, 0, stat);
|
||||
if (stat.lir) {
|
||||
totalstat.lir += stat.lir;
|
||||
totalstat.lirbytes += stat.lirbytes;
|
||||
while (true) {
|
||||
fragstats stat = { 0,0,0,0,0 };
|
||||
dumpFragStats(f, 0, stat);
|
||||
if (stat.lir) {
|
||||
totalstat.lir += stat.lir;
|
||||
totalstat.lirbytes += stat.lirbytes;
|
||||
}
|
||||
uint64_t bothDur = stat.traceDur + stat.interpDur;
|
||||
if (bothDur) {
|
||||
totalstat.interpDur += stat.interpDur;
|
||||
totalstat.traceDur += stat.traceDur;
|
||||
totalstat.size += stat.size;
|
||||
totaldur += bothDur;
|
||||
while (durs.containsKey(bothDur)) bothDur++;
|
||||
DurData d(f, stat.traceDur, stat.interpDur, stat.size);
|
||||
durs.put(bothDur, d);
|
||||
}
|
||||
if (!f->peer)
|
||||
break;
|
||||
f = f->peer;
|
||||
}
|
||||
uint64_t bothDur = stat.traceDur + stat.interpDur;
|
||||
if (bothDur) {
|
||||
totalstat.interpDur += stat.interpDur;
|
||||
totalstat.traceDur += stat.traceDur;
|
||||
totalstat.size += stat.size;
|
||||
totaldur += bothDur;
|
||||
while (durs.containsKey(bothDur)) bothDur++;
|
||||
DurData d(f, stat.traceDur, stat.interpDur, stat.size);
|
||||
durs.put(bothDur, d);
|
||||
}
|
||||
}
|
||||
uint64_t totaltrace = totalstat.traceDur;
|
||||
int totalsize = totalstat.size;
|
||||
|
@ -94,6 +94,7 @@ namespace nanojit
|
||||
Page* pageAlloc();
|
||||
void pageFree(Page* page);
|
||||
|
||||
Fragment* newLoop(const void* ip);
|
||||
Fragment* getLoop(const void* ip);
|
||||
void clearFrags(); // clear all fragments from the cache
|
||||
Fragment* getMerge(GuardRecord *lr, const void* ip);
|
||||
@ -204,6 +205,7 @@ namespace nanojit
|
||||
DWB(Fragment*) anchor;
|
||||
DWB(Fragment*) root;
|
||||
DWB(Fragment*) parent;
|
||||
DWB(Fragment*) peer;
|
||||
DWB(BlockHist*) mergeCounts;
|
||||
DWB(LirBuffer*) lirbuf;
|
||||
LIns* lastIns;
|
||||
|
Loading…
Reference in New Issue
Block a user