1 /* sr/cvm/jit/inline/parseRTstats.c -
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Carolyn Oates
29 $Id: parseRTstats.c 3829 2005-12-01 19:47:56Z twisti $
36 #include "toolbox/list.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"
46 int pClassHeirStatsOnly = 2;
49 /*--- Statistics ---------------------------------------------------------*/
51 int unRTclassHeirCnt=0;
52 int unRTmethodCnt = 0;
55 int RTclassHeirNotUsedCnt=0;
56 int RTclassHeirUsedCnt=0;
57 int RTclassHeirPartUsedCnt=0;
58 int RTclassHeirSuperCnt=0;
60 int RTmethodNotUsedCnt = 0;
61 int RTmethodNotUsedCnt1= 0;
62 int RTmethodNotUsedCnt2= 0;
63 int RTmethodUsedCnt = 0;
64 int RTmethodMarkedCnt= 0;
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;
73 int RTmethodPossiblePoly;
74 int RTmethodPolyReallyMono;
77 int RTmethodFinal100 = 0;
78 int RTmethodStatic100 = 0;
79 int RTmethodFinalStatic100 = 0;
80 int RTmethodNoSubs100 = 0;
84 int RTmethodNoSubsAbstract = 0;
85 int RTmethod1Used = 0;
87 int RTmethodAbstract = 0;
90 int subRedefsCntUsed =0;
94 /*--------------------------------------------------------------*/
95 void printCallgraph (list *rtaWorkList)
101 #if defined(STATISTICS)
102 printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
105 for (rta =list_first(rtaWorkList);
107 rta =list_next(rtaWorkList,rta))
109 rt_meth = rta->method;
111 printf(" (%i): ",i++);
112 method_display_w_class(rt_meth);
118 /*--------------------------------------------------------------*/
119 /*--------------------------------------------------------------*/
120 /*--------------------------------------------------------------*/
121 int subdefd(methodinfo *meth) {
125 printf("subdefd for:");
126 method_display_w_class(meth);
128 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
129 printf("\n\n\nPossible Poly call for FINAL or STATIC\n\n\n");
131 if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
134 if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
136 printf("sub exist for:");method_display_w_class(meth);
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) {
142 if (submeth->methodUsed == USED) {
147 if (subdefd(submeth) > 0)
152 if (subRedefsCntUsed > 0) return 1;
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); }
165 /*--------------------------------------------------------------*/
167 void printRTClassHeirarchy2(classinfo *class) {
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:: ");
178 printf("METHODs: "); fflush(stdout);
180 for (m=0; m < class->methodscount; m++) {
181 meth = &class->methods[m];
185 printf("---------------------------\n");fflush(stdout);
187 if (class->sub != NULL) printf("SUBS:\n:");
188 else printf("NO SUBS\n");
191 for (s = class->sub; s != NULL; s = s->nextsub) {
192 printRTClassHeirarchy2(s);
193 printf("---------------------------\n");fflush(stdout);
197 void printRTClassHeirarchy(classinfo *class) {
203 if (class == NULL) {return;}
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);
217 printf("\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
221 printf(" UNUSED METHOD "); fflush(stdout);
222 method_display_w_class(meth);
227 if (class->classUsed != NOTUSED) {
228 if (pClassHeirStatsOnly >= 2) {
230 utf_display(class->name);
231 printf(" <%i> (depth=%i) ",class->classUsed,class->index);
233 printf("\tbase/diff =%3d/%3d\n",
234 class->vftbl->baseval,
235 class->vftbl->diffval);
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");
242 RTclassHeirPartUsedCnt++;
245 if (pClassHeirStatsOnly >= 2) {
248 RTclassHeirUsedCnt++;
252 /* Print methods used */
254 for (m=0; m < class->methodscount; m++) {
256 meth = &class->methods[m];
258 if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
259 if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
260 if (meth->methodUsed == USED) {
262 if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
264 if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
267 if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
269 if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
272 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
273 RTmethodFinalStatic++;
274 if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
277 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
278 && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
280 if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
283 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
284 && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
286 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
288 if (meth->monoPoly == MONO) RTmethodMono++;
289 if (meth->monoPoly == POLY) {
290 RTmethodPossiblePoly++;
292 subRedefsCntUsed = 0;
293 if (meth->flags & ACC_ABSTRACT ) {
294 if (pClassHeirStatsOnly >= 2) {
295 printf("STATS: abstract_method=");
296 method_display_w_class(meth);
300 if (subdefd(meth) == 0) {
301 meth->monoPoly = MONO1;
302 RTmethodPolyReallyMono++;
306 meth->subRedefs = subRedefsCnt;
307 meth->subRedefsUsed = subRedefsCntUsed;
312 if (pClassHeirStatsOnly >= 2) {
314 printf("bMethods used:\n");
318 method_display_w_class(meth);
320 if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\n", meth->subRedefsUsed, meth->subRedefs);
324 if (pClassHeirStatsOnly >= 2) {
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);
334 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
335 printRTClassHeirarchy(subs);
338 /*--------------------------------------------------------------*/
339 void printRTInterfaceClasses() {
341 classinfo *ci = class_java_lang_Object;
344 int RTmethodInterfaceClassImplementedCnt = 0;
345 int RTmethodInterfaceClassUsedCnt = 0;
347 int RTmethodInterfaceMethodTotalCnt = 0;
348 int RTmethodInterfaceMethodNotUsedCnt = 0;
349 int RTmethodInterfaceMethodUsedCnt = 0;
351 int RTmethodClassesImpldByTotalCnt = 0;
353 int RTmethodInterfaceMonoCnt = 0;
354 int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
356 int RTmethodNoSubsAbstractCnt = 0;
358 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
359 classinfo * ici = subs->classType;
360 classinfo * isubs = subs->classType;
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);
369 RTmethodInterfaceClassImplementedCnt++;
370 if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
371 if (pClassHeir >= 2) {
372 printf("\n\t\t\tImplemented by classes:\n");
375 /* get the total impldBy classes Used */
376 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
378 RTmethodClassesImpldByTotalCnt++;
379 if (pClassHeir >= 2) {
380 printf("\t\t\t");utf_display(inBy->classType->name);
383 if (inBy->classType->classUsed == NOTUSED)
384 printf("\n\n\nprintRTInterfaceClasses: class in the implemented list without being used!!!??\n\n\n");
387 if (pClassHeir >= 2) {
388 printf("\t\t\tImpld by: %i\n",impldBycnt);
390 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
392 /* if interface class is used */
393 if (ici -> classUsed != NOTUSED) {
394 if (pClassHeir >= 2) {
395 printf(" cMethods used:\n");
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++;
405 if (imi->methodUsed == USED) {
406 RTmethodInterfaceMethodUsedCnt++;
407 if (pClassHeirStatsOnly >= 2) {
409 method_display_w_class(imi);
411 if (impldBycnt == 1) {
415 /* if only 1 implementing class then possibly really mono call */
417 cii = inBy->classType;
419 mii = class_findmethod(cii, imi->name, imi->descriptor);
421 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
422 imi->monoPoly = MONO1;
423 RTmethodInterfacePolyReallyMonoCnt++;
426 /**if (imi->monoPoly != POLY)
427 printf("\n\n\ninterface monopoly not POLY\n\n\n");
429 if (mii->monoPoly != POLY) {
430 imi->monoPoly = MONO1;
431 RTmethodInterfacePolyReallyMonoCnt++;
434 imi->monoPoly = POLY;
440 if (pClassHeir >= 2) {
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);
457 /*--------------------------------------------------------------*/
461 /*--------------------------------------------------------------*/
462 /*--------------------------------------------------------------*/
464 void printRThierarchyInfo(methodinfo *m) {
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;
475 RTmethodMarkedCnt= 0;
478 printf("RT Heirarchy:------------\n"); fflush(stdout);
480 printf("\nRT Class Hierarchy for ");
482 method_display_w_class(m);
486 printf(" called with NULL method\n");
489 /**printRTClassHeirarchy(class_java_lang_Object); **/
490 printRTClassHeirarchy(m->class);
491 printf("--- end of RT info ---------------\n");
493 if (pClassHeirStatsOnly >= 10) {
494 /*-- statistic results --*/
496 printRTInterfaceClasses();
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 );
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);
516 printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
517 RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
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);
527 /*--------------------------------------------------------------*/
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 * ---------------------------------------------------------------------
536 * indent-tabs-mode: t