2 /*--- Statistics ----------------------------------------------------------*/
4 int unRTclassHeirCnt=0;
8 int RTclassHeirNotUsedCnt=0;
9 int RTclassHeirUsedCnt=0;
10 int RTclassHeirPartUsedCnt=0;
11 int RTclassHeirSuperCnt=0;
13 int RTmethodNotUsedCnt = 0;
14 int RTmethodNotUsedCnt1= 0;
15 int RTmethodNotUsedCnt2= 0;
16 int RTmethodUsedCnt = 0;
17 int RTmethodMarkedCnt= 0;
19 /* What might be inlined of the Used Methods */
20 int RTmethodFinal = 0;
21 int RTmethodStatic = 0;
22 int RTmethodFinalStatic = 0;
23 int RTmethodNoSubs = 0;
26 int RTmethodPossiblePoly;
27 int RTmethodPolyReallyMono;
30 int RTmethodFinal100 = 0;
31 int RTmethodStatic100 = 0;
32 int RTmethodFinalStatic100 = 0;
33 int RTmethodNoSubs100 = 0;
37 int RTmethodNoSubsAbstract = 0;
38 int RTmethod1Used = 0;
40 int RTmethodAbstract = 0;
43 int subRedefsCntUsed =0;
45 /*------------- RTAprint flags ------------------------------------------------------------------*/
46 int pCallgraph = 0; /* 0 - dont print 1 - print at end from main */
47 /* 2 - print at end of RT parse call */
48 /* 3- print after each method RT parse */
49 int pClassHeir = 1; /* 0 - dont print 1 - print at end from main */
50 /* 2 - print at end of RT parse call 3-print after each method RT parse */
51 int pClassHeirStatsOnly = 1; /* usually 2 Print only the statistical summary info for class heirarchy */
53 int pOpcodes = 0; /* 0 - don't print 1- print in parse RT 2- print in parse */
54 /* 3 - print in both */
55 int pWhenMarked = 0; /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
56 /* 2 - print when marked+methods called */
57 /* 3 - print when class/method looked at */
58 int pStats = 0; /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
60 /*-----------------------------------------------------------------------------------------------*/
61 /*-----------------------------------------------------------------------------------------------*/
62 void printXTACallgraph ()
65 printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
66 for (i=0;i<=methXTAlast;i++) {
68 utf_display(XTAcallgraph[i]->class->name);
70 method_display(XTAcallgraph[i]);
77 /*-----------------------------------------------------------------------------------------------*/
78 /*-----------------------------------------------------------------------------------------------*/
80 void printCallgraph ()
83 printf("----- RTA Callgraph Worklist:<%i>\n",methRTlast);
84 for (i=0;i<=methRTlast;i++) {
86 utf_display(callgraph[i]->class->name);
88 method_display(callgraph[i]);
93 /*--------------------------------------------------------------*/
94 void printObjectClassHeirarchy1() {
98 printObjectClassHeirarchy(class_java_lang_Object);
99 printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
100 unRTclassHeirCnt,unRTmethodCnt);
104 /*--------------------------------------------------------------*/
105 void printObjectClassHeirarchy(classinfo *class) {
111 if (class == NULL) {return;}
112 unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
116 for (t=0;t<class->index;t++) printf("\t");
117 if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
120 utf_display(class->name);
121 printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
122 /* Print methods used */
124 for (m=0; m < class->methodscount; m++) {
125 meth = &class->methods[m];
127 for (t=0;t<class->index;t++) printf("\t");
128 printf("aMethods used:\n");
130 for (t=0;t<class->index;t++) printf("\t");
132 utf_display(meth->class->name);
134 method_display(meth);
137 if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
140 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
141 printObjectClassHeirarchy(subs);
145 /*--------------------------------------------------------------*/
146 /*--------------------------------------------------------------*/
147 int subdefd(methodinfo *meth) {
151 /*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
153 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
154 panic("Possible Poly call for FINAL or STATIC\n");
156 if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
159 if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
161 /*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
163 for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
164 submeth = class_findmethod(subs, meth->name, meth->descriptor);
165 if (submeth != NULL) {
167 if (submeth->methodUsed == USED) {
172 if (subdefd(submeth) > 0)
177 if (subRedefsCntUsed > 0) return 1;
180 /*--------------------------------------------------------------*/
182 void printRTClassHeirarchy(classinfo *class) {
188 if (class == NULL) {return;}
190 if (class->classUsed == NOTUSED) {
191 RTclassHeirNotUsedCnt++;
192 RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
193 RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
194 for (m=0; m < class->methodscount; m++) {
195 meth = &class->methods[m];
196 if (meth->methodUsed == USED) {
197 if (pClassHeirStatsOnly >= 2) {
198 printf("METHOD marked used in CLASS marked NOTUSED: ");
199 utf_display(class->name);
201 method_display(meth);
202 printf("<%i>\n\t",meth->methodUsed);
204 printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
210 if (class->classUsed != NOTUSED) {
211 if (pClassHeirStatsOnly >= 2) {
213 utf_display(class->name);
214 printf(" <%i> (depth=%i) ",class->classUsed,class->index);
216 printf("\tbase/diff =%3d/%3d\n",
217 class->vftbl->baseval,
218 class->vftbl->diffval);
221 if (class->classUsed == PARTUSED) {
222 if (pClassHeirStatsOnly >= 2) {
223 printf("\tClass not instanciated - but methods/fields resolved to this class' code (static,inits,fields,super)\n");
225 RTclassHeirPartUsedCnt++;
228 if (pClassHeirStatsOnly >= 2) {
231 RTclassHeirUsedCnt++;
235 /* Print methods used */
237 for (m=0; m < class->methodscount; m++) {
239 meth = &class->methods[m];
241 if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
242 if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
243 if (meth->methodUsed == USED) {
245 if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
247 if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
250 if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
252 if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
255 if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
256 RTmethodFinalStatic++;
257 if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
260 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
261 && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
263 if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
266 if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
267 && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
269 if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
271 if (meth->monoPoly == MONO) RTmethodMono++;
272 if (meth->monoPoly == POLY) {
273 RTmethodPossiblePoly++;
275 subRedefsCntUsed = 0;
276 if (meth->flags & ACC_ABSTRACT ) {
277 if (pClassHeirStatsOnly >= 2) {
278 printf("STATS: abstract_method=");
279 utf_display(meth->class->name);printf(".");
280 method_display(meth);
284 if (subdefd(meth) == 0) {
285 meth->monoPoly = MONO1;
286 RTmethodPolyReallyMono++;
290 meth->subRedefs = subRedefsCnt;
291 meth->subRedefsUsed = subRedefsCntUsed;
296 if (pClassHeirStatsOnly >= 2) {
298 printf("bMethods used:\n");
302 utf_display(meth->class->name);
304 method_display(meth);
306 if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
307 if ( (XTAOPTbypass3) || (opt_xta)) {
308 if (meth->XTAclassSet == NULL)
309 printf("class set never created\n");
311 printSet(meth->XTAclassSet->head);
316 if (pClassHeirStatsOnly >= 2) {
317 if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
321 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
322 printRTClassHeirarchy(subs);
325 /*--------------------------------------------------------------*/
326 void printRTInterfaceClasses() {
328 classinfo *ci = class_java_lang_Object;
331 int RTmethodInterfaceClassImplementedCnt = 0;
332 int RTmethodInterfaceClassUsedCnt = 0;
334 int RTmethodInterfaceMethodTotalCnt = 0;
335 int RTmethodInterfaceMethodNotUsedCnt = 0;
336 int RTmethodInterfaceMethodUsedCnt = 0;
338 int RTmethodClassesImpldByTotalCnt = 0;
340 int RTmethodInterfaceMonoCnt = 0;
341 int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
343 int RTmethodNoSubsAbstractCnt = 0;
345 for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
346 classinfo * ici = subs->classType;
347 classinfo * isubs = subs->classType;
352 if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
353 if (pClassHeir >= 2) {
354 printf("Interface class: ");fflush(stdout);
355 utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
357 RTmethodInterfaceClassImplementedCnt++;
358 if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
359 if (pClassHeir >= 2) {
360 printf("\n\t\t\tImplemented by classes:\n");
363 /* get the total impldBy classes Used */
364 for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
366 RTmethodClassesImpldByTotalCnt++;
367 if (pClassHeir >= 2) {
368 printf("\t\t\t");utf_display(inBy->classType->name);
371 if (inBy->classType->classUsed == NOTUSED)
372 panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
374 if (pClassHeir >= 2) {
375 printf("\t\t\tImpld by: %i\n",impldBycnt);
377 if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
379 /* if interface class is used */
380 if (ici -> classUsed != NOTUSED) {
381 if (pClassHeir >= 2) {
382 printf(" cMethods used:\n");
385 /* for each interface method implementation that has been used */
386 for (mm=0; mm< ici->methodscount; mm++) {
387 methodinfo *imi = &(ici->methods[mm]);
388 RTmethodInterfaceMethodTotalCnt++;
389 if (imi->methodUsed != USED) {
390 RTmethodInterfaceMethodNotUsedCnt++;
392 if (imi->methodUsed == USED) {
393 RTmethodInterfaceMethodUsedCnt++;
394 if (pClassHeirStatsOnly >= 2) {
396 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
398 if (impldBycnt == 1) {
403 /* if only 1 implementing class then possibly really mono call */
405 cii = inBy->classType;
407 mii = class_findmethod(cii, imi->name, imi->descriptor);
409 /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
410 imi->monoPoly = MONO1;
411 RTmethodInterfacePolyReallyMonoCnt++;
414 if (imi->monoPoly != POLY)
415 panic ("interface monopoly not POLY");
417 if (mii->monoPoly != POLY) {
418 imi->monoPoly = MONO1;
419 RTmethodInterfacePolyReallyMonoCnt++;
422 imi->monoPoly = POLY;
428 if (pClassHeir >= 2) {
433 if (pClassHeirStatsOnly >= 1) {
434 printf("\n\n >>>>>>>>>>>>>>>>>>>> Interface Statistics Summary: \n");
435 printf("Classes: Total: %i \tUSED: %i \tIMPLD BY: \t%i \tJUST 1 IMPLD BY: %i \tNOSUB: %i \n",
436 RTmethodInterfaceClassImplementedCnt,
437 RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
438 RTmethodNoSubsAbstractCnt);
439 printf("Methods: Total: %i \tNOTUSED: %i \tUSED: \t%i \tPoly that resolves to Mono %i \n",
440 RTmethodInterfaceMethodTotalCnt,
441 RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
444 /*--------------------------------------------------------------*/
446 void printRThierarchyInfo(methodinfo *m) {
448 /*-- init for statistics --*/
449 RTclassHeirNotUsedCnt=0;
450 RTclassHeirUsedCnt=0;
451 RTclassHeirPartUsedCnt=0;
452 RTclassHeirSuperCnt=0;
453 RTmethodNotUsedCnt = 0;
454 RTmethodNotUsedCnt1 = 0;
455 RTmethodNotUsedCnt2 = 0;
457 RTmethodMarkedCnt= 0;
461 if (pClassHeirStatsOnly >= 2) {
462 printf("\nRT Class Hierarchy for ");
463 printf("--- start of RT info --------------- after :\n");
465 utf_display(m->class->name);
471 printRTClassHeirarchy(class_java_lang_Object);
472 if (pClassHeirStatsOnly >= 2) {
473 printf("--- end of RT info ---------------\n");
475 if (pClassHeirStatsOnly >= 1) {
477 /*-- statistic results --*/
478 printRTInterfaceClasses();
480 printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Hierarchy Statistics:\n");
481 printf(" Used \t%i \tclasses\t/ Used \t%i methods \t of USED: %i%% \t of ALL: %i%% \n",
482 RTclassHeirUsedCnt,RTmethodUsedCnt,
483 ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
484 ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
485 printf(" Part Used \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt);
486 printf(" Not Used \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
487 printf(" \t \t \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt);
488 printf(" In Not Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt1);
489 printf(" In Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt2);
490 printf(" Total \t%i \tclasses\t/ Total \t%i methods\n\n",
491 RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,
492 RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2 + RTmethodUsedCnt + RTmethodMarkedCnt );
494 printf(" Mono vs. Polymorphic calls:\n");
495 printf(" Mono calls \t%i \tPoly that resolves to Mono \t%i \tPoly calls \t%i\n\n",
496 RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
498 printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
499 RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
501 printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
502 RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
503 printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
504 RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);