5d2fec633d1acaa1c0799e115b41b9212225871d
[cacao.git] / src / vm / jit / inline / parseRTstats.h
1
2 /*--- Statistics ----------------------------------------------------------*/
3
4 int unRTclassHeirCnt=0;
5 int unRTmethodCnt = 0;
6
7 /*-----*/
8 int RTclassHeirNotUsedCnt=0; 
9 int RTclassHeirUsedCnt=0;    
10 int RTclassHeirPartUsedCnt=0;
11 int RTclassHeirSuperCnt=0;
12
13 int RTmethodNotUsedCnt = 0;
14 int RTmethodNotUsedCnt1= 0;
15 int RTmethodNotUsedCnt2= 0;
16 int RTmethodUsedCnt = 0;
17 int RTmethodMarkedCnt= 0;
18
19 /* What might be inlined of the Used Methods */
20 int RTmethodFinal  = 0;
21 int RTmethodStatic = 0;
22 int RTmethodFinalStatic = 0;
23 int RTmethodNoSubs = 0;
24
25 int RTmethodMono; 
26 int RTmethodPossiblePoly;
27 int RTmethodPolyReallyMono;
28 int RTmethodPoly;
29
30 int RTmethodFinal100  = 0;
31 int RTmethodStatic100 = 0;
32 int RTmethodFinalStatic100 = 0;
33 int RTmethodNoSubs100 = 0;
34
35 #define MAXCODLEN 10
36
37 int RTmethodNoSubsAbstract = 0;
38 int RTmethod1Used  = 0;
39
40 int RTmethodAbstract = 0;
41
42 int subRedefsCnt =0;
43 int subRedefsCntUsed =0;
44
45 /*------------- RTAprint flags ------------------------------------------------------------------*/
46 int pCallgraph  = 0;    /* 0 - dont print 1 - print at end from main                             */ 
47                         /* 2 - print at end of RT parse call                                     */
48                         /* 3- print after each method RT parse                                   */
49 int pClassHeir  = 1;    /* 0 - dont print 1 - print at end from main                             */
50                         /* 2 - print at end of RT parse call  3-print after each method RT parse */
51 int pClassHeirStatsOnly = 1;  /* usually 2 Print only the statistical summary info for class heirarchy     */
52
53 int pOpcodes    = 0;    /* 0 - don't print 1- print in parse RT 2- print in parse                */
54                         /* 3 - print in both                                                     */
55 int pWhenMarked = 0;    /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
56                         /* 2 - print when marked+methods called                                  */
57                         /* 3 - print when class/method looked at                                 */
58 int pStats = 0;         /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
59
60 /*-----------------------------------------------------------------------------------------------*/
61 /*-----------------------------------------------------------------------------------------------*/
62 void printXTACallgraph ()
63   { int i;
64 if (XTAdebug >= 1) {
65 printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
66   for (i=0;i<=methXTAlast;i++) {
67     printf("  (%i): ",i);
68     utf_display(XTAcallgraph[i]->class->name);
69     printf(":");
70     method_display(XTAcallgraph[i]);
71     }
72
73   printf("\n\n");
74   }
75   }
76
77 /*-----------------------------------------------------------------------------------------------*/
78 /*-----------------------------------------------------------------------------------------------*/
79
80 void printCallgraph ()
81   { int i;
82
83 printf("----- RTA Callgraph Worklist:<%i>\n",methRTlast);
84   for (i=0;i<=methRTlast;i++) {
85     printf("  (%i): ",i);
86     utf_display(callgraph[i]->class->name);
87     printf(":");
88     method_display(callgraph[i]);
89     }
90
91   printf("\n\n");
92   }
93 /*--------------------------------------------------------------*/
94 void printObjectClassHeirarchy1() {
95 if (pStats >= 1) {
96         unRTclassHeirCnt=0;
97         unRTmethodCnt = 0;
98                 printObjectClassHeirarchy(class_java_lang_Object);
99         printf("\n >>>>>>>>>>>>>>>>>>>>  END of unanalysed Class Heirarchy: #%i classes /  #%i methods\n\n",
100                 unRTclassHeirCnt,unRTmethodCnt);
101         }
102
103 }
104 /*--------------------------------------------------------------*/
105 void printObjectClassHeirarchy(classinfo  *class) {
106   
107 classinfo  *subs;
108 methodinfo *meth;
109 int t,m,cnt;
110
111 if (class == NULL) {return;}
112   unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
113   if (pStats == 2) {
114     printf("\n");
115     /* Class Name */
116     for (t=0;t<class->index;t++) printf("\t"); 
117     if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
118
119     printf("Class: "); 
120     utf_display(class->name);    
121     printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
122     /* Print methods used */
123     cnt=0; 
124     for (m=0; m < class->methodscount; m++) {
125             meth = &class->methods[m];
126             if (cnt == 0) {
127               for (t=0;t<class->index;t++) printf("\t");
128                  printf("aMethods used:\n");
129                  }
130              for (t=0;t<class->index;t++) printf("\t");
131              printf("\t");
132              utf_display(meth->class->name); 
133              printf(".");
134              method_display(meth);
135              cnt++;
136             }
137     if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
138     }
139
140     for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
141         printObjectClassHeirarchy(subs);
142         }
143
144 }
145 /*--------------------------------------------------------------*/
146 /*--------------------------------------------------------------*/
147 int subdefd(methodinfo *meth) {
148     classinfo *subs;
149     methodinfo *submeth;
150
151 /*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
152
153     if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )  
154         panic("Possible Poly call for FINAL or STATIC\n");
155
156     if ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT )) ) { 
157         return 0;
158         }
159     if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
160
161 /*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
162
163     for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
164         submeth = class_findmethod(subs, meth->name, meth->descriptor); 
165         if (submeth != NULL) {
166                 subRedefsCnt++;
167                 if (submeth->methodUsed == USED) {
168                         subRedefsCntUsed++;
169                         /*return 1;*/
170                         }
171                 else {
172                    if (subdefd(submeth) > 0)
173                         ; /*return 1;*/
174                    }
175                 }
176         }
177     if (subRedefsCntUsed > 0) return 1;
178     return 0;
179 }
180 /*--------------------------------------------------------------*/
181
182 void printRTClassHeirarchy(classinfo  *class) {
183   
184 classinfo  *subs;
185 methodinfo *meth;
186 int m,cnt;
187
188 if (class == NULL) {return;}
189     /* Class Name */
190     if (class->classUsed == NOTUSED) {
191         RTclassHeirNotUsedCnt++;
192         RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
193         RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
194         for (m=0; m < class->methodscount; m++) {
195           meth = &class->methods[m];
196           if (meth->methodUsed == USED) {
197             if (pClassHeirStatsOnly >= 2) {
198                 printf("METHOD marked used in CLASS marked NOTUSED: "); 
199                 utf_display(class->name);
200                 printf(".");
201                 method_display(meth);
202                 printf("<%i>\n\t",meth->methodUsed);
203                 fflush(stdout);
204                 printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n"); 
205                 }
206              }
207           }
208         }
209
210     if (class->classUsed != NOTUSED) {
211         if (pClassHeirStatsOnly >= 2) {
212           printf("\nClass: "); 
213           utf_display(class->name);    
214           printf(" <%i> (depth=%i) ",class->classUsed,class->index);
215
216                   printf("\tbase/diff =%3d/%3d\n",
217                         class->vftbl->baseval,
218                         class->vftbl->diffval);
219           }
220
221         if (class->classUsed == PARTUSED) {
222             if (pClassHeirStatsOnly >= 2) {
223   printf("\tClass not instanciated - but  methods/fields resolved to this class' code (static,inits,fields,super)\n");
224               }
225             RTclassHeirPartUsedCnt++;
226             }   
227         else {
228               if (pClassHeirStatsOnly >= 2) {
229                 printf("\n");
230                 }
231               RTclassHeirUsedCnt++;
232               }
233
234
235         /* Print methods used */
236         cnt=0;
237         for (m=0; m < class->methodscount; m++) {
238
239             meth = &class->methods[m];
240                 
241             if (meth->methodUsed == NOTUSED)    RTmethodNotUsedCnt2++; 
242             if (meth->methodUsed == MARKED)   RTmethodMarkedCnt++;
243             if (meth->methodUsed == USED) {
244                 RTmethodUsedCnt++;
245                 if (  (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) { 
246                         RTmethodFinal++;
247                         if (meth->jcodelength < MAXCODLEN)  RTmethodFinal100++;
248                         }
249
250                 if (  (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) { 
251                         RTmethodStatic++;
252                         if (meth->jcodelength < MAXCODLEN)  RTmethodStatic100++;
253                         }
254
255                 if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) { 
256                         RTmethodFinalStatic++;
257                         if (meth->jcodelength < MAXCODLEN)  RTmethodFinalStatic100++;
258                         }
259
260                 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
261                    && ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT)) ))    {
262                         RTmethodNoSubs++;
263                         if (meth->jcodelength < MAXCODLEN)  RTmethodNoSubs100++;
264                         }
265
266                 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
267                    && ((meth->class->sub == NULL)  &&   (meth->flags & ACC_ABSTRACT)  ))    RTmethodNoSubsAbstract++;
268
269                 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
270                                                         
271                 if (meth->monoPoly == MONO) RTmethodMono++;
272                 if (meth->monoPoly == POLY) {
273                         RTmethodPossiblePoly++;
274                                 subRedefsCnt = 0;
275                                 subRedefsCntUsed = 0;
276                         if (meth->flags & ACC_ABSTRACT ) {
277                                 if (pClassHeirStatsOnly >= 2) {
278                                         printf("STATS: abstract_method=");
279                                         utf_display(meth->class->name);printf(".");
280                                         method_display(meth);
281                                         }
282                                 }
283                         else    {
284                                 if (subdefd(meth) == 0) {
285                                         meth->monoPoly = MONO1;
286                                         RTmethodPolyReallyMono++;
287                                         }                       
288                                 else    {
289                                         RTmethodPoly++;
290                                         meth->subRedefs = subRedefsCnt;
291                                         meth->subRedefsUsed = subRedefsCntUsed;
292                                         }
293                                 }
294                         }
295
296                 if (pClassHeirStatsOnly >= 2) {
297                   if (cnt == 0) {
298                      printf("bMethods used:\n");
299                      }
300                   cnt++;
301                   printf("\t");
302                   utf_display(meth->class->name); 
303                   printf(".");
304                   method_display(meth);
305                         printf("\t\t");
306                   if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
307                      if ( (XTAOPTbypass3) || (opt_xta)) {
308                         if (meth->xta->XTAclassSet == NULL)
309                                 printf("class set never created\n");
310                         else
311                                 printSet(meth->xta->XTAclassSet->head);
312                         }
313                   }
314                }
315             }
316          if (pClassHeirStatsOnly >= 2) {
317            if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
318            }
319          }
320
321     for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
322         printRTClassHeirarchy(subs);
323         }
324 }
325 /*--------------------------------------------------------------*/
326 void printRTInterfaceClasses() {
327   int mm;
328   classinfo *ci = class_java_lang_Object;
329   classSetNode *subs;
330
331   int RTmethodInterfaceClassImplementedCnt      = 0;
332   int RTmethodInterfaceClassUsedCnt             = 0;
333
334   int RTmethodInterfaceMethodTotalCnt           = 0;
335   int RTmethodInterfaceMethodNotUsedCnt         = 0;
336   int RTmethodInterfaceMethodUsedCnt            = 0;
337
338   int RTmethodClassesImpldByTotalCnt            = 0;
339
340   int RTmethodInterfaceMonoCnt                  = 0;
341   int RTmethodInterfacePolyReallyMonoCnt=0;  /* look at every method that implments and see if its poly or mono1*/
342
343   int RTmethodNoSubsAbstractCnt = 0;
344
345 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
346         classinfo * ici = subs->classType;
347         classinfo * isubs = subs->classType;
348         classSetNode * inBy;
349         int impldBycnt;
350
351         if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
352         if (pClassHeir >= 2) {
353                 printf("Interface class: ");fflush(stdout);
354                 utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
355                 }
356         RTmethodInterfaceClassImplementedCnt++;
357         if (ici -> classUsed == USED)     {RTmethodInterfaceClassUsedCnt++;}
358         if (pClassHeir >= 2) {
359                 printf("\n\t\t\tImplemented by classes:\n");
360                 }
361         impldBycnt = 0;
362         /* get the total impldBy classes Used */
363         for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
364                 impldBycnt++;
365                 RTmethodClassesImpldByTotalCnt++;
366                 if (pClassHeir >= 2) {
367                         printf("\t\t\t");utf_display(inBy->classType->name);
368                         printf("\n");
369                         }
370                 if (inBy->classType->classUsed == NOTUSED) 
371                         panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
372                 }
373         if (pClassHeir >= 2) {
374                 printf("\t\t\tImpld by: %i\n",impldBycnt);
375                 }
376         if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
377
378         /* if interface class is used */
379         if (ici -> classUsed != NOTUSED) {
380                 if (pClassHeir >= 2) {
381                         printf("    cMethods used:\n");
382                         }
383
384                 /* for each interface method implementation that has been used */
385                 for (mm=0; mm< ici->methodscount; mm++) {
386                         methodinfo *imi = &(ici->methods[mm]);
387                         RTmethodInterfaceMethodTotalCnt++;
388                         if  (imi->methodUsed != USED) {
389                                 RTmethodInterfaceMethodNotUsedCnt++;
390                                 }
391                         if  (imi->methodUsed == USED) {
392                         RTmethodInterfaceMethodUsedCnt++;
393                                 if (pClassHeirStatsOnly >= 2) {
394                                         printf("\t\t"); 
395                                         utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
396                                         }
397                                 if (impldBycnt == 1) {
398                                         classinfo  *cii;
399                                         methodinfo *mii;
400
401                                         /* if only 1 implementing class then possibly really mono call */
402                                         inBy = ici->impldBy;
403                                         cii = inBy->classType;
404                                                 
405                                         mii = class_findmethod(cii, imi->name, imi->descriptor); 
406                                         if (mii == NULL) {
407                                                 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
408                                                 imi->monoPoly = MONO1;
409                                                 RTmethodInterfacePolyReallyMonoCnt++;
410                                                 }
411                                         else    {
412                                                 if (imi->monoPoly != POLY) 
413                                                         panic ("interface monopoly not POLY");
414
415                                                 if (mii->monoPoly != POLY) {
416                                                         imi->monoPoly = MONO1;
417                                                         RTmethodInterfacePolyReallyMonoCnt++;
418                                                         }
419                                                 else    {
420                                                         imi->monoPoly = POLY;
421                                                         }
422                                                 }
423                                         }
424                                 }
425                         }
426                 if (pClassHeir >= 2) {
427                         printf("\n");
428                         }
429                 }
430         }
431 if (pClassHeirStatsOnly >= 1) {
432         printf("\n\n  >>>>>>>>>>>>>>>>>>>>  Interface Statistics Summary: \n");
433         printf("Classes:  Total:   %i \tUSED:      %i \tIMPLD BY:   \t%i \tJUST 1 IMPLD BY:  %i \tNOSUB:     %i \n",
434                 RTmethodInterfaceClassImplementedCnt,
435                 RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
436                 RTmethodNoSubsAbstractCnt);
437         printf("Methods:  Total:   %i \tNOTUSED:   %i  \tUSED:      \t%i \tPoly that resolves to Mono  %i \n",
438                 RTmethodInterfaceMethodTotalCnt,
439                 RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
440         }
441 }
442 /*--------------------------------------------------------------*/
443
444 void printRThierarchyInfo(methodinfo *m) {
445
446   /*-- init for statistics --*/
447   RTclassHeirNotUsedCnt=0; 
448   RTclassHeirUsedCnt=0;    
449   RTclassHeirPartUsedCnt=0;   
450   RTclassHeirSuperCnt=0;   
451   RTmethodNotUsedCnt = 0; 
452   RTmethodNotUsedCnt1 = 0; 
453   RTmethodNotUsedCnt2 = 0;  
454   RTmethodUsedCnt = 0;   
455   RTmethodMarkedCnt= 0;  
456
457
458   /*-- --*/
459   if (pClassHeirStatsOnly >= 2) {
460     printf("\nRT Class Hierarchy for ");
461     printf("--- start of RT info --------------- after :\n");
462     if (m != NULL) {
463         utf_display(m->class->name); 
464          printf(".");
465          method_display(m);
466         printf("\n");
467         }
468     }
469   printRTClassHeirarchy(class_java_lang_Object);
470   if (pClassHeirStatsOnly >= 2) {
471     printf("--- end  of RT info ---------------\n");
472     }
473  if (pClassHeirStatsOnly >= 1) {
474
475   /*--  statistic results --*/
476   printRTInterfaceClasses();
477         
478   printf("\n  >>>>>>>>>>>>>>>>>>>>  Analysed Class Hierarchy Statistics:\n"); 
479   printf(" Used            \t%i \tclasses\t/ Used       \t%i methods \t of USED: %i%% \t  of ALL: %i%% \n",
480                 RTclassHeirUsedCnt,RTmethodUsedCnt,
481                 ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
482                 ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt    + RTmethodUsedCnt    + RTmethodMarkedCnt)) );
483   printf(" Part Used       \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt); 
484   printf(" Not Used        \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt); 
485   printf("                 \t    \t       \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt); 
486   printf(" In Not Used     \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt1); 
487   printf(" In Used         \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt2);
488   printf(" Total           \t%i \tclasses\t/ Total       \t%i methods\n\n",
489         RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,  
490         RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2    + RTmethodUsedCnt    + RTmethodMarkedCnt ); 
491
492   printf(" Mono vs. Polymorphic calls:\n");
493   printf(" Mono calls     \t%i   \tPoly that resolves to Mono \t%i \tPoly calls     \t%i\n\n",
494            RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
495
496   printf(" No Subs: Total=\t%i   \tAbstract No Subs=           \t%i \tAbstract methods used =\t%i\n",
497           RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
498
499   printf(" Inlining possible:  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
500         RTmethodFinal, RTmethodStatic,RTmethodFinalStatic,  RTmethodNoSubs);
501   printf("    Code size < 100  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
502         RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100,  RTmethodNoSubs100);
503   }
504 }
505