1 /* jit/parseRTstats.c -
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
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 657 2003-11-20 15:18:33Z carolyn $
35 #include "parseRTstats.h"
38 /*--- Statistics ----------------------------------------------------------*/
40 int unRTclassHeirCnt=0;
41 int unRTmethodCnt = 0;
44 int RTclassHeirNotUsedCnt=0;
45 int RTclassHeirUsedCnt=0;
46 int RTclassHeirPartUsedCnt=0;
47 int RTclassHeirSuperCnt=0;
49 int RTmethodNotUsedCnt = 0;
50 int RTmethodNotUsedCnt1= 0;
51 int RTmethodNotUsedCnt2= 0;
52 int RTmethodUsedCnt = 0;
53 int RTmethodMarkedCnt= 0;
55 /* What might be inlined of the Used Methods */
56 int RTmethodFinal = 0;
57 int RTmethodStatic = 0;
58 int RTmethodFinalStatic = 0;
59 int RTmethodNoSubs = 0;
62 int RTmethodPossiblePoly;
63 int RTmethodPolyReallyMono;
66 int RTmethodFinal100 = 0;
67 int RTmethodStatic100 = 0;
68 int RTmethodFinalStatic100 = 0;
69 int RTmethodNoSubs100 = 0;
73 int RTmethodNoSubsAbstract = 0;
74 int RTmethod1Used = 0;
76 int RTmethodAbstract = 0;
79 int subRedefsCntUsed =0;
81 /*-----------------------------------------------------------------------------------------------*/
82 void printXTACallgraph()
86 // if (XTAdebug >= 1) {
87 printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
88 for (i=0;i<=methXTAlast;i++) {
90 utf_display(XTAcallgraph[i]->class->name);
92 method_display(XTAcallgraph[i]);
95 printf("----- end of XTA Callgraph Worklist:<%i>\n",methXTAlast);
100 /*-----------------------------------------------------------------------------------------------*/
101 /*-----------------------------------------------------------------------------------------------*/
103 void printCallgraph ()
106 printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",methRTlast);
107 for (i=0;i<=methRTlast;i++) {
109 utf_display(callgraph[i]->class->name);
111 method_display(callgraph[i]);
116 /*--------------------------------------------------------------*/
117 void printObjectClassHeirarchyAll() {
121 printObjectClassHeirarchy(class_java_lang_Object);
122 printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
123 unRTclassHeirCnt,unRTmethodCnt);
127 /*--------------------------------------------------------------*/
128 void printObjectClassHeirarchy(classinfo *class) {
134 if (class == NULL) {return;}
135 unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
139 for (t=0;t<class->index;t++) printf("\t");
140 if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
143 utf_display(class->name);
144 printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
145 /* Print methods used */
147 for (m=0; m < class->methodscount; m++) {
148 meth = &class->methods[m];
150 for (t=0;t<class->index;t++) printf("\t");
151 printf("aMethods used:\n");
153 for (t=0;t<class->index;t++) printf("\t");
155 utf_display(meth->class->name);
157 method_display(meth);
160 if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
163 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
164 printObjectClassHeirarchy(subs);
168 /*--------------------------------------------------------------*/
169 /*--------------------------------------------------------------*/
170 int subdefd(methodinfo *meth) {
174 /*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
176 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
177 panic("Possible Poly call for FINAL or STATIC\n");
179 if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
182 if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
184 /*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
186 for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
187 submeth = class_findmethod(subs, meth->name, meth->descriptor);
188 if (submeth != NULL) {
190 if (submeth->methodUsed == USED) {
195 if (subdefd(submeth) > 0)
200 if (subRedefsCntUsed > 0) return 1;
203 /*--------------------------------------------------------------*/
205 void printRTClassHeirarchy(classinfo *class) {
211 if (class == NULL) {return;}
213 if (class->classUsed == NOTUSED) {
214 RTclassHeirNotUsedCnt++;
215 RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
216 RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
217 for (m=0; m < class->methodscount; m++) {
218 meth = &class->methods[m];
219 if (meth->methodUsed == USED) {
220 if (pClassHeirStatsOnly >= 2) {
221 printf("METHOD marked used in CLASS marked NOTUSED: ");
222 utf_display(class->name);
224 method_display(meth);
225 printf("<%i>\n\t",meth->methodUsed);
227 printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
233 if (class->classUsed != NOTUSED) {
234 if (pClassHeirStatsOnly >= 2) {
236 utf_display(class->name);
237 printf(" <%i> (depth=%i) ",class->classUsed,class->index);
239 printf("\tbase/diff =%3d/%3d\n",
240 class->vftbl->baseval,
241 class->vftbl->diffval);
244 if (class->classUsed == PARTUSED) {
245 if (pClassHeirStatsOnly >= 2) {
246 printf("\tClass not instanciated - but methods/fields resolved to this class' code (static,inits,fields,super)\n");
248 RTclassHeirPartUsedCnt++;
251 if (pClassHeirStatsOnly >= 2) {
254 RTclassHeirUsedCnt++;
258 /* Print methods used */
260 for (m=0; m < class->methodscount; m++) {
262 meth = &class->methods[m];
264 if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
265 if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
266 if (meth->methodUsed == USED) {
268 if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
270 if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
273 if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
275 if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
278 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
279 RTmethodFinalStatic++;
280 if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
283 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
284 && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
286 if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
289 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
290 && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
292 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
294 if (meth->monoPoly == MONO) RTmethodMono++;
295 if (meth->monoPoly == POLY) {
296 RTmethodPossiblePoly++;
298 subRedefsCntUsed = 0;
299 if (meth->flags & ACC_ABSTRACT ) {
300 if (pClassHeirStatsOnly >= 2) {
301 printf("STATS: abstract_method=");
302 utf_display(meth->class->name);printf(".");
303 method_display(meth);
307 if (subdefd(meth) == 0) {
308 meth->monoPoly = MONO1;
309 RTmethodPolyReallyMono++;
313 meth->subRedefs = subRedefsCnt;
314 meth->subRedefsUsed = subRedefsCntUsed;
319 if (pClassHeirStatsOnly >= 2) {
321 printf("bMethods used:\n");
325 utf_display(meth->class->name);
327 method_display(meth);
329 if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
330 if ( (XTAOPTbypass3) || (opt_xta)) {
331 if (meth->xta == NULL) {
332 printf("class set never created\n");
335 if (meth->xta->XTAclassSet == NULL)
336 printf("class set never created\n");
338 printSet(meth->xta->XTAclassSet->head);
344 if (pClassHeirStatsOnly >= 2) {
345 if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
349 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
350 printRTClassHeirarchy(subs);
353 /*--------------------------------------------------------------*/
354 void printRTInterfaceClasses() {
356 classinfo *ci = class_java_lang_Object;
359 int RTmethodInterfaceClassImplementedCnt = 0;
360 int RTmethodInterfaceClassUsedCnt = 0;
362 int RTmethodInterfaceMethodTotalCnt = 0;
363 int RTmethodInterfaceMethodNotUsedCnt = 0;
364 int RTmethodInterfaceMethodUsedCnt = 0;
366 int RTmethodClassesImpldByTotalCnt = 0;
368 int RTmethodInterfaceMonoCnt = 0;
369 int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
371 int RTmethodNoSubsAbstractCnt = 0;
373 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
374 classinfo * ici = subs->classType;
375 classinfo * isubs = subs->classType;
379 if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
380 if (pClassHeir >= 2) {
381 printf("Interface class: ");fflush(stdout);
382 utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
384 RTmethodInterfaceClassImplementedCnt++;
385 if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
386 if (pClassHeir >= 2) {
387 printf("\n\t\t\tImplemented by classes:\n");
390 /* get the total impldBy classes Used */
391 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
393 RTmethodClassesImpldByTotalCnt++;
394 if (pClassHeir >= 2) {
395 printf("\t\t\t");utf_display(inBy->classType->name);
398 if (inBy->classType->classUsed == NOTUSED)
399 panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
401 if (pClassHeir >= 2) {
402 printf("\t\t\tImpld by: %i\n",impldBycnt);
404 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
406 /* if interface class is used */
407 if (ici -> classUsed != NOTUSED) {
408 if (pClassHeir >= 2) {
409 printf(" cMethods used:\n");
412 /* for each interface method implementation that has been used */
413 for (mm=0; mm< ici->methodscount; mm++) {
414 methodinfo *imi = &(ici->methods[mm]);
415 RTmethodInterfaceMethodTotalCnt++;
416 if (imi->methodUsed != USED) {
417 RTmethodInterfaceMethodNotUsedCnt++;
419 if (imi->methodUsed == USED) {
420 RTmethodInterfaceMethodUsedCnt++;
421 if (pClassHeirStatsOnly >= 2) {
423 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
425 if (impldBycnt == 1) {
429 /* if only 1 implementing class then possibly really mono call */
431 cii = inBy->classType;
433 mii = class_findmethod(cii, imi->name, imi->descriptor);
435 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
436 imi->monoPoly = MONO1;
437 RTmethodInterfacePolyReallyMonoCnt++;
440 /**if (imi->monoPoly != POLY)
441 panic ("interface monopoly not POLY");
443 if (mii->monoPoly != POLY) {
444 imi->monoPoly = MONO1;
445 RTmethodInterfacePolyReallyMonoCnt++;
448 imi->monoPoly = POLY;
454 if (pClassHeir >= 2) {
459 if (pClassHeirStatsOnly >= 1) {
460 printf("\n\n >>>>>>>>>>>>>>>>>>>> Interface Statistics Summary: \n");
461 printf("Classes: Total: %i \tUSED: %i \tIMPLD BY: \t%i \tJUST 1 IMPLD BY: %i \tNOSUB: %i \n",
462 RTmethodInterfaceClassImplementedCnt,
463 RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
464 RTmethodNoSubsAbstractCnt);
465 printf("Methods: Total: %i \tNOTUSED: %i \tUSED: \t%i \tPoly that resolves to Mono %i \n",
466 RTmethodInterfaceMethodTotalCnt,
467 RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
470 /*--------------------------------------------------------------*/
472 void printRThierarchyInfo(methodinfo *m) {
474 /*-- init for statistics --*/
475 RTclassHeirNotUsedCnt=0;
476 RTclassHeirUsedCnt=0;
477 RTclassHeirPartUsedCnt=0;
478 RTclassHeirSuperCnt=0;
479 RTmethodNotUsedCnt = 0;
480 RTmethodNotUsedCnt1 = 0;
481 RTmethodNotUsedCnt2 = 0;
483 RTmethodMarkedCnt= 0;
487 if (pClassHeirStatsOnly >= 2) {
488 printf("\nRT Class Hierarchy for ");
489 printf("--- start of RT info --------------- after :\n");
491 utf_display(m->class->name);
497 printRTClassHeirarchy(class_java_lang_Object);
498 if (pClassHeirStatsOnly >= 2) {
500 printf("--- end of RT info ---------------\n");
502 if (pClassHeirStatsOnly >= 1) {
503 /*-- statistic results --*/
505 printRTInterfaceClasses();
507 printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Hierarchy Statistics:\n");
508 printf(" Used \t%i \tclasses\t/ Used \t%i methods \t of USED: %i%% \t of ALL: %i%% \n",
509 RTclassHeirUsedCnt,RTmethodUsedCnt,
510 ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
511 ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
512 printf(" Part Used \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt);
513 printf(" Not Used \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
514 printf(" \t \t \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt);
515 printf(" In Not Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt1);
516 printf(" In Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt2);
517 printf(" Total \t%i \tclasses\t/ Total \t%i methods\n\n",
518 RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,
519 RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2 + RTmethodUsedCnt + RTmethodMarkedCnt );
521 printf(" Mono vs. Polymorphic calls:\n");
522 printf(" Mono calls \t%i \tPoly that resolves to Mono \t%i \tPoly calls \t%i\n\n",
523 RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
525 printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
526 RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
528 printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
529 RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
530 printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
531 RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
537 * These are local overrides for various environment variables in Emacs.
538 * Please do not remove this and leave it at the end of the file, where
539 * Emacs will automagically detect them.
540 * ---------------------------------------------------------------------
543 * indent-tabs-mode: t