mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-31 22:25:30 +00:00
Bug 509833 - Convert live() analyzer to Allocator, r=gal.
This commit is contained in:
parent
3e46bc7cdc
commit
0d7a76d147
@ -1454,58 +1454,68 @@ namespace nanojit
|
||||
}
|
||||
|
||||
#ifdef NJ_VERBOSE
|
||||
class RetiredEntry: public GCObject
|
||||
class RetiredEntry
|
||||
{
|
||||
public:
|
||||
List<LInsp, LIST_NonGCObjects> live;
|
||||
LInsp i;
|
||||
RetiredEntry(GC *gc): live(gc) {}
|
||||
Seq<LIns*>* live;
|
||||
LIns* i;
|
||||
RetiredEntry(): live(NULL), i(NULL) {}
|
||||
};
|
||||
class LiveTable
|
||||
{
|
||||
Allocator& alloc;
|
||||
public:
|
||||
SortedMap<LInsp,LInsp,LIST_NonGCObjects> live;
|
||||
List<RetiredEntry*, LIST_GCObjects> retired;
|
||||
HashMap<LIns*, LIns*> live;
|
||||
SeqBuilder<RetiredEntry*> retired;
|
||||
int retiredCount;
|
||||
int maxlive;
|
||||
LiveTable(GC *gc) : live(gc), retired(gc), maxlive(0) {}
|
||||
~LiveTable()
|
||||
{
|
||||
for (size_t i = 0; i < retired.size(); i++) {
|
||||
NJ_DELETE(retired.get(i));
|
||||
}
|
||||
LiveTable(Allocator& alloc)
|
||||
: alloc(alloc)
|
||||
, live(alloc)
|
||||
, retired(alloc)
|
||||
, retiredCount(0)
|
||||
, maxlive(0)
|
||||
{ }
|
||||
|
||||
}
|
||||
void add(LInsp i, LInsp use) {
|
||||
if (!i->isconst() && !i->isconstq() && !live.containsKey(i)) {
|
||||
NanoAssert(size_t(i->opcode()) < sizeof(lirNames) / sizeof(lirNames[0]));
|
||||
live.put(i,use);
|
||||
}
|
||||
}
|
||||
void retire(LInsp i, GC *gc) {
|
||||
RetiredEntry *e = NJ_NEW(gc, RetiredEntry)(gc);
|
||||
|
||||
void retire(LInsp i) {
|
||||
RetiredEntry *e = new (alloc) RetiredEntry();
|
||||
e->i = i;
|
||||
for (int j=0, n=live.size(); j < n; j++) {
|
||||
LInsp ins = live.keyAt(j);
|
||||
if (!ins->isStore() && !ins->isGuard())
|
||||
e->live.add(ins);
|
||||
SeqBuilder<LIns*> livelist(alloc);
|
||||
HashMap<LIns*, LIns*>::Iter iter(live);
|
||||
int live_count = 0;
|
||||
while (iter.next()) {
|
||||
LIns* ins = iter.key();
|
||||
if (!ins->isStore() && !ins->isGuard()) {
|
||||
live_count++;
|
||||
livelist.insert(ins);
|
||||
}
|
||||
}
|
||||
int size=0;
|
||||
if ((size = e->live.size()) > maxlive)
|
||||
maxlive = size;
|
||||
e->live = livelist.get();
|
||||
if (live_count > maxlive)
|
||||
maxlive = live_count;
|
||||
|
||||
live.remove(i);
|
||||
retired.add(e);
|
||||
retired.insert(e);
|
||||
retiredCount++;
|
||||
}
|
||||
|
||||
bool contains(LInsp i) {
|
||||
return live.containsKey(i);
|
||||
}
|
||||
};
|
||||
|
||||
void live(GC *gc, Allocator& alloc, Fragment *frag, LogControl *logc)
|
||||
void live(Allocator& alloc, Fragment *frag, LogControl *logc)
|
||||
{
|
||||
// traverse backwards to find live exprs and a few other stats.
|
||||
|
||||
LiveTable live(gc);
|
||||
LiveTable live(alloc);
|
||||
uint32_t exits = 0;
|
||||
LirReader br(frag->lastIns);
|
||||
StackFilter sf(&br, alloc, frag->lirbuf, frag->lirbuf->sp);
|
||||
@ -1528,7 +1538,7 @@ namespace nanojit
|
||||
// now propagate liveness
|
||||
if (live.contains(i))
|
||||
{
|
||||
live.retire(i,gc);
|
||||
live.retire(i);
|
||||
NanoAssert(size_t(i->opcode()) < sizeof(operandCount) / sizeof(operandCount[0]));
|
||||
if (i->isStore()) {
|
||||
live.add(i->oprnd2(),i); // base
|
||||
@ -1554,7 +1564,7 @@ namespace nanojit
|
||||
}
|
||||
|
||||
logc->printf(" Live instruction count %d, total %u, max pressure %d\n",
|
||||
live.retired.size(), total, live.maxlive);
|
||||
live.retiredCount, total, live.maxlive);
|
||||
logc->printf(" Side exits %u\n", exits);
|
||||
logc->printf(" Showing LIR instructions with live-after variables\n");
|
||||
logc->printf("\n");
|
||||
@ -1562,17 +1572,16 @@ namespace nanojit
|
||||
// print live exprs, going forwards
|
||||
LirNameMap *names = frag->lirbuf->names;
|
||||
bool newblock = true;
|
||||
for (int j=live.retired.size()-1; j >= 0; j--)
|
||||
{
|
||||
RetiredEntry *e = live.retired[j];
|
||||
for (Seq<RetiredEntry*>* p = live.retired.get(); p != NULL; p = p->tail) {
|
||||
RetiredEntry* e = p->head;
|
||||
char livebuf[4000], *s=livebuf;
|
||||
*s = 0;
|
||||
if (!newblock && e->i->isop(LIR_label)) {
|
||||
logc->printf("\n");
|
||||
}
|
||||
newblock = false;
|
||||
for (int k=0,n=e->live.size(); k < n; k++) {
|
||||
VMPI_strcpy(s, names->formatRef(e->live[k]));
|
||||
for (Seq<LIns*>* p = e->live; p != NULL; p = p->tail) {
|
||||
VMPI_strcpy(s, names->formatRef(p->head));
|
||||
s += VMPI_strlen(s);
|
||||
*s++ = ' '; *s = 0;
|
||||
NanoAssert(s < livebuf+sizeof(livebuf));
|
||||
@ -2008,7 +2017,7 @@ namespace nanojit
|
||||
logc->printf("\n");
|
||||
logc->printf("=== Results of liveness analysis:\n");
|
||||
logc->printf("===\n");
|
||||
live(gc, alloc, triggerFrag, logc);
|
||||
live(alloc, triggerFrag, logc);
|
||||
})
|
||||
|
||||
/* Set up the generic text output cache for the assembler */
|
||||
|
@ -1194,7 +1194,7 @@ namespace nanojit
|
||||
class Assembler;
|
||||
|
||||
void compile(Fragmento *frago, Assembler *assm, Fragment *frag, Allocator& alloc);
|
||||
verbose_only(void live(GC *gc, LirBuffer *lirbuf);)
|
||||
verbose_only(void live(Allocator& alloc, Fragment *frag, LirBuffer *lirbuf);)
|
||||
|
||||
class StackFilter: public LirFilter
|
||||
{
|
||||
|
@ -292,6 +292,7 @@ namespace MMgc {
|
||||
#define VMPI_strcat strcat
|
||||
#define VMPI_strcpy strcpy
|
||||
#define VMPI_sprintf sprintf
|
||||
#define VMPI_memset memset
|
||||
|
||||
extern void VMPI_setPageProtection(void *address,
|
||||
size_t size,
|
||||
|
Loading…
Reference in New Issue
Block a user