1 /* vm/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 1735 2004-12-07 14:33:27Z twisti $
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"
44 int pClassHeirStatsOnly = 2;
47 /*--- Statistics ---------------------------------------------------------*/
49 int unRTclassHeirCnt=0;
50 int unRTmethodCnt = 0;
53 int RTclassHeirNotUsedCnt=0;
54 int RTclassHeirUsedCnt=0;
55 int RTclassHeirPartUsedCnt=0;
56 int RTclassHeirSuperCnt=0;
58 int RTmethodNotUsedCnt = 0;
59 int RTmethodNotUsedCnt1= 0;
60 int RTmethodNotUsedCnt2= 0;
61 int RTmethodUsedCnt = 0;
62 int RTmethodMarkedCnt= 0;
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;
71 int RTmethodPossiblePoly;
72 int RTmethodPolyReallyMono;
75 int RTmethodFinal100 = 0;
76 int RTmethodStatic100 = 0;
77 int RTmethodFinalStatic100 = 0;
78 int RTmethodNoSubs100 = 0;
82 int RTmethodNoSubsAbstract = 0;
83 int RTmethod1Used = 0;
85 int RTmethodAbstract = 0;
88 int subRedefsCntUsed =0;
92 /*--------------------------------------------------------------*/
93 void printCallgraph (list *rtaWorkList)
99 printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
101 for (rta =list_first(rtaWorkList);
103 rta =list_next(rtaWorkList,rta))
105 rt_meth = rta->method;
107 printf(" (%i): ",i++);
108 method_display_w_class(rt_meth);
114 /*--------------------------------------------------------------*/
115 /*--------------------------------------------------------------*/
116 /*--------------------------------------------------------------*/
117 int subdefd(methodinfo *meth) {
121 printf("subdefd for:");
122 method_display_w_class(meth);
124 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
125 printf("\n\n\nPossible Poly call for FINAL or STATIC\n\n\n");
127 if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
130 if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
132 printf("sub exist for:");method_display_w_class(meth);
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) {
138 if (submeth->methodUsed == USED) {
143 if (subdefd(submeth) > 0)
148 if (subRedefsCntUsed > 0) return 1;
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); }
161 /*--------------------------------------------------------------*/
163 void printRTClassHeirarchy2(classinfo *class) {
168 if (class == NULL) {return;}
169 CLASSINFO(class,"CLASS: ");
170 for (s = class->super; s != NULL; s = s->super) {
171 CLASSINFO(s,"SUPER:: ");
174 printf("METHODs: "); fflush(stdout);
176 for (m=0; m < class->methodscount; m++) {
177 meth = &class->methods[m];
181 printf("---------------------------\n");fflush(stdout);
183 if (class->sub != NULL) printf("SUBS:\n:");
184 else printf("NO SUBS\n");
187 for (s = class->sub; s != NULL; s = s->nextsub) {
188 printRTClassHeirarchy2(s);
189 printf("---------------------------\n");fflush(stdout);
193 void printRTClassHeirarchy(classinfo *class) {
199 if (class == NULL) {return;}
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);
213 printf("\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
217 printf(" UNUSED METHOD "); fflush(stdout);
218 method_display_w_class(meth);
223 if (class->classUsed != NOTUSED) {
224 if (pClassHeirStatsOnly >= 2) {
226 utf_display(class->name);
227 printf(" <%i> (depth=%i) ",class->classUsed,class->index);
229 printf("\tbase/diff =%3d/%3d\n",
230 class->vftbl->baseval,
231 class->vftbl->diffval);
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");
238 RTclassHeirPartUsedCnt++;
241 if (pClassHeirStatsOnly >= 2) {
244 RTclassHeirUsedCnt++;
248 /* Print methods used */
250 for (m=0; m < class->methodscount; m++) {
252 meth = &class->methods[m];
254 if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
255 if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
256 if (meth->methodUsed == USED) {
258 if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
260 if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
263 if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
265 if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
268 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
269 RTmethodFinalStatic++;
270 if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
273 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
274 && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
276 if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
279 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
280 && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
282 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
284 if (meth->monoPoly == MONO) RTmethodMono++;
285 if (meth->monoPoly == POLY) {
286 RTmethodPossiblePoly++;
288 subRedefsCntUsed = 0;
289 if (meth->flags & ACC_ABSTRACT ) {
290 if (pClassHeirStatsOnly >= 2) {
291 printf("STATS: abstract_method=");
292 method_display_w_class(meth);
296 if (subdefd(meth) == 0) {
297 meth->monoPoly = MONO1;
298 RTmethodPolyReallyMono++;
302 meth->subRedefs = subRedefsCnt;
303 meth->subRedefsUsed = subRedefsCntUsed;
308 if (pClassHeirStatsOnly >= 2) {
310 printf("bMethods used:\n");
314 method_display_w_class(meth);
316 if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\n", meth->subRedefsUsed, meth->subRedefs);
320 if (pClassHeirStatsOnly >= 2) {
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);
330 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
331 printRTClassHeirarchy(subs);
334 /*--------------------------------------------------------------*/
335 void printRTInterfaceClasses() {
337 classinfo *ci = class_java_lang_Object;
340 int RTmethodInterfaceClassImplementedCnt = 0;
341 int RTmethodInterfaceClassUsedCnt = 0;
343 int RTmethodInterfaceMethodTotalCnt = 0;
344 int RTmethodInterfaceMethodNotUsedCnt = 0;
345 int RTmethodInterfaceMethodUsedCnt = 0;
347 int RTmethodClassesImpldByTotalCnt = 0;
349 int RTmethodInterfaceMonoCnt = 0;
350 int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
352 int RTmethodNoSubsAbstractCnt = 0;
354 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
355 classinfo * ici = subs->classType;
356 classinfo * isubs = subs->classType;
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);
365 RTmethodInterfaceClassImplementedCnt++;
366 if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
367 if (pClassHeir >= 2) {
368 printf("\n\t\t\tImplemented by classes:\n");
371 /* get the total impldBy classes Used */
372 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
374 RTmethodClassesImpldByTotalCnt++;
375 if (pClassHeir >= 2) {
376 printf("\t\t\t");utf_display(inBy->classType->name);
379 if (inBy->classType->classUsed == NOTUSED)
380 printf("\n\n\nprintRTInterfaceClasses: class in the implemented list without being used!!!??\n\n\n");
383 if (pClassHeir >= 2) {
384 printf("\t\t\tImpld by: %i\n",impldBycnt);
386 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
388 /* if interface class is used */
389 if (ici -> classUsed != NOTUSED) {
390 if (pClassHeir >= 2) {
391 printf(" cMethods used:\n");
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++;
401 if (imi->methodUsed == USED) {
402 RTmethodInterfaceMethodUsedCnt++;
403 if (pClassHeirStatsOnly >= 2) {
405 method_display_w_class(imi);
407 if (impldBycnt == 1) {
411 /* if only 1 implementing class then possibly really mono call */
413 cii = inBy->classType;
415 mii = class_fetchmethod(cii, imi->name, imi->descriptor);
417 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
418 imi->monoPoly = MONO1;
419 RTmethodInterfacePolyReallyMonoCnt++;
422 /**if (imi->monoPoly != POLY)
423 printf("\n\n\ninterface monopoly not POLY\n\n\n");
425 if (mii->monoPoly != POLY) {
426 imi->monoPoly = MONO1;
427 RTmethodInterfacePolyReallyMonoCnt++;
430 imi->monoPoly = POLY;
436 if (pClassHeir >= 2) {
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);
453 /*--------------------------------------------------------------*/
457 /*--------------------------------------------------------------*/
458 /*--------------------------------------------------------------*/
460 void printRThierarchyInfo(methodinfo *m) {
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;
471 RTmethodMarkedCnt= 0;
474 printf("RT Heirarchy:------------\n"); fflush(stdout);
476 printf("\nRT Class Hierarchy for ");
478 method_display_w_class(m);
482 printf(" called with NULL method\n");
485 /**printRTClassHeirarchy(class_java_lang_Object); **/
486 printRTClassHeirarchy(m->class);
487 printf("--- end of RT info ---------------\n");
489 if (pClassHeirStatsOnly >= 10) {
490 /*-- statistic results --*/
492 printRTInterfaceClasses();
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 );
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);
512 printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
513 RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
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);
523 /*--------------------------------------------------------------*/
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 * ---------------------------------------------------------------------
532 * indent-tabs-mode: t