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