1 /* jit/parseRT.c - parser and print functions for Rapid Type Analyis
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: parseRT.c 1009 2004-03-31 22:44:07Z edwin $
32 opcode put into functions
33 changed class_findmethod class_fetchmethod
41 /*------------ global variables -----------------------------------------*/
42 #define MAXCALLGRAPH 5000
44 #include "parseRTflags.h"
47 bool NATIVE = false; // Dez version chasing Native problems
49 int callgraphAddedBy[MAXCALLGRAPH]; // add comment
53 int methRTmax = MAXCALLGRAPH;
54 methodinfo **callgraph;
55 /*methodinfo *callgraph[MAXCALLGRAPH];*/
60 int methXTAmax = MAXCALLGRAPH;
61 methodinfo **XTAcallgraph;
62 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
64 static bool nativecallcompdone=0 ;
66 static bool firstCall= true;
67 static bool parse1 = true;
68 static bool AfterMain = false;
69 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
70 /* so easier to build dynmanic calls file */
71 static FILE *appldynm; /* Methods dynamically loaded by application */
73 static utf *utf_OBJECT; /* utf_new_char("Object"); */
74 static utf *utf_MAIN; /* utf_new_char("main"); */
75 static utf *INIT ; /* utf_new_char("<init>"); */
76 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
77 static utf *FINALIZE; /* utf_new_char("finalize"); */
78 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
79 static int missedCnt = 0;
82 /*--------------------------------------------------------------*/
83 /* addToCallgraph - adds to RTA callgraph and */
84 /* sets meth->methodUsed to USED */
85 /*--------------------------------------------------------------*/
86 // if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) {
87 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
89 callgraph[++methRTlast] = meth ; \
90 meth->methodUsed = USED; \
92 {printf("\n Added to Call Graph #%i:", \
94 printf("\t <used flags c/m> <%i/%i> %i\t", \
95 meth->class->classUsed, \
98 printf(" method name ="); \
99 utf_display(meth->class->name);printf("."); \
100 method_display(meth);fflush(stdout);} \
103 /*--------------------------------------------------------------*/
104 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
107 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
108 if (subs->classUsed == USED) {
109 if (class_findmethod_w(class, meth->name, meth->descriptor,"rtaSubUsed") == NULL)
114 if (rtaSubUsed(subs, meth))
121 /*--------------------------------------------------------------*/
122 /* Mark the method with same name /descriptor in topmethod */
125 /* Class not marked USED and method defined in this class -> */
126 /* -> if Method NOTUSED mark method as MARKED */
127 /* Class marked USED and method defined in this class -> */
128 /* -> mark method as USED */
130 /* Class USED, but method not defined in this class -> */
131 /* -> search up the heirarchy and mark method where defined */
132 /* if class where method is defined is not USED -> */
133 /* -> mark class with defined method as PARTUSED */
134 /*--------------------------------------------------------------*/
136 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
138 utf *name = topmethod -> name;
139 utf *descriptor = topmethod -> descriptor;
142 submeth = class_resolvemethod(class, name, descriptor);
144 panic("parse RT: Method not found in class hierarchy");
145 if (submeth->methodUsed == USED) return;
147 if (submeth->class == class) {
149 /*--- Method defined in class -----------------------------*/
150 if (submeth->class->classUsed != USED) {
151 if (submeth->methodUsed == NOTUSED) {
153 /* Class NOT marked USED and method defined in this class -> */
154 /* -> if Method NOTUSED mark method as MARKED */
155 if (pWhenMarked >= 1) {
156 printf("MARKED class.method\t");
157 utf_display(submeth->class->name);printf(".");method_display(submeth);
159 if (rtaSubUsed(submeth->class,submeth)) {
160 submeth->class->classUsed = PARTUSED;
161 ADDTOCALLGRAPH(submeth)
164 submeth->methodUsed = MARKED;
169 /* Class IS marked USED and method defined in this class -> */
170 /* -> mark method as USED */
171 ADDTOCALLGRAPH(submeth)
173 } /* end defined in class */
176 /*--- Method NOT defined in class -----------------------------*/
177 if (submeth->class->classUsed == NOTUSED) {
178 submeth->class->classUsed = PARTUSED;
179 if (class->classUsed != USED) {
180 submeth->methodUsed = MARKED;
183 if ( (submeth->class->classUsed == USED)
184 || (class->classUsed == USED)) {
185 ADDTOCALLGRAPH(submeth)
187 } /* end NOT defined in class */
190 /*-------------------------------------------------------------------------------*/
191 /* Mark the method with the same name and descriptor as topmethod */
192 /* and any subclass where the method is defined and/or class is used */
194 /*-------------------------------------------------------------------------------*/
195 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
197 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
198 if (class->sub != NULL) {
201 if (!(topmethod->flags & ACC_FINAL )) {
202 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
204 rtaMarkSubs(subs, topmethod);
211 /*-------------------------------------------------------------------------------*/
212 /* Add Marked methods for input class ci */
213 /* Add methods with the same name and descriptor as implemented interfaces */
214 /* with the same method name */
216 /*-------------------------------------------------------------------------------*/
217 void rtaAddMarkedMethods(classinfo *ci) {
220 /* add marked methods to callgraph */
221 for (ii=0; ii<ci->methodscount; ii++) {
222 methodinfo *mi = &(ci->methods[ii]);
223 if (mi->methodUsed == MARKED) {
224 if (pWhenMarked >= 1) {
225 printf("ADDED a method that was MARKED\n");
230 // from Dez if (NATIVE == true) { printf("NOT MARKED: "); method_display(mi);}
232 for (jj=0; jj < ci -> interfacescount; jj++) {
233 classinfo *ici = ci -> interfaces [jj];
234 /* use resolve method....!!!! */
235 if (ici -> classUsed != NOTUSED) {
236 for (mm=0; mm< ici->methodscount; mm++) {
237 methodinfo *imi = &(ici->methods[mm]);
239 if ( (imi->methodUsed == USED)
240 && ( (imi->name == mi->name)
241 && (imi->descriptor == mi->descriptor))) {
242 if (pWhenMarked >= 1)
243 printf("ADDED a method that was used by an interface\n");
252 /*-------------------------------------------------------------------------------*/
254 /*-------------------------------------------------------------------------------*/
256 xtainfo *xtainfoInit(methodinfo *m)
260 m ->xta = (xtainfo *) NEW(xtainfo);
261 m ->xta-> XTAmethodUsed = NOTUSED;
262 m ->xta-> XTAclassSet = NULL;
263 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
266 m->xta->paramClassSet = NULL;
267 m->xta->calls = NULL;
268 m->xta->calledBy = NULL;
270 m->xta->marked = NULL; /* comment out*/
271 m ->xta->markedBy = NULL;
272 m->xta->fldsUsed = NULL;
273 /*m ->xta->interfaceCalls = NULL*/
274 m->xta->chgdSinceLastParse = false;
279 xtafldinfo * xtafldinfoInit (fieldinfo *f)
284 f->xta = NEW(xtafldinfo);
286 f->xta->fieldChecked = false; /*XTA*/
287 f->xta->fldClassType = NULL; /*XTA*/
288 f->xta->XTAclassSet = NULL; /*XTA*/
294 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
303 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
305 printf("\tIN SmCalled set : ");
306 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
307 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
309 printf("\tIN SmCalls set: ");
310 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
311 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
313 printf("\tIN lastptrInto : (");
314 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
315 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
317 else {printf("NULL) ");}
319 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
320 method_display(lastptrInto->methRef); fflush(stdout);
321 printf("\n");fflush(stdout);
324 /* Get SmCalled ParamType set if null */
325 if (SmCalled->xta->paramClassSet == NULL) {
326 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
329 printf("\tParamPassed\n"); fflush(stdout);
330 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
331 printf("\n"); fflush(stdout);
334 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
335 if (SmCalls->xta->XTAclassSet != NULL)
336 c1 = SmCalls->xta->XTAclassSet->head;
341 /* start with type where left off */
342 c1 = lastptrInto->lastptrIntoClassSet2;
343 c1 = c1 -> nextClass; /* even if NULL */
348 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
351 printf("\tIN SmCalls ... start with :");fflush(stdout);
352 utf_display(c1->classType->name); printf("\n");
356 /* for each Param Class */
357 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
359 /* for each SmCalls class */
360 for (c=c1; c != NULL; c = c->nextClass) {
361 vftbl *p_cl_vt = p->classType->vftbl;
362 vftbl *c_cl_vt = c->classType->vftbl;
364 /* if SmCalls class is in the Params Class range */
365 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
366 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
368 /* add SmCalls class to SmCalledBy Class set */
369 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
375 lastptrInto->lastptrIntoClassSet2 = cprev;
377 printf("\tOUT SmCalled set: ");fflush(stdout);
378 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
380 printf("\tOUT SmCalls set: ");fflush(stdout);
381 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
383 printf("\tOUT lastptrInto="); fflush(stdout);
384 if (lastptrInto->lastptrIntoClassSet2 != NULL)
385 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
387 printf("<rc=%i>\n",rc);fflush(stdout);
392 /*-------------------------------------------------------------------------------*/
393 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
400 printf("xtaPassReturnType \n");
402 /* Get SmCalled return class is null */
403 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
404 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
407 if (SmCalled->returnclass == NULL) {
409 printf("\tReturn type is NULL\n");
414 printf("\tReturn type is: ");
415 utf_display(SmCalled->returnclass->name);
418 printf("\tIN SmCalls set: ");
419 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
420 printClassSet(SmCalls->xta->XTAclassSet);
422 printf("\tIN SmCalled set: ");
423 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
424 printClassSet(SmCalled->xta->XTAclassSet);
428 if (SmCalled->xta->XTAclassSet == NULL)
431 cs1 = SmCalled->xta->XTAclassSet->head;
432 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
433 classinfo *c = cs->classType;
434 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
435 vftbl *c_cl_vt = c->vftbl;
437 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
438 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
439 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
440 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
446 printf("\tOUT SmCalls set: ");
447 printClassSet(SmCalls->xta->XTAclassSet);
452 /*-------------------------------------------------------------------------------*/
453 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
456 mi->xta = xtainfoInit(mi);
457 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
458 mi->xta->XTAmethodUsed = USED;
459 if (!(mi->flags & ACC_ABSTRACT)) {
460 if (mi->methodUsed != USED) {
461 XTAcallgraph[++methXTAlast] = mi;
462 mi->methodUsed = USED;
463 /*RTprint*/ if (pClassHeir >= 1) {
470 /*RTAprint*/ if(pWhenMarked>=1) {
471 /*RTAprint*/ printf("\nxxxxxxxxxxxxxxxxx XTA set Used or Added to Call Graph #%i:",
472 /*RTAprint*/ methXTAlast);
473 /*RTAprint*/ printf(" method name ="); fflush(stdout);
474 /*RTAprint*/ utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
475 /*RTAprint*/ method_display(mi);fflush(stdout);
476 /*RTAprint*/ printf("\t\t\t\tcalledBy:");
477 /*RTAprint*/ utf_display(rt_method->class->name);fflush(stdout); printf(".");fflush(stdout);
478 /*RTAprint*/ method_display(rt_method);fflush(stdout);
481 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
482 rt_method->xta->calls->tail->monoPoly = monoPoly;
483 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
484 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
485 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
489 /*--------------------------------------------------------------*/
490 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
493 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
495 if (inSet(subtypesUsedSet,subs)) {
496 if (class_findmethod_w(class, meth->name, meth->descriptor, "xtaSubUsed") == NULL)
499 if (class_findmethod_w(subs, meth->name, meth->descriptor, "xtaSubUsed") == NULL)
503 if (xtaSubUsed(subs, meth, subtypesUsedSet))
510 /*-------------------------------------------------------------------------------*/
511 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
515 utf *name = topmethod -> name;
516 utf *descriptor = topmethod -> descriptor;
518 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
519 method_display(topmethod);
522 submeth = class_resolvemethod(class, name, descriptor);
525 printf(" def: "); utf_display(submeth->class->name); printf("\n");fflush(stdout);
530 panic("parse XTA: Method not found in class hierarchy");
531 if (submeth->xta == NULL)
532 submeth->xta = xtainfoInit(submeth);
534 if (rt_method->xta->calls != NULL) {
535 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
538 if (submeth->class == class) {
540 /*--- Method defined in class -----------------------------*/
541 if (inSet(subtypesUsedSet,submeth->class)) {
542 xtaAddCallEdges(submeth,POLY);
545 if (subtypesUsedSet != NULL) {
546 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
547 xtaAddCallEdges(submeth,POLY);
550 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
552 printf("\t(defd) Added to MarkBy Set\n"); fflush(stdout);
553 utf_display(submeth->class->name); printf("."); fflush(stdout);
554 method_display(submeth);
555 printMethodSet(submeth->xta->markedBy);
562 /*--- Method NOT defined in class -----------------------------*/
563 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
564 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
565 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
566 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
568 printf("\t(^^defd) Added to MarkBy Set\n"); fflush(stdout);
569 utf_display(submeth->class->name); printf("."); fflush(stdout);
570 method_display(submeth);
571 printMethodSet(submeth->xta->markedBy);
575 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
576 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
577 xtaAddCallEdges(submeth,POLY);
580 } /* end defined in class */
583 /*-------------------------------------------------------------------------------*/
584 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
585 /* xtaPRINTmarkSubs1*/
586 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
587 if (class->sub != NULL) {
590 if (!(topmethod->flags & ACC_FINAL )) {
591 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
592 /* xtaPRINTmarkSubs1 */
593 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
599 /*-------------------------------------------------------------------------------*/
600 /* Add Marked methods for input class ci */
601 /* Add methods with the same name and descriptor as implemented interfaces */
602 /* with the same method name */
604 /*-------------------------------------------------------------------------------*/
605 void xtaAddMarkedMethods(classinfo *ci) {
608 /* add marked methods to callgraph */
609 for (ii=0; ii<ci->methodscount; ii++) {
610 methodinfo *mi = &(ci->methods[ii]);
611 if (mi->xta != NULL) {
612 if (mi->xta->markedBy != NULL) {
614 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
615 methodinfo *mc = mcnode->methRef;
616 if (pWhenMarked >= 1) {
617 printf("ADDED a method that was MARKED\n");
619 xtaAddCallEdges(mi,POLY);
623 for (jj=0; jj < ci -> interfacescount; jj++) {
624 classinfo *ici = ci -> interfaces [jj];
625 /* use resolve method....!!!! */
626 if (ici -> classUsed != NOTUSED) {
627 for (mm=0; mm< ici->methodscount; mm++) {
628 methodinfo *imi = &(ici->methods[mm]);
629 if (imi->xta != NULL) {
630 if ((imi->xta->XTAmethodUsed == USED)
631 && ( (imi->name == mi->name)
632 && (imi->descriptor == mi->descriptor))) {
633 if (pWhenMarked >= 1)
634 printf("ADDED a method that was used by an interface\n");
635 xtaAddCallEdges(mi,POLY);
646 /*-------------------------------------------------------------------------------*/
647 /* Both RTA and XTA */
648 /*-------------------------------------------------------------------------------*/
650 int addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark) {
651 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
654 utf* utf_java_lang_system = utf_new_char("java/lang/System");
655 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
656 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
658 int m, m1=-1, m2=-1, mf=-1;
661 if (clinits) { /* No <clinit> available - ignore */
663 /* Get clinit methodinfo ptr */
664 if ((mi = class_resolvemethod(ci,CLINIT, EMPTY_DESC)) !=NULL) {
665 if (mi->class != ci) {
666 printf("WARNING:::::<clinit> method not found in class requested: ");
667 utf_display(ci->name); printf(" found in:"); utf_display(mi->class->name);
671 if ( mi->methodUsed != USED) {
672 mi->class->classUsed = PARTUSED;
677 if ((XTAOPTbypass) || (opt_xta)) {
678 xtaAddCallEdges(mi,MONO);
682 printf("class=");utf_display(ci->name);
684 if (ci->super != NULL)
685 utf_display(ci->super->name);
688 if ( (ci->super->name != utf_OBJECT) && (ci->name != utf_OBJECT) )
689 panic("<clinit> method not found");
695 /* Get finalize methodinfo ptr */
696 if ( (mi = class_findmethod (ci,FINALIZE, EMPTY_DESC)) != NULL) {
698 if ( mi->methodUsed != USED) {
699 mi->class->classUsed = PARTUSED;
704 if ((XTAOPTbypass) || (opt_xta)) {
705 xtaAddCallEdges(mi,MONO);
710 /*Special Case for System class init:
711 add java/lang/initializeSystemClass to callgraph */
712 if (class->name == utf_initializeSystemClass) {
713 /* Get clinit methodinfo ptr */
714 if ((mi = class_findmethod (ci,utf_initializeSystemClass, EMPTY_DESC)) != NULL) {
716 if ( mi->methodUsed != USED) {
717 mi->class->classUsed = PARTUSED;
722 if ((XTAOPTbypass) || (opt_xta)) {
723 xtaAddCallEdges(mi,MONO);
728 /* add marked methods to callgraph */
729 if ((XTAOPTbypass) || (opt_xta))
730 xtaAddMarkedMethods(ci);
732 rtaAddMarkedMethods(ci);
739 #define rt_code_get_u1(p) rt_jcode[p]
740 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
741 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
742 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
743 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
744 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
745 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
746 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
750 /*-------------------------------------------------------------------------------*/
751 void rtaAddUsedInterfaceMethods(classinfo *ci) {
754 /* add used interfaces methods to callgraph */
755 for (jj=0; jj < ci -> interfacescount; jj++) {
756 classinfo *ici = ci -> interfaces [jj];
758 if (pWhenMarked >= 1) {
759 printf("BInterface used: ");fflush(stdout);
760 utf_display(ici->name);
761 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
762 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
763 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
764 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
767 /* add class to interfaces list of classes that implement it */
768 ici -> impldBy = addElement(ici -> impldBy, ci);
770 /* if interface class is used */
771 if (ici -> classUsed != NOTUSED) {
773 /* for each interface method implementation that has already been used */
774 for (mm=0; mm< ici->methodscount; mm++) {
775 methodinfo *imi = &(ici->methods[mm]);
776 if (pWhenMarked >= 1) {
777 if (imi->methodUsed != USED) {
778 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
779 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
780 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
783 if (imi->methodUsed == USED) {
784 if (pWhenMarked >= 1) {
785 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
787 /* Mark this method used in the (used) implementing class and its subclasses */
788 printf("rMAY ADD methods that was used by an interface\n");
797 /*-------------------------------------------------------------------------------*/
798 void rtaMarkInterfaceSubs(methodinfo *mi) {
800 if (mi->class->classUsed == NOTUSED) {
801 mi->class->classUsed = USED;
802 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
805 /* add interface class to list kept in Object */
806 mi->methodUsed = USED;
809 subs = mi->class->impldBy;
810 RTAPRINT08invokeInterface1
811 while (subs != NULL) {
812 classinfo * isubs = subs->classType;
813 RTAPRINT09invokeInterface2
814 /* Mark method (mark/used) in classes that implement the method */
815 if (isubs->classUsed != NOTUSED) {
818 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
820 submeth->monoPoly = POLY; /* poly even if nosubs */
821 rtaMarkSubs(isubs, mi);
824 subs = subs->nextClass;
828 /*-------------------------------------------------------------------------------*/
829 /*-------------------------------------------------------------------------------*/
833 /*-------------------------------------------------------------------------------*/
834 void xtaAddUsedInterfaceMethods(classinfo *ci) {
837 /* add used interfaces methods to callgraph */
838 for (jj=0; jj < ci -> interfacescount; jj++) {
839 classinfo *ici = ci -> interfaces [jj];
841 if (pWhenMarked >= 1) {
842 printf("XInterface used: ");fflush(stdout);
843 utf_display(ici->name);
844 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
845 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
846 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
847 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
850 /* add class to interfaces list of classes that implement it */
851 ici -> impldBy = addElement(ici -> impldBy, ci);
853 /* if interface class is used */
854 if (ici -> classUsed != NOTUSED) {
856 /* for each interface method implementation that has already been used */
857 for (mm=0; mm< ici->methodscount; mm++) {
858 methodinfo *imi = &(ici->methods[mm]); /*interface method */
859 printf("==%i==%i\n",ici->methodscount,mm);
860 if (imi->xta == NULL)
862 /*RTAprint*/if (pWhenMarked >= 1) {
863 /*RTAprint*/ if (imi->xta->XTAmethodUsed != USED) {
864 /*RTAprint*/ if (imi->xta->XTAmethodUsed==NOTUSED)
865 printf("Interface Method notused: ");
866 /*RTAprint*/ if (imi->xta->XTAmethodUsed==MARKED)
867 printf("Interface Method marked: ");
868 /*RTAprint*/ utf_display(ici->name);printf(".");
869 /*RTAprint*/ method_display(imi);fflush(stdout);
872 if (imi->xta->XTAmethodUsed == USED) {
873 methSetNode *mCalledBy = NULL;
874 if (pWhenMarked >= 1) {
875 printf("Interface Method used: "); utf_display(ici->name);printf(".");
876 method_display(imi);fflush(stdout);
878 /* Mark this method used in the (used) implementing class &its subclasses */
879 printf("xMAY ADD methods that was used by an interface\n"); fflush(stdout);
881 if (pWhenMarked >= 1) {
882 printf("calledBy set ="); fflush(stdout);
883 printMethodSet(imi->xta->calledBy);
885 if (imi->xta->calledBy != NULL) {
886 /* for each calledBy method */
887 for ( mCalledBy = imi->xta->calledBy->head;
889 mCalledBy = mCalledBy->nextmethRef) {
890 if (pWhenMarked >= 1) {
891 printf("xtaMarkSubs(");
892 utf_display(ci->name); printf("."); fflush(stdout);
894 printf("mCalledBy method class set BEFORE\n"); fflush(stdout);
895 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
897 xtaMarkSubs(ci,imi,mCalledBy->methRef->xta->XTAclassSet->head);
898 if (pWhenMarked >= 1) {
899 printf("mCalledBy method class set AFTER \n"); fflush(stdout);
900 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
910 /*-------------------------------------------------------------------------------*/
912 /*-------------------------------------------------------------------------------*/
913 void xtaMarkInterfaceSubs(methodinfo *mi) {
920 if (mi->class->classUsed != USED) {
921 mi->class->classUsed = USED;
922 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
925 /* add interface class to list kept in Object */
926 if (pWhenMarked >= 1) {
927 printf("Marking Interface Method: "); fflush(stdout);
929 xtaAddCallEdges(mi,POLY);
931 subs = mi->class->impldBy;
932 RTAPRINT08invokeInterface1
933 while (subs != NULL) {
934 classinfo * isubs = subs->classType;
935 RTAPRINT09invokeInterface2
936 /* Mark method (mark/used) in classes that implement the method */
937 if (isubs->classUsed != NOTUSED) {
940 submeth = class_resolvemethod(isubs,mi->name, mi->descriptor);
941 if (submeth != NULL) ///+1
943 classSetNode *subtypesUsedSet = NULL;
944 submeth->monoPoly = POLY; /* poly even if nosubs */
946 mi->xta->XTAmethodUsed = USED;
947 if (rt_method->xta->XTAclassSet != NULL)
949 intersectSubtypesWithSet
950 (subs->classType, rt_method->xta->XTAclassSet->head);
952 if (pWhenMarked >= 1) {
953 /*RTAprint*/ printf(" \nXTA subtypesUsedSet: ");
954 /*RTAprint*/ fflush(stdout);
955 /*RTAprint*/ printSet(subtypesUsedSet);
957 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
960 subs = subs->nextClass;
963 /*-------------------------------------------------------------------------------*/
965 /*-------------------------------------------------------------------------------*/
966 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
970 if (fi->xta->fieldChecked) {
971 if (fi->xta->fldClassType != NULL)
972 return true; /* field has a class type */
976 fi->xta->fieldChecked = true;
978 if (fi->type == TYPE_ADDRESS) {
979 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
981 if (*utf_ptr != 'L') {
982 while (*utf_ptr++ =='[') ;
985 if (*utf_ptr =='L') {
987 if (fi->xta->fldClassType== NULL) {
992 desc = MNEW(char, 256);
993 strcpy(desc,++utf_ptr);
994 cname = strtok(desc,";");
996 printf("STATIC fields type is: %s\n",cname);
999 class = class_get(utf_new_char(cname));
1000 fi->xta->fldClassType= class; /* save field's type class ptr */
1007 /*-------------------------------------------------------------------------------*/
1008 void xtaPassFldPUT(fldSetNode *fN)
1010 /* Field type is a class */
1012 classSetNode *c1 = NULL;
1013 classSetNode *cp = NULL;
1014 classSetNode *cprev= NULL;
1022 /* Use lastptr so don't check whole XTA class set each time */
1023 cp = fN->lastptrPUT;
1025 if (cp->nextClass != NULL)
1026 c1 = cp -> nextClass;
1029 if (rt_method->xta->XTAclassSet != NULL)
1030 c1 = rt_method->xta->XTAclassSet->head;
1033 printf("rt XTA class set =");fflush(stdout);
1034 printClassSet(rt_method->xta->XTAclassSet);
1035 printf("\t\tField class type = ");fflush(stdout);
1036 utf_display(fi->xta->fldClassType->name); printf("\n");
1040 /*--- PUTSTATIC specific ---*/
1041 /* Sx = intersection of type+subtypes(field x) */
1042 /* and Sm (where putstatic code is) */
1043 for (c=c1; c != NULL; c=c->nextClass) {
1044 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
1045 vftbl *c_cl_vt = c-> classType->vftbl;
1047 printf("\tXTA class = ");fflush(stdout);
1048 utf_display(c->classType->name);
1049 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
1050 if (c->nextClass == NULL) {
1051 printf("next=NULL ");fflush(stdout);
1054 printf("next="); fflush(stdout);
1055 utf_display(c->nextClass->classType->name);
1056 printf("\n"); fflush(stdout);
1059 printf("\t\tField class type = ");fflush(stdout);
1060 utf_display(fi->xta->fldClassType->name);
1061 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
1064 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
1065 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
1066 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
1070 fN->lastptrPUT = cprev;
1072 /*-------------------------------------------------------------------------------*/
1073 void xtaPassFldGET(fldSetNode *fN)
1075 /* Field type is a class */
1077 classSetNode *c1 = NULL;
1078 classSetNode *cp = NULL;
1079 classSetNode *cprev= NULL;
1087 /* Use lastptr so don't check whole XTA class set each time */
1088 cp = fN->lastptrGET;
1090 if (cp->nextClass != NULL)
1091 c1 = cp -> nextClass;
1094 if (fi->xta->XTAclassSet != NULL)
1095 c1 = fi->xta->XTAclassSet->head;
1098 printf("fld XTA class set =");fflush(stdout);
1099 printClassSet(fi->xta->XTAclassSet);
1100 printf("\t\tField class type = ");fflush(stdout);
1101 utf_display(fi->xta->fldClassType->name); printf("\n");
1105 /*--- GETSTATIC specific ---*/
1106 /* Sm = union of Sm and Sx */
1107 for (c=c1; c != NULL; c=c->nextClass) {
1108 bool addFlg = false;
1109 if (rt_method->xta->XTAclassSet ==NULL)
1112 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
1116 rt_method->xta->XTAclassSet
1117 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
1122 fN->lastptrGET = cprev;
1126 /*-------------------------------------------------------------------------------*/
1127 void xtaPassAllCalledByParams () {
1128 methSetNode *SmCalled;
1130 if (XTAdebug >= 1) {
1131 printf("xta->calledBy method set: "); fflush(stdout);
1133 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
1134 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
1136 if (rt_method->xta->calledBy == NULL)
1139 s1 = rt_method->xta->calledBy->head;
1140 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1141 if (XTAdebug >= 1) {
1142 printf("SmCalled = "); fflush(stdout);
1143 utf_display(SmCalled->methRef->class->name); fflush(stdout);
1144 printf(".");fflush(stdout); method_display(SmCalled->methRef);
1147 rt_method->xta->chgdSinceLastParse = false;
1148 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
1152 /*-------------------------------------------------------------------------------*/
1153 void xtaAllFldsUsed ( ){
1155 fldSetNode *f1=NULL;
1156 /* bool chgd = false */
1158 if (rt_method->xta->fldsUsed == NULL) return;
1160 /* for each field that this method uses */
1161 f1 = rt_method->xta->fldsUsed->head;
1163 for (f=f1; f != NULL; f = f->nextfldRef) {
1171 /*-------------------------------------------------------------------------------*/
1172 void xtaMethodCalls_and_sendReturnType()
1174 methSetNode *SmCalled; /* for return type */
1175 methSetNode *SmCalls; /* for calls param types */
1176 methSetNode *s1=NULL;
1178 if (XTAdebug >= 1) {
1179 printf("calls method set Return type: ");
1180 printMethodSet(rt_method->xta->calls);
1184 /* for each method that this method calls */
1185 if (rt_method->xta->calls == NULL)
1188 s1 = SmCalls=rt_method->xta->calls->head;
1190 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
1191 /* pass param types */
1193 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
1194 /* if true chgd after its own parse */
1195 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
1196 SmCalls->methRef->xta->chgdSinceLastParse = true;
1200 /* for each calledBy method */
1201 /* send return type */
1202 if (rt_method->xta->calledBy == NULL)
1205 s1 = rt_method->xta->calledBy->head;
1206 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1208 if (XTAdebug >= 1) {
1209 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
1210 printf("."); method_display(SmCalled->methRef);
1213 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
1214 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1215 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
1220 /*-------------------------------------------------------------------------------*/
1221 /* -- Processes STATIC & PRIVATE methods
1223 /* -- called for INVOKESTATIC, INVOKESPECIAL - PRIVATE and
1224 /* STATIC / PRIVATE methods used by NATIVE methods
1225 /*-------------------------------------------------------------------------------*/
1227 // Dez Version but gives too many Missed
1228 void invokestatic2( methodinfo *mi) {
1230 mi->class->classUsed = PARTUSED;
1232 addClassInit(mi->class, true, true, true);
1233 RTAPRINT04invokestatic1
1240 if ((XTAOPTbypass) || (opt_xta)) {
1241 mi->class->classUsed = PARTUSED;
1242 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,mi->class);
1243 xtaAddCallEdges(mi,MONO);
1249 //// from just RTA version before Dez changes
1250 void invokestatic(methodinfo *mi){
1251 RTAPRINT04invokestatic1
1252 if (mi->class->classUsed == NOTUSED) {
1253 mi->class->classUsed = USED;
1254 RTAPRINT05invokestatic2
1256 addClassInit(mi->class,true, true, true);
1262 if ((XTAOPTbypass) || (opt_xta)) {
1263 xtaAddCallEdges(mi,MONO);
1268 /*-------------------------------------------------------------------------------*/
1269 /* -- Processes <INIT> methods
1271 /* -- called for INVOKESPECIAL - <init> and
1272 /* <init> methods used by NATIVE methods
1273 /*-------------------------------------------------------------------------------*/
1275 void initMethods(methodinfo *mi) {
1277 classinfo *ci = mi->class;
1279 /* new class so add marked methods */
1281 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1282 /*--- process NORMAL <init> method ---------------------------------------------*/
1283 if ( mi->methodUsed != USED) {
1285 - mark class as USED and <init> to callgraph */
1288 // addClassInit(mi->class,true, true, false);
1289 ci->classUsed = USED;
1290 rtaAddMarkedMethods(ci); /* add to callgraph marked methods */
1291 RTAPRINT06Binvoke_spec_init
1292 rtaAddUsedInterfaceMethods(ci);
1299 if ((XTAOPTbypass) || (opt_xta)) {
1300 if (mi->xta == NULL) {
1301 mi->xta = xtainfoInit(mi);
1303 if ((mi->xta->XTAmethodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1304 ci->classUsed = USED;
1305 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1306 xtaAddMarkedMethods(ci); /* add to callgraph marked methods */
1307 xtaAddUsedInterfaceMethods(ci);
1308 xtaAddCallEdges(mi,MONO);
1309 RTAPRINT06CXTAinvoke_spec_init1
1314 /*-------------------------------------------------------------------------------*/
1315 /* -- Processes VIRTUAL methods
1317 /* -- called for INVOKEVIRTUAL and
1318 /* virtual methods used by NATIVE methods
1319 /*-------------------------------------------------------------------------------*/
1321 void invokevirtual(methodinfo *mi) {
1324 RTAPRINT07invoke_spec_virt2
1325 mi->class->classUsed = USED; // Should this be later?
1327 if ((mi->flags & ACC_STATIC) || (mi->flags & ACC_PRIVATE) || (mi->flags & ACC_FINAL) ) {
1333 mi->monoPoly = POLY;
1336 rtaMarkSubs(mi->class,mi);
1340 if ((XTAOPTbypass) || (opt_xta)) {
1341 classSetNode *subtypesUsedSet = NULL;
1342 if (rt_method->xta->XTAclassSet != NULL)
1344 intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1346 subtypesUsedSet = addElement(subtypesUsedSet, rt_method->class);
1348 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1349 printSet(subtypesUsedSet);
1351 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1356 /*-------------------------------------------------------------------------------*/
1357 void invokeinterface( methodinfo *mi ) {
1358 /*RTAprint*/ if (pWhenMarked >= 1) {
1359 /*RTAprint*/ printf("\t");fflush(stdout);
1360 /*RTAprint*/ utf_display(mi->class->name); printf(".");fflush(stdout);
1361 /*RTAprint*/ method_display(mi); fflush(stdout);
1364 if (mi->flags & ACC_STATIC)
1365 panic ("Static/Nonstatic mismatch calling static method");
1366 RTAPRINT08AinvokeInterface0
1369 rtaMarkInterfaceSubs(mi);
1372 if ((XTAOPTbypass2) || (opt_xta)) {
1373 xtaMarkInterfaceSubs(mi);
1377 /*-------------------------------------------------------------------------------*/
1378 void newClasses(classinfo *ci) {
1379 if (pWhenMarked >= 1) {
1380 printf("\tclass=");fflush(stdout);
1381 utf_display(ci->name); fflush(stdout);
1382 printf("=\n");fflush(stdout);
1385 if (ci->classUsed != USED) {
1387 ci->classUsed = USED; /* add to heirarchy */
1388 /* Add this class to the implemented by list of the abstract interface */
1389 rtaAddUsedInterfaceMethods(ci);
1390 addClassInit(ci, true, true, false);
1393 if ((XTAOPTbypass) || (opt_xta))
1395 xtaAddUsedInterfaceMethods(ci);
1396 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1401 /*-------------------------------------------------------------------------------*/
1402 static void parseRT()
1404 int p; /* java instruction counter */
1405 int nextp; /* start of next java instruction */
1406 int opcode; /* java opcode */
1407 int i; /* temporary for different uses (counters) */
1408 bool iswide = false; /* true if last instruction was a wide */
1412 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1413 printf("XTA parseRT():"); fflush(stdout);
1414 method_display(rt_method);
1415 if (rt_method->xta == NULL)
1416 xtainfoInit (rt_method);
1417 xtaPassAllCalledByParams ();
1418 printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1422 /* scan all java instructions */
1424 for (p = 0; p < rt_jcodelength; p = nextp) {
1425 opcode = rt_code_get_u1 (p); /* fetch op code */
1428 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
1431 /*--------------------------------*/
1432 /* Code just to get the correct next instruction */
1471 /* wider index for loading, storing and incrementing */
1485 /* table jumps ********************************/
1487 case JAVA_LOOKUPSWITCH:
1490 nextp = ALIGN((p + 1), 4);
1491 num = rt_code_get_u4(nextp + 4);
1492 nextp = nextp + 8 + 8 * num;
1497 case JAVA_TABLESWITCH:
1500 nextp = ALIGN ((p + 1),4);
1501 num = rt_code_get_s4(nextp + 4);
1502 num = rt_code_get_s4(nextp + 8) - num;
1503 nextp = nextp + 16 + 4 * num;
1507 /*-------------------------------*/
1508 case JAVA_PUTSTATIC:
1509 i = rt_code_get_u2(p + 1);
1511 constant_FMIref *fr;
1514 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1515 /* descr has type of field ref'd */
1516 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1517 RTAPRINT03putstatic1
1520 /* class with field - marked in addClassinit */
1521 addClassInit(fr->class, true, true, false);
1524 if ((XTAOPTbypass) || (opt_xta))
1526 if (fi->xta == NULL)
1527 fi->xta = xtafldinfoInit(fi);
1528 if (xtaAddFldClassTypeInfo(fi)) {
1529 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1535 case JAVA_GETSTATIC:
1536 i = rt_code_get_u2(p + 1);
1538 constant_FMIref *fr;
1541 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1542 /* descr has type of field ref'd */
1543 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1544 RTAPRINT03putstatic1
1547 /* class with field - marked in addClassinit */
1548 addClassInit(fr->class,true, true, true);
1551 if ((XTAOPTbypass) || (opt_xta) )
1553 if (fi->xta == NULL)
1554 fi->xta = xtafldinfoInit(fi);
1555 if (xtaAddFldClassTypeInfo(fi)) {
1556 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1564 /*-------------------- method invocation ---------------------*/
1566 case JAVA_INVOKESTATIC:
1567 i = rt_code_get_u2(p + 1);
1569 constant_FMIref *mr;
1572 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1573 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1575 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1581 case JAVA_INVOKESPECIAL:
1582 i = rt_code_get_u2(p + 1);
1584 constant_FMIref *mr;
1587 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1588 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1590 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1591 RTAPRINT06invoke_spec_virt1
1592 /*--- PRIVATE Method -----------------------------------------------------*/
1593 if (mi->name != INIT) { /* if method called is PRIVATE */
1594 RTAPRINT07invoke_spec_virt2
1595 RTAPRINT04invokestatic1
1600 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1607 case JAVA_INVOKEVIRTUAL:
1608 i = rt_code_get_u2(p + 1);
1610 constant_FMIref *mr;
1613 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1614 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1616 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1622 case JAVA_INVOKEINTERFACE:
1623 i = rt_code_get_u2(p + 1);
1625 constant_FMIref *mr;
1628 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1629 mi = class_resolveinterfacemethod (mr->class, mr->name, mr->descriptor, class, true);
1631 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1632 invokeinterface(mi);
1636 /* miscellaneous object operations *******/
1639 i = rt_code_get_u2 (p+1);
1643 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1656 if (p != rt_jcodelength)
1657 panic("Command-sequence crosses code-boundary");
1659 if ((XTAOPTbypass) || (opt_xta))
1660 xtaMethodCalls_and_sendReturnType();
1665 /*-------------------------------------------------------------------------------*/
1666 /* RTA add Native Methods/ Class functions */
1667 /*-------------------------------------------------------------------------------*/
1668 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1673 class = class_get(c1);
1674 if (class == NULL) {
1676 printf(" WARNING: CLASS used by NATIVE method is NULL so loaded\n");
1677 loader_load_sysclass(NULL, c1);
1678 class = class_get(c1);
1679 if (class == NULL) {
1680 panic("CLASS used by NATIVE method is NULL and loading didn't help\n");
1681 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1685 if (class->classUsed == NOTUSED) {
1686 printf("NATIVE_MARKED CLASS USED "); utf_display(class->name); printf("\n");
1687 class->classUsed = USED; /* MARK CLASS USED */
1688 /* add marked methods to callgraph */
1689 rtaAddMarkedMethods(class);
1692 meth = class_findmethod_w (class, m1, d1,"findMarkNativeUsedMeth");
1694 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1695 panic("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1698 rtaMarkSubs(class,meth);
1701 /*-------------------------------------------------------------------------------*/
1703 void findMarkNativeUsedClass (utf * c) {
1706 class = class_get(c);
1707 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1708 class->classUsed = USED;
1710 /* add marked methods to callgraph */
1711 rtaAddMarkedMethods(class);
1715 /*-------------------------------------------------------------------------------*/
1717 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1721 nativecallcompdone = natcall2utf(nativecallcompdone);
1723 for (i=0; i<NATIVECALLSSIZE; i++) {
1724 if (rt_class == nativeCompCalls[i].classname) {
1726 /* find native class.method invoked */
1727 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1729 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1730 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1733 printf("#%i#\n",nativeCompCalls[i].callCnt[j]);
1734 /* mark methods and classes used by this native class.method */
1735 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1736 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1737 /* mark method used */
1738 findMarkNativeUsedMeth(
1739 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1740 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1741 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1744 printf("\nmark method used: "); fflush(stdout);
1745 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1746 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1747 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1751 /* mark class used */
1752 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1767 /*-------------------------------------------------------------------------------*/
1768 /*-------------------------------------------------------------------------------*/
1769 /* still need to look at field sets in 2nd pass and clinit ..... */
1770 void XTA_jit_parse2(methodinfo *m)
1772 int methRT; /* local */
1774 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1776 /* for each method in XTA worklist = callgraph (use RTA for now) */
1778 //while (methRT <= methRTlast) {
1779 while (methRT <= methXTAlast) {
1780 rt_method = XTAcallgraph[methRT];
1781 rt_class = rt_method->class;
1782 rt_descriptor = rt_method->descriptor;
1783 rt_jcodelength = rt_method->jcodelength;
1784 rt_jcode = rt_method->jcode;
1786 if (! ( (rt_method->flags & ACC_NATIVE )
1787 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1788 if (XTAdebug >= 1) {
1789 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1790 utf_display(rt_class->name); printf("."); fflush(stdout);
1791 method_display(rt_method);
1793 /* if XTA type set changed since last parse */
1794 if (rt_method->xta->chgdSinceLastParse) {
1796 /* get types from methods it is calledBy */
1797 xtaPassAllCalledByParams ();
1799 /* Pass parameter types to methods it calls and send the return type those called by */
1800 xtaMethodCalls_and_sendReturnType();
1805 if (XTAdebug >= 1) {
1807 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1808 printXTACallgraph ();
1811 RTAPRINT14CallgraphLast /*was >=2 */
1812 RTAPRINT15HeirarchyiLast /*was >= 2 */
1816 /*-------------------------------------------------------------------------------*/
1817 /*-------------------------------------------------------------------------------*/
1818 void mainRTAparseInit (methodinfo *m )
1820 /*printf("MAIN_NOT_STARTED \n");*/
1821 if (class_java_lang_Object->sub != NULL) {
1828 /* Frequently used utf strings */
1829 utf_OBJECT = utf_new_char("java/lang/Object");
1830 utf_MAIN = utf_new_char("main");
1831 INIT = utf_new_char("<init>");
1832 CLINIT = utf_new_char("<clinit>");
1833 FINALIZE = utf_new_char("finalize");
1834 EMPTY_DESC= utf_new_char("()V");
1836 /* open file for list of methods parsed before main method or missed and parsed after main */
1837 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1838 printf("CACAO - rtMissed file: cant open file to write\n");
1841 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1843 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1844 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1848 /* Allocate callgraph */
1850 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1852 if ((XTAOPTbypass) || (opt_xta)) {
1853 printf("XTAXTA CALLGRAPHS allocated\n");
1854 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1858 if (m->name == utf_MAIN) {
1859 rtMissed = fopen("rtMissed","a");
1860 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1865 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1866 printf("CACAO - rtMissed file: cant open file to write\n");
1869 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1870 utf_fprint(rtMissed,m->class->name);
1871 fprintf(rtMissed," ");
1872 fprintflags(rtMissed,m->flags);
1873 fprintf(rtMissed," ");
1874 utf_fprint(rtMissed,m->name);
1875 fprintf(rtMissed," ");
1876 utf_fprint(rtMissed,m->descriptor);
1877 fprintf(rtMissed,"\n");
1882 printf("#%i : ",methRT);
1883 printf("Method missed by static analysis Main parse. See ./rtMissed file\n");
1884 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1888 /* At moment start RTA before main when parsed */
1889 /* Will definitely use flag with to know if ok to apply in-lining. */
1893 /*-------------------------------------------------------------------------------*/
1894 /*-------------------------------------------------------------------------------*/
1896 void RTparseCGWorklist (methodinfo *m) {
1897 printf("IIIIIIIIIIIIIIIIIIIIn RTparseCGWorklist\n"); fflush(stdout);
1898 if (m->methodUsed == USED) return;
1899 if ((firstCall) || (parse1) || (m->name == utf_MAIN))
1900 mainRTAparseInit (m);
1902 m->methodUsed = USED;
1904 /* initialise parameter type descriptor */
1905 callgraph[++methRTlast] = m; /*-- RTA --*/
1906 RTAPRINT11addedtoCallgraph
1907 /* <init> then like a new class so add marked methods to callgraph */
1908 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1911 ci->classUsed = USED;
1912 if (pWhenMarked >= 1) {
1913 printf("Class=");utf_display(ci->name);
1915 /* add marked methods to callgraph */
1916 RTAPRINT11addedtoCallgraph2
1917 rtaAddMarkedMethods(ci);
1920 /*---- RTA call graph worklist -----***/
1921 while (methRT <= methRTlast) {
1922 rt_method = callgraph[methRT];
1923 rt_class = rt_method->class;
1924 rt_descriptor = rt_method->descriptor;
1925 rt_jcodelength = rt_method->jcodelength;
1926 rt_jcode = rt_method->jcode;
1928 if (! ( (rt_method->flags & ACC_NATIVE )
1929 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1932 //if (true == false) { // At moment nativecalls.h is not current and neither helps nor hinders
1934 RTAPRINT12bAbstractNative
1935 if (rt_method->flags & ACC_NATIVE ) {
1937 /* mark used and add to callgraph methods and classes used by NATIVE method */
1938 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1940 if (rt_method->flags & ACC_ABSTRACT) {
1941 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1949 if (m->class->classUsed == NOTUSED)
1950 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1954 /*-------------------------------------------------------------------------------*/
1955 /*--------------------------------------------------------*/
1956 int getdymline(char *line, int max, FILE *inFP) {
1957 if (fgets(line, max, inFP) == NULL)
1960 return strlen((const char *)line);
1964 /*-------------------------------------------------------------------------------*/
1966 methodinfo *getApplicationDynamics ( ) {
1976 if ( (appldynm = fopen("appldynm", "r")) == NULL) {
1977 printf("parseRT - appldynm file: no appldynm file - ok if nothing in rtMissed after Main\n");
1981 if ( getdymline(line,512,appldynm) != 0)
1983 printf("line=%s\n",line); fflush(stdout);
1985 classname = strtok(line," \n");
1986 methname = strtok(NULL," \n");
1987 if (methname == NULL) { /* if no meth */
1988 panic("parseRT - dynamic loaded class/method/desc in appldynm has no method");
1990 desc = strtok(NULL," \n");
1991 if (desc == NULL) { /* if no desc */
1992 panic("parseRT - dynamic loaded class/method/desc in appldynm has no descriptor");
1994 printf("appldynm class=%s meth=%s desc=%s\n",classname, methname,desc); fflush(stdout);
1996 class = class_get(utf_new_char(classname));
1997 if (class == NULL) {
1998 class = loader_load_sysclass(NULL, utf_new_char(classname));
2000 mi = class_fetchmethod(class,utf_new_char(methname), utf_new_char(desc)) ;
2001 printf("+++++--3--+++++\t");
2002 RTparseCGWorklist (mi) ;
2010 /*-------------------------------------------------------------------------------*/
2012 void RT_jit_parse(methodinfo *m)
2016 classinfo *topclass;
2018 /*-- RTA -- *******************************************************/
2021 /*---- java/lang/Object.<clinit> ----*/
2022 if ((firstCall == false) || (true == false))
2025 if (m->methodUsed == USED) return;
2026 printf("MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2027 RTparseCGWorklist (m) ;
2028 /*RTAprint*/ if (pCallgraph >= 1) {
2029 /*RTAprint*/ printCallgraph ();}
2030 /*RTprint*/ //if (pClassHeir >= 1) {
2031 /*RTprint*/ // printRThierarchyInfo(m);
2033 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2035 printf("END MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2041 printf("SSSSSSSSSSSSSSSSSSSSSStatic Analysis \n"); fflush(stdout);
2042 printf("+++++--1--+++++\t");
2043 RTparseCGWorklist (m) ;
2045 class = class_get(utf_new_char("java/lang/Thread"));
2046 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2047 printf("+++++--2--+++++\t");
2048 RTparseCGWorklist (mi) ;
2050 class = class_get(utf_new_char("java/lang/ThreadGroup"));
2051 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2052 printf("+++++--3--+++++\t");
2053 RTparseCGWorklist (mi) ;
2056 class = class_get(utf_new_char("java/lang/Throwable"));
2057 mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2058 printf("+++++--4--+++++\t");
2059 RTparseCGWorklist (mi) ;
2061 printf("mainString=%s=\n",mainString);fflush(stdout);
2062 class = loader_load_sysclass(NULL, utf_new_char(mainString));
2063 mi = class_fetchmethod( class,
2064 utf_new_char("main"),
2065 utf_new_char("([Ljava/lang/String;)V")
2067 printf("+++++--5--+++++\t");
2068 RTparseCGWorklist (mi) ;
2070 printf("+++++--6--+++++\t");
2071 getApplicationDynamics();
2073 printf("-+-+-+-+-+-+-+-+-+-+-33"); fflush(stdout);
2075 /*RTAprint*/ if (pCallgraph >= 1) {
2076 /*RTAprint*/ printCallgraph ();}
2077 /*RTprint*/ //if (pClassHeir >= 1) {
2078 /*RTprint*/ // printRThierarchyInfo(m);
2080 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2082 printf("-+-+-+-+-+-+-+-+-+-+-44"); fflush(stdout);
2083 /** MFREE(callgraph,methodinfo*,MAXCALLGRAPH); causes stack overflow **/
2087 /*-- XTA -- *******************************************************/
2088 if ((XTAOPTbypass) || (opt_xta)) {
2089 if (m->xta != NULL) {
2090 if (m->xta->XTAmethodUsed == USED) return;
2092 mainRTAparseInit (m);
2094 XTAcallgraph[++methXTAlast] = m;
2095 if (m->xta == NULL) {
2096 m->xta = xtainfoInit(m);
2098 m->xta->XTAmethodUsed = USED;
2099 {methodinfo *mi = m;
2100 printf("<");fflush(stdout);
2105 /*-- Call graph work list loop -----------------*/
2106 /*---- XTA call graph worklist -----***/
2107 useXTAcallgraph = true;
2108 if ((useXTAcallgraph) && (opt_xta)) {
2109 printf("USING XTA call graph>>>>>>>>>><<\n");
2111 while (methXTA <= methXTAlast) {
2112 rt_method = XTAcallgraph[methXTA];
2113 printf("xTA CALLGRAPH #%i:",methXTA); fflush(stdout);
2114 method_display(rt_method);
2115 rt_class = rt_method->class;
2116 rt_descriptor = rt_method->descriptor;
2117 rt_jcodelength = rt_method->jcodelength;
2118 rt_jcode = rt_method->jcode;
2120 if (! ( (rt_method->flags & ACC_NATIVE )
2121 || (rt_method->flags & ACC_ABSTRACT) ) ) {
2125 RTAPRINT12bAbstractNative
2126 if (rt_method->flags & ACC_NATIVE ) {
2128 /* mark used and add to callgraph methods and classes used by NATIVE method */
2129 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
2131 if (rt_method->flags & ACC_ABSTRACT) {
2132 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
2139 if (m->class->classUsed == NOTUSED)
2140 m->class->classUsed = USED; /* say Main's class has a method used ??*/
2141 printXTACallgraph ();
2143 if (m->name == utf_MAIN) { /*-- MAIN specific -- */
2144 /*RTAprint*/ if (pCallgraph >= 1) {
2145 /*RTAprint*/ printXTACallgraph (); }
2146 /*RTprint*/ if (pClassHeir >= 1) {
2147 /*RTprint*/ printf("Last RTA Info -+-+-");
2148 /*RTprint*/ printRThierarchyInfo(m);
2150 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
2152 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
2154 printf("XTAXTA CALLGRAPHS -SHOULD BE BUT ISNT- returned \n");
2155 //MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
2159 RTAPRINT14CallgraphLast /* was >=2*/
2160 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
2167 * These are local overrides for various environment variables in Emacs.
2168 * Please do not remove this and leave it at the end of the file, where
2169 * Emacs will automagically detect them.
2170 * ---------------------------------------------------------------------
2173 * indent-tabs-mode: t