more XTA updates
[cacao.git] / jit / parseRTstats.c
1 /* jit/parseRTstats.c -
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Carolyn Oates
28
29    $Id: parseRTstats.c 657 2003-11-20 15:18:33Z carolyn $
30
31 */
32
33
34 #include "parseRT.h"
35 #include "parseRTstats.h"
36
37
38 /*--- Statistics ----------------------------------------------------------*/
39
40 int unRTclassHeirCnt=0;
41 int unRTmethodCnt = 0;
42
43 /*-----*/
44 int RTclassHeirNotUsedCnt=0; 
45 int RTclassHeirUsedCnt=0;    
46 int RTclassHeirPartUsedCnt=0;
47 int RTclassHeirSuperCnt=0;
48
49 int RTmethodNotUsedCnt = 0;
50 int RTmethodNotUsedCnt1= 0;
51 int RTmethodNotUsedCnt2= 0;
52 int RTmethodUsedCnt = 0;
53 int RTmethodMarkedCnt= 0;
54
55 /* What might be inlined of the Used Methods */
56 int RTmethodFinal  = 0;
57 int RTmethodStatic = 0;
58 int RTmethodFinalStatic = 0;
59 int RTmethodNoSubs = 0;
60
61 int RTmethodMono; 
62 int RTmethodPossiblePoly;
63 int RTmethodPolyReallyMono;
64 int RTmethodPoly;
65
66 int RTmethodFinal100  = 0;
67 int RTmethodStatic100 = 0;
68 int RTmethodFinalStatic100 = 0;
69 int RTmethodNoSubs100 = 0;
70
71 #define MAXCODLEN 10
72
73 int RTmethodNoSubsAbstract = 0;
74 int RTmethod1Used  = 0;
75
76 int RTmethodAbstract = 0;
77
78 int subRedefsCnt =0;
79 int subRedefsCntUsed =0;
80
81 /*-----------------------------------------------------------------------------------------------*/
82 void printXTACallgraph()
83
84         int i;
85
86 //      if (XTAdebug >= 1) {
87                 printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
88                 for (i=0;i<=methXTAlast;i++) {
89                         printf("  (%i): ",i);
90                         utf_display(XTAcallgraph[i]->class->name);
91                         printf(":");
92                         method_display(XTAcallgraph[i]);
93                 }
94
95                 printf("----- end of XTA Callgraph Worklist:<%i>\n",methXTAlast);
96                 printf("\n\n");
97 //      }
98 }
99
100 /*-----------------------------------------------------------------------------------------------*/
101 /*-----------------------------------------------------------------------------------------------*/
102
103 void printCallgraph ()
104 { int i;
105
106  printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",methRTlast);
107  for (i=0;i<=methRTlast;i++) {
108          printf("  (%i): ",i);
109          utf_display(callgraph[i]->class->name);
110          printf(":");
111          method_display(callgraph[i]);
112  }
113
114  printf("\n\n");
115 }
116 /*--------------------------------------------------------------*/
117 void printObjectClassHeirarchyAll() {
118         if (pStats >= 1) {
119         unRTclassHeirCnt=0;
120         unRTmethodCnt = 0;
121                 printObjectClassHeirarchy(class_java_lang_Object);
122         printf("\n >>>>>>>>>>>>>>>>>>>>  END of unanalysed Class Heirarchy: #%i classes /  #%i methods\n\n",
123                            unRTclassHeirCnt,unRTmethodCnt);
124         }
125
126 }
127 /*--------------------------------------------------------------*/
128 void printObjectClassHeirarchy(classinfo  *class) {
129   
130         classinfo  *subs;
131         methodinfo *meth;
132         int t,m,cnt;
133
134         if (class == NULL) {return;}
135         unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
136         if (pStats == 2) {
137                 printf("\n");
138                 /* Class Name */
139                 for (t=0;t<class->index;t++) printf("\t"); 
140                 if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
141
142                 printf("Class: "); 
143                 utf_display(class->name);    
144                 printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
145                 /* Print methods used */
146                 cnt=0; 
147                 for (m=0; m < class->methodscount; m++) {
148             meth = &class->methods[m];
149                         if (cnt == 0) {
150                                 for (t=0;t<class->index;t++) printf("\t");
151                                 printf("aMethods used:\n");
152                         }
153                         for (t=0;t<class->index;t++) printf("\t");
154                         printf("\t");
155                         utf_display(meth->class->name); 
156                         printf(".");
157                         method_display(meth);
158                         cnt++;
159             }
160                 if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
161     }
162
163     for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
164                 printObjectClassHeirarchy(subs);
165         }
166
167 }
168 /*--------------------------------------------------------------*/
169 /*--------------------------------------------------------------*/
170 int subdefd(methodinfo *meth) {
171     classinfo *subs;
172     methodinfo *submeth;
173
174         /*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
175
176     if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )  
177         panic("Possible Poly call for FINAL or STATIC\n");
178
179     if ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT )) ) { 
180                 return 0;
181         }
182     if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
183
184         /*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
185
186     for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
187                 submeth = class_findmethod(subs, meth->name, meth->descriptor); 
188                 if (submeth != NULL) {
189                         subRedefsCnt++;
190                         if (submeth->methodUsed == USED) {
191                                 subRedefsCntUsed++;
192                                 /*return 1;*/
193                         }
194                         else {
195                                 if (subdefd(submeth) > 0)
196                                         ; /*return 1;*/
197                         }
198                 }
199         }
200     if (subRedefsCntUsed > 0) return 1;
201     return 0;
202 }
203 /*--------------------------------------------------------------*/
204
205 void printRTClassHeirarchy(classinfo  *class) {
206   
207         classinfo  *subs;
208         methodinfo *meth;
209         int m,cnt;
210
211         if (class == NULL) {return;}
212     /* Class Name */
213     if (class->classUsed == NOTUSED) {
214                 RTclassHeirNotUsedCnt++;
215                 RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
216                 RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
217                 for (m=0; m < class->methodscount; m++) {
218                         meth = &class->methods[m];
219                         if (meth->methodUsed == USED) {
220                                 if (pClassHeirStatsOnly >= 2) {
221                                         printf("METHOD marked used in CLASS marked NOTUSED: "); 
222                                         utf_display(class->name);
223                                         printf(".");
224                                         method_display(meth);
225                                         printf("<%i>\n\t",meth->methodUsed);
226                                         fflush(stdout);
227                                         printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n"); 
228                                 }
229                         }
230                 }
231         }
232
233     if (class->classUsed != NOTUSED) {
234         if (pClassHeirStatsOnly >= 2) {
235                         printf("\nClass: "); 
236                         utf_display(class->name);    
237                         printf(" <%i> (depth=%i) ",class->classUsed,class->index);
238
239                         printf("\tbase/diff =%3d/%3d\n",
240                                    class->vftbl->baseval,
241                                    class->vftbl->diffval);
242                 }
243
244         if (class->classUsed == PARTUSED) {
245             if (pClassHeirStatsOnly >= 2) {
246                                 printf("\tClass not instanciated - but  methods/fields resolved to this class' code (static,inits,fields,super)\n");
247                         }
248                         RTclassHeirPartUsedCnt++;
249             }   
250         else {
251                         if (pClassHeirStatsOnly >= 2) {
252                 printf("\n");
253                         }
254                         RTclassHeirUsedCnt++;
255                 }
256
257
258                 /* Print methods used */
259                 cnt=0;
260         for (m=0; m < class->methodscount; m++) {
261
262             meth = &class->methods[m];
263                 
264                         if (meth->methodUsed == NOTUSED)        RTmethodNotUsedCnt2++; 
265                         if (meth->methodUsed == MARKED)   RTmethodMarkedCnt++;
266                         if (meth->methodUsed == USED) {
267                                 RTmethodUsedCnt++;
268                                 if (  (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) { 
269                                         RTmethodFinal++;
270                                         if (meth->jcodelength < MAXCODLEN)  RTmethodFinal100++;
271                                 }
272
273                                 if (  (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) { 
274                                         RTmethodStatic++;
275                                         if (meth->jcodelength < MAXCODLEN)  RTmethodStatic100++;
276                                 }
277
278                                 if (  (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) { 
279                                         RTmethodFinalStatic++;
280                                         if (meth->jcodelength < MAXCODLEN)  RTmethodFinalStatic100++;
281                                 }
282
283                                 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
284                                         && ((meth->class->sub == NULL)  && (!(meth->flags & ACC_ABSTRACT)) ))    {
285                                         RTmethodNoSubs++;
286                                         if (meth->jcodelength < MAXCODLEN)  RTmethodNoSubs100++;
287                                 }
288
289                                 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) ) 
290                                         && ((meth->class->sub == NULL)  &&   (meth->flags & ACC_ABSTRACT)  ))    RTmethodNoSubsAbstract++;
291
292                                 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
293                                                         
294                                 if (meth->monoPoly == MONO) RTmethodMono++;
295                                 if (meth->monoPoly == POLY) {
296                                         RTmethodPossiblePoly++;
297                                         subRedefsCnt = 0;
298                                         subRedefsCntUsed = 0;
299                                         if (meth->flags & ACC_ABSTRACT ) {
300                                                 if (pClassHeirStatsOnly >= 2) {
301                                                         printf("STATS: abstract_method=");
302                                                         utf_display(meth->class->name);printf(".");
303                                                         method_display(meth);
304                                                 }
305                                         }
306                                         else    {
307                                                 if (subdefd(meth) == 0) {
308                                                         meth->monoPoly = MONO1;
309                                                         RTmethodPolyReallyMono++;
310                                                 }                       
311                                                 else    {
312                                                         RTmethodPoly++;
313                                                         meth->subRedefs = subRedefsCnt;
314                                                         meth->subRedefsUsed = subRedefsCntUsed;
315                                                 }
316                                         }
317                                 }
318
319                                 if (pClassHeirStatsOnly >= 2) {
320                                         if (cnt == 0) {
321                                                 printf("bMethods used:\n");
322                                         }
323                                         cnt++;
324                                         printf("\t");
325                                         utf_display(meth->class->name); 
326                                         printf(".");
327                                         method_display(meth);
328                                         printf("\t\t");
329                                         if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
330                                         if ( (XTAOPTbypass3) || (opt_xta)) {
331                                                 if (meth->xta == NULL) {
332                                                         printf("class set never created\n");
333                                                         }
334                                                 else    {
335                                                         if (meth->xta->XTAclassSet == NULL)
336                                                                 printf("class set never created\n");
337                                                         else
338                                                                 printSet(meth->xta->XTAclassSet->head);
339                                                         }
340                                         }
341                                 }
342                         }
343                 }
344                 if (pClassHeirStatsOnly >= 2) {
345                         if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
346                 }
347         }
348
349     for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
350                 printRTClassHeirarchy(subs);
351         }
352 }
353 /*--------------------------------------------------------------*/
354 void printRTInterfaceClasses() {
355         int mm;
356         classinfo *ci = class_java_lang_Object;
357         classSetNode *subs;
358
359         int RTmethodInterfaceClassImplementedCnt        = 0;
360         int RTmethodInterfaceClassUsedCnt               = 0;
361
362         int RTmethodInterfaceMethodTotalCnt             = 0;
363         int RTmethodInterfaceMethodNotUsedCnt   = 0;
364         int RTmethodInterfaceMethodUsedCnt              = 0;
365
366         int RTmethodClassesImpldByTotalCnt              = 0;
367
368         int RTmethodInterfaceMonoCnt                    = 0;
369         int RTmethodInterfacePolyReallyMonoCnt=0;  /* look at every method that implments and see if its poly or mono1*/
370
371         int RTmethodNoSubsAbstractCnt = 0;
372
373         for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
374         classinfo * ici = subs->classType;
375                 classinfo * isubs = subs->classType;
376                 classSetNode * inBy;
377                 int impldBycnt;
378
379                 if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
380                 if (pClassHeir >= 2) {
381                         printf("Interface class: ");fflush(stdout);
382                 utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
383                 }
384                 RTmethodInterfaceClassImplementedCnt++;
385                 if (ici -> classUsed == USED)     {RTmethodInterfaceClassUsedCnt++;}
386                 if (pClassHeir >= 2) {
387                         printf("\n\t\t\tImplemented by classes:\n");
388                 }
389                 impldBycnt = 0;
390                 /* get the total impldBy classes Used */
391                 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
392                         impldBycnt++;
393                         RTmethodClassesImpldByTotalCnt++;
394                         if (pClassHeir >= 2) {
395                                 printf("\t\t\t");utf_display(inBy->classType->name);
396                                 printf("\n");
397                         }
398                         if (inBy->classType->classUsed == NOTUSED) 
399                                 panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
400                 }
401                 if (pClassHeir >= 2) {
402                         printf("\t\t\tImpld by: %i\n",impldBycnt);
403                 }
404                 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
405
406         /* if interface class is used */
407         if (ici -> classUsed != NOTUSED) {
408                         if (pClassHeir >= 2) {
409                         printf("    cMethods used:\n");
410                         }
411
412                         /* for each interface method implementation that has been used */
413                         for (mm=0; mm< ici->methodscount; mm++) {
414                                 methodinfo *imi = &(ici->methods[mm]);
415                                 RTmethodInterfaceMethodTotalCnt++;
416                                 if  (imi->methodUsed != USED) {
417                                         RTmethodInterfaceMethodNotUsedCnt++;
418                                 }
419                                 if  (imi->methodUsed == USED) {
420                                         RTmethodInterfaceMethodUsedCnt++;
421                                         if (pClassHeirStatsOnly >= 2) {
422                                                 printf("\t\t"); 
423                                                 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
424                                         }
425                                         if (impldBycnt == 1) {
426                                                 classinfo  *cii;
427                                                 methodinfo *mii;
428
429                                                 /* if only 1 implementing class then possibly really mono call */
430                                         inBy = ici->impldBy;
431                                                 cii = inBy->classType;
432                                                 
433                                                 mii = class_findmethod(cii, imi->name, imi->descriptor); 
434                                                 if (mii == NULL) {
435                                                         /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
436                                                         imi->monoPoly = MONO1;
437                                                         RTmethodInterfacePolyReallyMonoCnt++;
438                                                 }
439                                                 else    {
440                                                         /**if (imi->monoPoly != POLY) 
441                                                                 panic ("interface monopoly not POLY");
442                                                         **/
443                                                         if (mii->monoPoly != POLY) {
444                                                                 imi->monoPoly = MONO1;
445                                                                 RTmethodInterfacePolyReallyMonoCnt++;
446                                                         }
447                                                         else    {
448                                                                 imi->monoPoly = POLY;
449                                                         }
450                                                 }
451                                         }
452                                 }
453                         }
454                         if (pClassHeir >= 2) {
455                                 printf("\n");
456                         }
457                 }
458         }
459         if (pClassHeirStatsOnly >= 1) {
460                 printf("\n\n  >>>>>>>>>>>>>>>>>>>>  Interface Statistics Summary: \n");
461                 printf("Classes:  Total:   %i \tUSED:      %i \tIMPLD BY:   \t%i \tJUST 1 IMPLD BY:  %i \tNOSUB:     %i \n",
462                            RTmethodInterfaceClassImplementedCnt,
463                            RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
464                            RTmethodNoSubsAbstractCnt);
465                 printf("Methods:  Total:   %i \tNOTUSED:   %i  \tUSED:      \t%i \tPoly that resolves to Mono  %i \n",
466                            RTmethodInterfaceMethodTotalCnt,
467                            RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
468         }
469 }
470 /*--------------------------------------------------------------*/
471
472 void printRThierarchyInfo(methodinfo *m) {
473
474         /*-- init for statistics --*/
475         RTclassHeirNotUsedCnt=0; 
476         RTclassHeirUsedCnt=0;    
477         RTclassHeirPartUsedCnt=0;   
478         RTclassHeirSuperCnt=0;   
479         RTmethodNotUsedCnt = 0; 
480         RTmethodNotUsedCnt1 = 0; 
481         RTmethodNotUsedCnt2 = 0;  
482         RTmethodUsedCnt = 0;   
483         RTmethodMarkedCnt= 0;  
484
485
486         /*-- --*/
487         if (pClassHeirStatsOnly >= 2) {
488                 printf("\nRT Class Hierarchy for ");
489                 printf("--- start of RT info --------------- after :\n");
490                 if (m != NULL) {
491                         utf_display(m->class->name); 
492                         printf(".");
493                         method_display(m);
494                         printf("\n");
495                 }
496     }
497         printRTClassHeirarchy(class_java_lang_Object);
498         if (pClassHeirStatsOnly >= 2) {
499                 fflush(stdout);
500                 printf("--- end  of RT info ---------------\n");
501     }
502         if (pClassHeirStatsOnly >= 1) {
503                 /*--  statistic results --*/
504                 if (opt_rt)
505                 printRTInterfaceClasses();
506         
507                 printf("\n  >>>>>>>>>>>>>>>>>>>>  Analysed Class Hierarchy Statistics:\n"); 
508                 printf(" Used            \t%i \tclasses\t/ Used       \t%i methods \t of USED: %i%% \t  of ALL: %i%% \n",
509                            RTclassHeirUsedCnt,RTmethodUsedCnt,
510                            ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
511                            ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt    + RTmethodUsedCnt    + RTmethodMarkedCnt)) );
512                 printf(" Part Used       \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt); 
513                 printf(" Not Used        \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt); 
514                 printf("                 \t    \t       \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt); 
515                 printf(" In Not Used     \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt1); 
516                 printf(" In Used         \t    \tclasses\t/ Not Used    \t%i methods\n",RTmethodNotUsedCnt2);
517                 printf(" Total           \t%i \tclasses\t/ Total       \t%i methods\n\n",
518                            RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,  
519                            RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2    + RTmethodUsedCnt    + RTmethodMarkedCnt ); 
520
521                 printf(" Mono vs. Polymorphic calls:\n");
522                 printf(" Mono calls     \t%i   \tPoly that resolves to Mono \t%i \tPoly calls     \t%i\n\n",
523                            RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
524
525                 printf(" No Subs: Total=\t%i   \tAbstract No Subs=           \t%i \tAbstract methods used =\t%i\n",
526                            RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
527
528                 printf(" Inlining possible:  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
529                            RTmethodFinal, RTmethodStatic,RTmethodFinalStatic,  RTmethodNoSubs);
530                 printf("    Code size < 100  \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
531                            RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100,  RTmethodNoSubs100);
532         }
533 }
534
535
536 /*
537  * These are local overrides for various environment variables in Emacs.
538  * Please do not remove this and leave it at the end of the file, where
539  * Emacs will automagically detect them.
540  * ---------------------------------------------------------------------
541  * Local variables:
542  * mode: c
543  * indent-tabs-mode: t
544  * c-basic-offset: 4
545  * tab-width: 4
546  * End:
547  */