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 557 2003-11-02 22:51:59Z twisti $
40 #include "parseRTprint.h"
41 #include "parseRTstats.h"
44 #include "toolbox/loging.h"
45 #include "toolbox/memory.h"
48 /*------------ global variables -----------------------------------------*/
49 #define MAXCALLGRAPH 5000
51 bool XTAOPTbypass = false;
52 bool XTAOPTbypass2 = false; /* for now invokeinterface */
53 bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
59 int methRTmax = MAXCALLGRAPH;
60 methodinfo **callgraph;
61 /*methodinfo *callgraph[MAXCALLGRAPH];*/
65 int methXTAlast = -1;;
66 int methXTAmax=MAXCALLGRAPH;
67 methodinfo **XTAcallgraph;
68 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
70 static bool nativecallcompdone=0 ;
72 static bool firstCall= true;
73 static bool AfterMain = false;
74 static FILE *rtMissed; /* Methods missed during RTA parse of Main */
75 /* so easier to build dynmanic calls file */
77 static utf *utf_MAIN; /* utf_new_char("main"); */
78 static utf *INIT ; /* utf_new_char("<init>"); */
79 static utf *CLINIT ; /* utf_new_char("<clinit>"); */
80 static utf *FINALIZE; /* utf_new_char("finalize"); */
81 static utf *EMPTY_DESC; /* utf_new_char("V()"); */
82 static int missedCnt = 0;
85 /*--------------------------------------------------------------*/
86 /* addToCallgraph - adds to RTA callgraph and */
87 /* sets meth->methodUsed to USED */
88 /*--------------------------------------------------------------*/
89 #define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
90 callgraph[++methRTlast] = meth ; \
91 meth->methodUsed = USED; \
93 {printf("\n Added to Call Graph #%i:", \
95 printf("\t <used flags c/m> <%i/%i> %i\t", \
96 meth->class->classUsed, \
99 printf(" method name ="); \
100 utf_display(meth->class->name);printf("."); \
101 method_display(meth);fflush(stdout);} \
105 /*--------------------------------------------------------------*/
106 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
109 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
110 if (subs->classUsed == USED) {
111 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
116 if (rtaSubUsed(subs, meth))
123 /*--------------------------------------------------------------*/
124 /* Mark the method with same name /descriptor in topmethod */
127 /* Class not marked USED and method defined in this class -> */
128 /* -> if Method NOTUSED mark method as MARKED */
129 /* Class marked USED and method defined in this class -> */
130 /* -> mark method as USED */
132 /* Class USED, but method not defined in this class -> */
133 /* -> search up the heirarchy and mark method where defined */
134 /* if class where method is defined is not USED -> */
135 /* -> mark class with defined method as PARTUSED */
136 /*--------------------------------------------------------------*/
138 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
140 utf *name = topmethod -> name;
141 utf *descriptor = topmethod -> descriptor;
144 submeth = class_resolvemethod(class, name, descriptor);
146 panic("parse RT: Method not found in class hierarchy");
147 if (submeth->methodUsed == USED) return;
149 if (submeth->class == class) {
151 /*--- Method defined in class -----------------------------*/
152 if (submeth->class->classUsed != USED) {
153 if (submeth->methodUsed == NOTUSED) {
155 /* Class NOT marked USED and method defined in this class -> */
156 /* -> if Method NOTUSED mark method as MARKED */
157 if (pWhenMarked >= 1) {
158 printf("MARKED class.method\t");
159 utf_display(submeth->class->name);printf(".");method_display(submeth);
161 if (rtaSubUsed(submeth->class,submeth)) {
162 submeth->class->classUsed = PARTUSED;
163 ADDTOCALLGRAPH(submeth)
166 submeth->methodUsed = MARKED;
171 /* Class IS marked USED and method defined in this class -> */
172 /* -> mark method as USED */
173 ADDTOCALLGRAPH(submeth)
175 } /* end defined in class */
178 /*--- Method NOT defined in class -----------------------------*/
179 if (submeth->class->classUsed == NOTUSED) {
180 submeth->class->classUsed = PARTUSED;
181 if (class->classUsed != USED) {
182 submeth->methodUsed = MARKED;
185 if ( (submeth->class->classUsed == USED)
186 || (class->classUsed == USED)) {
187 ADDTOCALLGRAPH(submeth)
189 } /* end NOT defined in class */
192 /*-------------------------------------------------------------------------------*/
193 /* Mark the method with the same name and descriptor as topmethod */
194 /* and any subclass where the method is defined and/or class is used */
196 /*-------------------------------------------------------------------------------*/
197 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
199 rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
200 if (class->sub != NULL) {
203 if (!(topmethod->flags & ACC_FINAL )) {
204 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
206 rtaMarkSubs(subs, topmethod);
213 /*-------------------------------------------------------------------------------*/
214 /* Add Marked methods for input class ci */
215 /* Add methods with the same name and descriptor as implemented interfaces */
216 /* with the same method name */
218 /*-------------------------------------------------------------------------------*/
219 void addMarkedMethods(classinfo *ci) {
222 /* add marked methods to callgraph */
223 for (ii=0; ii<ci->methodscount; ii++) {
224 methodinfo *mi = &(ci->methods[ii]);
225 if (mi->methodUsed == MARKED) {
226 if (pWhenMarked >= 1) {
227 printf("ADDED a method that was MARKED\n");
233 for (jj=0; jj < ci -> interfacescount; jj++) {
234 classinfo *ici = ci -> interfaces [jj];
235 /* use resolve method....!!!! */
236 if (ici -> classUsed != NOTUSED) {
237 for (mm=0; mm< ici->methodscount; mm++) {
238 methodinfo *imi = &(ici->methods[mm]);
240 if ( (imi->methodUsed == USED)
241 && ( (imi->name == mi->name)
242 && (imi->descriptor == mi->descriptor))) {
243 if (pWhenMarked >= 1)
244 printf("ADDED a method that was used by an interface\n");
253 /*-------------------------------------------------------------------------------*/
255 /*-------------------------------------------------------------------------------*/
257 xtainfo * xtainfoInit (methodinfo *m) {
259 if (m->xta != NULL) return m->xta;
260 m ->xta = (xtainfo *)malloc(sizeof(xtainfo));
261 m ->xta-> XTAmethodUsed = NOTUSED;
262 m ->xta-> XTAclassSet = NULL;
264 m ->xta-> paramClassSet = NULL;
265 m ->xta-> calls = NULL;
266 m ->xta-> calledBy = NULL;
268 m ->xta-> marked = NULL;
269 /*m ->xta-> markedBy = NULL */
270 m ->xta-> fldsUsed = NULL;
271 /*m ->xta-> interfaceCalls = NULL*/
272 m ->xta-> chgdSinceLastParse = false;
276 xtafldinfo * xtafldinfoInit (fieldinfo *f) {
278 if (f->xta != NULL) return f->xta;
280 f ->xta = (xtafldinfo *)malloc(sizeof(xtafldinfo));
281 f -> xta-> fieldChecked = false; /*XTA*/
282 f -> xta-> fldClassType = NULL; /*XTA*/
283 f -> xta-> XTAclassSet = NULL; /*XTA*/
287 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) {
296 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
298 printf("\tIN SmCalled set : ");
299 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
300 printClassSet(SmCalled->xta->XTAclassSet); printf("\n");
302 printf("\tIN SmCalls set: ");
303 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
304 printClassSet(SmCalls->xta->XTAclassSet); printf("\n");
306 printf("\tIN lastptrInto : (");
307 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
308 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
310 else {printf("NULL) ");}
312 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
313 method_display(lastptrInto->methRef); fflush(stdout);
314 printf("\n");fflush(stdout);
317 /* Get SmCalled ParamType set if null */
318 if (SmCalled->xta->paramClassSet == NULL) {
319 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
322 printf("\tParamPassed\n"); fflush(stdout);
323 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
324 printf("\n"); fflush(stdout);
327 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
328 if (SmCalls->xta->XTAclassSet != NULL)
329 c1 = SmCalls->xta->XTAclassSet->head;
334 /* start with type where left off */
335 c1 = lastptrInto->lastptrIntoClassSet2;
336 c1 = c1 -> nextClass; /* even if NULL */
341 printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
344 printf("\tIN SmCalls ... start with :");fflush(stdout);
345 utf_display(c1->classType->name); printf("\n");
349 /* for each Param Class */
350 for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
352 /* for each SmCalls class */
353 for (c=c1; c != NULL; c = c->nextClass) {
354 vftbl *p_cl_vt = p->classType->vftbl;
355 vftbl *c_cl_vt = c->classType->vftbl;
357 /* if SmCalls class is in the Params Class range */
358 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
359 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
361 /* add SmCalls class to SmCalledBy Class set */
362 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType);
368 lastptrInto->lastptrIntoClassSet2 = cprev;
370 printf("\tOUT SmCalled set: ");fflush(stdout);
371 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
373 printf("\tOUT SmCalls set: ");fflush(stdout);
374 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
376 printf("\tOUT lastptrInto="); fflush(stdout);
377 if (lastptrInto->lastptrIntoClassSet2 != NULL)
378 utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
380 printf("<rc=%i>\n",rc);fflush(stdout);
385 /*-------------------------------------------------------------------------------*/
386 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
393 printf("xtaPassReturnType \n");
395 /* Get SmCalled return class is null */
396 if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
397 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled);
400 if (SmCalled->returnclass == NULL) {
402 printf("\tReturn type is NULL\n");
407 printf("\tReturn type is: ");
408 utf_display(SmCalled->returnclass->name);
411 printf("\tIN SmCalls set: ");
412 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
413 printClassSet(SmCalls->xta->XTAclassSet);
415 printf("\tIN SmCalled set: ");
416 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
417 printClassSet(SmCalled->xta->XTAclassSet);
421 if (SmCalled->xta->XTAclassSet == NULL)
424 cs1 = SmCalled->xta->XTAclassSet->head;
425 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
426 classinfo *c = cs->classType;
427 vftbl *r_cl_vt = SmCalled->returnclass->vftbl;
428 vftbl *c_cl_vt = c->vftbl;
430 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
431 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
432 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
433 SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);
439 printf("\tOUT SmCalls set: ");
440 printClassSet(SmCalls->xta->XTAclassSet);
445 /*-------------------------------------------------------------------------------*/
446 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
449 mi->xta = xtainfoInit(mi);
450 if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */
451 XTAcallgraph[++methXTAlast] = mi;
452 mi->xta->XTAmethodUsed = USED;
453 // XTAPRINTcallgraph2
456 printf("\n XTA Added to Call Graph #%i:",
458 printf(" method name ="); fflush(stdout);
459 if (mi == NULL) panic ("Method ptr NULL!!!");
460 if (mi->class == NULL) panic ("Method class ptr NULL!!!");
461 if (mi->class->name == NULL) panic ("Method class name ptr NULL!!!");
462 utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout);
463 method_display(mi);fflush(stdout);
468 printf("AA1 "); fflush(stdout);
469 rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
470 rt_method->xta->calls->tail->monoPoly = monoPoly;
471 mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method);
472 if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!");
473 if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
477 /*--------------------------------------------------------------*/
478 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
481 for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
483 if (inSet(subtypesUsedSet,subs)) {
484 if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
489 if (xtaSubUsed(subs, meth, subtypesUsedSet))
496 /*-------------------------------------------------------------------------------*/
497 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
501 utf *name = topmethod -> name;
502 utf *descriptor = topmethod -> descriptor;
504 printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout);
505 method_display(topmethod);
508 submeth = class_resolvemethod(class, name, descriptor);
511 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
512 method_display(submeth);
517 panic("parse XTA: Method not found in class hierarchy");
518 if (submeth->xta == NULL)
519 submeth->xta = xtainfoInit(submeth);
521 if (rt_method->xta->calls != NULL) {
522 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
525 if (submeth->class == class) {
527 /*--- Method defined in class -----------------------------*/
528 if (inSet(subtypesUsedSet,submeth->class)) {
529 xtaAddCallEdges(submeth,POLY);
532 if (subtypesUsedSet != NULL) {
533 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
534 xtaAddCallEdges(submeth,POLY);
538 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
543 /*--- Method NOT defined in class -----------------------------*/
544 if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */
545 if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */
546 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
547 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/
550 if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */
551 || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */
552 xtaAddCallEdges(submeth,POLY);
555 } /* end defined in class */
558 /*-------------------------------------------------------------------------------*/
559 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
560 /* xtaPRINTmarkSubs1*/
561 xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */
562 if (class->sub != NULL) {
565 if (!(topmethod->flags & ACC_FINAL )) {
566 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
567 /* xtaPRINTmarkSubs1 */
568 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
575 /*-------------------------------------------------------------------------------*/
576 /*-------------------------------------------------------------------------------*/
578 int addClassInit(classinfo *ci) {
579 /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
582 utf* utf_java_lang_system = utf_new_char("java/lang/System");
583 utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass");
584 utf* utf_java_lang_Object = utf_new_char("java/lang/Object");
586 int m, m1=-1, m2=-1, mf=-1;
589 for (m=0; m < ci->methodscount; m++) {
590 /*<clnit> class init method */
591 if (ci->methods[m].name == CLINIT) {
594 /* Special case: System class has an extra initializer method */
595 if ((utf_java_lang_system == ci->name)
596 && (utf_initializeSystemClass == ci->methods[m].name)) {
600 /* Finalize methods */
601 if ((ci->methods[m].name == FINALIZE)
602 && (ci->name != utf_java_lang_Object)) {
608 if (m1 >= 0) { /* No <clinit> available - ignore */
610 /* Get clinit methodinfo ptr */
611 mi = class_findmethod (ci,ci->methods[m1].name , NULL);
614 if ( mi->methodUsed != USED) {
615 mi->class->classUsed = PARTUSED;
620 if ((XTAOPTbypass) || (opt_xta)) {
621 xtaAddCallEdges(mi,MONO);
628 /* Get finalize methodinfo ptr */
629 mi = class_findmethod (ci,ci->methods[mf].name , NULL);
632 if ( mi->methodUsed != USED) {
633 mi->class->classUsed = PARTUSED;
638 if ((XTAOPTbypass) || (opt_xta)) {
639 xtaAddCallEdges(mi,MONO);
643 /*Special Case for System class init:
644 add java/lang/initializeSystemClass to callgraph */
646 /* Get clinit methodinfo ptr */
647 mi = class_findmethod (ci,ci->methods[m2].name , NULL);
650 if ( mi->methodUsed != USED) {
651 mi->class->classUsed = PARTUSED;
656 if ((XTAOPTbypass) || (opt_xta)) {
657 xtaAddCallEdges(mi,MONO);
661 /* add marked methods to callgraph */
662 addMarkedMethods(ci);
668 #define rt_code_get_u1(p) rt_jcode[p]
669 #define rt_code_get_s1(p) ((s1)rt_jcode[p])
670 #define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
671 #define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
672 #define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
673 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
674 #define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
675 +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
679 /*-------------------------------------------------------------------------------*/
680 /*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
683 /* add used interfaces methods to callgraph */
684 for (jj=0; jj < ci -> interfacescount; jj++) {
685 classinfo *ici = ci -> interfaces [jj];
687 if (pWhenMarked >= 1) {
688 printf("BInterface used: ");fflush(stdout);
689 utf_display(ici->name);
690 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
691 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
692 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
693 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
696 /* add class to interfaces list of classes that implement it */
697 ici -> impldBy = addElement(ici -> impldBy, ci);
699 /* if interface class is used */
700 if (ici -> classUsed != NOTUSED) {
702 /* for each interface method implementation that has already been used */
703 for (mm=0; mm< ici->methodscount; mm++) {
704 methodinfo *imi = &(ici->methods[mm]);
705 if (pWhenMarked >= 1) {
706 if (imi->methodUsed != USED) {
707 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
708 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
709 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
712 if (imi->methodUsed == USED) {
713 if (pWhenMarked >= 1) {
714 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
716 /* Mark this method used in the (used) implementing class and its subclasses */
717 printf("MAY ADD methods that was used by an interface\n");
726 /*-------------------------------------------------------------------------------*/
727 /*-------------------------------------------------------------------------------*/
730 /*-------------------------------------------------------------------------------*/
731 void xtaMarkInterfaceSubs(methodinfo *mCalled) {
734 /* for every class that implements the interface of the method called */
735 for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
736 /* add all definitions of this method for this interface */
739 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor);
740 if (submeth == NULL) ; /* search up the heir - ignore for now!!! */
742 classSetNode *subtypesUsedSet = NULL;
744 if (rt_method->xta->XTAclassSet != NULL)
745 subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->xta->XTAclassSet->head);
747 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
748 printSet(subtypesUsedSet);
749 xtaMarkSubs(submeth->class, submeth, subtypesUsedSet);
754 /*-------------------------------------------------------------------------------*/
755 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
759 if (fi->xta->fieldChecked) {
760 if (fi->xta->fldClassType != NULL)
761 return true; /* field has a class type */
765 fi->xta->fieldChecked = true;
767 if (fi->type == TYPE_ADDRESS) {
768 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
770 if (*utf_ptr != 'L') {
771 while (*utf_ptr++ =='[') ;
774 if (*utf_ptr =='L') {
776 if (fi->xta->fldClassType== NULL) {
781 desc = MNEW(char, 256);
782 strcpy(desc,++utf_ptr);
783 cname = strtok(desc,";");
785 printf("STATIC field's type is: %s\n",cname);
788 class = class_get(utf_new_char(cname));
789 fi->xta->fldClassType= class; /* save field's type class ptr */
796 /*-------------------------------------------------------------------------------*/
797 void xtaPassFldPUT(fldSetNode *fN)
799 /* Field type is a class */
801 classSetNode *c1 = NULL;
802 classSetNode *cp = NULL;
803 classSetNode *cprev= NULL;
811 /* Use lastptr so don't check whole XTA class set each time */
814 if (cp->nextClass != NULL)
815 c1 = cp -> nextClass;
818 if (rt_method->xta->XTAclassSet != NULL)
819 c1 = rt_method->xta->XTAclassSet->head;
822 printf("rt XTA class set =");fflush(stdout);
823 printClassSet(rt_method->xta->XTAclassSet);
824 printf("\t\tField class type = ");fflush(stdout);
825 utf_display(fi->xta->fldClassType->name); printf("\n");
829 /*--- PUTSTATIC specific ---*/
830 /* Sx = intersection of type+subtypes(field x) */
831 /* and Sm (where putstatic code is) */
832 for (c=c1; c != NULL; c=c->nextClass) {
833 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
834 vftbl *c_cl_vt = c-> classType->vftbl;
836 printf("\tXTA class = ");fflush(stdout);
837 utf_display(c->classType->name);
838 printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
839 if (c->nextClass == NULL) {
840 printf("next=NULL ");fflush(stdout);
843 printf("next="); fflush(stdout);
844 utf_display(c->nextClass->classType->name);
845 printf("\n"); fflush(stdout);
848 printf("\t\tField class type = ");fflush(stdout);
849 utf_display(fi->xta->fldClassType->name);
850 printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
853 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
854 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
855 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
859 fN->lastptrPUT = cprev;
861 /*-------------------------------------------------------------------------------*/
862 void xtaPassFldGET(fldSetNode *fN)
864 /* Field type is a class */
866 classSetNode *c1 = NULL;
867 classSetNode *cp = NULL;
868 classSetNode *cprev= NULL;
876 /* Use lastptr so don't check whole XTA class set each time */
879 if (cp->nextClass != NULL)
880 c1 = cp -> nextClass;
883 if (fi->xta->XTAclassSet != NULL)
884 c1 = fi->xta->XTAclassSet->head;
887 printf("fld XTA class set =");fflush(stdout);
888 printClassSet(fi->xta->XTAclassSet);
889 printf("\t\tField class type = ");fflush(stdout);
890 utf_display(fi->xta->fldClassType->name); printf("\n");
894 /*--- GETSTATIC specific ---*/
895 /* Sm = union of Sm and Sx */
896 for (c=c1; c != NULL; c=c->nextClass) {
898 if (rt_method->xta->XTAclassSet ==NULL)
901 if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) ))
905 rt_method->xta->XTAclassSet
906 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
911 fN->lastptrGET = cprev;
915 /*-------------------------------------------------------------------------------*/
916 void xtaPassAllCalledByParams () {
917 methSetNode *SmCalled;
920 printf("xta->calledBy method set: "); fflush(stdout);
921 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
923 if (rt_method->xta->calledBy == NULL)
926 s1 = rt_method->xta->calledBy->head;
927 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
929 printf("SmCalled = "); fflush(stdout);
930 utf_display(SmCalled->methRef->class->name); fflush(stdout);
931 printf(".");fflush(stdout); method_display(SmCalled->methRef);
934 rt_method->xta->chgdSinceLastParse = false;
935 xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
939 /*-------------------------------------------------------------------------------*/
940 void xtaAllFldsUsed ( ){
943 /* bool chgd = false */
945 if (rt_method->xta->fldsUsed == NULL) return;
947 /* for each field that this method uses */
948 f1 = rt_method->xta->fldsUsed->head;
950 for (f=f1; f != NULL; f = f->nextfldRef) {
958 /*-------------------------------------------------------------------------------*/
959 void xtaMethodCalls_and_sendReturnType()
961 methSetNode *SmCalled; /* for return type */
962 methSetNode *SmCalls; /* for calls param types */
963 methSetNode *s1=NULL;
966 printf("calls method set Return type: ");
967 printMethodSet(rt_method->xta->calls);
968 printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->xta->calls)\n");fflush(stdout);
972 /* for each method that this method calls */
973 if (rt_method->xta->calls == NULL)
976 s1 = SmCalls=rt_method->xta->calls->head;
978 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
979 /* pass param types */
981 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);
982 /* if true chgd after its own parse */
983 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
984 SmCalls->methRef->xta->chgdSinceLastParse = true;
988 /* for each calledBy method */
989 /* send return type */
990 if (rt_method->xta->calledBy == NULL)
993 s1 = rt_method->xta->calledBy->head;
994 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
997 printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
998 printf("."); method_display(SmCalled->methRef);
1001 chgd = xtaPassReturnType(rt_method, SmCalled->methRef);
1002 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1003 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
1009 /*-------------------------------------------------------------------------------*/
1010 static void parseRT()
1012 int p; /* java instruction counter */
1013 int nextp; /* start of next java instruction */
1014 int opcode; /* java opcode */
1015 int i; /* temporary for different uses (counters) */
1016 bool iswide = false; /* true if last instruction was a wide */
1020 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1022 xtaPassAllCalledByParams ();
1025 /* scan all java instructions */
1027 for (p = 0; p < rt_jcodelength; p = nextp) {
1028 opcode = rt_code_get_u1 (p); /* fetch op code */
1031 nextp = p + jcommandsize[opcode]; /* compute next instruction start */
1034 /*--------------------------------*/
1035 /* Code just to get the correct next instruction */
1074 /* wider index for loading, storing and incrementing */
1088 /* table jumps ********************************/
1090 case JAVA_LOOKUPSWITCH:
1093 nextp = ALIGN((p + 1), 4);
1094 num = rt_code_get_u4(nextp + 4);
1095 nextp = nextp + 8 + 8 * num;
1100 case JAVA_TABLESWITCH:
1103 nextp = ALIGN ((p + 1),4);
1104 num = rt_code_get_s4(nextp + 4);
1105 num = rt_code_get_s4(nextp + 8) - num;
1106 nextp = nextp + 16 + 4 * num;
1110 /*-------------------------------*/
1111 case JAVA_PUTSTATIC:
1112 i = rt_code_get_u2(p + 1);
1114 constant_FMIref *fr;
1117 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1118 /* descr has type of field ref'd */
1119 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1120 RTAPRINT03putstatic1
1123 /* class with field - marked in addClassinit */
1124 addClassInit(fr->class);
1127 if ((XTAOPTbypass) || (opt_xta))
1129 if (fi->xta == NULL)
1130 fi->xta = xtafldinfoInit(fi);
1131 if (xtaAddFldClassTypeInfo(fi)) {
1132 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1138 case JAVA_GETSTATIC:
1139 i = rt_code_get_u2(p + 1);
1141 constant_FMIref *fr;
1144 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1145 /* descr has type of field ref'd */
1146 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1147 RTAPRINT03putstatic1
1150 /* class with field - marked in addClassinit */
1151 addClassInit(fr->class);
1154 if ((XTAOPTbypass) || (opt_xta) )
1156 if (fi->xta == NULL)
1157 fi->xta = xtafldinfoInit(fi);
1158 if (xtaAddFldClassTypeInfo(fi)) {
1159 rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1167 /*-------------------- method invocation ---------------------*/
1169 case JAVA_INVOKESTATIC:
1170 i = rt_code_get_u2(p + 1);
1172 constant_FMIref *mr;
1175 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1176 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1178 RTAPRINT04invokestatic1
1179 if (mi->class->classUsed == NOTUSED) {
1180 mi->class->classUsed = USED;
1181 RTAPRINT05invokestatic2
1183 addClassInit(mi->class);
1188 if ((XTAOPTbypass) || (opt_xta)) {
1189 xtaAddCallEdges(mi,MONO);
1194 case JAVA_INVOKESPECIAL:
1195 i = rt_code_get_u2(p + 1);
1197 constant_FMIref *mr;
1201 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1202 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1204 RTAPRINT06invoke_spec_virt1
1205 /*--- PRIVATE Method -----------------------------------------------------*/
1206 if (mi->name != INIT) { /* if method called is PRIVATE */
1207 RTAPRINT07invoke_spec_virt2
1208 RTAPRINT04invokestatic1
1209 /*-- RTA --*/ /* was just markSubs(mi); */
1213 if ((XTAOPTbypass) || (opt_xta)) {
1214 xtaAddCallEdges(mi,MONO);
1219 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1221 /* new class so add marked methods */
1222 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1223 /*--- process NORMAL <init> method ---------------------------------------------*/
1224 if ( mi->methodUsed != USED) {
1226 - mark class as USED and <init> to callgraph */
1229 ci->classUsed = USED;
1230 addMarkedMethods(ci); /* add to callgraph marked methods */
1231 RTAPRINT06Binvoke_spec_init
1232 addUsedInterfaceMethods(ci);
1236 if ((XTAOPTbypass) || (opt_xta)) {
1237 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci );
1238 xtaAddCallEdges(mi,MONO);
1239 RTAPRINT06CXTAinvoke_spec_init1
1249 case JAVA_INVOKEVIRTUAL:
1250 i = rt_code_get_u2(p + 1);
1252 constant_FMIref *mr;
1255 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1256 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1259 RTAPRINT07invoke_spec_virt2
1260 mi->monoPoly = POLY;
1261 rtaMarkSubs(mi->class,mi);
1264 if ((XTAOPTbypass) || (opt_xta)) {
1265 classSetNode *subtypesUsedSet = NULL;
1266 if (rt_method->xta->XTAclassSet != NULL)
1267 subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1269 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1270 printSet(subtypesUsedSet);
1272 xtaMarkSubs(mi->class, mi, subtypesUsedSet);
1277 case JAVA_INVOKEINTERFACE:
1278 i = rt_code_get_u2(p + 1);
1280 constant_FMIref *mr;
1284 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1285 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1287 if (mi->flags & ACC_STATIC)
1288 panic ("Static/Nonstatic mismatch calling static method");
1291 RTAPRINT08AinvokeInterface0
1292 if (mi->class->classUsed == NOTUSED) {
1293 mi->class->classUsed = USED; /*??PARTUSED;*/
1294 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1297 /* add interface class to list kept in Object */
1298 mi->methodUsed = USED;
1299 mi->monoPoly = POLY;
1301 subs = mi->class->impldBy;
1302 RTAPRINT08invokeInterface1
1303 while (subs != NULL) {
1304 classinfo * isubs = subs->classType;
1305 RTAPRINT09invokeInterface2
1306 /* Mark method (mark/used) in classes that implement the method */
1307 if (isubs->classUsed != NOTUSED) {
1308 methodinfo *submeth;
1310 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
1311 if (submeth != NULL)
1312 submeth->monoPoly = POLY; /* poly even if nosubs */
1313 rtaMarkSubs(isubs, mi);
1315 subs = subs->nextClass;
1319 if ((XTAOPTbypass2) || (opt_xta))
1321 xtaMarkInterfaceSubs(mi);
1326 /* miscellaneous object operations *******/
1329 i = rt_code_get_u2 (p+1);
1333 ci = class_getconstant (rt_class, i, CONSTANT_Class);
1334 if (pWhenMarked >= 1) {
1335 printf("\tclass=");fflush(stdout);
1336 utf_display(ci->name); fflush(stdout);
1337 printf("=\n");fflush(stdout);
1340 if (ci->classUsed != USED) {
1342 ci->classUsed = USED; /* add to heirarchy */
1343 /* Add this class to the implemented by list of the abstract interface */
1344 addUsedInterfaceMethods(ci);
1348 if ((XTAOPTbypass) || (opt_xta))
1350 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1364 if (p != rt_jcodelength)
1365 panic("Command-sequence crosses code-boundary");
1367 if ((XTAOPTbypass) || (opt_xta))
1368 xtaMethodCalls_and_sendReturnType();
1373 /*-------------------------------------------------------------------------------*/
1374 /* RTA add Native Methods/ Class functions */
1375 /*-------------------------------------------------------------------------------*/
1376 void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1381 class = class_get(c1);
1382 if (class == NULL) {
1383 return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1386 if (class->classUsed == NOTUSED) {
1387 class->classUsed = USED; /* MARK CLASS USED */
1388 /* add marked methods to callgraph */
1389 addMarkedMethods(class);
1392 meth = class_findmethod (class, m1, d1);
1394 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1395 printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
1398 rtaMarkSubs(class,meth);
1401 /*-------------------------------------------------------------------------------*/
1403 void findMarkNativeUsedClass (utf * c) {
1406 class = class_get(c);
1407 if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!");
1408 class->classUsed = USED;
1410 /* add marked methods to callgraph */
1411 addMarkedMethods(class);
1415 /*-------------------------------------------------------------------------------*/
1417 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1421 nativecallcompdone = natcall2utf(nativecallcompdone);
1423 for (i=0; i<NATIVECALLSSIZE; i++) {
1424 if (rt_class == nativeCompCalls[i].classname) {
1426 /* find native class.method invoked */
1427 for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1429 if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
1430 && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1434 /* mark methods and classes used by this native class.method */
1435 for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1436 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1437 /* mark method used */
1438 findMarkNativeUsedMeth(
1439 nativeCompCalls[i].methods[j].methodCalls[k].classname,
1440 nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1441 nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
1444 printf("\nmark method used: "); fflush(stdout);
1445 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1446 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1447 utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1451 /* mark class used */
1452 findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1466 /*-------------------------------------------------------------------------------*/
1467 /*-------------------------------------------------------------------------------*/
1468 void mainRTAparseInit (methodinfo *m )
1470 /*printf("MAIN_NOT_STARTED \n");*/
1471 if (class_java_lang_Object->sub != NULL) {
1478 utf_MAIN = utf_new_char("main");
1479 INIT = utf_new_char("<init>");
1480 CLINIT = utf_new_char("<clinit>");
1481 FINALIZE = utf_new_char("finalize");
1482 EMPTY_DESC= utf_new_char("()V");
1484 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1485 printf("CACAO - rtMissed file: can't open file to write\n");
1488 fprintf(rtMissed,"To Help User create a dymLoad file \n");
1490 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1491 fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1495 callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/
1496 if ((XTAOPTbypass) || (opt_xta)) {
1497 printf("XTAXTA CALLGRAPHS allocated\n");
1498 XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1502 if (m->name == utf_MAIN) {
1503 rtMissed = fopen("rtMissed","a");
1504 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1509 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1510 printf("CACAO - rtMissed file: can't open file to write\n");
1513 fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1514 utf_fprint(rtMissed,m->class->name);
1515 fprintf(rtMissed," ");
1516 fprintflags(rtMissed,m->flags);
1517 fprintf(rtMissed," ");
1518 utf_fprint(rtMissed,m->name);
1519 fprintf(rtMissed," ");
1520 utf_fprint(rtMissed,m->descriptor);
1521 fprintf(rtMissed,"\n");
1526 printf("#%i : ",methRT);
1527 printf("Method missed by static analysis Main parse. See rtMissed file");
1528 /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1532 /* At moment start RTA before main when parsed */
1533 /* Will definitely use flag with to know if ok to apply in-lining. */
1537 /*-------------------------------------------------------------------------------*/
1538 /*-------------------------------------------------------------------------------*/
1539 /* still need to look at field sets in 2nd pass and clinit ..... */
1540 void XTA_jit_parse2(methodinfo *m)
1543 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1545 /* for each method in XTA worklist = callgraph (use RTA for now) */
1547 while (methRT <= methRTlast) {
1548 rt_method = callgraph[methRT];
1549 rt_class = rt_method->class;
1550 rt_descriptor = rt_method->descriptor;
1551 rt_jcodelength = rt_method->jcodelength;
1552 rt_jcode = rt_method->jcode;
1554 if (! ( (rt_method->flags & ACC_NATIVE )
1555 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1556 if (XTAdebug >= 1) {
1557 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1558 utf_display(rt_class->name); printf("."); fflush(stdout);
1559 method_display(rt_method);
1561 /* if XTA type set changed since last parse */
1562 if (rt_method->xta->chgdSinceLastParse) {
1564 /* get types from methods it is calledBy */
1565 xtaPassAllCalledByParams ();
1567 /* Pass parameter types to methods it calls and send the return type those called by */
1568 xtaMethodCalls_and_sendReturnType();
1573 if (XTAdebug >= 1) {
1575 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1576 printXTACallgraph ();
1579 RTAPRINT14CallgraphLast /*was >=2 */
1580 RTAPRINT15HeirarchyiLast /*was >= 2 */
1584 /*-------------------------------------------------------------------------------*/
1586 void RT_jit_parse(methodinfo *m)
1589 if (m->methodUsed == USED) return;
1590 mainRTAparseInit (m);
1592 /* initialise parameter type descriptor */
1593 callgraph[++methRTlast] = m; /*-- RTA --*/
1594 m->methodUsed = USED;
1595 RTAPRINT11addedtoCallgraph
1596 /* <init> then like a new class so add marked methods to callgraph */
1597 if (m->name == INIT) { /* need for <init>s parsed efore Main */
1600 ci->classUsed = USED;
1601 if (pWhenMarked >= 1) {
1602 printf("Class=");utf_display(ci->name);
1604 /* add marked methods to callgraph */
1605 RTAPRINT11addedtoCallgraph2
1606 addMarkedMethods(ci);
1610 if ((XTAOPTbypass) || (opt_xta)) {
1611 XTAcallgraph[++methXTAlast] = m;
1612 if (m->xta == NULL) {
1613 m->xta = xtainfoInit(m);
1615 m->xta->XTAmethodUsed = USED;
1616 {methodinfo *mi = m;
1621 /*-- Call graph work list loop -----------------*/
1623 while (methRT <= methRTlast) {
1624 rt_method = callgraph[methRT];
1625 rt_class = rt_method->class;
1626 rt_descriptor = rt_method->descriptor;
1627 rt_jcodelength = rt_method->jcodelength;
1628 rt_jcode = rt_method->jcode;
1630 if (! ( (rt_method->flags & ACC_NATIVE )
1631 || (rt_method->flags & ACC_ABSTRACT) ) ) {
1635 RTAPRINT12bAbstractNative
1636 if (rt_method->flags & ACC_NATIVE ) {
1638 /* mark used and add to callgraph methods and classes used by NATIVE method */
1639 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
1641 if (rt_method->flags & ACC_ABSTRACT) {
1642 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
1651 if (m->class->classUsed == NOTUSED)
1652 m->class->classUsed = USED; /* say Main's class has a method used ??*/
1653 printXTACallgraph ();
1654 RTAPRINT14CallgraphLast /* was >=2*/
1655 //RTAPRINT15HeirarchyiLast /*was >= 2 */
1657 if ((XTAOPTbypass) || (opt_xta)) {
1658 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
1661 /**** DO NOT free if RTA or XTA for now
1662 if (m->name == utf_MAIN) {
1663 MFREE(callgraph,methodinfo*,MAXCALLGRAPH);
1664 if ((XTAOPTbypass) || (opt_xta)) {
1665 printf("XTAXTA CALLGRAPHS returned \n");
1666 MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
1676 * These are local overrides for various environment variables in Emacs.
1677 * Please do not remove this and leave it at the end of the file, where
1678 * Emacs will automagically detect them.
1679 * ---------------------------------------------------------------------
1682 * indent-tabs-mode: t