update to RT statistics for verbose
[cacao.git] / src / vm / jit / inline / parseRTstats.c
index 3a734f5bd48f9bd95800a4ed3cc347782cbb7340..0db7b44b4330052a4345de3c665bdedaca348e53 100644 (file)
 
    Authors: Carolyn Oates
 
-   $Id: parseRTstats.c 1416 2004-10-19 12:07:18Z carolyn $
+   $Id: parseRTstats.c 1469 2004-11-08 21:08:13Z carolyn $
 
 */
+#include <stdio.h>
+#include "toolbox/list.h"
+#include "options.h"
+#include "tables.h"
+#include "statistics.h"
+#include "loader.h"
+#include "parseRT.h"
+#include "parseRTstats.h"
+
+int pClassHeirStatsOnly = 2;
+int pClassHeir = 2;
+
+/*--- Statistics ----------------------------------------------------------*/
+
+int unRTclassHeirCnt=0;
+int unRTmethodCnt = 0;
+
+/*-----*/
+int RTclassHeirNotUsedCnt=0; 
+int RTclassHeirUsedCnt=0;    
+int RTclassHeirPartUsedCnt=0;
+int RTclassHeirSuperCnt=0;
+
+int RTmethodNotUsedCnt = 0;
+int RTmethodNotUsedCnt1= 0;
+int RTmethodNotUsedCnt2= 0;
+int RTmethodUsedCnt = 0;
+int RTmethodMarkedCnt= 0;
+
+/* What might be inlined of the Used Methods */
+int RTmethodFinal  = 0;
+int RTmethodStatic = 0;
+int RTmethodFinalStatic = 0;
+int RTmethodNoSubs = 0;
+
+int RTmethodMono; 
+int RTmethodPossiblePoly;
+int RTmethodPolyReallyMono;
+int RTmethodPoly;
+
+int RTmethodFinal100  = 0;
+int RTmethodStatic100 = 0;
+int RTmethodFinalStatic100 = 0;
+int RTmethodNoSubs100 = 0;
+
+#define MAXCODLEN 10
+
+int RTmethodNoSubsAbstract = 0;
+int RTmethod1Used  = 0;
+
+int RTmethodAbstract = 0;
+
+int subRedefsCnt =0;
+int subRedefsCntUsed =0;
+
+
 
-/*-- new RTA analysis routines will go here */
 /*--------------------------------------------------------------*/
-void printCallgraph ()
+void printCallgraph (list *rtaWorkList)
 { 
+    int i = 1;
+    rtaNode    *rta;
+    methodinfo *rt_meth;  
+
+ printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
+
+   for (rta =list_first(rtaWorkList);
+         rta != NULL;
+         rta =list_next(rtaWorkList,rta))
+       {
+        rt_meth = rta->method;
+
+         printf("  (%i): ",i++); 
+         utf_display(rt_meth->class->name);
+         printf(":");
+         method_display(rt_meth);
+       }
+
+ printf("\n\n");
+
+}
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+int subdefd(methodinfo *meth) {
+    classinfo *subs;
+    methodinfo *submeth;
+
+       printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);
+
+    if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )  
+       printf("\n\n\nPossible Poly call for FINAL or STATIC\n\n\n");
+
+    if ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT )) ) { 
+               return 0;
+       }
+    if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
+
+       printf("sub exist for:");utf_display(meth->class->name);printf(".");method_display(meth);
+
+    for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
+               submeth = class_findmethod_approx(subs, meth->name, meth->descriptor); 
+               if (submeth != NULL) {
+                       subRedefsCnt++;
+                       if (submeth->methodUsed == USED) {
+                               subRedefsCntUsed++;
+                               /*return 1;*/
+                       }
+                       else {
+                               if (subdefd(submeth) > 0)
+                                       ; /*return 1;*/
+                       }
+               }
+       }
+    if (subRedefsCntUsed > 0) return 1;
+    return 0;
+}
+
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+
+void printRTClassHeirarchy(classinfo  *class) {
+  
+       classinfo  *subs;
+       methodinfo *meth;
+       int m,cnt;
+
+       if (class == NULL) {return;}
+    /* Class Name */
+    if (class->classUsed == NOTUSED) {
+               RTclassHeirNotUsedCnt++;
+               RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
+               RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
+               for (m=0; m < class->methodscount; m++) {
+                       meth = &class->methods[m];
+                       if (meth->methodUsed == USED) {
+                               if (pClassHeirStatsOnly >= 2) {
+                                       printf("\nMETHOD marked used in CLASS marked NOTUSED: \n\t"); 
+                                       utf_display(class->name);
+                                       printf(".");
+                                       method_display(meth);
+                                       printf("<%i>\n\t",meth->methodUsed);
+                                       fflush(stdout);
+                                       printf("\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n"); 
+                               }
+                       }
+               }
+       }
+
+    if (class->classUsed != NOTUSED) {
+        if (pClassHeirStatsOnly >= 2) {
+                       printf("\nClass: "); 
+                       utf_display(class->name);    
+                       printf(" <%i> (depth=%i) ",class->classUsed,class->index);
+
+                       printf("\tbase/diff =%3d/%3d\n",
+                                  class->vftbl->baseval,
+                                  class->vftbl->diffval);
+               }
+
+        if (class->classUsed == PARTUSED) {
+            if (pClassHeirStatsOnly >= 2) {
+                               printf("\tClass not instanciated - but  methods/fields resolved to this class' code (static,inits,fields,super)\n");
+                       }
+                       RTclassHeirPartUsedCnt++;
+           }   
+        else {
+                       if (pClassHeirStatsOnly >= 2) {
+                printf("\n");
+                       }
+                       RTclassHeirUsedCnt++;
+               }
+
+
+               /* Print methods used */
+               cnt=0;
+        for (m=0; m < class->methodscount; m++) {
+
+            meth = &class->methods[m];
+               
+                       if (meth->methodUsed == NOTUSED)        RTmethodNotUsedCnt2++; 
+                       if (meth->methodUsed == MARKED)   RTmethodMarkedCnt++;
+                       if (meth->methodUsed == USED) {
+                               RTmethodUsedCnt++;
+                               if (  (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) { 
+                                       RTmethodFinal++;
+                                       if (meth->jcodelength < MAXCODLEN)  RTmethodFinal100++;
+                               }
+
+                               if (  (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) { 
+                                       RTmethodStatic++;
+                                       if (meth->jcodelength < MAXCODLEN)  RTmethodStatic100++;
+                               }
+
+                               if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) { 
+                                       RTmethodFinalStatic++;
+                                       if (meth->jcodelength < MAXCODLEN)  RTmethodFinalStatic100++;
+                               }
+
+                               if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
+                                       && ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT)) ))    {
+                                       RTmethodNoSubs++;
+                                       if (meth->jcodelength < MAXCODLEN)  RTmethodNoSubs100++;
+                               }
+
+                               if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
+                                       && ((meth->class->sub == NULL)  &&   (meth->flags & ACC_ABSTRACT)  ))    RTmethodNoSubsAbstract++;
+
+                               if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
+                                                       
+                               if (meth->monoPoly == MONO) RTmethodMono++;
+                               if (meth->monoPoly == POLY) {
+                                       RTmethodPossiblePoly++;
+                                       subRedefsCnt = 0;
+                                       subRedefsCntUsed = 0;
+                                       if (meth->flags & ACC_ABSTRACT ) {
+                                               if (pClassHeirStatsOnly >= 2) {
+                                                       printf("STATS: abstract_method=");
+                                                       utf_display(meth->class->name);printf(".");
+                                                       method_display(meth);
+                                               }
+                                       }
+                                       else    {
+                                               if (subdefd(meth) == 0) {
+                                                       meth->monoPoly = MONO1;
+                                                       RTmethodPolyReallyMono++;
+                                               }                       
+                                               else    {
+                                                       RTmethodPoly++;
+                                                       meth->subRedefs = subRedefsCnt;
+                                                       meth->subRedefsUsed = subRedefsCntUsed;
+                                               }
+                                       }
+                               }
+
+                               if (pClassHeirStatsOnly >= 2) {
+                                       if (cnt == 0) {
+                                               printf("bMethods used:\n");
+                                       }
+                                       cnt++;
+                                       printf("\t");
+                                       utf_display(meth->class->name); 
+                                       printf(".");
+                                       method_display(meth);
+                                       printf("\t\t");
+                                       if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\n", meth->subRedefsUsed, meth->subRedefs);
+                               }
+                       }
+               }
+               if (pClassHeirStatsOnly >= 2) {
+                       if (cnt > 0) {
+                               if (class->classUsed == PARTUSED)
+                                 printf("> %i of %i methods (part)used\n",cnt, class->methodscount);
+                               if (class->classUsed == USED)
+                                 printf("> %i of %i methods used\n",cnt, class->methodscount);
+                               }
+               }
+       }
+
+    for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
+               printRTClassHeirarchy(subs);
+       }
+}
+/*--------------------------------------------------------------*/
+void printRTInterfaceClasses() {
+       int mm;
+       classinfo *ci = class_java_lang_Object;
+       classSetNode *subs;
+
+       int RTmethodInterfaceClassImplementedCnt        = 0;
+       int RTmethodInterfaceClassUsedCnt               = 0;
+
+       int RTmethodInterfaceMethodTotalCnt             = 0;
+       int RTmethodInterfaceMethodNotUsedCnt   = 0;
+       int RTmethodInterfaceMethodUsedCnt              = 0;
+
+       int RTmethodClassesImpldByTotalCnt              = 0;
+
+       int RTmethodInterfaceMonoCnt                    = 0;
+       int RTmethodInterfacePolyReallyMonoCnt=0;  /* look at every method that implments and see if its poly or mono1*/
+
+       int RTmethodNoSubsAbstractCnt = 0;
+
+       for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
+        classinfo * ici = subs->classType;
+               classinfo * isubs = subs->classType;
+               classSetNode * inBy;
+               int impldBycnt;
+
+               if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
+               if (pClassHeir >= 2) {
+                       printf("Interface class: ");fflush(stdout);
+                       utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
+               }
+               RTmethodInterfaceClassImplementedCnt++;
+               if (ici -> classUsed == USED)     {RTmethodInterfaceClassUsedCnt++;}
+               if (pClassHeir >= 2) {
+                       printf("\n\t\t\tImplemented by classes:\n");
+               }
+               impldBycnt = 0;
+               /* get the total impldBy classes Used */
+               for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
+                       impldBycnt++;
+                       RTmethodClassesImpldByTotalCnt++;
+                       if (pClassHeir >= 2) {
+                               printf("\t\t\t");utf_display(inBy->classType->name);
+                               printf("\n");
+                       }
+                       if (inBy->classType->classUsed == NOTUSED) 
+                               printf("\n\n\nprintRTInterfaceClasses: class in the implemented list without being used!!!??\n\n\n");
+                       fflush(stdout);
+               }
+               if (pClassHeir >= 2) {
+                       printf("\t\t\tImpld by: %i\n",impldBycnt);
+               }
+               if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
+
+        /* if interface class is used */
+        if (ici -> classUsed != NOTUSED) {
+                       if (pClassHeir >= 2) {
+                       printf("    cMethods used:\n");
+                       }
+
+                       /* for each interface method implementation that has been used */
+                       for (mm=0; mm< ici->methodscount; mm++) {
+                               methodinfo *imi = &(ici->methods[mm]);
+                               RTmethodInterfaceMethodTotalCnt++;
+                               if  (imi->methodUsed != USED) {
+                                       RTmethodInterfaceMethodNotUsedCnt++;
+                               }
+                               if  (imi->methodUsed == USED) {
+                                       RTmethodInterfaceMethodUsedCnt++;
+                                       if (pClassHeirStatsOnly >= 2) {
+                                               printf("\t\t"); 
+                                               utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+                                       }
+                                       if (impldBycnt == 1) {
+                                               classinfo  *cii;
+                                               methodinfo *mii;
+
+                                               /* if only 1 implementing class then possibly really mono call */
+                                       inBy = ici->impldBy;
+                                               cii = inBy->classType;
+                                               
+                                               mii = class_fetchmethod(cii, imi->name, imi->descriptor); 
+                                               if (mii == NULL) {
+                                                       /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
+                                                       imi->monoPoly = MONO1;
+                                                       RTmethodInterfacePolyReallyMonoCnt++;
+                                               }
+                                               else    {
+                                                       /**if (imi->monoPoly != POLY) 
+                                                               printf("\n\n\ninterface monopoly not POLY\n\n\n");
+                                                       **/
+                                                       if (mii->monoPoly != POLY) {
+                                                               imi->monoPoly = MONO1;
+                                                               RTmethodInterfacePolyReallyMonoCnt++;
+                                                       }
+                                                       else    {
+                                                               imi->monoPoly = POLY;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       if (pClassHeir >= 2) {
+                               printf("\n");
+                       }
+               }
+       }
+       if (pClassHeirStatsOnly >= 1) {
+               printf("\n\n  >>>>>>>>>>>>>>>>>>>>  Interface Statistics Summary: \n");
+               printf("Classes:  Total:   %i \tUSED:      %i \tIMPLD BY:   \t%i \tJUST 1 IMPLD BY:  %i \tNOSUB:     %i \n",
+                          RTmethodInterfaceClassImplementedCnt,
+                          RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
+                          RTmethodNoSubsAbstractCnt);
+               printf("Methods:  Total:   %i \tNOTUSED:   %i  \tUSED:      \t%i \tPoly that resolves to Mono  %i \n",
+                          RTmethodInterfaceMethodTotalCnt,
+                          RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
+       }
 }
+
+/*--------------------------------------------------------------*/
+
+
+
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+
+void printRThierarchyInfo(methodinfo *m) {
+
+       /*-- init for statistics --*/
+       RTclassHeirNotUsedCnt=0; 
+       RTclassHeirUsedCnt=0;    
+       RTclassHeirPartUsedCnt=0;   
+       RTclassHeirSuperCnt=0;   
+       RTmethodNotUsedCnt = 0; 
+       RTmethodNotUsedCnt1 = 0; 
+       RTmethodNotUsedCnt2 = 0;  
+       RTmethodUsedCnt = 0;   
+       RTmethodMarkedCnt= 0;  
+
+
+printf("RT Heirarchy:------------\n"); fflush(stdout);
+       /*-- --*/
+       if (pClassHeirStatsOnly >= 2) {
+               printf("\nRT Class Hierarchy for ");
+               printf("--- start of RT info --------------- after :\n");
+               if (m != NULL) {
+                       utf_display(m->class->name); 
+                       printf(".");
+                       method_display(m);
+                       printf("\n");
+               }
+    }
+       printRTClassHeirarchy(class_java_lang_Object);
+       //printRTClassHeirarchy(m->class);
+       if (pClassHeirStatsOnly >= 2) {
+               fflush(stdout);
+               printf("--- end  of RT info ---------------\n");
+    }
+       if (pClassHeirStatsOnly >= 1) {
+               /*--  statistic results --*/
+               if (opt_rt)
+               printRTInterfaceClasses();
+       
+               printf("\n  >>>>>>>>>>>>>>>>>>>>  Analysed Class Hierarchy Statistics:\n"); 
+               printf(" Used            \t%i \tclasses\t/ Used       \t%i methods \t of USED: %i%% \t  of ALL: %i%% \n",
+                          RTclassHeirUsedCnt,RTmethodUsedCnt,
+                          ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
+                          ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt    + RTmethodUsedCnt    + RTmethodMarkedCnt)) );
+               printf(" Part Used       \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt); 
+               printf(" Not Used        \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt); 
+               printf("                 \t    \t       \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt); 
+               printf(" In Not Used     \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt1); 
+               printf(" In Used         \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt2);
+               printf(" Total           \t%i \tclasses\t/ Total       \t%i methods\n\n",
+                          RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,  
+                          RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2    + RTmethodUsedCnt    + RTmethodMarkedCnt ); 
+
+               printf(" Mono vs. Polymorphic calls:\n");
+               printf(" Mono calls     \t%i   \tPoly that resolves to Mono \t%i \tPoly calls     \t%i\n\n",
+                          RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
+
+               printf(" No Subs: Total=\t%i   \tAbstract No Subs=           \t%i \tAbstract methods used =\t%i\n",
+                          RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
+
+               printf(" Inlining possible:  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+                          RTmethodFinal, RTmethodStatic,RTmethodFinalStatic,  RTmethodNoSubs);
+               printf("    Code size < 100  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+                          RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100,  RTmethodNoSubs100);
+       }
+}
+
+
 /*--------------------------------------------------------------*/
 
 /*