2 If V() then why add call edges since no type info passed?
3 does nothing happen when the method with V() is XTA parsed? class info is standalone then
5 Check initialization... need at least a dummy called by ...
7 ... why no error now????
9 What about recursion??? x.a calls x.a
11 Now wondering if there is a memory corruption because XTA seems to finish ok
14 /* jit/parseXTA.c - parser and print functions for Rapid Type Analyis
16 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
17 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
18 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
19 Institut f. Computersprachen - TU Wien
21 This file is part of CACAO.
23 This program is free software; you can redistribute it and/or
24 modify it under the terms of the GNU General Public License as
25 published by the Free Software Foundation; either version 2, or (at
26 your option) any later version.
28 This program is distributed in the hope that it will be useful, but
29 WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31 General Public License for more details.
33 You should have received a copy of the GNU General Public License
34 along with this program; if not, write to the Free Software
35 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
38 Contact: cacao@complang.tuwien.ac.at
40 Authors: Carolyn Oates
42 $Id: parseXTA.c 2186 2005-04-02 00:43:25Z edwin $
46 /*--------------------------------------
53 general initialization
56 + hand coded calls for system
57 2nd interation (want to try it in inlining)
62 ----------------------------------*/
65 XTA Type Static Analysis of Java program
66 used -xta option is turned on either explicitly
67 or automatically with inlining of virtuals.
69 XTA is called for reachable methods and keeps sets for each Method and Field used as follows:
70 1. Work list of reachable methods is initialized to main + JVM called methods
72 2. For virtual method call from M of e.m then
73 a. Add all static lookup of m in the cone of e = ce.mi to reachable worklist
74 JAVA_INVOKESTATIC/ JAVA_INVOKESPECIAL - xtaAddCallEdges
75 JAVA_INVOKEVIRTUAL - xtaMarkSubs
77 b. Add mi's parameters class + subtypes that are used by M to mi used classes
78 When XTA parsed follow the calls list (beg. parseXTA)
79 c. Add mi's return type + subtypes used by mi to M's used classes
80 When XTA parsed follow the calledBy list (end parseXTA)
81 d. Add ce of mi to mi's used classes
82 static/special - addXTAcalledges
83 virtual - xtaMarkSubs if subclass used -> xtaAddCallEdges
84 if subclass not used -> add ce.mi to markedby temp set
86 3. new C (new, <init>, & similiar) then add C to M's used classes
87 JAVA_NEW, INVOKE_SPECIAL <init>, JAVA_CHECKCAST / JAVA_INSTANCEOF - classinit
88 4. read Field X.f: add X to M's used classes
90 5. write Field X.f: add X+subtypes that are used by M to X's classes
96 Methods called by NATIVE methods and classes loaded dynamically
97 cannot be found by parsing. The following files supply missing methods:
99 xtaMissedIn0 - (provided) has the methods missed by every java program
100 xtaMissed||mainClassName - is program specific.
102 A file xtaMissed will be written by XTA analysis of any methods missed.
104 This file can be renamed to xtaMissed concatenated with the main class name.
109 inlining with virtuals should fail if the returned xtaMissed is not empty.
111 mv xtaMissed xtaMissedhello
114 Results: (currently) with -stat see # methods marked used
122 #include "cacao/cacao.h"
123 #include "mm/memory.h"
124 #include "toolbox/list.h"
125 #include "vm/class.h"
126 #include "vm/linker.h"
127 #include "vm/loader.h"
128 #include "vm/options.h"
129 #include "vm/statistics.h"
130 #include "vm/tables.h"
131 #include "vm/jit/jit.h"
132 #include "vm/jit/parse.h"
133 #include "vm/jit/inline/parseXTA.h"
134 #include "vm/jit/inline/parseRTstats.h"
135 #include "vm/jit/inline/parseRTprint.h"
139 static bool firstCall= true;
140 static list *xtaWorkList;
141 FILE *xtaMissed; /* Methods missed during XTA parse of Main */
143 bool XTA_DEBUGinf = false;
144 bool XTA_DEBUGr = false;
145 bool XTA_DEBUGopcodes = false;
147 char * clsFlgs [] = {"NOTUSED", "PARTUSED", "USED"};
148 char * methFlgs [] = {"NOTUSED", "MARKED", "USED"};
150 /*********************************************************************/
151 /*********************************************************************/
153 /* function descriptor2typesL ***************************************************
155 decodes a already checked method descriptor. The parameter count, the
156 return type and the argument types are stored in the passed methodinfo.
157 gets and saves classptr for object ref.s
159 *******************************************************************************/
161 static classSetNode *descriptor2typesL(methodinfo *m)
168 classinfo** classtypes;
171 classSetNode *p=NULL;
172 if (debugInfo >= 1) {
173 printf("In descriptor2typesL >>>\t"); fflush(stdout);
174 utf_display(m->class->name); printf(".");
175 method_display(m);fflush(stdout);
179 desc = MNEW (char, 256);
180 types = DMNEW (u1, m->descriptor->blength);
181 classtypes = MNEW (classinfo*, m->descriptor->blength+1);
182 m->returnclass = NULL;
184 if (!(m->flags & ACC_STATIC)) {
186 if (debugInfo >= 1) {
187 printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
189 classtypes[pcount] = m->class;
190 p = addClassCone(p, m->class);
194 utf_ptr = m->descriptor->text + 1;
195 strcpy (desc,utf_ptr);
197 while ((c = *desc++) != ')') {
204 case 'Z': *tptr++ = TYPE_INT;
206 case 'J': *tptr++ = TYPE_LNG;
208 case 'F': *tptr++ = TYPE_FLT;
210 case 'D': *tptr++ = TYPE_DBL;
212 case 'L': *tptr++ = TYPE_ADR;
213 /* get class string */
214 class = strtok(desc,";");
215 desc = strtok(NULL,"\0");
216 /* get/save classinfo ptr */
217 classtypes[pcount-1] = class_get(utf_new_char(class));
218 p = addClassCone(p, class_get(utf_new_char(class)));
219 if (debugInfo >= 1) {
220 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
221 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
222 utf_display(classtypes[pcount-1]->name);
225 case '[': *tptr++ = TYPE_ADR;
228 /* get class string */
230 class = strtok(desc,";");
231 desc = strtok(NULL,"\0");
232 /* get/save classinfo ptr */
233 classtypes[pcount-1] = class_get(utf_new_char(class));
234 p= addClassCone(p, class_get(utf_new_char(class)));
235 if (debugInfo >= 1) {
236 printf("[Param#%i 's class type is: %s\n",pcount-1,class);
237 printf("[classtypes[%i]=",pcount-1);fflush(stdout);
238 utf_display(classtypes[pcount-1]->name);
243 classtypes[pcount-1] = NULL;
246 panic("Ill formed methodtype-descriptor");
250 /* compute return type */
256 case 'Z': m->returntype = TYPE_INT;
258 case 'J': m->returntype = TYPE_LNG;
260 case 'F': m->returntype = TYPE_FLT;
262 case 'D': m->returntype = TYPE_DBL;
265 m->returntype = TYPE_ADR;
275 m->returntype = TYPE_ADR;
277 /* get class string */
278 class = strtok(desc,";");
279 m->returnclass = class_get(utf_new_char(class));
280 if (m->returnclass == NULL) {
281 printf("class=<%s>\t",class); fflush(stdout);
282 panic ("return class not found");
285 case 'V': m->returntype = TYPE_VOID;
288 default: panic("Ill formed methodtype-descriptor-ReturnType");
291 m->paramcount = pcount;
292 m->paramtypes = types;
293 m->paramclass = classtypes;
297 for (i=0; i< m->paramcount; i++) {
298 if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
299 printf("Param #%i is:\t",i);
300 utf_display(m->paramclass[i]->name);
305 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
306 printf("\tReturn Type is:\t"); fflush(stdout);
307 utf_display(m->returnclass->name);
311 printf("params2types: START results in a set \n");
312 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
321 /*-------------------------------------------------------------------------------*/
323 xtafldinfo * xtafldinfoInit (fieldinfo *f)
328 f->xta = NEW(xtafldinfo);
330 f->xta->fieldChecked = false;
331 f->xta->fldClassType = NULL;
332 f->xta->XTAclassSet = NULL;
337 /*-------------------------------------------------------------------------------*/
339 xtainfo *xtainfoInit(methodinfo *m)
342 return m->xta; /* already initialized */
344 #if defined(STATISTICS)
345 count_methods_marked_used++;
348 m ->xta = (xtainfo *) NEW(xtainfo);
349 m ->xta-> XTAmethodUsed = NOTUSED;
351 /* xta sets for a method */
352 m->xta->fldsUsed = NULL;
353 m ->xta-> XTAclassSet = NULL;
354 /* Methods's have access to the class they are a part of */
355 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
356 /* cone set of methods parameters */
357 /* what if no param?? is it NULL then, too? */
358 /****** class not loaded so take param info from superclass ??? */
359 m->xta->paramClassSet = descriptor2typesL(m);
362 m->xta->calls = NULL;
363 m->xta->calledBy = NULL;
364 m ->xta->markedBy = NULL;
366 m->xta->chgdSinceLastParse = false;
369 /* thought needed at some earlier point */
370 /*m ->xta->interfaceCalls = NULL*/
373 /*-------------------------------------------------------------------------------*/
374 void xtaAddCallEdges(methodinfo *mCalls, methodinfo *mCalled, s4 monoPoly, char *info) {
378 if (mCalled->flags & ACC_ABSTRACT) return;
379 /* First call to this method initializations */
381 printf("mCalled->methodUsed =%i != %i = USED is ",mCalled->methodUsed, USED); fflush(stdout);
382 printf(" <%i> T%i/%iF\n",(mCalled->methodUsed!= USED), true,false); fflush(stdout);
385 if (mCalled->methodUsed != USED) {
387 printf("\n>>>>>>%s:\n",info); fflush(stdout);
388 printf("Add to Worklist mCalls_=");fflush(stdout);
390 printf("<"); fflush(stdout);
392 printf("> "); fflush(stdout);
396 printf("NULL\n");fflush(stdout);
399 printf("mCalled=");fflush(stdout);
401 printf("<"); fflush(stdout);
403 printf("> "); fflush(stdout);
406 {printf("NULL\n");fflush(stdout);}
408 mCalled->xta = xtainfoInit(mCalled);
409 mCalled ->methodUsed = USED; /* used to see if method in the work list of methods */
411 xta->method = mCalled ;
412 list_addlast(xtaWorkList,xta);
415 if ((mCalls == NULL) && (!(monoPoly == SYSCALL)) ) {} /* panic when init file correct is */
417 if ((mCalls == mCalled) /* recursion doesn't change class set nor field set so ignore */
418 || (mCalls == NULL)) {return; }
421 /*** printf(" AddCallEdges\n"); fflush(stdout); ***/
423 mCalls->xta = xtainfoInit(mCalls);
424 mCalls->xta->calls = add2MethSet(mCalls->xta->calls, mCalled);
425 /* mono if static, private, final else virtual so poly */
426 mCalls->xta->calls->tail->monoPoly = monoPoly;
428 mCalled->xta->calledBy = add2MethSet(mCalled->xta->calledBy, mCalls);
430 /* IS THIS REALLY NEEDED???? */
431 if (mCalled->xta->calledBy == NULL) panic("mCalled->xta->calledBy is NULL!!!");
432 if (mCalls->xta->calls == NULL) panic("mCalls->xta->calls is NULL!!!");
437 /*-------------------------------------------------------------------------------*/
438 bool xtaPassParams (methodinfo *Called, methodinfo *Calls, methSetNode *lastptrInto)
446 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
447 if (Calls->xta->XTAclassSet != NULL)
448 c1 = Calls->xta->XTAclassSet->head;
449 /*else already c1 = NULL; */
452 /* start with type where left off */
453 c1 = lastptrInto->lastptrIntoClassSet2;
454 c1 = c1 -> nextClass; /* even if NULL */
456 if (c1 == NULL) return false;
459 /* for each Param Class */
460 for ( p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
462 /* for each SmCalls class */
463 for (c=c1; c != NULL; c = c->nextClass) {
467 LAZYLOADING(c->classType) /* if not loaded is it really needed ??? */
469 p_cl_vt = p->classType->vftbl;
470 c_cl_vt = c->classType->vftbl;
472 /* if SmCalls class is in the Params Class range */
473 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
474 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
476 /* add Calls class to CalledBy Class set */
477 Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
483 lastptrInto->lastptrIntoClassSet2 = cprev;
488 /*-------------------------------------------------------------------------------*/
489 void xtaPassAllCalledByParams (methodinfo *m) {
490 methSetNode *SmCalled;
491 if (m->xta->calledBy == NULL)
493 for (SmCalled = m->xta->calledBy->head;
495 SmCalled = SmCalled->nextmethRef) {
496 m->xta->chgdSinceLastParse = false; /* re'init flag */
497 xtaPassParams(m, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
502 /*-------------------------------------------------------------------------------*/
503 void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
505 /* Field type is a class */
507 classSetNode *c1 = NULL;
508 classSetNode *cp = NULL;
509 classSetNode *cprev= NULL;
518 /* Use lastptr so don't check whole XTA class set each time */
521 if (cp->nextClass != NULL)
522 c1 = cp -> nextClass;
525 if (m->xta->XTAclassSet != NULL)
526 c1 = m->xta->XTAclassSet->head;
529 /*--- PUTSTATIC specific ---*/
530 /* Sx = intersection of type+subtypes(field x) */
531 /* and Sm (where putstatic code is) */
532 for (c=c1; c != NULL; c=c->nextClass) {
536 LAZYLOADING1(fi->xta->fldClassType)
538 f_cl_vt = fi->xta->fldClassType->vftbl;
539 c_cl_vt = c-> classType->vftbl;
540 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
541 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
542 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
546 fN->lastptrPUT = cprev;
548 /*-------------------------------------------------------------------------------*/
549 void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
551 /* Field type is a class */
553 classSetNode *c1 = NULL;
554 classSetNode *cp = NULL;
555 classSetNode *cprev= NULL;
563 /* Use lastptr so don't check whole XTA class set each time */
566 if (cp->nextClass != NULL)
567 c1 = cp -> nextClass;
570 if (fi->xta->XTAclassSet != NULL)
571 c1 = fi->xta->XTAclassSet->head;
574 /*--- GETSTATIC specific ---*/
575 /* Sm = union of Sm and Sx */
576 for (c=c1; c != NULL; c=c->nextClass) {
578 if (m->xta->XTAclassSet ==NULL)
581 if (!(inSet (m->xta->XTAclassSet->head, c->classType) ))
586 = add2ClassSet(m->xta->XTAclassSet,c->classType);
591 fN->lastptrGET = cprev;
595 /*-------------------------------------------------------------------------------*/
596 void xtaAllFldsUsed (methodinfo *m) {
599 /* bool chgd = false */
601 if (m->xta->fldsUsed == NULL) return;
603 /* for each field that this method uses */
604 f1 = m->xta->fldsUsed->head;
606 for (f=f1; f != NULL; f = f->nextfldRef) {
615 /*-------------------------------------------------------------------------------*/
616 bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
622 /* Get Called return class is null */
623 if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
624 Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */
627 if (Called->returnclass == NULL) {
631 if (Called->xta->XTAclassSet == NULL)
634 cs1 = Called->xta->XTAclassSet->head;
636 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
637 classinfo *c = cs->classType;
641 LAZYLOADING(Called->returnclass)
642 r_cl_vt = Called->returnclass->vftbl;
645 /* if class is a subtype of the return type, then add to Calls class set (ie.interscection)*/
646 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
647 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
648 Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);
657 /*-------------------------------------------------------------------------------*/
658 void xtaMethodCalls_and_sendReturnType(methodinfo *m)
660 methSetNode *SmCalled; /* for return type */
661 methSetNode *SmCalls; /* for calls param types */
662 methSetNode *s1=NULL;
667 if (m->xta == NULL) panic("m->xta null for return type\n");
668 /* for each method that this method calls */
669 if (m->xta->calls == NULL)
672 s1 = SmCalls=m->xta->calls->head;
674 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
675 /* pass param types */
677 chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
678 /* if true chgd after its own parse */
679 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
680 SmCalls->methRef->xta->chgdSinceLastParse = true;
684 /* for each calledBy method */
685 /* send return type */
686 if (m->xta->calledBy == NULL)
689 s1 = m->xta->calledBy->head;
690 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
692 chgd = xtaPassReturnType(m, SmCalled->methRef);
693 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
694 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
700 /*-------------------------------------------------------------------------------*/
701 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
703 bool is_classtype = false; /* return value */
705 if (fi->xta->fieldChecked) {
706 if (fi->xta->fldClassType != NULL)
707 return true; /* field has a class type */
711 fi->xta->fieldChecked = true;
713 if (fi->type == TYPE_ADDRESS) {
714 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
716 if (*utf_ptr != 'L') {
717 while (*utf_ptr++ =='[') ;
720 if (*utf_ptr =='L') {
722 if (fi->xta->fldClassType== NULL) {
727 desc = MNEW(char, 256);
728 strcpy(desc,++utf_ptr);
729 cname = strtok(desc,";");
730 class = class_get(utf_new_char(cname));
731 fi->xta->fldClassType= class; /* save field's type class ptr */
738 /*--------------------------------------------------------------*/
739 /* Mark the method with same name /descriptor in topmethod */
742 /* Class marked USED and method defined in this class -> */
743 /* -> add call edges = USED */
744 /* Class not marked USED and method defined in this class -> */
745 /* -> if Method NOTUSED mark method as MARKED */
747 /* Class USED, but method not defined in this class -> */
748 /* -> 1) search up the heirarchy and mark method where defined */
749 /* 2) if class where method is defined is not USED -> */
750 /* -> ????mark class with defined method as PARTUSED */
751 /*--------------------------------------------------------------*/
754 void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
756 utf *name = topmethod->name;
757 utf *descriptor = topmethod->descriptor;
760 /* See if method defined in class heirarchy */
761 submeth = class_resolvemethod(class, name, descriptor);
762 METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
763 if (submeth == NULL) {
764 utf_display(class->name); printf(".");
765 METHINFOx(topmethod);
766 printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
767 panic("parse XTA: Method not found in class hierarchy");
770 /* if submeth called previously from this method then return */
771 if (mCalls->xta->calls != NULL) {
772 if (inMethSet(mCalls->xta->calls->head,submeth)) return;
777 XTAaddClassInit(submeth, submeth->class,
778 CLINITS_T,FINALIZE_T,ADDMARKED_T);
779 if (inSet(subtypesUsedSet,submeth->class)) {
780 submeth->monoPoly = POLY;
781 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
782 "00addTo XTA VIRT CONE:");
787 if (submeth->class == class) {
789 /*--- Method defined in class -----------------------------*/
790 if (inSet(subtypesUsedSet,submeth->class)) {
791 /* method defined in this class -> */
792 /* Class IS marked USED */
793 /* -> mark method as USED */
794 submeth->monoPoly = POLY;
795 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
796 "01addTo VIRT CONE 1:");
799 /* method defined in this class -> */
800 /* Class IS NOT marked USED (PART or NOTUSED) */
801 /* -> if Method NOTUSED mark method as MARKED */
803 "\tmarked VIRT CONE 2:",XTA_DEBUGr);
804 submeth->monoPoly = POLY;
805 if (submeth->xta == NULL) {
806 submeth->xta = xtainfoInit(submeth);
808 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
809 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
810 /* Note: if class NOTUSED and subclass is used handled */
811 /* by subsequent calls to xtaMarkMethods for cone */
813 } /* end defined in class */
816 /*--- Method NOT defined in class - defined up the heirarchy ---------------*/
817 /* then check class the method could be called with */
819 /* first mark classes if needed */
820 if (!(inSet(subtypesUsedSet,submeth->class))) {
821 submeth->class->classUsed = PARTUSED;
822 if (!(inSet(subtypesUsedSet,class))) {
823 submeth->monoPoly = POLY;
824 if (submeth->xta == NULL)
825 submeth->xta = xtainfoInit(submeth);
826 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
827 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
828 METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
831 /* add method to xta work list if conditions met */
832 if (inSet(subtypesUsedSet,class)) {
833 submeth->monoPoly = POLY;
834 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
835 "02addTo VIRT CONE 3:");
837 } /* end NOT defined in class */
841 /*----------------------------------------------------------------------*/
842 /* Mark the method with the same name and descriptor as topmethod */
843 /* and any subclass where the method is defined and/or class is used */
845 /*----------------------------------------------------------------------*/
847 void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
848 /* xtaPRINTmarkSubs1*/
849 xtaMarkMethod(class, mCalls, topmethod, subtypesUsedSet); /* Mark method in class where it was found */
850 if (class->sub != NULL) {
853 if (!(topmethod->flags & ACC_FINAL )) {
854 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
855 xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
862 /**************************************************************************/
863 /* Add Marked methods for input class ci */
864 /* Add methods with the same name and descriptor as implemented interfaces*/
865 /* with the same method name */
866 /* ??? interface part not XTA checked */
867 /*------------------------------------------------------------------------*/
868 void xtaAddMarkedMethods(methodinfo *mCalls, classinfo *ci) {
871 /* add marked methods to callgraph */
872 for (ii=0; ii<ci->methodscount; ii++) {
873 methodinfo *mi = &(ci->methods[ii]);
875 if (mi->xta != NULL) {
876 if (mi->xta->markedBy != NULL) {
878 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
879 methodinfo *mCalls = mcnode->methRef;
880 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
881 "03addToInit was Marked added:");
885 else { /* NOT XTA checked yet */
886 for (jj=0; jj < ci -> interfacescount; jj++) {
887 classinfo *ici = ci -> interfaces [jj].cls;
888 /* use resolve method....!!!! */
889 if (ici -> classUsed != NOTUSED) {
890 for (mm=0; mm< ici->methodscount; mm++) {
891 methodinfo *imi = &(ici->methods[mm]);
892 METHINFOt(imi,"NEW IMPD INTERFACE:",XTA_DEBUGinf)
893 /*if interface method=method is used*/
894 if ( (imi->methodUsed == USED)
895 && ( (imi->name == mi->name)
896 && (imi->descriptor == mi->descriptor))) {
897 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
898 "04addTo was interfaced used/MARKED:");
909 /*------------------------------------------------------------------------*/
910 void xtaAddUsedInterfaceMethods(methodinfo *m, classinfo *ci) {
913 /* add used interfaces methods to callgraph */
914 for (jj=0; jj < ci -> interfacescount; jj++) {
915 classinfo *ici = ci -> interfaces [jj].cls;
918 printf("BInterface used: ");fflush(stdout);
919 utf_display(ici->name);
920 printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); fflush(stdout);
922 /* add class to interfaces list of classes that implement it */
923 ici -> impldBy = addElement(ici -> impldBy, ci);
925 /* if interface class is used */
926 if (ici -> classUsed != NOTUSED) {
928 /* for each interface method implementation that has already been used */
929 for (mm=0; mm< ici->methodscount; mm++) {
930 methodinfo *imi = &(ici->methods[mm]);
931 if ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
932 printf("Interface Method %s: ", methFlgs[imi->methodUsed]);
933 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
935 if (imi->methodUsed == USED) {
937 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
938 /* Mark this method used in the (used) implementing class &its subclasses */
939 printf("rMAY ADD methods that was used by an interface\n");
941 if ((utf_clinit != imi->name) &&
942 (utf_init != imi->name))
944 classSetNode *subtypesUsedSet = NULL;
945 if (m->xta->XTAclassSet != NULL) {
947 intersectSubtypesWithSet
948 (imi->class, m->xta->XTAclassSet->head);
950 else /* can any methods be added if 1 set is NULL ??? */
951 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
952 xtaMarkSubs(m, ci, imi, subtypesUsedSet);
953 imi->monoPoly = POLY;
957 } /* end for method */
958 } /* end != NOTUSED */
959 } /* end for interface */
964 /*----------------------------------------------------------------------*/
966 #define CLINITS_T true
967 #define FINALIZE_T true
968 #define ADDMARKED_T true
970 #define CLINITS_F false
971 #define FINALIZE_F false
972 #define ADDMARKED_F false
973 /*-----------------------*/
975 void XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
980 ci->classUsed = USED;
982 if (clinits) { /* No <clinit> available - ignore */
983 mi = class_findmethod(ci, utf_clinit, utf_void__void);
985 if (ci->classUsed != USED)
986 ci->classUsed = PARTUSED;
988 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
989 "05addTo CLINIT added:");
993 /*Special Case for System class init:
994 add java/lang/initializeSystemClass to callgraph */
995 if (ci->name == utf_new_char("initializeSystemClass")) {
996 /* ?? what is name of method ?? */
1000 mi = class_findmethod(ci, utf_finalize, utf_void__void);
1002 if (ci->classUsed != USED)
1003 ci->classUsed = PARTUSED;
1004 mi->monoPoly = MONO;
1005 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1006 "06addTo FINALIZE added:");
1011 xtaAddMarkedMethods(mCalls, ci);
1014 /* always so know have access to the interface methods */
1015 xtaAddUsedInterfaceMethods(mCalls,ci);
1019 /*-------------------------------------------------------------------------------*/
1021 /*********************************************************************/
1022 /*********************************************************************/
1024 /*-------------------------------------------------------------------*/
1026 void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {
1028 if (mi->class->classUsed == NOTUSED) {
1029 mi->class->classUsed = USED;
1030 /* add interface class to list kept in Object */
1031 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1034 mi->methodUsed = USED;
1035 mi->monoPoly = POLY;
1037 /*XTAPRINT08invokeInterface1*/
1039 subs = mi->class->impldBy;
1040 METHINFO(mi,XTA_DEBUGinf)
1041 printf("Implemented By classes :\n");fflush(stdout);
1042 if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
1044 for (subs = mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
1045 methodinfo *submeth;
1047 printf("\t");utf_display(subs->classType->name);fflush(stdout);
1048 printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
1051 /*Mark method (mark/used) in classes that implement method*/
1052 submeth = class_findmethod(subs->classType, mi->name, mi->descriptor);
1053 if (submeth != NULL) {
1054 classSetNode *subtypesUsedSet = NULL;
1055 submeth->monoPoly = POLY; /* poly even if nosubs */
1056 submeth->xta = xtainfoInit(submeth);
1058 submeth->xta->XTAmethodUsed = USED;
1059 if (m->xta->XTAclassSet != NULL) {
1060 subtypesUsedSet = /* interface classes cone */
1061 intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
1063 else { /* can any methods be added if 1 set is NULL ??? */
1064 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1066 xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
1074 /*********************************************************************/
1076 int parseXTA(methodinfo *m)
1078 int p; /* java instruction counter */
1079 int nextp; /* start of next java instruction */
1080 int opcode; /* java opcode */
1081 int i; /* temp for different uses (counters)*/
1082 bool iswide = false; /* true if last instruction was a wide*/
1085 if (m->methodXTAparsed) return 0;
1086 else m->methodXTAparsed = true;
1088 /***XTA_DEBUGopcodes=false;***/
1089 /***printf("\n-----------------------------------\n"); **/
1090 METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes);
1091 if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
1092 /***XTA_DEBUGopcodes=false;***/
1093 if (m->xta == NULL) {
1097 xtaPassAllCalledByParams (m);
1100 /* scan all java instructions */
1101 for (p = 0; p < m->jcodelength; p = nextp) {
1103 opcode = code_get_u1(p,m); /* fetch op code */
1104 SHOWOPCODE(XTA_DEBUGopcodes)
1106 nextp = p + jcommandsize[opcode]; /* compute next instr start */
1107 if (nextp > m->jcodelength)
1108 panic("Unexpected end of bytecode");
1140 /* wider index for loading, storing and incrementing */
1154 case JAVA_LOOKUPSWITCH:
1157 nextp = ALIGN((p + 1), 4) + 4;
1158 num = code_get_u4(nextp,m);
1159 nextp += (code_get_u4(nextp,m)) * 8 + 4;
1164 case JAVA_TABLESWITCH:
1167 nextp = ALIGN ((p + 1),4);
1168 num = code_get_s4(nextp + 4, m);
1169 num = code_get_s4(nextp + 8, m) - num;
1170 nextp = nextp + 16 + 4 * num;
1173 /*********************/
1175 case JAVA_PUTSTATIC: /* write */
1177 i = code_get_u2(p + 1,m);
1179 constant_FMIref *fr;
1182 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1183 LAZYLOADING(fr->class)
1185 fi = class_resolvefield(fr->class,
1192 return 0; /* was NULL */
1194 printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1195 utf_display(fi->name);printf("\n");fflush(stdout);
1197 fi->xta = xtafldinfoInit(fi);
1198 XTAaddClassInit(m, fi->class,
1199 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1200 if (xtaAddFldClassTypeInfo(fi)) {
1201 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
1207 case JAVA_GETSTATIC: /* read */
1209 i = code_get_u2(p + 1,m);
1211 constant_FMIref *fr;
1214 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1215 LAZYLOADING(fr->class)
1217 fi = class_resolvefield(fr->class,
1224 return 0; /* was NULL */
1227 printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1228 utf_display(fi->name);printf("\n");fflush(stdout);
1230 fi->xta = xtafldinfoInit(fi);
1231 XTAaddClassInit(m, fi->class,
1232 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1233 if (xtaAddFldClassTypeInfo(fi)) {
1234 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
1242 case JAVA_INVOKESTATIC:
1243 case JAVA_INVOKESPECIAL:
1244 i = code_get_u2(p + 1,m);
1246 constant_FMIref *mr;
1249 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1250 LAZYLOADING(mr->class)
1251 mi = class_resolveclassmethod( mr->class,
1259 METHINFOt(mi,"INVOKESTAT/SPEC:: ",XTA_DEBUGopcodes)
1260 mi->monoPoly = MONO;
1262 /*---- Handle "leaf" = static, private, final calls-------------*/
1263 if ((opcode == JAVA_INVOKESTATIC)
1264 || (mi->flags & ACC_STATIC)
1265 || (mi->flags & ACC_PRIVATE)
1266 || (mi->flags & ACC_FINAL) )
1268 if (mi->class->classUsed != USED) { /* = NOTUSED or PARTUSED */
1269 XTAaddClassInit(m, mi->class,
1270 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1271 /* Leaf methods are used whether class is or not */
1272 /* so mark class as PARTlyUSED */
1273 mi->class->classUsed = PARTUSED;
1275 /* Add to XTA working list/set of reachable methods */
1276 if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
1277 /* calls , called */
1278 xtaAddCallEdges(m, mi, MONO,
1279 "07addTo INVOKESTATIC ");
1281 xtaAddCallEdges(m, mi, MONO,
1282 "08addTo INVOKESPECIAL ");
1283 } /* end STATIC, PRIVATE, FINAL */
1286 /*---- Handle special <init> calls ---------------------------------------------*/
1288 if (mi->class->classUsed != USED) {
1289 /* XTA special case:
1290 call of super's <init> then
1291 methods of super class not all used */
1293 /*--- <init> ()V is equivalent to "new"
1294 indicating a class is used = instaniated ---- */
1295 if (utf_init==mi->name) {
1296 if ((m->class->super.cls == mi->class)
1297 && (m->descriptor == utf_void__void) )
1299 METHINFOt(mi,"SUPER INIT:",XTA_DEBUGopcodes);
1300 /* super init so class may be only used because of its sub-class */
1301 XTAaddClassInit(m,mi->class,
1302 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1303 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
1306 /* since <init> indicates classes is used, then add marked methods, too */
1307 METHINFOt(mi,"NORMAL INIT:",XTA_DEBUGopcodes);
1308 XTAaddClassInit(m, mi->class,
1309 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1311 xtaAddCallEdges(m, mi, MONO,
1313 } /* end just for <init> ()V */
1315 /* <clinit> for class inits do not add marked methods;
1316 class not yet instaniated */
1317 if (utf_clinit==mi->name)
1318 XTAaddClassInit(m, mi->class,
1319 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1321 if (!((utf_init==mi->name))
1322 || (utf_clinit==mi->name)) {
1323 METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
1324 if (mi->class->classUsed !=USED)
1325 mi->class->classUsed = PARTUSED;
1326 xtaAddCallEdges(m, mi, MONO,
1327 "10addTo SPEC notINIT ");
1330 } /* end init'd class not used = class init process was needed */
1332 /* add method to XTA list = set of reachable methods */
1333 xtaAddCallEdges(m, mi, MONO,
1334 "11addTo SPEC whymissed ");
1337 /*** assume if method can't be resolved won't actually be called or
1338 there is a real error in classpath and in normal parse an exception
1339 will be thrown. Following debug print can verify this
1341 CLASSNAME1(mr->class,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
1342 utf_display(mr->name); printf(" "); fflush(stdout);
1343 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1348 case JAVA_INVOKEVIRTUAL:
1349 i = code_get_u2(p + 1,m);
1351 constant_FMIref *mr;
1354 mr = m->class->cpinfos[i];
1355 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
1356 LAZYLOADING(mr->class)
1357 mi = class_resolveclassmethod(mr->class,
1366 METHINFOt(mi,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
1367 if ((mi->flags & ACC_STATIC)
1368 || (mi->flags & ACC_PRIVATE)
1369 || (mi->flags & ACC_FINAL) )
1370 { /*** DOES THIS EVER OCCUR ??? */
1371 if (mi->class->classUsed == NOTUSED){
1372 XTAaddClassInit(m, mi->class,
1373 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1375 mi->monoPoly = MONO;
1376 xtaAddCallEdges(m, mi, MONO,
1377 "12addTo INVOKEVIRTUAL ");
1379 else { /* normal virtual */
1380 /* get the set of used subtypes if none at least the current methods class */
1381 classSetNode *subtypesUsedSet = NULL;
1382 if (m->xta->XTAclassSet != NULL) {
1384 intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
1386 else { /* can any methods be added if 1 set is NULL ??? */
1387 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1389 mi->monoPoly = POLY;
1390 xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
1394 CLASSNAME1(mr->class,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
1395 utf_display(mr->name); printf(" "); fflush(stdout);
1396 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1401 case JAVA_INVOKEINTERFACE:
1402 i = code_get_u2(p + 1,m);
1404 constant_FMIref *mr;
1407 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1408 LAZYLOADING(mr->class)
1410 mi = class_resolveinterfacemethod(mr->class,
1417 METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
1418 xtaMarkInterfaceSubs(m,mi);
1420 /* see INVOKESTATIC for explanation about */
1421 /* case when Interface is not resolved */
1422 /*method_descriptor2types(mi);
1423 ?? do need paramcnt? for XTA (or just XTA)*/
1428 /* means class is at least passed as a parameter */
1429 /* class is really instantiated when class.<init> called*/
1430 i = code_get_u2(p + 1,m);
1433 cls = class_getconstant(m->class, i, CONSTANT_Class);
1434 /*** s_count++; look for s_counts for VTA */
1435 /* add marked methods */
1436 CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
1437 XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T);
1438 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1442 case JAVA_CHECKCAST:
1443 case JAVA_INSTANCEOF:
1445 i = code_get_u2(p + 1,m);
1449 class_getconstant(m->class, i, CONSTANT_Class);
1451 CLASSNAMEop(cls,XTA_DEBUGr);
1452 if (cls->classUsed == NOTUSED){
1453 XTAaddClassInit(m, cls,
1454 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1455 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1466 xtaMethodCalls_and_sendReturnType(m);
1471 /* Helper fn for initialize **********************************************/
1473 int XTAgetline(char *line, int max, FILE *inFP) {
1474 if (fgets(line, max, inFP) == NULL)
1477 return strlen((const char *) line);
1480 /* Initialize XTA Work list ***********************************************/
1482 /*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
1483 #define SYSADD(cls,meth,desc, is_mono_poly, txt) \
1484 c = class_new(utf_new_char(cls)); \
1486 callmeth = class_resolveclassmethod(c, \
1487 utf_new_char(meth), \
1488 utf_new_char(desc), \
1491 if (callmeth->class->classUsed != USED) { \
1492 c->classUsed = PARTUSED; \
1493 XTAaddClassInit(callmeth, callmeth->class, \
1494 CLINITS_T,FINALIZE_T,ADDMARKED_T);\
1496 callmeth->monoPoly = is_mono_poly; \
1497 xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt);
1499 /*-- ----------------------------------------------------------------------------
1500 Initialize XTA work list with methods/classes from:
1503 xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
1504 -------------------------------------------------------------------------------*/
1505 methodinfo *initializeXTAworklist(methodinfo *m) {
1507 methodinfo* callmeth;
1508 char systxt[] = "2S addTo System Call :";
1509 char missedtxt[] = "2M addTo xtaMissedIn Call :";
1511 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1513 char* class, *meth, *desc;
1514 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1517 /* Create XTA call work list */
1518 xtaWorkList = NEW(list);
1519 list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
1521 /* Add first method to call list */
1522 m->class->classUsed = USED;
1523 xtaAddCallEdges(NULL, m, SYSCALL, systxt);
1525 /* Add system called methods */
1526 /*** SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
1527 SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
1529 /*** SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
1530 SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
1531 /*----- xtaMissedIn 0 */
1532 if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
1533 /*if (opt_verbose) */
1534 {printf("No xtaMissedIn0 file\n");fflush(stdout);}
1537 while (XTAgetline(line,256,xtaMissedIn)) {
1538 class = strtok(line, " \n");
1539 meth = strtok(NULL, " \n");
1540 desc = strtok(NULL, " \n");
1541 SYSADD(class,meth,desc, POLY, missedtxt)
1542 /* ??? Need to hand / hard code who calls it ??? */
1544 fclose(xtaMissedIn);
1553 /*- end initializeXTAworklist-------- */
1556 /*-------------------------------------------------------------------------------*/
1557 methodinfo *missedXTAworklist()
1559 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1560 char filenameIn[256] = "xtaIn/";
1562 char* class, *meth, *desc;
1564 char* calls_class, *calls_meth, *calls_desc;
1566 char missedtxt[] = "xtaIn/ missed Call :";
1568 methodinfo* callmeth;
1570 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1573 #if defined(USE_THREADS)
1574 SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
1575 SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
1577 /*----- xtaMissedIn pgm specific */
1578 strcat(filenameIn, (const char *)mainstring);
1579 if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
1580 /*if (opt_verbose)*/
1581 {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);}
1584 while (XTAgetline(line,256,xtaMissedIn)) {
1586 calls_class = strtok(line, " \n");
1587 calls_meth = strtok(NULL, " \n");
1588 calls_desc = strtok(NULL, " \n");
1590 class = strtok(NULL, " \n");
1592 class = strtok(line, " \n");
1593 meth = strtok(NULL, " \n");
1594 desc = strtok(NULL, " \n");
1597 if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL)
1598 || (class == NULL) || (meth == NULL) || (desc == NULL))
1600 if ( (class == NULL) || (meth == NULL) || (desc == NULL))
1602 "Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc \n");
1603 SYSADD(class,meth,desc, POLY, missedtxt)
1605 fclose(xtaMissedIn);
1612 /*--------------------------------------------------------*/
1613 /* parseXTAmethod */
1614 /* input: method to be XTA static parsed */
1615 /*--------------------------------------------------------*/
1616 void parseXTAmethod(methodinfo *xta_method) {
1617 if (! ( (xta_method->flags & ACC_NATIVE )
1618 || (xta_method->flags & ACC_ABSTRACT) ) )
1620 /* XTA parse to approxmate....
1621 what classes/methods will really be used during execution */
1622 parseXTA(xta_method);
1625 if (xta_method->flags & ACC_NATIVE )
1627 METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
1628 /* parseXTApseudo(xta_method); */
1631 printf("Abstract method in XTA Work List: ");
1632 METHINFOx(xta_method);
1633 panic("Abstract method in XTA Work List.");
1638 void XTAprintCallgraph (list *xtaWorkList, char * txt);
1640 /*-- XTA -- *******************************************************/
1641 int XTA_jit_parse(methodinfo *m)
1644 methodinfo *mainmeth;
1646 /* Should only be called once */
1649 /*----- XTA initializations --------*/
1651 log_text("XTA static analysis started.\n");
1653 mainmeth = initializeXTAworklist(m);
1654 /** XTAprintCallgraph (xtaWorkList, "after init1"); **/
1655 firstCall = false; /* turn flag off */
1657 if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
1658 printf("CACAO - xtaMissed file: cant open file to write\n");
1660 /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
1662 /*------ process XTA call work list --------*/
1663 for (xta =list_first(xtaWorkList);
1665 xta =list_next(xtaWorkList,xta))
1667 parseXTAmethod(xta->method);
1668 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
1670 missedXTAworklist();
1671 /** XTAprintCallgraph (xtaWorkList, "after missed"); **/
1672 for (xta =list_first(xtaWorkList);
1674 xta =list_next(xtaWorkList,xta))
1676 parseXTAmethod(xta->method);
1677 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
1683 printf("printXTAhierarchyInfo(m); not yet there\n");
1685 XTAprintCallgraph (xtaWorkList, "After all XTA parses");
1689 log_text("XTA static analysis done.\n");
1695 /*--------------------------------------------------------------*/
1696 void XTAprintCallgraph (list *xtaWorkList, char * txt)
1700 methodinfo *xta_meth;
1702 printf("\n%s\n",txt);
1703 #if defined(STATISTICS)
1704 printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
1707 for (xta =list_first(xtaWorkList);
1709 xta =list_next(xtaWorkList,xta))
1711 xta_meth = xta->method;
1713 printf(" (%i): ",i++);
1714 method_display_w_class(xta_meth);
1723 * These are local overrides for various environment variables in Emacs.
1724 * Please do not remove this and leave it at the end of the file, where
1725 * Emacs will automagically detect them.
1726 * ---------------------------------------------------------------------
1729 * indent-tabs-mode: t