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