Bug 509833 - Convert live() analyzer to Allocator, r=gal.
authorEdwin Smith <edwsmith@adobe.com>
Tue, 04 Aug 2009 10:18:25 -0400
changeset 31508 b735c829735ec00c506b4f6f0f29981ee7621567
parent 31507 c9c15d92f6a98bfabca36ff3f34e5d1fe74c85ff
child 31509 bb6086ec04b8d5d0d99f596bb77e73a15a891ba4
push id8556
push userrsayre@mozilla.com
push dateThu, 13 Aug 2009 21:38:45 +0000
treeherderautoland@9734564871cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs509833
milestone1.9.2a1pre
Bug 509833 - Convert live() analyzer to Allocator, r=gal.
js/src/nanojit/LIR.cpp
js/src/nanojit/LIR.h
js/src/nanojit/avmplus.h
--- a/js/src/nanojit/LIR.cpp
+++ b/js/src/nanojit/LIR.cpp
@@ -1449,68 +1449,78 @@ namespace nanojit
 
     GuardRecord *LIns::record()
     {
         NanoAssert(isGuard());
         return (GuardRecord*)oprnd2()->payload();
     }
 
 #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);
         StackFilter r(&sf, alloc, frag->lirbuf, frag->lirbuf->rp);
         int total = 0;
         if (frag->lirbuf->state)
             live.add(frag->lirbuf->state, r.pos());
         for (LInsp i = r.read(); !i->isop(LIR_start); i = r.read())
@@ -1523,17 +1533,17 @@ namespace nanojit
                 live.add(i,0);
                 if (i->isGuard())
                     exits++;
             }
 
             // 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
                     live.add(i->oprnd1(),i); // val
                 }
                 else if (i->isop(LIR_cmov) || i->isop(LIR_qcmov)) {
                     live.add(i->oprnd1(),i);
                     live.add(i->oprnd2(),i);
@@ -1549,35 +1559,34 @@ namespace nanojit
                 else if (i->isCall()) {
                     for (int j=0, c=i->argc(); j < c; j++)
                         live.add(i->arg(j),i);
                 }
             }
         }
 
         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");
 
         // 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));
             }
             /* If the LIR insn is pretty short, print it and its
                live-after set on the same line.  If not, put
                live-after set on a new line, suitably indented. */
             const char* insn_text = names->formatIns(e->i);
@@ -2003,17 +2012,17 @@ namespace nanojit
             logc->printf("===\n");
         })
         /* END decorative preamble */
 
         verbose_only( if (liveVerb) {
             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 */
         verbose_only( StringList asmOutput(alloc); )
         verbose_only( assm->_outputCache = &asmOutput; )
 
         bool treeCompile = core->config.tree_opt && (triggerFrag->kind == BranchTrace);
         RegAllocMap regMap(gc);
--- a/js/src/nanojit/LIR.h
+++ b/js/src/nanojit/LIR.h
@@ -1189,17 +1189,17 @@ namespace nanojit
         void setpos(LIns *i) {
             _i = i;
         }
     };
 
     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
     {
         LirBuffer *lirbuf;
         LInsp sp;
         BitSet stk;
         int top;
         int getTop(LInsp br);
--- a/js/src/nanojit/avmplus.h
+++ b/js/src/nanojit/avmplus.h
@@ -287,16 +287,17 @@ namespace MMgc {
 #define WBRC(gc, container, addr, value) do { *(addr) = (value); } while(0)
 
 #define MMGC_MEM_TYPE(x)
 
 #define VMPI_strlen strlen
 #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,
                                    bool executableFlag,
                                    bool writeableFlag);
 
 namespace avmplus {