1 /* sr/cvm/jit/inline/parseRTstats.c -
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Carolyn Oates
29 Changes: Christian Thalinger
31 $Id: parseRTstats.c 4357 2006-01-22 23:33:38Z twisti $
38 #include "toolbox/list.h"
40 #include "vm/loader.h"
41 #include "vm/options.h"
42 #include "vm/statistics.h"
43 #include "vm/jit/inline/parseRT.h"
44 #include "vm/jit/inline/parseRTstats.h"
45 #include "vm/jit/inline/parseRTprint.h"
48 int pClassHeirStatsOnly = 2;
51 /*--- Statistics ---------------------------------------------------------*/
53 int unRTclassHeirCnt=0;
54 int unRTmethodCnt = 0;
57 int RTclassHeirNotUsedCnt=0;
58 int RTclassHeirUsedCnt=0;
59 int RTclassHeirPartUsedCnt=0;
60 int RTclassHeirSuperCnt=0;
62 int RTmethodNotUsedCnt = 0;
63 int RTmethodNotUsedCnt1= 0;
64 int RTmethodNotUsedCnt2= 0;
65 int RTmethodUsedCnt = 0;
66 int RTmethodMarkedCnt= 0;
68 /* What might be inlined of the Used Methods */
69 int RTmethodFinal = 0;
70 int RTmethodStatic = 0;
71 int RTmethodFinalStatic = 0;
72 int RTmethodNoSubs = 0;
75 int RTmethodPossiblePoly;
76 int RTmethodPolyReallyMono;
79 int RTmethodFinal100 = 0;
80 int RTmethodStatic100 = 0;
81 int RTmethodFinalStatic100 = 0;
82 int RTmethodNoSubs100 = 0;
86 int RTmethodNoSubsAbstract = 0;
87 int RTmethod1Used = 0;
89 int RTmethodAbstract = 0;
92 int subRedefsCntUsed =0;
96 /*--------------------------------------------------------------*/
97 void printCallgraph (list *rtaWorkList)
103 #if defined(ENABLE_STATISTICS)
104 printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
107 for (rta =list_first(rtaWorkList);
109 rta =list_next(rtaWorkList,rta))
111 rt_meth = rta->method;
113 printf(" (%i): ",i++);
114 method_println(rt_meth);
120 /*--------------------------------------------------------------*/
121 /*--------------------------------------------------------------*/
122 /*--------------------------------------------------------------*/
123 int subdefd(methodinfo *meth) {
127 printf("subdefd for:");
128 method_println(meth);
130 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
131 printf("\n\n\nPossible Poly call for FINAL or STATIC\n\n\n");
133 if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
136 if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
138 printf("sub exist for:");method_println(meth);
140 for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
141 submeth = class_findmethod_approx(subs, meth->name, meth->descriptor);
142 if (submeth != NULL) {
144 if (submeth->methodUsed == USED) {
149 if (subdefd(submeth) > 0)
154 if (subRedefsCntUsed > 0) return 1;
158 /*--------------------------------------------------------------*/
159 #define CLASSINFO(cls,txt) { \
160 printf(txt); fflush(stdout); \
161 printf(" <c%i>(depth=%i) ",cls->classUsed,cls->index); \
162 printf("\tbase/diff =%3d/%3d\t", \
163 cls->vftbl->baseval, \
164 cls->vftbl->diffval); \
165 utf_display(cls->name); printf("\n"); fflush(stdout); }
167 /*--------------------------------------------------------------*/
169 void printRTClassHeirarchy2(classinfo *class) {
174 if (class == NULL) {return;}
175 CLASSINFO(class,"CLASS: ");
176 for (s = class->super.cls; s != NULL; s = s->super.cls) {
177 CLASSINFO(s,"SUPER:: ");
180 printf("METHODs: "); fflush(stdout);
182 for (m=0; m < class->methodscount; m++) {
183 meth = &class->methods[m];
187 printf("---------------------------\n");fflush(stdout);
189 if (class->sub != NULL) printf("SUBS:\n:");
190 else printf("NO SUBS\n");
193 for (s = class->sub; s != NULL; s = s->nextsub) {
194 printRTClassHeirarchy2(s);
195 printf("---------------------------\n");fflush(stdout);
199 void printRTClassHeirarchy(classinfo *class) {
205 if (class == NULL) {return;}
207 if (class->classUsed == NOTUSED) {
208 RTclassHeirNotUsedCnt++;
209 RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
210 RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
211 for (m=0; m < class->methodscount; m++) {
212 meth = &class->methods[m];
213 if (meth->methodUsed == USED) {
214 if (pClassHeirStatsOnly >= 2) {
215 printf("\nMETHOD marked used in CLASS marked NOTUSED: \n\t");
216 method_println(meth);
217 printf("<%i>\n\t",meth->methodUsed);
219 printf("\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
223 printf(" UNUSED METHOD "); fflush(stdout);
224 method_println(meth);
229 if (class->classUsed != NOTUSED) {
230 if (pClassHeirStatsOnly >= 2) {
232 utf_display(class->name);
233 printf(" <%i> (depth=%i) ",class->classUsed,class->index);
235 printf("\tbase/diff =%3d/%3d\n",
236 class->vftbl->baseval,
237 class->vftbl->diffval);
240 if (class->classUsed == PARTUSED) {
241 if (pClassHeirStatsOnly >= 2) {
242 printf("\tClass not instanciated - but methods/fields resolved to this class' code (static,inits,fields,super)\n");
244 RTclassHeirPartUsedCnt++;
247 if (pClassHeirStatsOnly >= 2) {
250 RTclassHeirUsedCnt++;
254 /* Print methods used */
256 for (m=0; m < class->methodscount; m++) {
258 meth = &class->methods[m];
260 if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
261 if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
262 if (meth->methodUsed == USED) {
264 if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
266 if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
269 if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
271 if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
274 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
275 RTmethodFinalStatic++;
276 if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
279 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
280 && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
282 if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
285 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
286 && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
288 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
290 if (meth->monoPoly == MONO) RTmethodMono++;
291 if (meth->monoPoly == POLY) {
292 RTmethodPossiblePoly++;
294 subRedefsCntUsed = 0;
295 if (meth->flags & ACC_ABSTRACT ) {
296 if (pClassHeirStatsOnly >= 2) {
297 printf("STATS: abstract_method=");
298 method_println(meth);
302 if (subdefd(meth) == 0) {
303 meth->monoPoly = MONO1;
304 RTmethodPolyReallyMono++;
308 meth->subRedefs = subRedefsCnt;
309 meth->subRedefsUsed = subRedefsCntUsed;
314 if (pClassHeirStatsOnly >= 2) {
316 printf("bMethods used:\n");
320 method_println(meth);
322 if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\n", meth->subRedefsUsed, meth->subRedefs);
326 if (pClassHeirStatsOnly >= 2) {
328 if (class->classUsed == PARTUSED)
329 printf("> %i of %i methods (part)used\n",cnt, class->methodscount);
330 if (class->classUsed == USED)
331 printf("> %i of %i methods used\n",cnt, class->methodscount);
336 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
337 printRTClassHeirarchy(subs);
340 /*--------------------------------------------------------------*/
341 void printRTInterfaceClasses() {
343 classinfo *ci = class_java_lang_Object;
346 int RTmethodInterfaceClassImplementedCnt = 0;
347 int RTmethodInterfaceClassUsedCnt = 0;
349 int RTmethodInterfaceMethodTotalCnt = 0;
350 int RTmethodInterfaceMethodNotUsedCnt = 0;
351 int RTmethodInterfaceMethodUsedCnt = 0;
353 int RTmethodClassesImpldByTotalCnt = 0;
355 int RTmethodInterfaceMonoCnt = 0;
356 int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
358 int RTmethodNoSubsAbstractCnt = 0;
360 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
361 classinfo * ici = subs->classType;
362 classinfo * isubs = subs->classType;
366 if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
367 if (pClassHeir >= 2) {
368 printf("Interface class: ");fflush(stdout);
369 utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
371 RTmethodInterfaceClassImplementedCnt++;
372 if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
373 if (pClassHeir >= 2) {
374 printf("\n\t\t\tImplemented by classes:\n");
377 /* get the total impldBy classes Used */
378 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
380 RTmethodClassesImpldByTotalCnt++;
381 if (pClassHeir >= 2) {
382 printf("\t\t\t");utf_display(inBy->classType->name);
385 if (inBy->classType->classUsed == NOTUSED)
386 printf("\n\n\nprintRTInterfaceClasses: class in the implemented list without being used!!!??\n\n\n");
389 if (pClassHeir >= 2) {
390 printf("\t\t\tImpld by: %i\n",impldBycnt);
392 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
394 /* if interface class is used */
395 if (ici -> classUsed != NOTUSED) {
396 if (pClassHeir >= 2) {
397 printf(" cMethods used:\n");
400 /* for each interface method implementation that has been used */
401 for (mm=0; mm< ici->methodscount; mm++) {
402 methodinfo *imi = &(ici->methods[mm]);
403 RTmethodInterfaceMethodTotalCnt++;
404 if (imi->methodUsed != USED) {
405 RTmethodInterfaceMethodNotUsedCnt++;
407 if (imi->methodUsed == USED) {
408 RTmethodInterfaceMethodUsedCnt++;
409 if (pClassHeirStatsOnly >= 2) {
413 if (impldBycnt == 1) {
417 /* if only 1 implementing class then possibly really mono call */
419 cii = inBy->classType;
421 mii = class_findmethod(cii, imi->name, imi->descriptor);
423 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
424 imi->monoPoly = MONO1;
425 RTmethodInterfacePolyReallyMonoCnt++;
428 /**if (imi->monoPoly != POLY)
429 printf("\n\n\ninterface monopoly not POLY\n\n\n");
431 if (mii->monoPoly != POLY) {
432 imi->monoPoly = MONO1;
433 RTmethodInterfacePolyReallyMonoCnt++;
436 imi->monoPoly = POLY;
442 if (pClassHeir >= 2) {
447 if (pClassHeirStatsOnly >= 1) {
448 printf("\n\n >>>>>>>>>>>>>>>>>>>> Interface Statistics Summary: \n");
449 printf("Classes: Total: %i \tUSED: %i \tIMPLD BY: \t%i \tJUST 1 IMPLD BY: %i \tNOSUB: %i \n",
450 RTmethodInterfaceClassImplementedCnt,
451 RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
452 RTmethodNoSubsAbstractCnt);
453 printf("Methods: Total: %i \tNOTUSED: %i \tUSED: \t%i \tPoly that resolves to Mono %i \n",
454 RTmethodInterfaceMethodTotalCnt,
455 RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
459 /*--------------------------------------------------------------*/
463 /*--------------------------------------------------------------*/
464 /*--------------------------------------------------------------*/
466 void printRThierarchyInfo(methodinfo *m) {
468 /*-- init for statistics --*/
469 RTclassHeirNotUsedCnt=0;
470 RTclassHeirUsedCnt=0;
471 RTclassHeirPartUsedCnt=0;
472 RTclassHeirSuperCnt=0;
473 RTmethodNotUsedCnt = 0;
474 RTmethodNotUsedCnt1 = 0;
475 RTmethodNotUsedCnt2 = 0;
477 RTmethodMarkedCnt= 0;
480 printf("RT Heirarchy:------------\n"); fflush(stdout);
482 printf("\nRT Class Hierarchy for ");
488 printf(" called with NULL method\n");
491 /**printRTClassHeirarchy(class_java_lang_Object); **/
492 printRTClassHeirarchy(m->class);
493 printf("--- end of RT info ---------------\n");
495 if (pClassHeirStatsOnly >= 10) {
496 /*-- statistic results --*/
498 printRTInterfaceClasses();
500 printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Hierarchy Statistics:\n");
501 printf(" Used \t%i \tclasses\t/ Used \t%i methods \t of USED: %i%% \t of ALL: %i%% \n",
502 RTclassHeirUsedCnt,RTmethodUsedCnt,
503 ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
504 ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
505 printf(" Part Used \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt);
506 printf(" Not Used \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
507 printf(" \t \t \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt);
508 printf(" In Not Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt1);
509 printf(" In Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt2);
510 printf(" Total \t%i \tclasses\t/ Total \t%i methods\n\n",
511 RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,
512 RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2 + RTmethodUsedCnt + RTmethodMarkedCnt );
514 printf(" Mono vs. Polymorphic calls:\n");
515 printf(" Mono calls \t%i \tPoly that resolves to Mono \t%i \tPoly calls \t%i\n\n",
516 RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
518 printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
519 RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
521 printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
522 RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
523 printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
524 RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
529 /*--------------------------------------------------------------*/
532 * These are local overrides for various environment variables in Emacs.
533 * Please do not remove this and leave it at the end of the file, where
534 * Emacs will automagically detect them.
535 * ---------------------------------------------------------------------
538 * indent-tabs-mode: t