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 3365 2005-10-06 08:42:58Z 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 /* prevent compiler warnings */
481 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
482 if (Calls->xta->XTAclassSet != NULL)
483 c1 = Calls->xta->XTAclassSet->head;
484 /*else already c1 = NULL; */
487 /* start with type where left off */
488 c1 = lastptrInto->lastptrIntoClassSet2;
489 c1 = c1 -> nextClass; /* even if NULL */
491 if (c1 == NULL) return false;
494 /* for each Param Class */
495 for ( p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
497 /* for each SmCalls class */
498 for (c=c1; c != NULL; c = c->nextClass) {
502 LAZYLOADING(c->classType) /* if not loaded is it really needed ??? */
504 p_cl_vt = p->classType->vftbl;
505 c_cl_vt = c->classType->vftbl;
507 /* if SmCalls class is in the Params Class range */
508 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
509 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
511 /* add Calls class to CalledBy Class set */
512 Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
518 lastptrInto->lastptrIntoClassSet2 = cprev;
523 /*-------------------------------------------------------------------------------*/
524 void xtaPassAllCalledByParams (methodinfo *m) {
525 methSetNode *SmCalled;
526 if (m->xta->calledBy == NULL)
528 for (SmCalled = m->xta->calledBy->head;
530 SmCalled = SmCalled->nextmethRef) {
531 m->xta->chgdSinceLastParse = false; /* re'init flag */
532 xtaPassParams(m, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
537 /*-------------------------------------------------------------------------------*/
538 void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
540 /* Field type is a class */
542 classSetNode *c1 = NULL;
543 classSetNode *cp = NULL;
544 classSetNode *cprev= NULL;
553 /* Use lastptr so don't check whole XTA class set each time */
556 if (cp->nextClass != NULL)
557 c1 = cp -> nextClass;
560 if (m->xta->XTAclassSet != NULL)
561 c1 = m->xta->XTAclassSet->head;
564 /*--- PUTSTATIC specific ---*/
565 /* Sx = intersection of type+subtypes(field x) */
566 /* and Sm (where putstatic code is) */
567 for (c=c1; c != NULL; c=c->nextClass) {
571 LAZYLOADING1(fi->xta->fldClassType)
573 f_cl_vt = fi->xta->fldClassType->vftbl;
574 c_cl_vt = c-> classType->vftbl;
575 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
576 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
577 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
581 fN->lastptrPUT = cprev;
583 /*-------------------------------------------------------------------------------*/
584 void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
586 /* Field type is a class */
588 classSetNode *c1 = NULL;
589 classSetNode *cp = NULL;
590 classSetNode *cprev= NULL;
598 /* Use lastptr so don't check whole XTA class set each time */
601 if (cp->nextClass != NULL)
602 c1 = cp -> nextClass;
605 if (fi->xta->XTAclassSet != NULL)
606 c1 = fi->xta->XTAclassSet->head;
609 /*--- GETSTATIC specific ---*/
610 /* Sm = union of Sm and Sx */
611 for (c=c1; c != NULL; c=c->nextClass) {
613 if (m->xta->XTAclassSet ==NULL)
616 if (!(inSet (m->xta->XTAclassSet->head, c->classType) ))
621 = add2ClassSet(m->xta->XTAclassSet,c->classType);
626 fN->lastptrGET = cprev;
630 /*-------------------------------------------------------------------------------*/
631 void xtaAllFldsUsed (methodinfo *m) {
634 /* bool chgd = false */
636 if (m->xta->fldsUsed == NULL) return;
638 /* for each field that this method uses */
639 f1 = m->xta->fldsUsed->head;
641 for (f=f1; f != NULL; f = f->nextfldRef) {
650 /*-------------------------------------------------------------------------------*/
651 bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
657 /* Get Called return class is null */
658 if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
659 Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */
662 if (Called->returnclass == NULL) {
666 if (Called->xta->XTAclassSet == NULL)
669 cs1 = Called->xta->XTAclassSet->head;
671 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
672 classinfo *c = cs->classType;
676 LAZYLOADING(Called->returnclass)
677 r_cl_vt = Called->returnclass->vftbl;
680 /* if class is a subtype of the return type, then add to Calls class set (ie.interscection)*/
681 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
682 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
683 Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);
692 /*-------------------------------------------------------------------------------*/
693 void xtaMethodCalls_and_sendReturnType(methodinfo *m)
695 methSetNode *SmCalled; /* for return type */
696 methSetNode *SmCalls; /* for calls param types */
697 methSetNode *s1=NULL;
702 if (m->xta == NULL) {
703 log_text("m->xta null for return type");
707 /* for each method that this method calls */
708 if (m->xta->calls == NULL)
711 s1 = SmCalls=m->xta->calls->head;
713 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
714 /* pass param types */
716 chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
717 /* if true chgd after its own parse */
718 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
719 SmCalls->methRef->xta->chgdSinceLastParse = true;
723 /* for each calledBy method */
724 /* send return type */
725 if (m->xta->calledBy == NULL)
728 s1 = m->xta->calledBy->head;
729 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
731 chgd = xtaPassReturnType(m, SmCalled->methRef);
732 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
733 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
739 /*-------------------------------------------------------------------------------*/
740 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
742 bool is_classtype = false; /* return value */
744 if (fi->xta->fieldChecked) {
745 if (fi->xta->fldClassType != NULL)
746 return true; /* field has a class type */
750 fi->xta->fieldChecked = true;
752 if (fi->type == TYPE_ADDRESS) {
753 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
755 if (*utf_ptr != 'L') {
756 while (*utf_ptr++ =='[') ;
759 if (*utf_ptr =='L') {
761 if (fi->xta->fldClassType== NULL) {
766 desc = MNEW(char, 256);
767 strcpy(desc,++utf_ptr);
768 cname = strtok(desc,";");
769 if (!(class = load_class_bootstrap(utf_new_char(cname)))) {
770 log_text("could not load class in xtaAddFldClassTypeInfo");
773 fi->xta->fldClassType= class; /* save field's type class ptr */
780 /*--------------------------------------------------------------*/
781 /* Mark the method with same name /descriptor in topmethod */
784 /* Class marked USED and method defined in this class -> */
785 /* -> add call edges = USED */
786 /* Class not marked USED and method defined in this class -> */
787 /* -> if Method NOTUSED mark method as MARKED */
789 /* Class USED, but method not defined in this class -> */
790 /* -> 1) search up the heirarchy and mark method where defined */
791 /* 2) if class where method is defined is not USED -> */
792 /* -> ????mark class with defined method as PARTUSED */
793 /*--------------------------------------------------------------*/
796 void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
798 utf *name = topmethod->name;
799 utf *descriptor = topmethod->descriptor;
802 /* See if method defined in class heirarchy */
803 submeth = class_resolvemethod(class, name, descriptor);
804 METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
805 if (submeth == NULL) {
806 utf_display(class->name); printf(".");
807 METHINFOx(topmethod);
808 printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
812 /* if submeth called previously from this method then return */
813 if (mCalls->xta->calls != NULL) {
814 if (inMethSet(mCalls->xta->calls->head,submeth)) return;
819 XTAaddClassInit(submeth, submeth->class,
820 CLINITS_T,FINALIZE_T,ADDMARKED_T);
821 if (inSet(subtypesUsedSet,submeth->class)) {
822 submeth->monoPoly = POLY;
823 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
824 "00addTo XTA VIRT CONE:");
829 if (submeth->class == class) {
831 /*--- Method defined in class -----------------------------*/
832 if (inSet(subtypesUsedSet,submeth->class)) {
833 /* method defined in this class -> */
834 /* Class IS marked USED */
835 /* -> mark method as USED */
836 submeth->monoPoly = POLY;
837 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
838 "01addTo VIRT CONE 1:");
841 /* method defined in this class -> */
842 /* Class IS NOT marked USED (PART or NOTUSED) */
843 /* -> if Method NOTUSED mark method as MARKED */
845 "\tmarked VIRT CONE 2:",XTA_DEBUGr);
846 submeth->monoPoly = POLY;
847 if (submeth->xta == NULL) {
848 submeth->xta = xtainfoInit(submeth);
850 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
851 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
852 /* Note: if class NOTUSED and subclass is used handled */
853 /* by subsequent calls to xtaMarkMethods for cone */
855 } /* end defined in class */
858 /*--- Method NOT defined in class - defined up the heirarchy ---------------*/
859 /* then check class the method could be called with */
861 /* first mark classes if needed */
862 if (!(inSet(subtypesUsedSet,submeth->class))) {
863 submeth->class->classUsed = PARTUSED;
864 if (!(inSet(subtypesUsedSet,class))) {
865 submeth->monoPoly = POLY;
866 if (submeth->xta == NULL)
867 submeth->xta = xtainfoInit(submeth);
868 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
869 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
870 METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
873 /* add method to xta work list if conditions met */
874 if (inSet(subtypesUsedSet,class)) {
875 submeth->monoPoly = POLY;
876 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
877 "02addTo VIRT CONE 3:");
879 } /* end NOT defined in class */
883 /*----------------------------------------------------------------------*/
884 /* Mark the method with the same name and descriptor as topmethod */
885 /* and any subclass where the method is defined and/or class is used */
887 /*----------------------------------------------------------------------*/
889 void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
890 /* xtaPRINTmarkSubs1*/
891 xtaMarkMethod(class, mCalls, topmethod, subtypesUsedSet); /* Mark method in class where it was found */
892 if (class->sub != NULL) {
895 if (!(topmethod->flags & ACC_FINAL )) {
896 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
897 xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
904 /**************************************************************************/
905 /* Add Marked methods for input class ci */
906 /* Add methods with the same name and descriptor as implemented interfaces*/
907 /* with the same method name */
908 /* ??? interface part not XTA checked */
909 /*------------------------------------------------------------------------*/
910 void xtaAddMarkedMethods(methodinfo *mCalls, classinfo *ci) {
913 /* add marked methods to callgraph */
914 for (ii=0; ii<ci->methodscount; ii++) {
915 methodinfo *mi = &(ci->methods[ii]);
917 if (mi->xta != NULL) {
918 if (mi->xta->markedBy != NULL) {
920 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
921 methodinfo *mCalls = mcnode->methRef;
922 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
923 "03addToInit was Marked added:");
927 else { /* NOT XTA checked yet */
928 for (jj=0; jj < ci -> interfacescount; jj++) {
929 classinfo *ici = ci -> interfaces [jj].cls;
930 /* use resolve method....!!!! */
931 if (ici -> classUsed != NOTUSED) {
932 for (mm=0; mm< ici->methodscount; mm++) {
933 methodinfo *imi = &(ici->methods[mm]);
934 METHINFOt(imi,"NEW IMPD INTERFACE:",XTA_DEBUGinf)
935 /*if interface method=method is used*/
936 if ( (imi->methodUsed == USED)
937 && ( (imi->name == mi->name)
938 && (imi->descriptor == mi->descriptor))) {
939 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
940 "04addTo was interfaced used/MARKED:");
951 /*------------------------------------------------------------------------*/
952 void xtaAddUsedInterfaceMethods(methodinfo *m, classinfo *ci) {
955 /* add used interfaces methods to callgraph */
956 for (jj=0; jj < ci -> interfacescount; jj++) {
957 classinfo *ici = ci -> interfaces [jj].cls;
960 printf("BInterface used: ");fflush(stdout);
961 utf_display(ici->name);
962 printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); fflush(stdout);
964 /* add class to interfaces list of classes that implement it */
965 ici -> impldBy = addElement(ici -> impldBy, ci);
967 /* if interface class is used */
968 if (ici -> classUsed != NOTUSED) {
970 /* for each interface method implementation that has already been used */
971 for (mm=0; mm< ici->methodscount; mm++) {
972 methodinfo *imi = &(ici->methods[mm]);
973 if ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
974 printf("Interface Method %s: ", methFlgs[imi->methodUsed]);
975 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
977 if (imi->methodUsed == USED) {
979 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
980 /* Mark this method used in the (used) implementing class &its subclasses */
981 printf("rMAY ADD methods that was used by an interface\n");
983 if ((utf_clinit != imi->name) &&
984 (utf_init != imi->name))
986 classSetNode *subtypesUsedSet = NULL;
987 if (m->xta->XTAclassSet != NULL) {
989 intersectSubtypesWithSet
990 (imi->class, m->xta->XTAclassSet->head);
992 else /* can any methods be added if 1 set is NULL ??? */
993 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
994 xtaMarkSubs(m, ci, imi, subtypesUsedSet);
995 imi->monoPoly = POLY;
999 } /* end for method */
1000 } /* end != NOTUSED */
1001 } /* end for interface */
1006 /*----------------------------------------------------------------------*/
1008 #define CLINITS_T true
1009 #define FINALIZE_T true
1010 #define ADDMARKED_T true
1012 #define CLINITS_F false
1013 #define FINALIZE_F false
1014 #define ADDMARKED_F false
1015 /*-----------------------*/
1017 void XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
1022 ci->classUsed = USED;
1024 if (clinits) { /* No <clinit> available - ignore */
1025 mi = class_findmethod(ci, utf_clinit, utf_void__void);
1027 if (ci->classUsed != USED)
1028 ci->classUsed = PARTUSED;
1029 mi->monoPoly = MONO;
1030 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1031 "05addTo CLINIT added:");
1035 /*Special Case for System class init:
1036 add java/lang/initializeSystemClass to callgraph */
1037 if (ci->name == utf_new_char("initializeSystemClass")) {
1038 /* ?? what is name of method ?? */
1042 mi = class_findmethod(ci, utf_finalize, utf_void__void);
1044 if (ci->classUsed != USED)
1045 ci->classUsed = PARTUSED;
1046 mi->monoPoly = MONO;
1047 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1048 "06addTo FINALIZE added:");
1053 xtaAddMarkedMethods(mCalls, ci);
1056 /* always so know have access to the interface methods */
1057 xtaAddUsedInterfaceMethods(mCalls,ci);
1061 /*-------------------------------------------------------------------------------*/
1063 /*********************************************************************/
1064 /*********************************************************************/
1066 /*-------------------------------------------------------------------*/
1068 void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {
1070 if (mi->class->classUsed == NOTUSED) {
1071 mi->class->classUsed = USED;
1072 /* add interface class to list kept in Object */
1073 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1076 mi->methodUsed = USED;
1077 mi->monoPoly = POLY;
1079 /*XTAPRINT08invokeInterface1*/
1081 subs = mi->class->impldBy;
1082 METHINFO(mi,XTA_DEBUGinf)
1083 printf("Implemented By classes :\n");fflush(stdout);
1084 if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
1086 for (subs = mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
1087 methodinfo *submeth;
1089 printf("\t");utf_display(subs->classType->name);fflush(stdout);
1090 printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
1093 /*Mark method (mark/used) in classes that implement method*/
1094 submeth = class_findmethod(subs->classType, mi->name, mi->descriptor);
1095 if (submeth != NULL) {
1096 classSetNode *subtypesUsedSet = NULL;
1097 submeth->monoPoly = POLY; /* poly even if nosubs */
1098 submeth->xta = xtainfoInit(submeth);
1100 submeth->xta->XTAmethodUsed = USED;
1101 if (m->xta->XTAclassSet != NULL) {
1102 subtypesUsedSet = /* interface classes cone */
1103 intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
1105 else { /* can any methods be added if 1 set is NULL ??? */
1106 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1108 xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
1116 /*********************************************************************/
1118 int parseXTA(methodinfo *m)
1120 int p; /* java instruction counter */
1121 int nextp; /* start of next java instruction */
1122 int opcode; /* java opcode */
1123 int i; /* temp for different uses (counters)*/
1124 bool iswide = false; /* true if last instruction was a wide*/
1127 if (m->methodXTAparsed) return 0;
1128 else m->methodXTAparsed = true;
1130 /***XTA_DEBUGopcodes=false;***/
1131 /***printf("\n-----------------------------------\n"); **/
1132 METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes);
1133 if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
1134 /***XTA_DEBUGopcodes=false;***/
1135 if (m->xta == NULL) {
1139 xtaPassAllCalledByParams (m);
1142 /* scan all java instructions */
1143 for (p = 0; p < m->jcodelength; p = nextp) {
1145 opcode = code_get_u1(p,m); /* fetch op code */
1146 SHOWOPCODE(XTA_DEBUGopcodes)
1148 nextp = p + jcommandsize[opcode]; /* compute next instr start */
1149 if (nextp > m->jcodelength) {
1150 log_text("Unexpected end of bytecode");
1184 /* wider index for loading, storing and incrementing */
1198 case JAVA_LOOKUPSWITCH:
1201 nextp = ALIGN((p + 1), 4) + 4;
1202 num = code_get_u4(nextp,m);
1203 nextp += (code_get_u4(nextp,m)) * 8 + 4;
1208 case JAVA_TABLESWITCH:
1211 nextp = ALIGN ((p + 1),4);
1212 num = code_get_s4(nextp + 4, m);
1213 num = code_get_s4(nextp + 8, m) - num;
1214 nextp = nextp + 16 + 4 * num;
1217 /*********************/
1219 case JAVA_PUTSTATIC: /* write */
1221 i = code_get_u2(p + 1,m);
1223 constant_FMIref *fr;
1227 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1230 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1231 log_text("Could not resolve class reference");
1234 LAZYLOADING(frclass)
1236 fi = class_resolvefield(frclass,
1243 return 0; /* was NULL */
1245 printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1246 utf_display(fi->name);printf("\n");fflush(stdout);
1248 fi->xta = xtafldinfoInit(fi);
1249 XTAaddClassInit(m, fi->class,
1250 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1251 if (xtaAddFldClassTypeInfo(fi)) {
1252 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
1258 case JAVA_GETSTATIC: /* read */
1260 i = code_get_u2(p + 1,m);
1262 constant_FMIref *fr;
1266 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1269 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1270 log_text("Could not resolve class reference");
1274 LAZYLOADING(frclass)
1276 fi = class_resolvefield(frclass,
1283 return 0; /* was NULL */
1286 printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1287 utf_display(fi->name);printf("\n");fflush(stdout);
1289 fi->xta = xtafldinfoInit(fi);
1290 XTAaddClassInit(m, fi->class,
1291 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1292 if (xtaAddFldClassTypeInfo(fi)) {
1293 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
1301 case JAVA_INVOKESTATIC:
1302 case JAVA_INVOKESPECIAL:
1303 i = code_get_u2(p + 1,m);
1305 constant_FMIref *mr;
1309 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1312 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1313 log_text("Could not resolve class reference");
1317 LAZYLOADING(mrclass)
1318 mi = class_resolveclassmethod( mrclass,
1326 METHINFOt(mi,"INVOKESTAT/SPEC:: ",XTA_DEBUGopcodes)
1327 mi->monoPoly = MONO;
1329 /*---- Handle "leaf" = static, private, final calls-------------*/
1330 if ((opcode == JAVA_INVOKESTATIC)
1331 || (mi->flags & ACC_STATIC)
1332 || (mi->flags & ACC_PRIVATE)
1333 || (mi->flags & ACC_FINAL) )
1335 if (mi->class->classUsed != USED) { /* = NOTUSED or PARTUSED */
1336 XTAaddClassInit(m, mi->class,
1337 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1338 /* Leaf methods are used whether class is or not */
1339 /* so mark class as PARTlyUSED */
1340 mi->class->classUsed = PARTUSED;
1342 /* Add to XTA working list/set of reachable methods */
1343 if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
1344 /* calls , called */
1345 xtaAddCallEdges(m, mi, MONO,
1346 "07addTo INVOKESTATIC ");
1348 xtaAddCallEdges(m, mi, MONO,
1349 "08addTo INVOKESPECIAL ");
1350 } /* end STATIC, PRIVATE, FINAL */
1353 /*---- Handle special <init> calls ---------------------------------------------*/
1355 if (mi->class->classUsed != USED) {
1356 /* XTA special case:
1357 call of super's <init> then
1358 methods of super class not all used */
1360 /*--- <init> ()V is equivalent to "new"
1361 indicating a class is used = instaniated ---- */
1362 if (utf_init==mi->name) {
1363 if ((m->class->super.cls == mi->class)
1364 && (m->descriptor == utf_void__void) )
1366 METHINFOt(mi,"SUPER INIT:",XTA_DEBUGopcodes);
1367 /* super init so class may be only used because of its sub-class */
1368 XTAaddClassInit(m,mi->class,
1369 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1370 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
1373 /* since <init> indicates classes is used, then add marked methods, too */
1374 METHINFOt(mi,"NORMAL INIT:",XTA_DEBUGopcodes);
1375 XTAaddClassInit(m, mi->class,
1376 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1378 xtaAddCallEdges(m, mi, MONO,
1380 } /* end just for <init> ()V */
1382 /* <clinit> for class inits do not add marked methods;
1383 class not yet instaniated */
1384 if (utf_clinit==mi->name)
1385 XTAaddClassInit(m, mi->class,
1386 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1388 if (!((utf_init==mi->name))
1389 || (utf_clinit==mi->name)) {
1390 METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
1391 if (mi->class->classUsed !=USED)
1392 mi->class->classUsed = PARTUSED;
1393 xtaAddCallEdges(m, mi, MONO,
1394 "10addTo SPEC notINIT ");
1397 } /* end init'd class not used = class init process was needed */
1399 /* add method to XTA list = set of reachable methods */
1400 xtaAddCallEdges(m, mi, MONO,
1401 "11addTo SPEC whymissed ");
1404 /*** assume if method can't be resolved won't actually be called or
1405 there is a real error in classpath and in normal parse an exception
1406 will be thrown. Following debug print can verify this
1408 CLASSNAME1(mrclass,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
1409 utf_display(mr->name); printf(" "); fflush(stdout);
1410 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1415 case JAVA_INVOKEVIRTUAL:
1416 i = code_get_u2(p + 1,m);
1418 constant_FMIref *mr;
1422 /* XXX remove direct access */
1423 mr = m->class->cpinfos[i];
1424 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
1425 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1426 log_text("Could not resolve class reference");
1430 LAZYLOADING(mrclass)
1431 mi = class_resolveclassmethod(mrclass,
1440 METHINFOt(mi,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
1441 if ((mi->flags & ACC_STATIC)
1442 || (mi->flags & ACC_PRIVATE)
1443 || (mi->flags & ACC_FINAL) )
1444 { /*** DOES THIS EVER OCCUR ??? */
1445 if (mi->class->classUsed == NOTUSED){
1446 XTAaddClassInit(m, mi->class,
1447 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1449 mi->monoPoly = MONO;
1450 xtaAddCallEdges(m, mi, MONO,
1451 "12addTo INVOKEVIRTUAL ");
1453 else { /* normal virtual */
1454 /* get the set of used subtypes if none at least the current methods class */
1455 classSetNode *subtypesUsedSet = NULL;
1456 if (m->xta->XTAclassSet != NULL) {
1458 intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
1460 else { /* can any methods be added if 1 set is NULL ??? */
1461 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1463 mi->monoPoly = POLY;
1464 xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
1468 CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
1469 utf_display(mr->name); printf(" "); fflush(stdout);
1470 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1475 case JAVA_INVOKEINTERFACE:
1476 i = code_get_u2(p + 1,m);
1478 constant_FMIref *mr;
1482 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1485 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1486 log_text("Could not resolve class reference");
1490 LAZYLOADING(mrclass)
1492 mi = class_resolveinterfacemethod(mrclass,
1499 METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
1500 xtaMarkInterfaceSubs(m,mi);
1502 /* see INVOKESTATIC for explanation about */
1503 /* case when Interface is not resolved */
1504 /*method_descriptor2types(mi);
1505 ?? do need paramcnt? for XTA (or just XTA)*/
1510 /* means class is at least passed as a parameter */
1511 /* class is really instantiated when class.<init> called*/
1512 i = code_get_u2(p + 1,m);
1515 constant_classref *cr;
1516 cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
1519 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1520 /*** s_count++; look for s_counts for VTA */
1521 /* add marked methods */
1522 CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
1523 XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T);
1524 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1528 case JAVA_CHECKCAST:
1529 case JAVA_INSTANCEOF:
1531 i = code_get_u2(p + 1,m);
1533 constant_classref *cr;
1535 cr = (constant_classref*) class_getconstant(m->class, i, CONSTANT_Class);
1538 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1540 CLASSNAMEop(cls,XTA_DEBUGr);
1541 if (cls->classUsed == NOTUSED){
1542 XTAaddClassInit(m, cls,
1543 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1544 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1555 xtaMethodCalls_and_sendReturnType(m);
1560 /* Helper fn for initialize **********************************************/
1562 int XTAgetline(char *line, int max, FILE *inFP) {
1563 if (fgets(line, max, inFP) == NULL)
1566 return strlen((const char *) line);
1569 /* Initialize XTA Work list ***********************************************/
1571 /*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
1572 #define SYSADD(cls,meth,desc, is_mono_poly, txt) \
1573 c = load_class_bootstrap(utf_new_char(cls)); \
1575 callmeth = class_resolveclassmethod(c, \
1576 utf_new_char(meth), \
1577 utf_new_char(desc), \
1580 if (callmeth->class->classUsed != USED) { \
1581 c->classUsed = PARTUSED; \
1582 XTAaddClassInit(callmeth, callmeth->class, \
1583 CLINITS_T,FINALIZE_T,ADDMARKED_T);\
1585 callmeth->monoPoly = is_mono_poly; \
1586 xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt);
1588 /*-- ----------------------------------------------------------------------------
1589 Initialize XTA work list with methods/classes from:
1592 xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
1593 -------------------------------------------------------------------------------*/
1594 methodinfo *initializeXTAworklist(methodinfo *m) {
1596 methodinfo* callmeth;
1597 char systxt[] = "2S addTo System Call :";
1598 char missedtxt[] = "2M addTo xtaMissedIn Call :";
1600 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1602 char* class, *meth, *desc;
1603 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1606 /* Create XTA call work list */
1607 xtaWorkList = NEW(list);
1608 list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
1610 /* Add first method to call list */
1611 m->class->classUsed = USED;
1612 xtaAddCallEdges(NULL, m, SYSCALL, systxt);
1614 /* Add system called methods */
1615 /*** SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
1616 SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
1618 /*** SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
1619 SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
1620 /*----- xtaMissedIn 0 */
1621 if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
1622 /*if (opt_verbose) */
1623 {printf("No xtaMissedIn0 file\n");fflush(stdout);}
1626 while (XTAgetline(line,256,xtaMissedIn)) {
1627 class = strtok(line, " \n");
1628 meth = strtok(NULL, " \n");
1629 desc = strtok(NULL, " \n");
1630 SYSADD(class,meth,desc, POLY, missedtxt)
1631 /* ??? Need to hand / hard code who calls it ??? */
1633 fclose(xtaMissedIn);
1642 /*- end initializeXTAworklist-------- */
1645 /*-------------------------------------------------------------------------------*/
1646 methodinfo *missedXTAworklist()
1648 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1649 char filenameIn[256] = "xtaIn/";
1651 char* class, *meth, *desc;
1653 char* calls_class, *calls_meth, *calls_desc;
1655 char missedtxt[] = "xtaIn/ missed Call :";
1657 methodinfo* callmeth;
1659 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1662 #if defined(USE_THREADS)
1663 SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
1664 SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
1666 /*----- xtaMissedIn pgm specific */
1667 strcat(filenameIn, (const char *)mainstring);
1668 if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
1669 /*if (opt_verbose)*/
1670 {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);}
1673 while (XTAgetline(line,256,xtaMissedIn)) {
1675 calls_class = strtok(line, " \n");
1676 calls_meth = strtok(NULL, " \n");
1677 calls_desc = strtok(NULL, " \n");
1679 class = strtok(NULL, " \n");
1681 class = strtok(line, " \n");
1682 meth = strtok(NULL, " \n");
1683 desc = strtok(NULL, " \n");
1686 if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL)
1687 || (class == NULL) || (meth == NULL) || (desc == NULL))
1689 if ( (class == NULL) || (meth == NULL) || (desc == NULL)) {
1690 log_text("Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc");
1693 SYSADD(class,meth,desc, POLY, missedtxt)
1695 fclose(xtaMissedIn);
1702 /*--------------------------------------------------------*/
1703 /* parseXTAmethod */
1704 /* input: method to be XTA static parsed */
1705 /*--------------------------------------------------------*/
1706 void parseXTAmethod(methodinfo *xta_method) {
1707 if (! ( (xta_method->flags & ACC_NATIVE )
1708 || (xta_method->flags & ACC_ABSTRACT) ) )
1710 /* XTA parse to approxmate....
1711 what classes/methods will really be used during execution */
1712 parseXTA(xta_method);
1715 if (xta_method->flags & ACC_NATIVE )
1717 METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
1718 /* parseXTApseudo(xta_method); */
1721 printf("Abstract method in XTA Work List: ");
1722 METHINFOx(xta_method);
1723 log_text("Abstract method in XTA Work List.");
1729 void XTAprintCallgraph (list *xtaWorkList, char * txt);
1731 /*-- XTA -- *******************************************************/
1732 int XTA_jit_parse(methodinfo *m)
1735 methodinfo *mainmeth;
1737 /* Should only be called once */
1740 /*----- XTA initializations --------*/
1742 log_text("XTA static analysis started.\n");
1744 mainmeth = initializeXTAworklist(m);
1745 /** XTAprintCallgraph (xtaWorkList, "after init1"); **/
1746 firstCall = false; /* turn flag off */
1748 if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
1749 printf("CACAO - xtaMissed file: cant open file to write\n");
1751 /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
1753 /*------ process XTA call work list --------*/
1754 for (xta =list_first(xtaWorkList);
1756 xta =list_next(xtaWorkList,xta))
1758 parseXTAmethod(xta->method);
1759 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
1761 missedXTAworklist();
1762 /** XTAprintCallgraph (xtaWorkList, "after missed"); **/
1763 for (xta =list_first(xtaWorkList);
1765 xta =list_next(xtaWorkList,xta))
1767 parseXTAmethod(xta->method);
1768 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
1774 printf("printXTAhierarchyInfo(m); not yet there\n");
1776 XTAprintCallgraph (xtaWorkList, "After all XTA parses");
1780 log_text("XTA static analysis done.\n");
1786 /*--------------------------------------------------------------*/
1787 void XTAprintCallgraph (list *xtaWorkList, char * txt)
1791 methodinfo *xta_meth;
1793 printf("\n%s\n",txt);
1794 #if defined(STATISTICS)
1795 printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
1798 for (xta =list_first(xtaWorkList);
1800 xta =list_next(xtaWorkList,xta))
1802 xta_meth = xta->method;
1804 printf(" (%i): ",i++);
1805 method_display_w_class(xta_meth);
1814 * These are local overrides for various environment variables in Emacs.
1815 * Please do not remove this and leave it at the end of the file, where
1816 * Emacs will automagically detect them.
1817 * ---------------------------------------------------------------------
1820 * indent-tabs-mode: t