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 /* src/vm/jit/inline/parseXTA.c - parser and print functions for
17 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
18 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
19 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
20 Institut f. Computersprachen - TU Wien
22 This file is part of CACAO.
24 This program is free software; you can redistribute it and/or
25 modify it under the terms of the GNU General Public License as
26 published by the Free Software Foundation; either version 2, or (at
27 your option) any later version.
29 This program is distributed in the hope that it will be useful, but
30 WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32 General Public License for more details.
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
39 Contact: cacao@complang.tuwien.ac.at
41 Authors: Carolyn Oates
43 Changes: Christian Thalinger
45 $Id: parseXTA.c 2788 2005-06-22 16:08:51Z edwin $
49 /*--------------------------------------
56 general initialization
59 + hand coded calls for system
60 2nd interation (want to try it in inlining)
65 ----------------------------------*/
68 XTA Type Static Analysis of Java program
69 used -xta option is turned on either explicitly
70 or automatically with inlining of virtuals.
72 XTA is called for reachable methods and keeps sets for each Method and Field used as follows:
73 1. Work list of reachable methods is initialized to main + JVM called methods
75 2. For virtual method call from M of e.m then
76 a. Add all static lookup of m in the cone of e = ce.mi to reachable worklist
77 JAVA_INVOKESTATIC/ JAVA_INVOKESPECIAL - xtaAddCallEdges
78 JAVA_INVOKEVIRTUAL - xtaMarkSubs
80 b. Add mi's parameters class + subtypes that are used by M to mi used classes
81 When XTA parsed follow the calls list (beg. parseXTA)
82 c. Add mi's return type + subtypes used by mi to M's used classes
83 When XTA parsed follow the calledBy list (end parseXTA)
84 d. Add ce of mi to mi's used classes
85 static/special - addXTAcalledges
86 virtual - xtaMarkSubs if subclass used -> xtaAddCallEdges
87 if subclass not used -> add ce.mi to markedby temp set
89 3. new C (new, <init>, & similiar) then add C to M's used classes
90 JAVA_NEW, INVOKE_SPECIAL <init>, JAVA_CHECKCAST / JAVA_INSTANCEOF - classinit
91 4. read Field X.f: add X to M's used classes
93 5. write Field X.f: add X+subtypes that are used by M to X's classes
99 Methods called by NATIVE methods and classes loaded dynamically
100 cannot be found by parsing. The following files supply missing methods:
102 xtaMissedIn0 - (provided) has the methods missed by every java program
103 xtaMissed||mainClassName - is program specific.
105 A file xtaMissed will be written by XTA analysis of any methods missed.
107 This file can be renamed to xtaMissed concatenated with the main class name.
112 inlining with virtuals should fail if the returned xtaMissed is not empty.
114 mv xtaMissed xtaMissedhello
117 Results: (currently) with -stat see # methods marked used
127 #include "cacao/cacao.h"
128 #include "mm/memory.h"
129 #include "toolbox/list.h"
130 #include "toolbox/logging.h"
131 #include "vm/class.h"
132 #include "vm/linker.h"
133 #include "vm/loader.h"
134 #include "vm/resolve.h"
135 #include "vm/options.h"
136 #include "vm/statistics.h"
137 #include "vm/tables.h"
138 #include "vm/jit/jit.h"
139 #include "vm/jit/parse.h"
140 #include "vm/jit/inline/parseXTA.h"
141 #include "vm/jit/inline/parseRTstats.h"
142 #include "vm/jit/inline/parseRTprint.h"
146 static bool firstCall= true;
147 static list *xtaWorkList;
148 FILE *xtaMissed; /* Methods missed during XTA parse of Main */
150 bool XTA_DEBUGinf = false;
151 bool XTA_DEBUGr = false;
152 bool XTA_DEBUGopcodes = false;
154 char * clsFlgs [] = {"NOTUSED", "PARTUSED", "USED"};
155 char * methFlgs [] = {"NOTUSED", "MARKED", "USED"};
157 /*********************************************************************/
158 /*********************************************************************/
160 /* function descriptor2typesL ***************************************************
162 decodes a already checked method descriptor. The parameter count, the
163 return type and the argument types are stored in the passed methodinfo.
164 gets and saves classptr for object ref.s
166 *******************************************************************************/
168 static classSetNode *descriptor2typesL(methodinfo *m)
175 classinfo** classtypes;
178 classSetNode *p=NULL;
181 if (debugInfo >= 1) {
182 printf("In descriptor2typesL >>>\t"); fflush(stdout);
183 utf_display(m->class->name); printf(".");
184 method_display(m);fflush(stdout);
188 desc = MNEW (char, 256);
189 types = DMNEW (u1, m->descriptor->blength);
190 classtypes = MNEW (classinfo*, m->descriptor->blength+1);
191 m->returnclass = NULL;
193 if (!(m->flags & ACC_STATIC)) {
195 if (debugInfo >= 1) {
196 printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
198 classtypes[pcount] = m->class;
199 p = addClassCone(p, m->class);
203 utf_ptr = m->descriptor->text + 1;
204 strcpy (desc,utf_ptr);
206 while ((c = *desc++) != ')') {
213 case 'Z': *tptr++ = TYPE_INT;
215 case 'J': *tptr++ = TYPE_LNG;
217 case 'F': *tptr++ = TYPE_FLT;
219 case 'D': *tptr++ = TYPE_DBL;
221 case 'L': *tptr++ = TYPE_ADR;
222 /* get class string */
223 class = strtok(desc,";");
224 desc = strtok(NULL,"\0");
225 /* get/save classinfo ptr */
226 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
227 log_text("could not load class in descriptor2typesL");
230 classtypes[pcount-1] = clsinfo;
231 p = addClassCone(p, clsinfo);
232 if (debugInfo >= 1) {
233 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
234 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
235 utf_display(classtypes[pcount-1]->name);
238 case '[': *tptr++ = TYPE_ADR;
241 /* get class string */
243 class = strtok(desc,";");
244 desc = strtok(NULL,"\0");
245 /* get/save classinfo ptr */
246 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
247 log_text("could not load class in descriptor2typesL");
250 classtypes[pcount-1] = clsinfo;
251 p= addClassCone(p, clsinfo);
252 if (debugInfo >= 1) {
253 printf("[Param#%i 's class type is: %s\n",pcount-1,class);
254 printf("[classtypes[%i]=",pcount-1);fflush(stdout);
255 utf_display(classtypes[pcount-1]->name);
260 classtypes[pcount-1] = NULL;
263 log_text("Ill formed methodtype-descriptor");
268 /* compute return type */
274 case 'Z': m->returntype = TYPE_INT;
276 case 'J': m->returntype = TYPE_LNG;
278 case 'F': m->returntype = TYPE_FLT;
280 case 'D': m->returntype = TYPE_DBL;
283 m->returntype = TYPE_ADR;
293 m->returntype = TYPE_ADR;
295 /* get class string */
296 class = strtok(desc,";");
297 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
298 log_text("could not load class in descriptor2typesL");
301 m->returnclass = clsinfo;
302 if (m->returnclass == NULL) {
303 printf("class=<%s>\t",class); fflush(stdout);
304 log_text("return class not found");
308 case 'V': m->returntype = TYPE_VOID;
312 log_text("Ill formed methodtype-descriptor-ReturnType");
316 m->paramcount = pcount;
317 m->paramtypes = types;
318 m->paramclass = classtypes;
322 for (i=0; i< m->paramcount; i++) {
323 if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
324 printf("Param #%i is:\t",i);
325 utf_display(m->paramclass[i]->name);
330 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
331 printf("\tReturn Type is:\t"); fflush(stdout);
332 utf_display(m->returnclass->name);
336 printf("params2types: START results in a set \n");
337 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
346 /*-------------------------------------------------------------------------------*/
348 xtafldinfo * xtafldinfoInit (fieldinfo *f)
353 f->xta = NEW(xtafldinfo);
355 f->xta->fieldChecked = false;
356 f->xta->fldClassType = NULL;
357 f->xta->XTAclassSet = NULL;
362 /*-------------------------------------------------------------------------------*/
364 xtainfo *xtainfoInit(methodinfo *m)
367 return m->xta; /* already initialized */
369 #if defined(STATISTICS)
370 count_methods_marked_used++;
373 m ->xta = (xtainfo *) NEW(xtainfo);
374 m ->xta-> XTAmethodUsed = NOTUSED;
376 /* xta sets for a method */
377 m->xta->fldsUsed = NULL;
378 m ->xta-> XTAclassSet = NULL;
379 /* Methods's have access to the class they are a part of */
380 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
381 /* cone set of methods parameters */
382 /* what if no param?? is it NULL then, too? */
383 /****** class not loaded so take param info from superclass ??? */
384 m->xta->paramClassSet = descriptor2typesL(m);
387 m->xta->calls = NULL;
388 m->xta->calledBy = NULL;
389 m ->xta->markedBy = NULL;
391 m->xta->chgdSinceLastParse = false;
394 /* thought needed at some earlier point */
395 /*m ->xta->interfaceCalls = NULL*/
398 /*-------------------------------------------------------------------------------*/
399 void xtaAddCallEdges(methodinfo *mCalls, methodinfo *mCalled, s4 monoPoly, char *info) {
403 if (mCalled->flags & ACC_ABSTRACT) return;
404 /* First call to this method initializations */
406 printf("mCalled->methodUsed =%i != %i = USED is ",mCalled->methodUsed, USED); fflush(stdout);
407 printf(" <%i> T%i/%iF\n",(mCalled->methodUsed!= USED), true,false); fflush(stdout);
410 if (mCalled->methodUsed != USED) {
412 printf("\n>>>>>>%s:\n",info); fflush(stdout);
413 printf("Add to Worklist mCalls_=");fflush(stdout);
415 printf("<"); fflush(stdout);
417 printf("> "); fflush(stdout);
421 printf("NULL\n");fflush(stdout);
424 printf("mCalled=");fflush(stdout);
426 printf("<"); fflush(stdout);
428 printf("> "); fflush(stdout);
431 {printf("NULL\n");fflush(stdout);}
433 mCalled->xta = xtainfoInit(mCalled);
434 mCalled ->methodUsed = USED; /* used to see if method in the work list of methods */
436 xta->method = mCalled ;
437 list_addlast(xtaWorkList,xta);
440 if ((mCalls == NULL) && (!(monoPoly == SYSCALL)) ) {} /* panic when init file correct is */
442 if ((mCalls == mCalled) /* recursion doesn't change class set nor field set so ignore */
443 || (mCalls == NULL)) {return; }
446 /*** printf(" AddCallEdges\n"); fflush(stdout); ***/
448 mCalls->xta = xtainfoInit(mCalls);
449 mCalls->xta->calls = add2MethSet(mCalls->xta->calls, mCalled);
450 /* mono if static, private, final else virtual so poly */
451 mCalls->xta->calls->tail->monoPoly = monoPoly;
453 mCalled->xta->calledBy = add2MethSet(mCalled->xta->calledBy, mCalls);
455 /* IS THIS REALLY NEEDED???? */
456 if (mCalled->xta->calledBy == NULL) {
457 log_text("mCalled->xta->calledBy is NULL!!!");
460 if (mCalls->xta->calls == NULL) {
461 log_text("mCalls->xta->calls is NULL!!!");
468 /*-------------------------------------------------------------------------------*/
469 bool xtaPassParams (methodinfo *Called, methodinfo *Calls, methSetNode *lastptrInto)
477 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
478 if (Calls->xta->XTAclassSet != NULL)
479 c1 = Calls->xta->XTAclassSet->head;
480 /*else already c1 = NULL; */
483 /* start with type where left off */
484 c1 = lastptrInto->lastptrIntoClassSet2;
485 c1 = c1 -> nextClass; /* even if NULL */
487 if (c1 == NULL) return false;
490 /* for each Param Class */
491 for ( p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
493 /* for each SmCalls class */
494 for (c=c1; c != NULL; c = c->nextClass) {
498 LAZYLOADING(c->classType) /* if not loaded is it really needed ??? */
500 p_cl_vt = p->classType->vftbl;
501 c_cl_vt = c->classType->vftbl;
503 /* if SmCalls class is in the Params Class range */
504 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
505 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
507 /* add Calls class to CalledBy Class set */
508 Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
514 lastptrInto->lastptrIntoClassSet2 = cprev;
519 /*-------------------------------------------------------------------------------*/
520 void xtaPassAllCalledByParams (methodinfo *m) {
521 methSetNode *SmCalled;
522 if (m->xta->calledBy == NULL)
524 for (SmCalled = m->xta->calledBy->head;
526 SmCalled = SmCalled->nextmethRef) {
527 m->xta->chgdSinceLastParse = false; /* re'init flag */
528 xtaPassParams(m, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
533 /*-------------------------------------------------------------------------------*/
534 void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
536 /* Field type is a class */
538 classSetNode *c1 = NULL;
539 classSetNode *cp = NULL;
540 classSetNode *cprev= NULL;
549 /* Use lastptr so don't check whole XTA class set each time */
552 if (cp->nextClass != NULL)
553 c1 = cp -> nextClass;
556 if (m->xta->XTAclassSet != NULL)
557 c1 = m->xta->XTAclassSet->head;
560 /*--- PUTSTATIC specific ---*/
561 /* Sx = intersection of type+subtypes(field x) */
562 /* and Sm (where putstatic code is) */
563 for (c=c1; c != NULL; c=c->nextClass) {
567 LAZYLOADING1(fi->xta->fldClassType)
569 f_cl_vt = fi->xta->fldClassType->vftbl;
570 c_cl_vt = c-> classType->vftbl;
571 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
572 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
573 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
577 fN->lastptrPUT = cprev;
579 /*-------------------------------------------------------------------------------*/
580 void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
582 /* Field type is a class */
584 classSetNode *c1 = NULL;
585 classSetNode *cp = NULL;
586 classSetNode *cprev= NULL;
594 /* Use lastptr so don't check whole XTA class set each time */
597 if (cp->nextClass != NULL)
598 c1 = cp -> nextClass;
601 if (fi->xta->XTAclassSet != NULL)
602 c1 = fi->xta->XTAclassSet->head;
605 /*--- GETSTATIC specific ---*/
606 /* Sm = union of Sm and Sx */
607 for (c=c1; c != NULL; c=c->nextClass) {
609 if (m->xta->XTAclassSet ==NULL)
612 if (!(inSet (m->xta->XTAclassSet->head, c->classType) ))
617 = add2ClassSet(m->xta->XTAclassSet,c->classType);
622 fN->lastptrGET = cprev;
626 /*-------------------------------------------------------------------------------*/
627 void xtaAllFldsUsed (methodinfo *m) {
630 /* bool chgd = false */
632 if (m->xta->fldsUsed == NULL) return;
634 /* for each field that this method uses */
635 f1 = m->xta->fldsUsed->head;
637 for (f=f1; f != NULL; f = f->nextfldRef) {
646 /*-------------------------------------------------------------------------------*/
647 bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
653 /* Get Called return class is null */
654 if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
655 Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */
658 if (Called->returnclass == NULL) {
662 if (Called->xta->XTAclassSet == NULL)
665 cs1 = Called->xta->XTAclassSet->head;
667 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
668 classinfo *c = cs->classType;
672 LAZYLOADING(Called->returnclass)
673 r_cl_vt = Called->returnclass->vftbl;
676 /* if class is a subtype of the return type, then add to Calls class set (ie.interscection)*/
677 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
678 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
679 Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);
688 /*-------------------------------------------------------------------------------*/
689 void xtaMethodCalls_and_sendReturnType(methodinfo *m)
691 methSetNode *SmCalled; /* for return type */
692 methSetNode *SmCalls; /* for calls param types */
693 methSetNode *s1=NULL;
698 if (m->xta == NULL) {
699 log_text("m->xta null for return type");
703 /* for each method that this method calls */
704 if (m->xta->calls == NULL)
707 s1 = SmCalls=m->xta->calls->head;
709 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
710 /* pass param types */
712 chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
713 /* if true chgd after its own parse */
714 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
715 SmCalls->methRef->xta->chgdSinceLastParse = true;
719 /* for each calledBy method */
720 /* send return type */
721 if (m->xta->calledBy == NULL)
724 s1 = m->xta->calledBy->head;
725 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
727 chgd = xtaPassReturnType(m, SmCalled->methRef);
728 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
729 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
735 /*-------------------------------------------------------------------------------*/
736 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
738 bool is_classtype = false; /* return value */
740 if (fi->xta->fieldChecked) {
741 if (fi->xta->fldClassType != NULL)
742 return true; /* field has a class type */
746 fi->xta->fieldChecked = true;
748 if (fi->type == TYPE_ADDRESS) {
749 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
751 if (*utf_ptr != 'L') {
752 while (*utf_ptr++ =='[') ;
755 if (*utf_ptr =='L') {
757 if (fi->xta->fldClassType== NULL) {
762 desc = MNEW(char, 256);
763 strcpy(desc,++utf_ptr);
764 cname = strtok(desc,";");
765 if (!(class = load_class_bootstrap(utf_new_char(cname)))) {
766 log_text("could not load class in xtaAddFldClassTypeInfo");
769 fi->xta->fldClassType= class; /* save field's type class ptr */
776 /*--------------------------------------------------------------*/
777 /* Mark the method with same name /descriptor in topmethod */
780 /* Class marked USED and method defined in this class -> */
781 /* -> add call edges = USED */
782 /* Class not marked USED and method defined in this class -> */
783 /* -> if Method NOTUSED mark method as MARKED */
785 /* Class USED, but method not defined in this class -> */
786 /* -> 1) search up the heirarchy and mark method where defined */
787 /* 2) if class where method is defined is not USED -> */
788 /* -> ????mark class with defined method as PARTUSED */
789 /*--------------------------------------------------------------*/
792 void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
794 utf *name = topmethod->name;
795 utf *descriptor = topmethod->descriptor;
798 /* See if method defined in class heirarchy */
799 submeth = class_resolvemethod(class, name, descriptor);
800 METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
801 if (submeth == NULL) {
802 utf_display(class->name); printf(".");
803 METHINFOx(topmethod);
804 printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
808 /* if submeth called previously from this method then return */
809 if (mCalls->xta->calls != NULL) {
810 if (inMethSet(mCalls->xta->calls->head,submeth)) return;
815 XTAaddClassInit(submeth, submeth->class,
816 CLINITS_T,FINALIZE_T,ADDMARKED_T);
817 if (inSet(subtypesUsedSet,submeth->class)) {
818 submeth->monoPoly = POLY;
819 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
820 "00addTo XTA VIRT CONE:");
825 if (submeth->class == class) {
827 /*--- Method defined in class -----------------------------*/
828 if (inSet(subtypesUsedSet,submeth->class)) {
829 /* method defined in this class -> */
830 /* Class IS marked USED */
831 /* -> mark method as USED */
832 submeth->monoPoly = POLY;
833 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
834 "01addTo VIRT CONE 1:");
837 /* method defined in this class -> */
838 /* Class IS NOT marked USED (PART or NOTUSED) */
839 /* -> if Method NOTUSED mark method as MARKED */
841 "\tmarked VIRT CONE 2:",XTA_DEBUGr);
842 submeth->monoPoly = POLY;
843 if (submeth->xta == NULL) {
844 submeth->xta = xtainfoInit(submeth);
846 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
847 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
848 /* Note: if class NOTUSED and subclass is used handled */
849 /* by subsequent calls to xtaMarkMethods for cone */
851 } /* end defined in class */
854 /*--- Method NOT defined in class - defined up the heirarchy ---------------*/
855 /* then check class the method could be called with */
857 /* first mark classes if needed */
858 if (!(inSet(subtypesUsedSet,submeth->class))) {
859 submeth->class->classUsed = PARTUSED;
860 if (!(inSet(subtypesUsedSet,class))) {
861 submeth->monoPoly = POLY;
862 if (submeth->xta == NULL)
863 submeth->xta = xtainfoInit(submeth);
864 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
865 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
866 METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
869 /* add method to xta work list if conditions met */
870 if (inSet(subtypesUsedSet,class)) {
871 submeth->monoPoly = POLY;
872 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
873 "02addTo VIRT CONE 3:");
875 } /* end NOT defined in class */
879 /*----------------------------------------------------------------------*/
880 /* Mark the method with the same name and descriptor as topmethod */
881 /* and any subclass where the method is defined and/or class is used */
883 /*----------------------------------------------------------------------*/
885 void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
886 /* xtaPRINTmarkSubs1*/
887 xtaMarkMethod(class, mCalls, topmethod, subtypesUsedSet); /* Mark method in class where it was found */
888 if (class->sub != NULL) {
891 if (!(topmethod->flags & ACC_FINAL )) {
892 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
893 xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
900 /**************************************************************************/
901 /* Add Marked methods for input class ci */
902 /* Add methods with the same name and descriptor as implemented interfaces*/
903 /* with the same method name */
904 /* ??? interface part not XTA checked */
905 /*------------------------------------------------------------------------*/
906 void xtaAddMarkedMethods(methodinfo *mCalls, classinfo *ci) {
909 /* add marked methods to callgraph */
910 for (ii=0; ii<ci->methodscount; ii++) {
911 methodinfo *mi = &(ci->methods[ii]);
913 if (mi->xta != NULL) {
914 if (mi->xta->markedBy != NULL) {
916 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
917 methodinfo *mCalls = mcnode->methRef;
918 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
919 "03addToInit was Marked added:");
923 else { /* NOT XTA checked yet */
924 for (jj=0; jj < ci -> interfacescount; jj++) {
925 classinfo *ici = ci -> interfaces [jj].cls;
926 /* use resolve method....!!!! */
927 if (ici -> classUsed != NOTUSED) {
928 for (mm=0; mm< ici->methodscount; mm++) {
929 methodinfo *imi = &(ici->methods[mm]);
930 METHINFOt(imi,"NEW IMPD INTERFACE:",XTA_DEBUGinf)
931 /*if interface method=method is used*/
932 if ( (imi->methodUsed == USED)
933 && ( (imi->name == mi->name)
934 && (imi->descriptor == mi->descriptor))) {
935 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
936 "04addTo was interfaced used/MARKED:");
947 /*------------------------------------------------------------------------*/
948 void xtaAddUsedInterfaceMethods(methodinfo *m, classinfo *ci) {
951 /* add used interfaces methods to callgraph */
952 for (jj=0; jj < ci -> interfacescount; jj++) {
953 classinfo *ici = ci -> interfaces [jj].cls;
956 printf("BInterface used: ");fflush(stdout);
957 utf_display(ici->name);
958 printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); fflush(stdout);
960 /* add class to interfaces list of classes that implement it */
961 ici -> impldBy = addElement(ici -> impldBy, ci);
963 /* if interface class is used */
964 if (ici -> classUsed != NOTUSED) {
966 /* for each interface method implementation that has already been used */
967 for (mm=0; mm< ici->methodscount; mm++) {
968 methodinfo *imi = &(ici->methods[mm]);
969 if ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
970 printf("Interface Method %s: ", methFlgs[imi->methodUsed]);
971 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
973 if (imi->methodUsed == USED) {
975 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
976 /* Mark this method used in the (used) implementing class &its subclasses */
977 printf("rMAY ADD methods that was used by an interface\n");
979 if ((utf_clinit != imi->name) &&
980 (utf_init != imi->name))
982 classSetNode *subtypesUsedSet = NULL;
983 if (m->xta->XTAclassSet != NULL) {
985 intersectSubtypesWithSet
986 (imi->class, m->xta->XTAclassSet->head);
988 else /* can any methods be added if 1 set is NULL ??? */
989 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
990 xtaMarkSubs(m, ci, imi, subtypesUsedSet);
991 imi->monoPoly = POLY;
995 } /* end for method */
996 } /* end != NOTUSED */
997 } /* end for interface */
1002 /*----------------------------------------------------------------------*/
1004 #define CLINITS_T true
1005 #define FINALIZE_T true
1006 #define ADDMARKED_T true
1008 #define CLINITS_F false
1009 #define FINALIZE_F false
1010 #define ADDMARKED_F false
1011 /*-----------------------*/
1013 void XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
1018 ci->classUsed = USED;
1020 if (clinits) { /* No <clinit> available - ignore */
1021 mi = class_findmethod(ci, utf_clinit, utf_void__void);
1023 if (ci->classUsed != USED)
1024 ci->classUsed = PARTUSED;
1025 mi->monoPoly = MONO;
1026 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1027 "05addTo CLINIT added:");
1031 /*Special Case for System class init:
1032 add java/lang/initializeSystemClass to callgraph */
1033 if (ci->name == utf_new_char("initializeSystemClass")) {
1034 /* ?? what is name of method ?? */
1038 mi = class_findmethod(ci, utf_finalize, utf_void__void);
1040 if (ci->classUsed != USED)
1041 ci->classUsed = PARTUSED;
1042 mi->monoPoly = MONO;
1043 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1044 "06addTo FINALIZE added:");
1049 xtaAddMarkedMethods(mCalls, ci);
1052 /* always so know have access to the interface methods */
1053 xtaAddUsedInterfaceMethods(mCalls,ci);
1057 /*-------------------------------------------------------------------------------*/
1059 /*********************************************************************/
1060 /*********************************************************************/
1062 /*-------------------------------------------------------------------*/
1064 void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {
1066 if (mi->class->classUsed == NOTUSED) {
1067 mi->class->classUsed = USED;
1068 /* add interface class to list kept in Object */
1069 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1072 mi->methodUsed = USED;
1073 mi->monoPoly = POLY;
1075 /*XTAPRINT08invokeInterface1*/
1077 subs = mi->class->impldBy;
1078 METHINFO(mi,XTA_DEBUGinf)
1079 printf("Implemented By classes :\n");fflush(stdout);
1080 if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
1082 for (subs = mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
1083 methodinfo *submeth;
1085 printf("\t");utf_display(subs->classType->name);fflush(stdout);
1086 printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
1089 /*Mark method (mark/used) in classes that implement method*/
1090 submeth = class_findmethod(subs->classType, mi->name, mi->descriptor);
1091 if (submeth != NULL) {
1092 classSetNode *subtypesUsedSet = NULL;
1093 submeth->monoPoly = POLY; /* poly even if nosubs */
1094 submeth->xta = xtainfoInit(submeth);
1096 submeth->xta->XTAmethodUsed = USED;
1097 if (m->xta->XTAclassSet != NULL) {
1098 subtypesUsedSet = /* interface classes cone */
1099 intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
1101 else { /* can any methods be added if 1 set is NULL ??? */
1102 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1104 xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
1112 /*********************************************************************/
1114 int parseXTA(methodinfo *m)
1116 int p; /* java instruction counter */
1117 int nextp; /* start of next java instruction */
1118 int opcode; /* java opcode */
1119 int i; /* temp for different uses (counters)*/
1120 bool iswide = false; /* true if last instruction was a wide*/
1123 if (m->methodXTAparsed) return 0;
1124 else m->methodXTAparsed = true;
1126 /***XTA_DEBUGopcodes=false;***/
1127 /***printf("\n-----------------------------------\n"); **/
1128 METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes);
1129 if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
1130 /***XTA_DEBUGopcodes=false;***/
1131 if (m->xta == NULL) {
1135 xtaPassAllCalledByParams (m);
1138 /* scan all java instructions */
1139 for (p = 0; p < m->jcodelength; p = nextp) {
1141 opcode = code_get_u1(p,m); /* fetch op code */
1142 SHOWOPCODE(XTA_DEBUGopcodes)
1144 nextp = p + jcommandsize[opcode]; /* compute next instr start */
1145 if (nextp > m->jcodelength) {
1146 log_text("Unexpected end of bytecode");
1180 /* wider index for loading, storing and incrementing */
1194 case JAVA_LOOKUPSWITCH:
1197 nextp = ALIGN((p + 1), 4) + 4;
1198 num = code_get_u4(nextp,m);
1199 nextp += (code_get_u4(nextp,m)) * 8 + 4;
1204 case JAVA_TABLESWITCH:
1207 nextp = ALIGN ((p + 1),4);
1208 num = code_get_s4(nextp + 4, m);
1209 num = code_get_s4(nextp + 8, m) - num;
1210 nextp = nextp + 16 + 4 * num;
1213 /*********************/
1215 case JAVA_PUTSTATIC: /* write */
1217 i = code_get_u2(p + 1,m);
1219 constant_FMIref *fr;
1223 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1224 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1225 log_text("Could not resolve class reference");
1228 LAZYLOADING(frclass)
1230 fi = class_resolvefield(frclass,
1237 return 0; /* was NULL */
1239 printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1240 utf_display(fi->name);printf("\n");fflush(stdout);
1242 fi->xta = xtafldinfoInit(fi);
1243 XTAaddClassInit(m, fi->class,
1244 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1245 if (xtaAddFldClassTypeInfo(fi)) {
1246 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
1252 case JAVA_GETSTATIC: /* read */
1254 i = code_get_u2(p + 1,m);
1256 constant_FMIref *fr;
1260 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1261 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1262 log_text("Could not resolve class reference");
1266 LAZYLOADING(frclass)
1268 fi = class_resolvefield(frclass,
1275 return 0; /* was NULL */
1278 printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1279 utf_display(fi->name);printf("\n");fflush(stdout);
1281 fi->xta = xtafldinfoInit(fi);
1282 XTAaddClassInit(m, fi->class,
1283 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1284 if (xtaAddFldClassTypeInfo(fi)) {
1285 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
1293 case JAVA_INVOKESTATIC:
1294 case JAVA_INVOKESPECIAL:
1295 i = code_get_u2(p + 1,m);
1297 constant_FMIref *mr;
1301 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1302 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1303 log_text("Could not resolve class reference");
1307 LAZYLOADING(mrclass)
1308 mi = class_resolveclassmethod( mrclass,
1316 METHINFOt(mi,"INVOKESTAT/SPEC:: ",XTA_DEBUGopcodes)
1317 mi->monoPoly = MONO;
1319 /*---- Handle "leaf" = static, private, final calls-------------*/
1320 if ((opcode == JAVA_INVOKESTATIC)
1321 || (mi->flags & ACC_STATIC)
1322 || (mi->flags & ACC_PRIVATE)
1323 || (mi->flags & ACC_FINAL) )
1325 if (mi->class->classUsed != USED) { /* = NOTUSED or PARTUSED */
1326 XTAaddClassInit(m, mi->class,
1327 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1328 /* Leaf methods are used whether class is or not */
1329 /* so mark class as PARTlyUSED */
1330 mi->class->classUsed = PARTUSED;
1332 /* Add to XTA working list/set of reachable methods */
1333 if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
1334 /* calls , called */
1335 xtaAddCallEdges(m, mi, MONO,
1336 "07addTo INVOKESTATIC ");
1338 xtaAddCallEdges(m, mi, MONO,
1339 "08addTo INVOKESPECIAL ");
1340 } /* end STATIC, PRIVATE, FINAL */
1343 /*---- Handle special <init> calls ---------------------------------------------*/
1345 if (mi->class->classUsed != USED) {
1346 /* XTA special case:
1347 call of super's <init> then
1348 methods of super class not all used */
1350 /*--- <init> ()V is equivalent to "new"
1351 indicating a class is used = instaniated ---- */
1352 if (utf_init==mi->name) {
1353 if ((m->class->super.cls == mi->class)
1354 && (m->descriptor == utf_void__void) )
1356 METHINFOt(mi,"SUPER INIT:",XTA_DEBUGopcodes);
1357 /* super init so class may be only used because of its sub-class */
1358 XTAaddClassInit(m,mi->class,
1359 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1360 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
1363 /* since <init> indicates classes is used, then add marked methods, too */
1364 METHINFOt(mi,"NORMAL INIT:",XTA_DEBUGopcodes);
1365 XTAaddClassInit(m, mi->class,
1366 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1368 xtaAddCallEdges(m, mi, MONO,
1370 } /* end just for <init> ()V */
1372 /* <clinit> for class inits do not add marked methods;
1373 class not yet instaniated */
1374 if (utf_clinit==mi->name)
1375 XTAaddClassInit(m, mi->class,
1376 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1378 if (!((utf_init==mi->name))
1379 || (utf_clinit==mi->name)) {
1380 METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
1381 if (mi->class->classUsed !=USED)
1382 mi->class->classUsed = PARTUSED;
1383 xtaAddCallEdges(m, mi, MONO,
1384 "10addTo SPEC notINIT ");
1387 } /* end init'd class not used = class init process was needed */
1389 /* add method to XTA list = set of reachable methods */
1390 xtaAddCallEdges(m, mi, MONO,
1391 "11addTo SPEC whymissed ");
1394 /*** assume if method can't be resolved won't actually be called or
1395 there is a real error in classpath and in normal parse an exception
1396 will be thrown. Following debug print can verify this
1398 CLASSNAME1(mrclass,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
1399 utf_display(mr->name); printf(" "); fflush(stdout);
1400 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1405 case JAVA_INVOKEVIRTUAL:
1406 i = code_get_u2(p + 1,m);
1408 constant_FMIref *mr;
1412 mr = m->class->cpinfos[i];
1413 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
1414 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1415 log_text("Could not resolve class reference");
1419 LAZYLOADING(mrclass)
1420 mi = class_resolveclassmethod(mrclass,
1429 METHINFOt(mi,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
1430 if ((mi->flags & ACC_STATIC)
1431 || (mi->flags & ACC_PRIVATE)
1432 || (mi->flags & ACC_FINAL) )
1433 { /*** DOES THIS EVER OCCUR ??? */
1434 if (mi->class->classUsed == NOTUSED){
1435 XTAaddClassInit(m, mi->class,
1436 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1438 mi->monoPoly = MONO;
1439 xtaAddCallEdges(m, mi, MONO,
1440 "12addTo INVOKEVIRTUAL ");
1442 else { /* normal virtual */
1443 /* get the set of used subtypes if none at least the current methods class */
1444 classSetNode *subtypesUsedSet = NULL;
1445 if (m->xta->XTAclassSet != NULL) {
1447 intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
1449 else { /* can any methods be added if 1 set is NULL ??? */
1450 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1452 mi->monoPoly = POLY;
1453 xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
1457 CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
1458 utf_display(mr->name); printf(" "); fflush(stdout);
1459 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1464 case JAVA_INVOKEINTERFACE:
1465 i = code_get_u2(p + 1,m);
1467 constant_FMIref *mr;
1471 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1472 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1473 log_text("Could not resolve class reference");
1477 LAZYLOADING(mrclass)
1479 mi = class_resolveinterfacemethod(mrclass,
1486 METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
1487 xtaMarkInterfaceSubs(m,mi);
1489 /* see INVOKESTATIC for explanation about */
1490 /* case when Interface is not resolved */
1491 /*method_descriptor2types(mi);
1492 ?? do need paramcnt? for XTA (or just XTA)*/
1497 /* means class is at least passed as a parameter */
1498 /* class is really instantiated when class.<init> called*/
1499 i = code_get_u2(p + 1,m);
1502 constant_classref *cr;
1503 cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
1504 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1505 /*** s_count++; look for s_counts for VTA */
1506 /* add marked methods */
1507 CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
1508 XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T);
1509 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1513 case JAVA_CHECKCAST:
1514 case JAVA_INSTANCEOF:
1516 i = code_get_u2(p + 1,m);
1518 constant_classref *cr;
1520 cr = (constant_classref*) class_getconstant(m->class, i, CONSTANT_Class);
1521 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1523 CLASSNAMEop(cls,XTA_DEBUGr);
1524 if (cls->classUsed == NOTUSED){
1525 XTAaddClassInit(m, cls,
1526 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1527 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1538 xtaMethodCalls_and_sendReturnType(m);
1543 /* Helper fn for initialize **********************************************/
1545 int XTAgetline(char *line, int max, FILE *inFP) {
1546 if (fgets(line, max, inFP) == NULL)
1549 return strlen((const char *) line);
1552 /* Initialize XTA Work list ***********************************************/
1554 /*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
1555 #define SYSADD(cls,meth,desc, is_mono_poly, txt) \
1556 c = load_class_bootstrap(utf_new_char(cls)); \
1558 callmeth = class_resolveclassmethod(c, \
1559 utf_new_char(meth), \
1560 utf_new_char(desc), \
1563 if (callmeth->class->classUsed != USED) { \
1564 c->classUsed = PARTUSED; \
1565 XTAaddClassInit(callmeth, callmeth->class, \
1566 CLINITS_T,FINALIZE_T,ADDMARKED_T);\
1568 callmeth->monoPoly = is_mono_poly; \
1569 xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt);
1571 /*-- ----------------------------------------------------------------------------
1572 Initialize XTA work list with methods/classes from:
1575 xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
1576 -------------------------------------------------------------------------------*/
1577 methodinfo *initializeXTAworklist(methodinfo *m) {
1579 methodinfo* callmeth;
1580 char systxt[] = "2S addTo System Call :";
1581 char missedtxt[] = "2M addTo xtaMissedIn Call :";
1583 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1585 char* class, *meth, *desc;
1586 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1589 /* Create XTA call work list */
1590 xtaWorkList = NEW(list);
1591 list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
1593 /* Add first method to call list */
1594 m->class->classUsed = USED;
1595 xtaAddCallEdges(NULL, m, SYSCALL, systxt);
1597 /* Add system called methods */
1598 /*** SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
1599 SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
1601 /*** SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
1602 SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
1603 /*----- xtaMissedIn 0 */
1604 if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
1605 /*if (opt_verbose) */
1606 {printf("No xtaMissedIn0 file\n");fflush(stdout);}
1609 while (XTAgetline(line,256,xtaMissedIn)) {
1610 class = strtok(line, " \n");
1611 meth = strtok(NULL, " \n");
1612 desc = strtok(NULL, " \n");
1613 SYSADD(class,meth,desc, POLY, missedtxt)
1614 /* ??? Need to hand / hard code who calls it ??? */
1616 fclose(xtaMissedIn);
1625 /*- end initializeXTAworklist-------- */
1628 /*-------------------------------------------------------------------------------*/
1629 methodinfo *missedXTAworklist()
1631 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1632 char filenameIn[256] = "xtaIn/";
1634 char* class, *meth, *desc;
1636 char* calls_class, *calls_meth, *calls_desc;
1638 char missedtxt[] = "xtaIn/ missed Call :";
1640 methodinfo* callmeth;
1642 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1645 #if defined(USE_THREADS)
1646 SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
1647 SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
1649 /*----- xtaMissedIn pgm specific */
1650 strcat(filenameIn, (const char *)mainstring);
1651 if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
1652 /*if (opt_verbose)*/
1653 {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);}
1656 while (XTAgetline(line,256,xtaMissedIn)) {
1658 calls_class = strtok(line, " \n");
1659 calls_meth = strtok(NULL, " \n");
1660 calls_desc = strtok(NULL, " \n");
1662 class = strtok(NULL, " \n");
1664 class = strtok(line, " \n");
1665 meth = strtok(NULL, " \n");
1666 desc = strtok(NULL, " \n");
1669 if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL)
1670 || (class == NULL) || (meth == NULL) || (desc == NULL))
1672 if ( (class == NULL) || (meth == NULL) || (desc == NULL)) {
1673 log_text("Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc");
1676 SYSADD(class,meth,desc, POLY, missedtxt)
1678 fclose(xtaMissedIn);
1685 /*--------------------------------------------------------*/
1686 /* parseXTAmethod */
1687 /* input: method to be XTA static parsed */
1688 /*--------------------------------------------------------*/
1689 void parseXTAmethod(methodinfo *xta_method) {
1690 if (! ( (xta_method->flags & ACC_NATIVE )
1691 || (xta_method->flags & ACC_ABSTRACT) ) )
1693 /* XTA parse to approxmate....
1694 what classes/methods will really be used during execution */
1695 parseXTA(xta_method);
1698 if (xta_method->flags & ACC_NATIVE )
1700 METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
1701 /* parseXTApseudo(xta_method); */
1704 printf("Abstract method in XTA Work List: ");
1705 METHINFOx(xta_method);
1706 log_text("Abstract method in XTA Work List.");
1712 void XTAprintCallgraph (list *xtaWorkList, char * txt);
1714 /*-- XTA -- *******************************************************/
1715 int XTA_jit_parse(methodinfo *m)
1718 methodinfo *mainmeth;
1720 /* Should only be called once */
1723 /*----- XTA initializations --------*/
1725 log_text("XTA static analysis started.\n");
1727 mainmeth = initializeXTAworklist(m);
1728 /** XTAprintCallgraph (xtaWorkList, "after init1"); **/
1729 firstCall = false; /* turn flag off */
1731 if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
1732 printf("CACAO - xtaMissed file: cant open file to write\n");
1734 /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
1736 /*------ process XTA call work list --------*/
1737 for (xta =list_first(xtaWorkList);
1739 xta =list_next(xtaWorkList,xta))
1741 parseXTAmethod(xta->method);
1742 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
1744 missedXTAworklist();
1745 /** XTAprintCallgraph (xtaWorkList, "after missed"); **/
1746 for (xta =list_first(xtaWorkList);
1748 xta =list_next(xtaWorkList,xta))
1750 parseXTAmethod(xta->method);
1751 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
1757 printf("printXTAhierarchyInfo(m); not yet there\n");
1759 XTAprintCallgraph (xtaWorkList, "After all XTA parses");
1763 log_text("XTA static analysis done.\n");
1769 /*--------------------------------------------------------------*/
1770 void XTAprintCallgraph (list *xtaWorkList, char * txt)
1774 methodinfo *xta_meth;
1776 printf("\n%s\n",txt);
1777 #if defined(STATISTICS)
1778 printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
1781 for (xta =list_first(xtaWorkList);
1783 xta =list_next(xtaWorkList,xta))
1785 xta_meth = xta->method;
1787 printf(" (%i): ",i++);
1788 method_display_w_class(xta_meth);
1797 * These are local overrides for various environment variables in Emacs.
1798 * Please do not remove this and leave it at the end of the file, where
1799 * Emacs will automagically detect them.
1800 * ---------------------------------------------------------------------
1803 * indent-tabs-mode: t