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 657 2003-11-20 15:18:33Z carolyn $
36 /*------------ global variables -----------------------------------------*/
37 #define MAXCALLGRAPH 5000
39 #include "parseRTflags.h"
43 int methRTmax = MAXCALLGRAPH;
44 methodinfo **callgraph;
45 /*methodinfo *callgraph[MAXCALLGRAPH];*/
50 int methXTAmax = MAXCALLGRAPH;
51 methodinfo **XTAcallgraph;
52 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
54 static bool nativecallcompdone=0 ;
56 static bool firstCall= true;
57 static bool AfterMain = false;
58 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
59 /* so easier to build dynmanic calls file */
61 static utf *utf_MAIN; /* utf_new_char("main"); */
62 static utf *INIT ; /* utf_new_char("<init>"); */
63 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
64 static utf *FINALIZE; /* utf_new_char("finalize"); */
65 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
66 static int missedCnt = 0;
69 /*--------------------------------------------------------------*/
70 /* addToCallgraph - adds to RTA callgraph and */
71 /* sets meth->methodUsed to USED */
72 /*--------------------------------------------------------------*/
73 // if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) {
74 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
76 callgraph[++methRTlast] = meth ; \
77 meth->methodUsed = USED; \
79 {printf("\n Added to Call Graph #%i:", \
81 printf("\t <used flags c/m> <%i/%i> %i\t", \
82 meth->class->classUsed, \
85 printf(" method name ="); \
86 utf_display(meth->class->name);printf("."); \
87 method_display(meth);fflush(stdout);} \
90 /*--------------------------------------------------------------*/
91 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
94 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
95 if (subs->classUsed == USED) {
96 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
101 if (rtaSubUsed(subs, meth))
108 /*--------------------------------------------------------------*/
109 /* Mark the method with same name /descriptor in topmethod */
112 /* Class not marked USED and method defined in this class -> */
113 /* -> if Method NOTUSED mark method as MARKED */
114 /* Class marked USED and method defined in this class -> */
115 /* -> mark method as USED */
117 /* Class USED, but method not defined in this class -> */
118 /* -> search up the heirarchy and mark method where defined */
119 /* if class where method is defined is not USED -> */
120 /* -> mark class with defined method as PARTUSED */
121 /*--------------------------------------------------------------*/
123 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
125 utf *name = topmethod -> name;
126 utf *descriptor = topmethod -> descriptor;
129 submeth = class_resolvemethod(class, name, descriptor);
131 panic("parse RT: Method not found in class hierarchy");
132 if (submeth->methodUsed == USED) return;
134 if (submeth->class == class) {
136 /*--- Method defined in class -----------------------------*/
137 if (submeth->class->classUsed != USED) {
138 if (submeth->methodUsed == NOTUSED) {
140 /* Class NOT marked USED and method defined in this class -> */
141 /* -> if Method NOTUSED mark method as MARKED */
142 if (pWhenMarked >= 1) {
143 printf("MARKED class.method\t");
144 utf_display(submeth->class->name);printf(".");method_display(submeth);
146 if (rtaSubUsed(submeth->class,submeth)) {
147 submeth->class->classUsed = PARTUSED;
148 ADDTOCALLGRAPH(submeth)
151 submeth->methodUsed = MARKED;
156 /* Class IS marked USED and method defined in this class -> */
157 /* -> mark method as USED */
158 ADDTOCALLGRAPH(submeth)
160 } /* end defined in class */
163 /*--- Method NOT defined in class -----------------------------*/
164 if (submeth->class->classUsed == NOTUSED) {
165 submeth->class->classUsed = PARTUSED;
166 if (class->classUsed != USED) {
167 submeth->methodUsed = MARKED;
170 if ( (submeth->class->classUsed == USED)
171 || (class->classUsed == USED)) {
172 ADDTOCALLGRAPH(submeth)
174 } /* end NOT defined in class */
177 /*-------------------------------------------------------------------------------*/
178 /* Mark the method with the same name and descriptor as topmethod */
179 /* and any subclass where the method is defined and/or class is used */
181 /*-------------------------------------------------------------------------------*/
182 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
184 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
185 if (class->sub != NULL) {
188 if (!(topmethod->flags & ACC_FINAL )) {
189 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
191 rtaMarkSubs(subs, topmethod);
198 /*-------------------------------------------------------------------------------*/
199 /* Add Marked methods for input class ci */
200 /* Add methods with the same name and descriptor as implemented interfaces */
201 /* with the same method name */
203 /*-------------------------------------------------------------------------------*/
204 void addMarkedMethods(classinfo *ci) {
207 /* add marked methods to callgraph */
208 for (ii=0; ii<ci->methodscount; ii++) {
209 methodinfo *mi = &(ci->methods[ii]);
210 if (mi->methodUsed == MARKED) {
211 if (pWhenMarked >= 1) {
212 printf("ADDED a method that was MARKED\n");
218 for (jj=0; jj < ci -> interfacescount; jj++) {
219 classinfo *ici = ci -> interfaces [jj];
220 /* use resolve method....!!!! */
221 if (ici -> classUsed != NOTUSED) {
222 for (mm=0; mm< ici->methodscount; mm++) {
223 methodinfo *imi = &(ici->methods[mm]);
225 if ( (imi->methodUsed == USED)
226 && ( (imi->name == mi->name)
227 && (imi->descriptor == mi->descriptor))) {
228 if (pWhenMarked >= 1)
229 printf("ADDED a method that was used by an interface\n");
238 /*-------------------------------------------------------------------------------*/
240 /*-------------------------------------------------------------------------------*/
242 xtainfo *xtainfoInit(methodinfo *m)
246 m ->xta = (xtainfo *) NEW(xtainfo);
247 m ->xta-> XTAmethodUsed = NOTUSED;
248 m ->xta-> XTAclassSet = NULL;
249 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
252 m->xta->paramClassSet = NULL;
253 m->xta->calls = NULL;
254 m->xta->calledBy = NULL;
256 m->xta->marked = NULL;
257 /*m ->xta->markedBy = NULL */
258 m->xta->fldsUsed = NULL;
259 /*m ->xta->interfaceCalls = NULL*/
260 m->xta->chgdSinceLastParse = false;
265 xtafldinfo * xtafldinfoInit (fieldinfo *f)
270 f->xta = NEW(xtafldinfo);
272 f->xta->fieldChecked = false; /*XTA*/
273 f->xta->fldClassType = NULL; /*XTA*/
274 f->xta->XTAclassSet = NULL; /*XTA*/
280 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
289 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
291 printf("\tIN SmCalled set : ");
292 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
293 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
295 printf("\tIN SmCalls set: ");
296 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
297 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
299 printf("\tIN lastptrInto : (");
300 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
301 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
303 else {printf("NULL) ");}
305 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
306 method_display(lastptrInto->methRef); fflush(stdout);
307 printf("\n");fflush(stdout);
310 /* Get SmCalled ParamType set if null */
311 if (SmCalled->xta->paramClassSet == NULL) {
312 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
315 printf("\tParamPassed\n"); fflush(stdout);
316 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
317 printf("\n"); fflush(stdout);
320 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
321 if (SmCalls->xta->XTAclassSet != NULL)
322 c1 = SmCalls->xta->XTAclassSet->head;
327 /* start with type where left off */
328 c1 = lastptrInto->lastptrIntoClassSet2;
329 c1 = c1 -> nextClass; /* even if NULL */
334 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
337 printf("\tIN SmCalls ... start with :");fflush(stdout);
338 utf_display(c1->classType->name); printf("\n");
342 /* for each Param Class */
343 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
345 /* for each SmCalls class */
346 for (c=c1; c != NULL; c = c->nextClass) {
347 vftbl *p_cl_vt = p->classType->vftbl;
348 vftbl *c_cl_vt = c->classType->vftbl;
350 /* if SmCalls class is in the Params Class range */
351 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
352 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
354 /* add SmCalls class to SmCalledBy Class set */
355 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
361 lastptrInto->lastptrIntoClassSet2 = cprev;
363 printf("\tOUT SmCalled set: ");fflush(stdout);
364 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
366 printf("\tOUT SmCalls set: ");fflush(stdout);
367 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
369 printf("\tOUT lastptrInto="); fflush(stdout);
370 if (lastptrInto->lastptrIntoClassSet2 != NULL)
371 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
373 printf("<rc=%i>\n",rc);fflush(stdout);
378 /*-------------------------------------------------------------------------------*/
379 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
386 printf("xtaPassReturnType \n");
388 /* Get SmCalled return class is null */
389 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
390 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
393 if (SmCalled->returnclass == NULL) {
395 printf("\tReturn type is NULL\n");
400 printf("\tReturn type is: ");
401 utf_display(SmCalled->returnclass->name);
404 printf("\tIN SmCalls set: ");
405 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
406 printClassSet(SmCalls->xta->XTAclassSet);
408 printf("\tIN SmCalled set: ");
409 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
410 printClassSet(SmCalled->xta->XTAclassSet);
414 if (SmCalled->xta->XTAclassSet == NULL)
417 cs1 = SmCalled->xta->XTAclassSet->head;
418 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
419 classinfo *c = cs->classType;
420 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
421 vftbl *c_cl_vt = c->vftbl;
423 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
424 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
425 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
426 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
432 printf("\tOUT SmCalls set: ");
433 printClassSet(SmCalls->xta->XTAclassSet);
438 /*-------------------------------------------------------------------------------*/
439 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
442 mi->xta = xtainfoInit(mi);
443 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
444 mi->xta->XTAmethodUsed = USED;
445 if (!(mi->flags & ACC_ABSTRACT)) {
446 XTAcallgraph[++methXTAlast] = mi;
451 /*RTAprint*/ if(pWhenMarked>=1) {
452 /*RTAprint*/ printf("\nxxxxxxxxxxxxxxxxx XTA set Used or Added to Call Graph #%i:",
453 /*RTAprint*/ methXTAlast);
454 /*RTAprint*/ printf(" method name ="); fflush(stdout);
455 /*RTAprint*/ utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
456 /*RTAprint*/ method_display(mi);fflush(stdout);
457 /*RTAprint*/ printf("\t\t\t\tcalledBy:");
458 /*RTAprint*/ utf_display(rt_method->class->name);fflush(stdout); printf(".");fflush(stdout);
459 /*RTAprint*/ method_display(rt_method);fflush(stdout);
462 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
463 rt_method->xta->calls->tail->monoPoly = monoPoly;
464 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
465 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
466 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
470 /*--------------------------------------------------------------*/
471 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
474 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
476 if (inSet(subtypesUsedSet,subs)) {
477 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
480 if (class_findmethod(subs, meth->name, meth->descriptor) == NULL)
484 if (xtaSubUsed(subs, meth, subtypesUsedSet))
491 /*-------------------------------------------------------------------------------*/
492 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
496 utf *name = topmethod -> name;
497 utf *descriptor = topmethod -> descriptor;
499 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
500 method_display(topmethod);
503 submeth = class_resolvemethod(class, name, descriptor);
506 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
507 method_display(submeth);
512 panic("parse XTA: Method not found in class hierarchy");
513 if (submeth->xta == NULL)
514 submeth->xta = xtainfoInit(submeth);
516 if (rt_method->xta->calls != NULL) {
517 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
520 if (submeth->class == class) {
522 /*--- Method defined in class -----------------------------*/
523 if (inSet(subtypesUsedSet,submeth->class)) {
524 printf("in set submeth->class:"); utf_display(submeth->class->name);
525 xtaAddCallEdges(submeth,POLY);
528 if (subtypesUsedSet != NULL) {
529 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
530 printf("xtaSubUsed ");
531 xtaAddCallEdges(submeth,POLY);
535 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
540 /*--- Method NOT defined in class -----------------------------*/
541 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
542 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
543 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
544 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/
547 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
548 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
549 xtaAddCallEdges(submeth,POLY);
552 } /* end defined in class */
555 /*-------------------------------------------------------------------------------*/
556 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
557 /* xtaPRINTmarkSubs1*/
558 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
559 if (class->sub != NULL) {
562 if (!(topmethod->flags & ACC_FINAL )) {
563 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
564 /* xtaPRINTmarkSubs1 */
565 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
571 /*-------------------------------------------------------------------------------*/
572 /* Both RTA and XTA */
573 /*-------------------------------------------------------------------------------*/
575 int addClassInit(classinfo *ci) {
576 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
579 utf* utf_java_lang_system = utf_new_char("java/lang/System");
580 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
581 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
583 int m, m1=-1, m2=-1, mf=-1;
586 for (m=0; m < ci->methodscount; m++) {
587 /*<clnit> class init method */
588 if (ci->methods[m].name == CLINIT) {
591 /* Special case: System class has an extra initializer method */
592 if ((utf_java_lang_system == ci->name)
593 && (utf_initializeSystemClass == ci->methods[m].name)) {
597 /* Finalize methods */
598 if ((ci->methods[m].name == FINALIZE)
599 && (ci->name != utf_java_lang_Object)) {
605 if (m1 >= 0) { /* No <clinit> available - ignore */
607 /* Get clinit methodinfo ptr */
608 mi = class_findmethod (ci,ci->methods[m1].name , NULL);
611 if ( mi->methodUsed != USED) {
612 mi->class->classUsed = PARTUSED;
617 if ((XTAOPTbypass) || (opt_xta)) {
618 xtaAddCallEdges(mi,MONO);
625 /* Get finalize methodinfo ptr */
626 mi = class_findmethod (ci,ci->methods[mf].name , NULL);
629 if ( mi->methodUsed != USED) {
630 mi->class->classUsed = PARTUSED;
635 if ((XTAOPTbypass) || (opt_xta)) {
636 xtaAddCallEdges(mi,MONO);
640 /*Special Case for System class init:
641 add java/lang/initializeSystemClass to callgraph */
643 /* Get clinit methodinfo ptr */
644 mi = class_findmethod (ci,ci->methods[m2].name , NULL);
647 if ( mi->methodUsed != USED) {
648 mi->class->classUsed = PARTUSED;
653 if ((XTAOPTbypass) || (opt_xta)) {
654 xtaAddCallEdges(mi,MONO);
658 /* add marked methods to callgraph */
659 addMarkedMethods(ci);
665 #define rt_code_get_u1(p) rt_jcode[p]
666 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
667 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
668 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
669 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
670 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
671 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
672 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
676 /*-------------------------------------------------------------------------------*/
677 void rtaAddUsedInterfaceMethods(classinfo *ci) {
680 /* add used interfaces methods to callgraph */
681 for (jj=0; jj < ci -> interfacescount; jj++) {
682 classinfo *ici = ci -> interfaces [jj];
684 if (pWhenMarked >= 1) {
685 printf("BInterface used: ");fflush(stdout);
686 utf_display(ici->name);
687 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
688 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
689 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
690 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
693 /* add class to interfaces list of classes that implement it */
694 ici -> impldBy = addElement(ici -> impldBy, ci);
696 /* if interface class is used */
697 if (ici -> classUsed != NOTUSED) {
699 /* for each interface method implementation that has already been used */
700 for (mm=0; mm< ici->methodscount; mm++) {
701 methodinfo *imi = &(ici->methods[mm]);
702 if (pWhenMarked >= 1) {
703 if (imi->methodUsed != USED) {
704 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
705 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
706 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
709 if (imi->methodUsed == USED) {
710 if (pWhenMarked >= 1) {
711 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
713 /* Mark this method used in the (used) implementing class and its subclasses */
714 printf("rMAY ADD methods that was used by an interface\n");
723 /*-------------------------------------------------------------------------------*/
724 void rtaMarkInterfaceSubs(methodinfo *mi) {
726 if (mi->class->classUsed == NOTUSED) {
727 mi->class->classUsed = USED;
728 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
731 /* add interface class to list kept in Object */
732 mi->methodUsed = USED;
735 subs = mi->class->impldBy;
736 RTAPRINT08invokeInterface1
737 while (subs != NULL) {
738 classinfo * isubs = subs->classType;
739 RTAPRINT09invokeInterface2
740 /* Mark method (mark/used) in classes that implement the method */
741 if (isubs->classUsed != NOTUSED) {
744 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
746 submeth->monoPoly = POLY; /* poly even if nosubs */
747 rtaMarkSubs(isubs, mi);
750 subs = subs->nextClass;
754 /*-------------------------------------------------------------------------------*/
755 /*-------------------------------------------------------------------------------*/
759 /*-------------------------------------------------------------------------------*/
760 void xtaAddUsedInterfaceMethods(classinfo *ci) {
763 /* add used interfaces methods to callgraph */
764 for (jj=0; jj < ci -> interfacescount; jj++) {
765 classinfo *ici = ci -> interfaces [jj];
767 if (pWhenMarked >= 1) {
768 printf("XInterface used: ");fflush(stdout);
769 utf_display(ici->name);
770 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
771 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
772 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
773 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
776 /* add class to interfaces list of classes that implement it */
777 ici -> impldBy = addElement(ici -> impldBy, ci);
779 /* if interface class is used */
780 if (ici -> classUsed != NOTUSED) {
782 /* for each interface method implementation that has already been used */
783 for (mm=0; mm< ici->methodscount; mm++) {
784 methodinfo *imi = &(ici->methods[mm]); /*interface method */
785 printf("==%i==%i\n",ici->methodscount,mm);
786 if (imi->xta == NULL)
788 /*RTAprint*/if (pWhenMarked >= 1) {
789 /*RTAprint*/ if (imi->xta->XTAmethodUsed != USED) {
790 /*RTAprint*/ if (imi->xta->XTAmethodUsed==NOTUSED)
791 printf("Interface Method notused: ");
792 /*RTAprint*/ if (imi->xta->XTAmethodUsed==MARKED)
793 printf("Interface Method marked: ");
794 /*RTAprint*/ utf_display(ici->name);printf(".");
795 /*RTAprint*/ method_display(imi);fflush(stdout);
798 if (imi->xta->XTAmethodUsed == USED) {
799 methSetNode *mCalledBy = NULL;
800 if (pWhenMarked >= 1) {
801 printf("Interface Method used: "); utf_display(ici->name);printf(".");
802 method_display(imi);fflush(stdout);
804 /* Mark this method used in the (used) implementing class &its subclasses */
805 printf("xMAY ADD methods that was used by an interface\n"); fflush(stdout);
807 printf("calledBy set ="); fflush(stdout);
808 printMethodSet(imi->xta->calledBy);
809 if (imi->xta->calledBy != NULL) {
810 /* for each calledBy method */
811 for ( mCalledBy = imi->xta->calledBy->head;
813 mCalledBy = mCalledBy->nextmethRef) {
814 printf("xtaMarkSubs(");
815 utf_display(ci->name); printf("."); fflush(stdout);
817 printf("mCalledBy method class set BEFORE\n"); fflush(stdout);
818 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
819 xtaMarkSubs(ci,imi,mCalledBy->methRef->xta->XTAclassSet->head);
820 printf("mCalledBy method class set AFTER \n"); fflush(stdout);
821 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
830 /*-------------------------------------------------------------------------------*/
832 /*-------------------------------------------------------------------------------*/
833 void xtaMarkInterfaceSubs(methodinfo *mi) {
840 if (mi->class->classUsed != USED) {
841 mi->class->classUsed = USED;
842 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
845 /* add interface class to list kept in Object */
846 printf("Marking Interface Method: "); fflush(stdout);
847 xtaAddCallEdges(mi,POLY);
849 subs = mi->class->impldBy;
850 RTAPRINT08invokeInterface1
851 while (subs != NULL) {
852 classinfo * isubs = subs->classType;
853 RTAPRINT09invokeInterface2
854 /* Mark method (mark/used) in classes that implement the method */
855 if (isubs->classUsed != NOTUSED) {
858 submeth = class_resolvemethod(isubs,mi->name, mi->descriptor);
859 if (submeth != NULL) ///+1
861 classSetNode *subtypesUsedSet = NULL;
862 submeth->monoPoly = POLY; /* poly even if nosubs */
864 mi->xta->XTAmethodUsed = USED;
865 if (rt_method->xta->XTAclassSet != NULL)
867 intersectSubtypesWithSet
868 (subs->classType, rt_method->xta->XTAclassSet->head);
870 /*RTAprint*/ printf(" \nXTA subtypesUsedSet: ");
871 /*RTAprint*/ fflush(stdout);
872 /*RTAprint*/ printSet(subtypesUsedSet);
873 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
876 subs = subs->nextClass;
879 /*-------------------------------------------------------------------------------*/
880 void xxxtaMarkInterfaceSubs(methodinfo *mCalled) {
883 /* for every class that implements the interface of the method called */
884 for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
885 /* add all definitions of this method for this interface */
887 classSetNode *subtypesUsedSet = NULL;
889 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor);
890 if (submeth == NULL) { /* search up the heir - ignore for now!!! */
891 submeth = class_resolvemethod(Si->classType, mCalled->name, mCalled->descriptor);
894 if (rt_method->xta->XTAclassSet != NULL)
895 subtypesUsedSet = intersectSubtypesWithSet(Si->classType, rt_method->xta->XTAclassSet->head);
897 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
898 printSet(subtypesUsedSet);
899 xtaMarkSubs(Si->classType, submeth, subtypesUsedSet);
903 /*-------------------------------------------------------------------------------*/
904 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
908 if (fi->xta->fieldChecked) {
909 if (fi->xta->fldClassType != NULL)
910 return true; /* field has a class type */
914 fi->xta->fieldChecked = true;
916 if (fi->type == TYPE_ADDRESS) {
917 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
919 if (*utf_ptr != 'L') {
920 while (*utf_ptr++ =='[') ;
923 if (*utf_ptr =='L') {
925 if (fi->xta->fldClassType== NULL) {
930 desc = MNEW(char, 256);
931 strcpy(desc,++utf_ptr);
932 cname = strtok(desc,";");
934 printf("STATIC fields type is: %s\n",cname);
937 class = class_get(utf_new_char(cname));
938 fi->xta->fldClassType= class; /* save field's type class ptr */
945 /*-------------------------------------------------------------------------------*/
946 void xtaPassFldPUT(fldSetNode *fN)
948 /* Field type is a class */
950 classSetNode *c1 = NULL;
951 classSetNode *cp = NULL;
952 classSetNode *cprev= NULL;
960 /* Use lastptr so don't check whole XTA class set each time */
963 if (cp->nextClass != NULL)
964 c1 = cp -> nextClass;
967 if (rt_method->xta->XTAclassSet != NULL)
968 c1 = rt_method->xta->XTAclassSet->head;
971 printf("rt XTA class set =");fflush(stdout);
972 printClassSet(rt_method->xta->XTAclassSet);
973 printf("\t\tField class type = ");fflush(stdout);
974 utf_display(fi->xta->fldClassType->name); printf("\n");
978 /*--- PUTSTATIC specific ---*/
979 /* Sx = intersection of type+subtypes(field x) */
980 /* and Sm (where putstatic code is) */
981 for (c=c1; c != NULL; c=c->nextClass) {
982 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
983 vftbl *c_cl_vt = c-> classType->vftbl;
985 printf("\tXTA class = ");fflush(stdout);
986 utf_display(c->classType->name);
987 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
988 if (c->nextClass == NULL) {
989 printf("next=NULL ");fflush(stdout);
992 printf("next="); fflush(stdout);
993 utf_display(c->nextClass->classType->name);
994 printf("\n"); fflush(stdout);
997 printf("\t\tField class type = ");fflush(stdout);
998 utf_display(fi->xta->fldClassType->name);
999 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
1002 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
1003 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
1004 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
1008 fN->lastptrPUT = cprev;
1010 /*-------------------------------------------------------------------------------*/
1011 void xtaPassFldGET(fldSetNode *fN)
1013 /* Field type is a class */
1015 classSetNode *c1 = NULL;
1016 classSetNode *cp = NULL;
1017 classSetNode *cprev= NULL;
1025 /* Use lastptr so don't check whole XTA class set each time */
1026 cp = fN->lastptrGET;
1028 if (cp->nextClass != NULL)
1029 c1 = cp -> nextClass;
1032 if (fi->xta->XTAclassSet != NULL)
1033 c1 = fi->xta->XTAclassSet->head;
1036 printf("fld XTA class set =");fflush(stdout);
1037 printClassSet(fi->xta->XTAclassSet);
1038 printf("\t\tField class type = ");fflush(stdout);
1039 utf_display(fi->xta->fldClassType->name); printf("\n");
1043 /*--- GETSTATIC specific ---*/
1044 /* Sm = union of Sm and Sx */
1045 for (c=c1; c != NULL; c=c->nextClass) {
1046 bool addFlg = false;
1047 if (rt_method->xta->XTAclassSet ==NULL)
1050 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
1054 rt_method->xta->XTAclassSet
1055 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
1060 fN->lastptrGET = cprev;
1064 /*-------------------------------------------------------------------------------*/
1065 void xtaPassAllCalledByParams () {
1066 methSetNode *SmCalled;
1068 if (XTAdebug >= 1) {
1069 printf("xta->calledBy method set: "); fflush(stdout);
1071 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
1072 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
1074 if (rt_method->xta->calledBy == NULL)
1077 s1 = rt_method->xta->calledBy->head;
1078 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1079 if (XTAdebug >= 1) {
1080 printf("SmCalled = "); fflush(stdout);
1081 utf_display(SmCalled->methRef->class->name); fflush(stdout);
1082 printf(".");fflush(stdout); method_display(SmCalled->methRef);
1085 rt_method->xta->chgdSinceLastParse = false;
1086 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
1090 /*-------------------------------------------------------------------------------*/
1091 void xtaAllFldsUsed ( ){
1093 fldSetNode *f1=NULL;
1094 /* bool chgd = false */
1096 if (rt_method->xta->fldsUsed == NULL) return;
1098 /* for each field that this method uses */
1099 f1 = rt_method->xta->fldsUsed->head;
1101 for (f=f1; f != NULL; f = f->nextfldRef) {
1109 /*-------------------------------------------------------------------------------*/
1110 void xtaMethodCalls_and_sendReturnType()
1112 methSetNode *SmCalled; /* for return type */
1113 methSetNode *SmCalls; /* for calls param types */
1114 methSetNode *s1=NULL;
1116 if (XTAdebug >= 1) {
1117 printf("calls method set Return type: ");
1118 printMethodSet(rt_method->xta->calls);
1122 /* for each method that this method calls */
1123 if (rt_method->xta->calls == NULL)
1126 s1 = SmCalls=rt_method->xta->calls->head;
1128 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
1129 /* pass param types */
1131 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
1132 /* if true chgd after its own parse */
1133 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
1134 SmCalls->methRef->xta->chgdSinceLastParse = true;
1138 /* for each calledBy method */
1139 /* send return type */
1140 if (rt_method->xta->calledBy == NULL)
1143 s1 = rt_method->xta->calledBy->head;
1144 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1146 if (XTAdebug >= 1) {
1147 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
1148 printf("."); method_display(SmCalled->methRef);
1151 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
1152 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1153 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
1159 /*-------------------------------------------------------------------------------*/
1160 static void parseRT()
1162 int p; /* java instruction counter */
1163 int nextp; /* start of next java instruction */
1164 int opcode; /* java opcode */
1165 int i; /* temporary for different uses (counters) */
1166 bool iswide = false; /* true if last instruction was a wide */
1170 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1171 printf("XTA parseRT():"); fflush(stdout);
1172 method_display(rt_method);
1173 if (rt_method->xta == NULL)
1174 xtainfoInit (rt_method);
1175 xtaPassAllCalledByParams ();
1176 printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1180 /* scan all java instructions */
1182 for (p = 0; p < rt_jcodelength; p = nextp) {
1183 opcode = rt_code_get_u1 (p); /* fetch op code */
1186 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
1189 /*--------------------------------*/
1190 /* Code just to get the correct next instruction */
1229 /* wider index for loading, storing and incrementing */
1243 /* table jumps ********************************/
1245 case JAVA_LOOKUPSWITCH:
1248 nextp = ALIGN((p + 1), 4);
1249 num = rt_code_get_u4(nextp + 4);
1250 nextp = nextp + 8 + 8 * num;
1255 case JAVA_TABLESWITCH:
1258 nextp = ALIGN ((p + 1),4);
1259 num = rt_code_get_s4(nextp + 4);
1260 num = rt_code_get_s4(nextp + 8) - num;
1261 nextp = nextp + 16 + 4 * num;
1265 /*-------------------------------*/
1266 case JAVA_PUTSTATIC:
1267 i = rt_code_get_u2(p + 1);
1269 constant_FMIref *fr;
1272 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1273 /* descr has type of field ref'd */
1274 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1275 RTAPRINT03putstatic1
1278 /* class with field - marked in addClassinit */
1279 addClassInit(fr->class);
1282 if ((XTAOPTbypass) || (opt_xta))
1284 if (fi->xta == NULL)
1285 fi->xta = xtafldinfoInit(fi);
1286 if (xtaAddFldClassTypeInfo(fi)) {
1287 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1293 case JAVA_GETSTATIC:
1294 i = rt_code_get_u2(p + 1);
1296 constant_FMIref *fr;
1299 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1300 /* descr has type of field ref'd */
1301 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1302 RTAPRINT03putstatic1
1305 /* class with field - marked in addClassinit */
1306 addClassInit(fr->class);
1309 if ((XTAOPTbypass) || (opt_xta) )
1311 if (fi->xta == NULL)
1312 fi->xta = xtafldinfoInit(fi);
1313 if (xtaAddFldClassTypeInfo(fi)) {
1314 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1322 /*-------------------- method invocation ---------------------*/
1324 case JAVA_INVOKESTATIC:
1325 i = rt_code_get_u2(p + 1);
1327 constant_FMIref *mr;
1330 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1331 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1333 RTAPRINT04invokestatic1
1334 if (mi->class->classUsed == NOTUSED) {
1335 mi->class->classUsed = USED;
1336 RTAPRINT05invokestatic2
1338 addClassInit(mi->class);
1344 if ((XTAOPTbypass) || (opt_xta)) {
1345 xtaAddCallEdges(mi,MONO);
1350 case JAVA_INVOKESPECIAL:
1351 i = rt_code_get_u2(p + 1);
1353 constant_FMIref *mr;
1357 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1358 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1360 RTAPRINT06invoke_spec_virt1
1361 /*--- PRIVATE Method -----------------------------------------------------*/
1362 if (mi->name != INIT) { /* if method called is PRIVATE */
1363 RTAPRINT07invoke_spec_virt2
1364 RTAPRINT04invokestatic1
1365 /*-- RTA --*/ /* was just markSubs(mi); */
1371 if ((XTAOPTbypass) || (opt_xta)) {
1372 xtaAddCallEdges(mi,MONO);
1377 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1379 /* new class so add marked methods */
1381 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1382 /*--- process NORMAL <init> method ---------------------------------------------*/
1383 if ( mi->methodUsed != USED) {
1385 - mark class as USED and <init> to callgraph */
1388 ci->classUsed = USED;
1389 addMarkedMethods(ci); /* add to callgraph marked methods */
1390 RTAPRINT06Binvoke_spec_init
1391 rtaAddUsedInterfaceMethods(ci);
1398 if ((XTAOPTbypass) || (opt_xta)) {
1399 if (mi->xta == NULL) {
1400 mi->xta = xtainfoInit(mi);
1402 if ((mi->xta->XTAmethodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1403 ci->classUsed = USED;
1404 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1405 xtaAddUsedInterfaceMethods(ci);
1406 xtaAddCallEdges(mi,MONO);
1407 RTAPRINT06CXTAinvoke_spec_init1
1416 case JAVA_INVOKEVIRTUAL:
1417 i = rt_code_get_u2(p + 1);
1419 constant_FMIref *mr;
1422 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1423 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1426 RTAPRINT07invoke_spec_virt2
1427 mi->monoPoly = POLY;
1429 rtaMarkSubs(mi->class,mi);
1433 if ((XTAOPTbypass) || (opt_xta)) {
1434 classSetNode *subtypesUsedSet = NULL;
1435 if (rt_method->xta->XTAclassSet != NULL)
1437 intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1439 subtypesUsedSet = addElement(subtypesUsedSet, rt_method->class);
1441 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1442 printSet(subtypesUsedSet);
1444 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1449 case JAVA_INVOKEINTERFACE:
1450 i = rt_code_get_u2(p + 1);
1452 constant_FMIref *mr;
1455 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1456 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1458 /*RTAprint*/ if (pWhenMarked >= 1) {
1459 /*RTAprint*/ printf("\t");fflush(stdout);
1460 /*RTAprint*/ utf_display(mr->class->name); printf(".");fflush(stdout);
1461 /*RTAprint*/ method_display(mi); fflush(stdout);
1464 if (mi->flags & ACC_STATIC)
1465 panic ("Static/Nonstatic mismatch calling static method");
1466 RTAPRINT08AinvokeInterface0
1469 rtaMarkInterfaceSubs(mi);
1472 if ((XTAOPTbypass2) || (opt_xta)) {
1473 xtaMarkInterfaceSubs(mi);
1478 /* miscellaneous object operations *******/
1481 i = rt_code_get_u2 (p+1);
1485 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1486 if (pWhenMarked >= 1) {
1487 printf("\tclass=");fflush(stdout);
1488 utf_display(ci->name); fflush(stdout);
1489 printf("=\n");fflush(stdout);
1492 if (ci->classUsed != USED) {
1494 ci->classUsed = USED; /* add to heirarchy */
1495 /* Add this class to the implemented by list of the abstract interface */
1496 rtaAddUsedInterfaceMethods(ci);
1500 if ((XTAOPTbypass) || (opt_xta))
1502 xtaAddUsedInterfaceMethods(ci);
1503 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1517 if (p != rt_jcodelength)
1518 panic("Command-sequence crosses code-boundary");
1520 if ((XTAOPTbypass) || (opt_xta))
1521 xtaMethodCalls_and_sendReturnType();
1526 /*-------------------------------------------------------------------------------*/
1527 /* RTA add Native Methods/ Class functions */
1528 /*-------------------------------------------------------------------------------*/
1529 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1534 class = class_get(c1);
1535 if (class == NULL) {
1536 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1539 if (class->classUsed == NOTUSED) {
1540 class->classUsed = USED; /* MARK CLASS USED */
1541 /* add marked methods to callgraph */
1542 addMarkedMethods(class);
1545 meth = class_findmethod (class, m1, d1);
1547 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1548 printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1551 rtaMarkSubs(class,meth);
1554 /*-------------------------------------------------------------------------------*/
1556 void findMarkNativeUsedClass (utf * c) {
1559 class = class_get(c);
1560 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1561 class->classUsed = USED;
1563 /* add marked methods to callgraph */
1564 addMarkedMethods(class);
1568 /*-------------------------------------------------------------------------------*/
1570 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1574 nativecallcompdone = natcall2utf(nativecallcompdone);
1576 for (i=0; i<NATIVECALLSSIZE; i++) {
1577 if (rt_class == nativeCompCalls[i].classname) {
1579 /* find native class.method invoked */
1580 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1582 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1583 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1587 /* mark methods and classes used by this native class.method */
1588 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1589 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1590 /* mark method used */
1591 findMarkNativeUsedMeth(
1592 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1593 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1594 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1597 printf("\nmark method used: "); fflush(stdout);
1598 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1599 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1600 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1604 /* mark class used */
1605 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1619 /*-------------------------------------------------------------------------------*/
1620 /*-------------------------------------------------------------------------------*/
1621 void mainRTAparseInit (methodinfo *m )
1623 /*printf("MAIN_NOT_STARTED \n");*/
1624 if (class_java_lang_Object->sub != NULL) {
1631 /* Frequently used utf strings */
1632 utf_MAIN = utf_new_char("main");
1633 INIT = utf_new_char("<init>");
1634 CLINIT = utf_new_char("<clinit>");
1635 FINALIZE = utf_new_char("finalize");
1636 EMPTY_DESC= utf_new_char("()V");
1638 /* open file for list of methods parsed before main method or missed and parsed after main */
1639 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1640 printf("CACAO - rtMissed file: cant open file to write\n");
1643 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1645 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1646 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1650 /* Allocate callgraph */
1652 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1654 if ((XTAOPTbypass) || (opt_xta)) {
1655 printf("XTAXTA CALLGRAPHS allocated\n");
1656 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1660 if (m->name == utf_MAIN) {
1661 rtMissed = fopen("rtMissed","a");
1662 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1667 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1668 printf("CACAO - rtMissed file: cant open file to write\n");
1671 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1672 utf_fprint(rtMissed,m->class->name);
1673 fprintf(rtMissed," ");
1674 fprintflags(rtMissed,m->flags);
1675 fprintf(rtMissed," ");
1676 utf_fprint(rtMissed,m->name);
1677 fprintf(rtMissed," ");
1678 utf_fprint(rtMissed,m->descriptor);
1679 fprintf(rtMissed,"\n");
1684 printf("#%i : ",methRT);
1685 printf("Method missed by static analysis Main parse. See rtMissed file");
1686 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1690 /* At moment start RTA before main when parsed */
1691 /* Will definitely use flag with to know if ok to apply in-lining. */
1695 /*-------------------------------------------------------------------------------*/
1696 /*-------------------------------------------------------------------------------*/
1697 /* still need to look at field sets in 2nd pass and clinit ..... */
1698 void XTA_jit_parse2(methodinfo *m)
1700 int methRT; /* local */
1702 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1704 /* for each method in XTA worklist = callgraph (use RTA for now) */
1706 //while (methRT <= methRTlast) {
1707 while (methRT <= methXTAlast) {
1708 rt_method = XTAcallgraph[methRT];
1709 rt_class = rt_method->class;
1710 rt_descriptor = rt_method->descriptor;
1711 rt_jcodelength = rt_method->jcodelength;
1712 rt_jcode = rt_method->jcode;
1714 if (! ( (rt_method->flags & ACC_NATIVE )
1715 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1716 if (XTAdebug >= 1) {
1717 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1718 utf_display(rt_class->name); printf("."); fflush(stdout);
1719 method_display(rt_method);
1721 /* if XTA type set changed since last parse */
1722 if (rt_method->xta->chgdSinceLastParse) {
1724 /* get types from methods it is calledBy */
1725 xtaPassAllCalledByParams ();
1727 /* Pass parameter types to methods it calls and send the return type those called by */
1728 xtaMethodCalls_and_sendReturnType();
1733 if (XTAdebug >= 1) {
1735 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1736 printXTACallgraph ();
1739 RTAPRINT14CallgraphLast /*was >=2 */
1740 RTAPRINT15HeirarchyiLast /*was >= 2 */
1744 /*-------------------------------------------------------------------------------*/
1746 void RT_jit_parse(methodinfo *m)
1749 /*-- RTA -- *******************************************************/
1752 if (m->methodUsed == USED) return;
1753 mainRTAparseInit (m);
1754 m->methodUsed = USED;
1756 /* initialise parameter type descriptor */
1757 callgraph[++methRTlast] = m; /*-- RTA --*/
1758 RTAPRINT11addedtoCallgraph
1759 /* <init> then like a new class so add marked methods to callgraph */
1760 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1763 ci->classUsed = USED;
1764 if (pWhenMarked >= 1) {
1765 printf("Class=");utf_display(ci->name);
1767 /* add marked methods to callgraph */
1768 RTAPRINT11addedtoCallgraph2
1769 addMarkedMethods(ci);
1772 /*---- RTA call graph worklist -----***/
1773 while (methRT <= methRTlast) {
1774 rt_method = callgraph[methRT];
1775 rt_class = rt_method->class;
1776 rt_descriptor = rt_method->descriptor;
1777 rt_jcodelength = rt_method->jcodelength;
1778 rt_jcode = rt_method->jcode;
1780 if (! ( (rt_method->flags & ACC_NATIVE )
1781 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1785 RTAPRINT12bAbstractNative
1786 if (rt_method->flags & ACC_NATIVE ) {
1788 /* mark used and add to callgraph methods and classes used by NATIVE method */
1789 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1791 if (rt_method->flags & ACC_ABSTRACT) {
1792 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1800 if (m->class->classUsed == NOTUSED)
1801 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1803 if (m->name == utf_MAIN) { /*-- MAIN specific -- */
1805 /*RTAprint*/ if (pCallgraph >= 1) {
1806 /*RTAprint*/ printCallgraph ();}
1807 /*RTprint*/ if (pClassHeir >= 1) {
1808 /*RTprint*/ printRThierarchyInfo(m);
1810 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
1812 MFREE(callgraph,methodinfo*,MAXCALLGRAPH);
1816 /*-- XTA -- *******************************************************/
1817 if ((XTAOPTbypass) || (opt_xta)) {
1818 if (m->xta != NULL) {
1819 if (m->xta->XTAmethodUsed == USED) return;
1821 mainRTAparseInit (m);
1823 XTAcallgraph[++methXTAlast] = m;
1824 if (m->xta == NULL) {
1825 m->xta = xtainfoInit(m);
1827 m->xta->XTAmethodUsed = USED;
1828 {methodinfo *mi = m;
1829 printf("<");fflush(stdout);
1834 /*-- Call graph work list loop -----------------*/
1835 /*---- XTA call graph worklist -----***/
1836 useXTAcallgraph = true;
1837 if ((useXTAcallgraph) && (opt_xta)) {
1838 printf("USING XTA call graph>>>>>>>>>><<\n");
1840 while (methXTA <= methXTAlast) {
1841 rt_method = XTAcallgraph[methXTA];
1842 printf("xTA CALLGRAPH #%i:",methXTA); fflush(stdout);
1843 method_display(rt_method);
1844 rt_class = rt_method->class;
1845 rt_descriptor = rt_method->descriptor;
1846 rt_jcodelength = rt_method->jcodelength;
1847 rt_jcode = rt_method->jcode;
1849 if (! ( (rt_method->flags & ACC_NATIVE )
1850 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1854 RTAPRINT12bAbstractNative
1855 if (rt_method->flags & ACC_NATIVE ) {
1857 /* mark used and add to callgraph methods and classes used by NATIVE method */
1858 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1860 if (rt_method->flags & ACC_ABSTRACT) {
1861 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1868 if (m->class->classUsed == NOTUSED)
1869 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1870 printXTACallgraph ();
1872 if (m->name == utf_MAIN) { /*-- MAIN specific -- */
1873 /*RTAprint*/ if (pCallgraph >= 1) {
1874 /*RTAprint*/ printXTACallgraph (); }
1875 /*RTprint*/ if (pClassHeir >= 1) {
1876 /*RTprint*/ printf("Last RTA Info -+-+-");
1877 /*RTprint*/ printRThierarchyInfo(m);
1879 /*RTprint*/ /**printObjectClassHeirarchyAll( );**/
1881 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
1883 printf("XTAXTA CALLGRAPHS -SHOULD BE BUT ISNT- returned \n");
1884 //MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
1888 RTAPRINT14CallgraphLast /* was >=2*/
1889 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
1896 * These are local overrides for various environment variables in Emacs.
1897 * Please do not remove this and leave it at the end of the file, where
1898 * Emacs will automagically detect them.
1899 * ---------------------------------------------------------------------
1902 * indent-tabs-mode: t