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, 2006 R. Grafl, A. Krall, C. Kruegel,
18 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
19 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
20 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
39 Contact: cacao@cacaojvm.org
41 Authors: Carolyn Oates
43 Changes: Christian Thalinger
45 $Id: parseXTA.c 4357 2006-01-22 23:33:38Z twisti $
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/jit/jit.h"
138 #include "vm/jit/parse.h"
139 #include "vm/jit/inline/parseXTA.h"
140 #include "vm/jit/inline/parseRTstats.h"
141 #include "vm/jit/inline/parseRTprint.h"
145 static bool firstCall= true;
146 static list *xtaWorkList;
147 FILE *xtaMissed; /* Methods missed during XTA parse of Main */
149 bool XTA_DEBUGinf = false;
150 bool XTA_DEBUGr = false;
151 bool XTA_DEBUGopcodes = false;
153 char * clsFlgs [] = {"NOTUSED", "PARTUSED", "USED"};
154 char * methFlgs [] = {"NOTUSED", "MARKED", "USED"};
156 /*********************************************************************/
157 /*********************************************************************/
159 /* function descriptor2typesL ***************************************************
161 decodes a already checked method descriptor. The parameter count, the
162 return type and the argument types are stored in the passed methodinfo.
163 gets and saves classptr for object ref.s
165 *******************************************************************************/
167 static classSetNode *descriptor2typesL(methodinfo *m)
174 classinfo** classtypes;
177 classSetNode *p=NULL;
180 if (debugInfo >= 1) {
181 printf("In descriptor2typesL >>>\t"); fflush(stdout);
182 utf_display(m->class->name); printf(".");
183 method_println(m);fflush(stdout);
187 desc = MNEW (char, 256);
188 types = DMNEW (u1, m->descriptor->blength);
189 classtypes = MNEW (classinfo*, m->descriptor->blength+1);
190 m->returnclass = NULL;
192 if (!(m->flags & ACC_STATIC)) {
194 if (debugInfo >= 1) {
195 printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
197 classtypes[pcount] = m->class;
198 p = addClassCone(p, m->class);
202 utf_ptr = m->descriptor->text + 1;
203 strcpy (desc,utf_ptr);
205 while ((c = *desc++) != ')') {
212 case 'Z': *tptr++ = TYPE_INT;
214 case 'J': *tptr++ = TYPE_LNG;
216 case 'F': *tptr++ = TYPE_FLT;
218 case 'D': *tptr++ = TYPE_DBL;
220 case 'L': *tptr++ = TYPE_ADR;
221 /* get class string */
222 class = strtok(desc,";");
223 desc = strtok(NULL,"\0");
224 /* get/save classinfo ptr */
225 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
226 log_text("could not load class in descriptor2typesL");
229 classtypes[pcount-1] = clsinfo;
230 p = addClassCone(p, clsinfo);
231 if (debugInfo >= 1) {
232 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
233 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
234 utf_display(classtypes[pcount-1]->name);
237 case '[': *tptr++ = TYPE_ADR;
240 /* get class string */
242 class = strtok(desc,";");
243 desc = strtok(NULL,"\0");
244 /* get/save classinfo ptr */
245 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
246 log_text("could not load class in descriptor2typesL");
249 classtypes[pcount-1] = clsinfo;
250 p= addClassCone(p, clsinfo);
251 if (debugInfo >= 1) {
252 printf("[Param#%i 's class type is: %s\n",pcount-1,class);
253 printf("[classtypes[%i]=",pcount-1);fflush(stdout);
254 utf_display(classtypes[pcount-1]->name);
259 classtypes[pcount-1] = NULL;
262 log_text("Ill formed methodtype-descriptor");
267 /* compute return type */
273 case 'Z': m->returntype = TYPE_INT;
275 case 'J': m->returntype = TYPE_LNG;
277 case 'F': m->returntype = TYPE_FLT;
279 case 'D': m->returntype = TYPE_DBL;
282 m->returntype = TYPE_ADR;
292 m->returntype = TYPE_ADR;
294 /* get class string */
295 class = strtok(desc,";");
296 if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
297 log_text("could not load class in descriptor2typesL");
300 m->returnclass = clsinfo;
301 if (m->returnclass == NULL) {
302 printf("class=<%s>\t",class); fflush(stdout);
303 log_text("return class not found");
307 case 'V': m->returntype = TYPE_VOID;
311 log_text("Ill formed methodtype-descriptor-ReturnType");
315 m->paramcount = pcount;
316 m->paramtypes = types;
317 m->paramclass = classtypes;
321 for (i=0; i< m->paramcount; i++) {
322 if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
323 printf("Param #%i is:\t",i);
324 utf_display(m->paramclass[i]->name);
329 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
330 printf("\tReturn Type is:\t"); fflush(stdout);
331 utf_display(m->returnclass->name);
335 printf("params2types: START results in a set \n");
336 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
345 /*-------------------------------------------------------------------------------*/
347 xtafldinfo * xtafldinfoInit (fieldinfo *f)
352 f->xta = NEW(xtafldinfo);
354 f->xta->fieldChecked = false;
355 f->xta->fldClassType = NULL;
356 f->xta->XTAclassSet = NULL;
361 /*-------------------------------------------------------------------------------*/
363 xtainfo *xtainfoInit(methodinfo *m)
366 return m->xta; /* already initialized */
368 #if defined(ENABLE_STATISTICS)
369 count_methods_marked_used++;
372 m ->xta = (xtainfo *) NEW(xtainfo);
373 m ->xta-> XTAmethodUsed = NOTUSED;
375 /* xta sets for a method */
376 m->xta->fldsUsed = NULL;
377 m ->xta-> XTAclassSet = NULL;
378 /* Methods's have access to the class they are a part of */
379 m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
380 /* cone set of methods parameters */
381 /* what if no param?? is it NULL then, too? */
382 /****** class not loaded so take param info from superclass ??? */
383 m->xta->paramClassSet = descriptor2typesL(m);
386 m->xta->calls = NULL;
387 m->xta->calledBy = NULL;
388 m ->xta->markedBy = NULL;
390 m->xta->chgdSinceLastParse = false;
393 /* thought needed at some earlier point */
394 /*m ->xta->interfaceCalls = NULL*/
397 /*-------------------------------------------------------------------------------*/
398 void xtaAddCallEdges(methodinfo *mCalls, methodinfo *mCalled, s4 monoPoly, char *info) {
402 if (mCalled->flags & ACC_ABSTRACT) return;
403 /* First call to this method initializations */
405 printf("mCalled->methodUsed =%i != %i = USED is ",mCalled->methodUsed, USED); fflush(stdout);
406 printf(" <%i> T%i/%iF\n",(mCalled->methodUsed!= USED), true,false); fflush(stdout);
409 if (mCalled->methodUsed != USED) {
411 printf("\n>>>>>>%s:\n",info); fflush(stdout);
412 printf("Add to Worklist mCalls_=");fflush(stdout);
414 printf("<"); fflush(stdout);
416 printf("> "); fflush(stdout);
420 printf("NULL\n");fflush(stdout);
423 printf("mCalled=");fflush(stdout);
425 printf("<"); fflush(stdout);
427 printf("> "); fflush(stdout);
430 {printf("NULL\n");fflush(stdout);}
432 mCalled->xta = xtainfoInit(mCalled);
433 mCalled ->methodUsed = USED; /* used to see if method in the work list of methods */
435 xta->method = mCalled ;
436 list_addlast(xtaWorkList,xta);
439 if ((mCalls == NULL) && (!(monoPoly == SYSCALL)) ) {} /* panic when init file correct is */
441 if ((mCalls == mCalled) /* recursion doesn't change class set nor field set so ignore */
442 || (mCalls == NULL)) {return; }
445 /*** printf(" AddCallEdges\n"); fflush(stdout); ***/
447 mCalls->xta = xtainfoInit(mCalls);
448 mCalls->xta->calls = add2MethSet(mCalls->xta->calls, mCalled);
449 /* mono if static, private, final else virtual so poly */
450 mCalls->xta->calls->tail->monoPoly = monoPoly;
452 mCalled->xta->calledBy = add2MethSet(mCalled->xta->calledBy, mCalls);
454 /* IS THIS REALLY NEEDED???? */
455 if (mCalled->xta->calledBy == NULL) {
456 log_text("mCalled->xta->calledBy is NULL!!!");
459 if (mCalls->xta->calls == NULL) {
460 log_text("mCalls->xta->calls is NULL!!!");
467 /*-------------------------------------------------------------------------------*/
468 bool xtaPassParams (methodinfo *Called, methodinfo *Calls, methSetNode *lastptrInto)
476 /* prevent compiler warnings */
480 if (lastptrInto->lastptrIntoClassSet2 == NULL) {
481 if (Calls->xta->XTAclassSet != NULL)
482 c1 = Calls->xta->XTAclassSet->head;
483 /*else already c1 = NULL; */
486 /* start with type where left off */
487 c1 = lastptrInto->lastptrIntoClassSet2;
488 c1 = c1 -> nextClass; /* even if NULL */
490 if (c1 == NULL) return false;
493 /* for each Param Class */
494 for ( p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
496 /* for each SmCalls class */
497 for (c=c1; c != NULL; c = c->nextClass) {
501 LAZYLOADING(c->classType) /* if not loaded is it really needed ??? */
503 p_cl_vt = p->classType->vftbl;
504 c_cl_vt = c->classType->vftbl;
506 /* if SmCalls class is in the Params Class range */
507 if ( (p_cl_vt->baseval <= c_cl_vt->baseval)
508 && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
510 /* add Calls class to CalledBy Class set */
511 Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
517 lastptrInto->lastptrIntoClassSet2 = cprev;
522 /*-------------------------------------------------------------------------------*/
523 void xtaPassAllCalledByParams (methodinfo *m) {
524 methSetNode *SmCalled;
525 if (m->xta->calledBy == NULL)
527 for (SmCalled = m->xta->calledBy->head;
529 SmCalled = SmCalled->nextmethRef) {
530 m->xta->chgdSinceLastParse = false; /* re'init flag */
531 xtaPassParams(m, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
536 /*-------------------------------------------------------------------------------*/
537 void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
539 /* Field type is a class */
541 classSetNode *c1 = NULL;
542 classSetNode *cp = NULL;
543 classSetNode *cprev= NULL;
552 /* Use lastptr so don't check whole XTA class set each time */
555 if (cp->nextClass != NULL)
556 c1 = cp -> nextClass;
559 if (m->xta->XTAclassSet != NULL)
560 c1 = m->xta->XTAclassSet->head;
563 /*--- PUTSTATIC specific ---*/
564 /* Sx = intersection of type+subtypes(field x) */
565 /* and Sm (where putstatic code is) */
566 for (c=c1; c != NULL; c=c->nextClass) {
570 LAZYLOADING1(fi->xta->fldClassType)
572 f_cl_vt = fi->xta->fldClassType->vftbl;
573 c_cl_vt = c-> classType->vftbl;
574 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
575 && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
576 fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
580 fN->lastptrPUT = cprev;
582 /*-------------------------------------------------------------------------------*/
583 void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
585 /* Field type is a class */
587 classSetNode *c1 = NULL;
588 classSetNode *cp = NULL;
589 classSetNode *cprev= NULL;
597 /* Use lastptr so don't check whole XTA class set each time */
600 if (cp->nextClass != NULL)
601 c1 = cp -> nextClass;
604 if (fi->xta->XTAclassSet != NULL)
605 c1 = fi->xta->XTAclassSet->head;
608 /*--- GETSTATIC specific ---*/
609 /* Sm = union of Sm and Sx */
610 for (c=c1; c != NULL; c=c->nextClass) {
612 if (m->xta->XTAclassSet ==NULL)
615 if (!(inSet (m->xta->XTAclassSet->head, c->classType) ))
620 = add2ClassSet(m->xta->XTAclassSet,c->classType);
625 fN->lastptrGET = cprev;
629 /*-------------------------------------------------------------------------------*/
630 void xtaAllFldsUsed (methodinfo *m) {
633 /* bool chgd = false */
635 if (m->xta->fldsUsed == NULL) return;
637 /* for each field that this method uses */
638 f1 = m->xta->fldsUsed->head;
640 for (f=f1; f != NULL; f = f->nextfldRef) {
649 /*-------------------------------------------------------------------------------*/
650 bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
656 /* Get Called return class is null */
657 if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
658 Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */
661 if (Called->returnclass == NULL) {
665 if (Called->xta->XTAclassSet == NULL)
668 cs1 = Called->xta->XTAclassSet->head;
670 for (cs =cs1; cs != NULL; cs = cs->nextClass) {
671 classinfo *c = cs->classType;
675 LAZYLOADING(Called->returnclass)
676 r_cl_vt = Called->returnclass->vftbl;
679 /* if class is a subtype of the return type, then add to Calls class set (ie.interscection)*/
680 if ( (r_cl_vt->baseval <= r_cl_vt->baseval)
681 && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
682 Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);
691 /*-------------------------------------------------------------------------------*/
692 void xtaMethodCalls_and_sendReturnType(methodinfo *m)
694 methSetNode *SmCalled; /* for return type */
695 methSetNode *SmCalls; /* for calls param types */
696 methSetNode *s1=NULL;
701 if (m->xta == NULL) {
702 log_text("m->xta null for return type");
706 /* for each method that this method calls */
707 if (m->xta->calls == NULL)
710 s1 = SmCalls=m->xta->calls->head;
712 for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
713 /* pass param types */
715 chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
716 /* if true chgd after its own parse */
717 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
718 SmCalls->methRef->xta->chgdSinceLastParse = true;
722 /* for each calledBy method */
723 /* send return type */
724 if (m->xta->calledBy == NULL)
727 s1 = m->xta->calledBy->head;
728 for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
730 chgd = xtaPassReturnType(m, SmCalled->methRef);
731 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
732 SmCalled->methRef->xta->chgdSinceLastParse = chgd;
738 /*-------------------------------------------------------------------------------*/
739 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
741 bool is_classtype = false; /* return value */
743 if (fi->xta->fieldChecked) {
744 if (fi->xta->fldClassType != NULL)
745 return true; /* field has a class type */
749 fi->xta->fieldChecked = true;
751 if (fi->type == TYPE_ADDRESS) {
752 char *utf_ptr = fi->descriptor->text; /* current position in utf text */
754 if (*utf_ptr != 'L') {
755 while (*utf_ptr++ =='[') ;
758 if (*utf_ptr =='L') {
760 if (fi->xta->fldClassType== NULL) {
765 desc = MNEW(char, 256);
766 strcpy(desc,++utf_ptr);
767 cname = strtok(desc,";");
768 if (!(class = load_class_bootstrap(utf_new_char(cname)))) {
769 log_text("could not load class in xtaAddFldClassTypeInfo");
772 fi->xta->fldClassType= class; /* save field's type class ptr */
779 /*--------------------------------------------------------------*/
780 /* Mark the method with same name /descriptor in topmethod */
783 /* Class marked USED and method defined in this class -> */
784 /* -> add call edges = USED */
785 /* Class not marked USED and method defined in this class -> */
786 /* -> if Method NOTUSED mark method as MARKED */
788 /* Class USED, but method not defined in this class -> */
789 /* -> 1) search up the heirarchy and mark method where defined */
790 /* 2) if class where method is defined is not USED -> */
791 /* -> ????mark class with defined method as PARTUSED */
792 /*--------------------------------------------------------------*/
795 void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
797 utf *name = topmethod->name;
798 utf *descriptor = topmethod->descriptor;
801 /* See if method defined in class heirarchy */
802 submeth = class_resolvemethod(class, name, descriptor);
803 METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
804 if (submeth == NULL) {
805 utf_display(class->name); printf(".");
806 METHINFOx(topmethod);
807 printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
811 /* if submeth called previously from this method then return */
812 if (mCalls->xta->calls != NULL) {
813 if (inMethSet(mCalls->xta->calls->head,submeth)) return;
818 XTAaddClassInit(submeth, submeth->class,
819 CLINITS_T,FINALIZE_T,ADDMARKED_T);
820 if (inSet(subtypesUsedSet,submeth->class)) {
821 submeth->monoPoly = POLY;
822 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
823 "00addTo XTA VIRT CONE:");
828 if (submeth->class == class) {
830 /*--- Method defined in class -----------------------------*/
831 if (inSet(subtypesUsedSet,submeth->class)) {
832 /* method defined in this class -> */
833 /* Class IS marked USED */
834 /* -> mark method as USED */
835 submeth->monoPoly = POLY;
836 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
837 "01addTo VIRT CONE 1:");
840 /* method defined in this class -> */
841 /* Class IS NOT marked USED (PART or NOTUSED) */
842 /* -> if Method NOTUSED mark method as MARKED */
844 "\tmarked VIRT CONE 2:",XTA_DEBUGr);
845 submeth->monoPoly = POLY;
846 if (submeth->xta == NULL) {
847 submeth->xta = xtainfoInit(submeth);
849 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
850 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
851 /* Note: if class NOTUSED and subclass is used handled */
852 /* by subsequent calls to xtaMarkMethods for cone */
854 } /* end defined in class */
857 /*--- Method NOT defined in class - defined up the heirarchy ---------------*/
858 /* then check class the method could be called with */
860 /* first mark classes if needed */
861 if (!(inSet(subtypesUsedSet,submeth->class))) {
862 submeth->class->classUsed = PARTUSED;
863 if (!(inSet(subtypesUsedSet,class))) {
864 submeth->monoPoly = POLY;
865 if (submeth->xta == NULL)
866 submeth->xta = xtainfoInit(submeth);
867 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
868 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
869 METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
872 /* add method to xta work list if conditions met */
873 if (inSet(subtypesUsedSet,class)) {
874 submeth->monoPoly = POLY;
875 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
876 "02addTo VIRT CONE 3:");
878 } /* end NOT defined in class */
882 /*----------------------------------------------------------------------*/
883 /* Mark the method with the same name and descriptor as topmethod */
884 /* and any subclass where the method is defined and/or class is used */
886 /*----------------------------------------------------------------------*/
888 void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
889 /* xtaPRINTmarkSubs1*/
890 xtaMarkMethod(class, mCalls, topmethod, subtypesUsedSet); /* Mark method in class where it was found */
891 if (class->sub != NULL) {
894 if (!(topmethod->flags & ACC_FINAL )) {
895 for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
896 xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
903 /**************************************************************************/
904 /* Add Marked methods for input class ci */
905 /* Add methods with the same name and descriptor as implemented interfaces*/
906 /* with the same method name */
907 /* ??? interface part not XTA checked */
908 /*------------------------------------------------------------------------*/
909 void xtaAddMarkedMethods(methodinfo *mCalls, classinfo *ci) {
912 /* add marked methods to callgraph */
913 for (ii=0; ii<ci->methodscount; ii++) {
914 methodinfo *mi = &(ci->methods[ii]);
916 if (mi->xta != NULL) {
917 if (mi->xta->markedBy != NULL) {
919 for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
920 methodinfo *mCalls = mcnode->methRef;
921 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
922 "03addToInit was Marked added:");
926 else { /* NOT XTA checked yet */
927 for (jj=0; jj < ci -> interfacescount; jj++) {
928 classinfo *ici = ci -> interfaces [jj].cls;
929 /* use resolve method....!!!! */
930 if (ici -> classUsed != NOTUSED) {
931 for (mm=0; mm< ici->methodscount; mm++) {
932 methodinfo *imi = &(ici->methods[mm]);
933 METHINFOt(imi,"NEW IMPD INTERFACE:",XTA_DEBUGinf)
934 /*if interface method=method is used*/
935 if ( (imi->methodUsed == USED)
936 && ( (imi->name == mi->name)
937 && (imi->descriptor == mi->descriptor))) {
938 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
939 "04addTo was interfaced used/MARKED:");
950 /*------------------------------------------------------------------------*/
951 void xtaAddUsedInterfaceMethods(methodinfo *m, classinfo *ci) {
954 /* add used interfaces methods to callgraph */
955 for (jj=0; jj < ci -> interfacescount; jj++) {
956 classinfo *ici = ci -> interfaces [jj].cls;
959 printf("BInterface used: ");fflush(stdout);
960 utf_display(ici->name);
961 printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); fflush(stdout);
963 /* add class to interfaces list of classes that implement it */
964 ici -> impldBy = addElement(ici -> impldBy, ci);
966 /* if interface class is used */
967 if (ici -> classUsed != NOTUSED) {
969 /* for each interface method implementation that has already been used */
970 for (mm=0; mm< ici->methodscount; mm++) {
971 methodinfo *imi = &(ici->methods[mm]);
972 if ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
973 printf("Interface Method %s: ", methFlgs[imi->methodUsed]);
974 utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
976 if (imi->methodUsed == USED) {
978 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
979 /* Mark this method used in the (used) implementing class &its subclasses */
980 printf("rMAY ADD methods that was used by an interface\n");
982 if ((utf_clinit != imi->name) &&
983 (utf_init != imi->name))
985 classSetNode *subtypesUsedSet = NULL;
986 if (m->xta->XTAclassSet != NULL) {
988 intersectSubtypesWithSet
989 (imi->class, m->xta->XTAclassSet->head);
991 else /* can any methods be added if 1 set is NULL ??? */
992 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
993 xtaMarkSubs(m, ci, imi, subtypesUsedSet);
994 imi->monoPoly = POLY;
998 } /* end for method */
999 } /* end != NOTUSED */
1000 } /* end for interface */
1005 /*----------------------------------------------------------------------*/
1007 #define CLINITS_T true
1008 #define FINALIZE_T true
1009 #define ADDMARKED_T true
1011 #define CLINITS_F false
1012 #define FINALIZE_F false
1013 #define ADDMARKED_F false
1014 /*-----------------------*/
1016 void XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
1021 ci->classUsed = USED;
1023 if (clinits) { /* No <clinit> available - ignore */
1024 mi = class_findmethod(ci, utf_clinit, utf_void__void);
1026 if (ci->classUsed != USED)
1027 ci->classUsed = PARTUSED;
1028 mi->monoPoly = MONO;
1029 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1030 "05addTo CLINIT added:");
1034 /*Special Case for System class init:
1035 add java/lang/initializeSystemClass to callgraph */
1036 if (ci->name == utf_new_char("initializeSystemClass")) {
1037 /* ?? what is name of method ?? */
1041 mi = class_findmethod(ci, utf_finalize, utf_void__void);
1043 if (ci->classUsed != USED)
1044 ci->classUsed = PARTUSED;
1045 mi->monoPoly = MONO;
1046 xtaAddCallEdges(mCalls, mi, mi->monoPoly,
1047 "06addTo FINALIZE added:");
1052 xtaAddMarkedMethods(mCalls, ci);
1055 /* always so know have access to the interface methods */
1056 xtaAddUsedInterfaceMethods(mCalls,ci);
1060 /*-------------------------------------------------------------------------------*/
1062 /*********************************************************************/
1063 /*********************************************************************/
1065 /*-------------------------------------------------------------------*/
1067 void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {
1069 if (mi->class->classUsed == NOTUSED) {
1070 mi->class->classUsed = USED;
1071 /* add interface class to list kept in Object */
1072 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
1075 mi->methodUsed = USED;
1076 mi->monoPoly = POLY;
1078 /*XTAPRINT08invokeInterface1*/
1080 subs = mi->class->impldBy;
1081 METHINFO(mi,XTA_DEBUGinf)
1082 printf("Implemented By classes :\n");fflush(stdout);
1083 if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
1085 for (subs = mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
1086 methodinfo *submeth;
1088 printf("\t");utf_display(subs->classType->name);fflush(stdout);
1089 printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
1092 /*Mark method (mark/used) in classes that implement method*/
1093 submeth = class_findmethod(subs->classType, mi->name, mi->descriptor);
1094 if (submeth != NULL) {
1095 classSetNode *subtypesUsedSet = NULL;
1096 submeth->monoPoly = POLY; /* poly even if nosubs */
1097 submeth->xta = xtainfoInit(submeth);
1099 submeth->xta->XTAmethodUsed = USED;
1100 if (m->xta->XTAclassSet != NULL) {
1101 subtypesUsedSet = /* interface classes cone */
1102 intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
1104 else { /* can any methods be added if 1 set is NULL ??? */
1105 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1107 xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
1115 /*********************************************************************/
1117 int parseXTA(methodinfo *m)
1119 int p; /* java instruction counter */
1120 int nextp; /* start of next java instruction */
1121 int opcode; /* java opcode */
1122 int i; /* temp for different uses (counters)*/
1123 bool iswide = false; /* true if last instruction was a wide*/
1126 if (m->methodXTAparsed) return 0;
1127 else m->methodXTAparsed = true;
1129 /***XTA_DEBUGopcodes=false;***/
1130 /***printf("\n-----------------------------------\n"); **/
1131 METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes);
1132 if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
1133 /***XTA_DEBUGopcodes=false;***/
1134 if (m->xta == NULL) {
1138 xtaPassAllCalledByParams (m);
1141 /* scan all java instructions */
1142 for (p = 0; p < m->jcodelength; p = nextp) {
1144 opcode = code_get_u1(p,m); /* fetch op code */
1145 SHOWOPCODE(XTA_DEBUGopcodes)
1147 nextp = p + jcommandsize[opcode]; /* compute next instr start */
1148 if (nextp > m->jcodelength) {
1149 log_text("Unexpected end of bytecode");
1183 /* wider index for loading, storing and incrementing */
1197 case JAVA_LOOKUPSWITCH:
1200 nextp = ALIGN((p + 1), 4) + 4;
1201 num = code_get_u4(nextp,m);
1202 nextp += (code_get_u4(nextp,m)) * 8 + 4;
1207 case JAVA_TABLESWITCH:
1210 nextp = ALIGN ((p + 1),4);
1211 num = code_get_s4(nextp + 4, m);
1212 num = code_get_s4(nextp + 8, m) - num;
1213 nextp = nextp + 16 + 4 * num;
1216 /*********************/
1218 case JAVA_PUTSTATIC: /* write */
1220 i = code_get_u2(p + 1,m);
1222 constant_FMIref *fr;
1226 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1229 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1230 log_text("Could not resolve class reference");
1233 LAZYLOADING(frclass)
1235 fi = class_resolvefield(frclass,
1242 return 0; /* was NULL */
1244 printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1245 utf_display(fi->name);printf("\n");fflush(stdout);
1247 fi->xta = xtafldinfoInit(fi);
1248 XTAaddClassInit(m, fi->class,
1249 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1250 if (xtaAddFldClassTypeInfo(fi)) {
1251 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
1257 case JAVA_GETSTATIC: /* read */
1259 i = code_get_u2(p + 1,m);
1261 constant_FMIref *fr;
1265 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1268 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
1269 log_text("Could not resolve class reference");
1273 LAZYLOADING(frclass)
1275 fi = class_resolvefield(frclass,
1282 return 0; /* was NULL */
1285 printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1286 utf_display(fi->name);printf("\n");fflush(stdout);
1288 fi->xta = xtafldinfoInit(fi);
1289 XTAaddClassInit(m, fi->class,
1290 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1291 if (xtaAddFldClassTypeInfo(fi)) {
1292 m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
1300 case JAVA_INVOKESTATIC:
1301 case JAVA_INVOKESPECIAL:
1302 i = code_get_u2(p + 1,m);
1304 constant_FMIref *mr;
1308 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1311 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1312 log_text("Could not resolve class reference");
1316 LAZYLOADING(mrclass)
1317 mi = class_resolveclassmethod( mrclass,
1325 METHINFOt(mi,"INVOKESTAT/SPEC:: ",XTA_DEBUGopcodes)
1326 mi->monoPoly = MONO;
1328 /*---- Handle "leaf" = static, private, final calls-------------*/
1329 if ((opcode == JAVA_INVOKESTATIC)
1330 || (mi->flags & ACC_STATIC)
1331 || (mi->flags & ACC_PRIVATE)
1332 || (mi->flags & ACC_FINAL) )
1334 if (mi->class->classUsed != USED) { /* = NOTUSED or PARTUSED */
1335 XTAaddClassInit(m, mi->class,
1336 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1337 /* Leaf methods are used whether class is or not */
1338 /* so mark class as PARTlyUSED */
1339 mi->class->classUsed = PARTUSED;
1341 /* Add to XTA working list/set of reachable methods */
1342 if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
1343 /* calls , called */
1344 xtaAddCallEdges(m, mi, MONO,
1345 "07addTo INVOKESTATIC ");
1347 xtaAddCallEdges(m, mi, MONO,
1348 "08addTo INVOKESPECIAL ");
1349 } /* end STATIC, PRIVATE, FINAL */
1352 /*---- Handle special <init> calls ---------------------------------------------*/
1354 if (mi->class->classUsed != USED) {
1355 /* XTA special case:
1356 call of super's <init> then
1357 methods of super class not all used */
1359 /*--- <init> ()V is equivalent to "new"
1360 indicating a class is used = instaniated ---- */
1361 if (utf_init==mi->name) {
1362 if ((m->class->super.cls == mi->class)
1363 && (m->descriptor == utf_void__void) )
1365 METHINFOt(mi,"SUPER INIT:",XTA_DEBUGopcodes);
1366 /* super init so class may be only used because of its sub-class */
1367 XTAaddClassInit(m,mi->class,
1368 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1369 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
1372 /* since <init> indicates classes is used, then add marked methods, too */
1373 METHINFOt(mi,"NORMAL INIT:",XTA_DEBUGopcodes);
1374 XTAaddClassInit(m, mi->class,
1375 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1377 xtaAddCallEdges(m, mi, MONO,
1379 } /* end just for <init> ()V */
1381 /* <clinit> for class inits do not add marked methods;
1382 class not yet instaniated */
1383 if (utf_clinit==mi->name)
1384 XTAaddClassInit(m, mi->class,
1385 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1387 if (!((utf_init==mi->name))
1388 || (utf_clinit==mi->name)) {
1389 METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
1390 if (mi->class->classUsed !=USED)
1391 mi->class->classUsed = PARTUSED;
1392 xtaAddCallEdges(m, mi, MONO,
1393 "10addTo SPEC notINIT ");
1396 } /* end init'd class not used = class init process was needed */
1398 /* add method to XTA list = set of reachable methods */
1399 xtaAddCallEdges(m, mi, MONO,
1400 "11addTo SPEC whymissed ");
1403 /*** assume if method can't be resolved won't actually be called or
1404 there is a real error in classpath and in normal parse an exception
1405 will be thrown. Following debug print can verify this
1407 CLASSNAME1(mrclass,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
1408 utf_display(mr->name); printf(" "); fflush(stdout);
1409 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1414 case JAVA_INVOKEVIRTUAL:
1415 i = code_get_u2(p + 1,m);
1417 constant_FMIref *mr;
1421 /* XXX remove direct access */
1422 mr = m->class->cpinfos[i];
1423 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
1424 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1425 log_text("Could not resolve class reference");
1429 LAZYLOADING(mrclass)
1430 mi = class_resolveclassmethod(mrclass,
1439 METHINFOt(mi,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
1440 if ((mi->flags & ACC_STATIC)
1441 || (mi->flags & ACC_PRIVATE)
1442 || (mi->flags & ACC_FINAL) )
1443 { /*** DOES THIS EVER OCCUR ??? */
1444 if (mi->class->classUsed == NOTUSED){
1445 XTAaddClassInit(m, mi->class,
1446 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1448 mi->monoPoly = MONO;
1449 xtaAddCallEdges(m, mi, MONO,
1450 "12addTo INVOKEVIRTUAL ");
1452 else { /* normal virtual */
1453 /* get the set of used subtypes if none at least the current methods class */
1454 classSetNode *subtypesUsedSet = NULL;
1455 if (m->xta->XTAclassSet != NULL) {
1457 intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
1459 else { /* can any methods be added if 1 set is NULL ??? */
1460 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1462 mi->monoPoly = POLY;
1463 xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
1467 CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
1468 utf_display(mr->name); printf(" "); fflush(stdout);
1469 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1474 case JAVA_INVOKEINTERFACE:
1475 i = code_get_u2(p + 1,m);
1477 constant_FMIref *mr;
1481 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1484 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
1485 log_text("Could not resolve class reference");
1489 LAZYLOADING(mrclass)
1491 mi = class_resolveinterfacemethod(mrclass,
1498 METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
1499 xtaMarkInterfaceSubs(m,mi);
1501 /* see INVOKESTATIC for explanation about */
1502 /* case when Interface is not resolved */
1503 /*method_descriptor2types(mi);
1504 ?? do need paramcnt? for XTA (or just XTA)*/
1509 /* means class is at least passed as a parameter */
1510 /* class is really instantiated when class.<init> called*/
1511 i = code_get_u2(p + 1,m);
1514 constant_classref *cr;
1515 cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
1518 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1519 /*** s_count++; look for s_counts for VTA */
1520 /* add marked methods */
1521 CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
1522 XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T);
1523 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1527 case JAVA_CHECKCAST:
1528 case JAVA_INSTANCEOF:
1530 i = code_get_u2(p + 1,m);
1532 constant_classref *cr;
1534 cr = (constant_classref*) class_getconstant(m->class, i, CONSTANT_Class);
1537 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
1539 CLASSNAMEop(cls,XTA_DEBUGr);
1540 if (cls->classUsed == NOTUSED){
1541 XTAaddClassInit(m, cls,
1542 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1543 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1554 xtaMethodCalls_and_sendReturnType(m);
1559 /* Helper fn for initialize **********************************************/
1561 int XTAgetline(char *line, int max, FILE *inFP) {
1562 if (fgets(line, max, inFP) == NULL)
1565 return strlen((const char *) line);
1568 /* Initialize XTA Work list ***********************************************/
1570 /*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
1571 #define SYSADD(cls,meth,desc, is_mono_poly, txt) \
1572 c = load_class_bootstrap(utf_new_char(cls)); \
1574 callmeth = class_resolveclassmethod(c, \
1575 utf_new_char(meth), \
1576 utf_new_char(desc), \
1579 if (callmeth->class->classUsed != USED) { \
1580 c->classUsed = PARTUSED; \
1581 XTAaddClassInit(callmeth, callmeth->class, \
1582 CLINITS_T,FINALIZE_T,ADDMARKED_T);\
1584 callmeth->monoPoly = is_mono_poly; \
1585 xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt);
1587 /*-- ----------------------------------------------------------------------------
1588 Initialize XTA work list with methods/classes from:
1591 xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
1592 -------------------------------------------------------------------------------*/
1593 methodinfo *initializeXTAworklist(methodinfo *m) {
1595 methodinfo* callmeth;
1596 char systxt[] = "2S addTo System Call :";
1597 char missedtxt[] = "2M addTo xtaMissedIn Call :";
1599 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1601 char* class, *meth, *desc;
1602 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1605 /* Create XTA call work list */
1606 xtaWorkList = NEW(list);
1607 list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
1609 /* Add first method to call list */
1610 m->class->classUsed = USED;
1611 xtaAddCallEdges(NULL, m, SYSCALL, systxt);
1613 /* Add system called methods */
1614 /*** SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
1615 SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
1617 /*** SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
1618 SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
1619 /*----- xtaMissedIn 0 */
1620 if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
1621 /*if (opt_verbose) */
1622 {printf("No xtaMissedIn0 file\n");fflush(stdout);}
1625 while (XTAgetline(line,256,xtaMissedIn)) {
1626 class = strtok(line, " \n");
1627 meth = strtok(NULL, " \n");
1628 desc = strtok(NULL, " \n");
1629 SYSADD(class,meth,desc, POLY, missedtxt)
1630 /* ??? Need to hand / hard code who calls it ??? */
1632 fclose(xtaMissedIn);
1641 /*- end initializeXTAworklist-------- */
1644 /*-------------------------------------------------------------------------------*/
1645 methodinfo *missedXTAworklist()
1647 FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1648 char filenameIn[256] = "xtaIn/";
1650 char* class, *meth, *desc;
1652 char* calls_class, *calls_meth, *calls_desc;
1654 char missedtxt[] = "xtaIn/ missed Call :";
1656 methodinfo* callmeth;
1658 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
1661 #if defined(USE_THREADS)
1662 SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
1663 SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
1665 /*----- xtaMissedIn pgm specific */
1666 strcat(filenameIn, (const char *)mainstring);
1667 if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
1668 /*if (opt_verbose)*/
1669 {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);}
1672 while (XTAgetline(line,256,xtaMissedIn)) {
1674 calls_class = strtok(line, " \n");
1675 calls_meth = strtok(NULL, " \n");
1676 calls_desc = strtok(NULL, " \n");
1678 class = strtok(NULL, " \n");
1680 class = strtok(line, " \n");
1681 meth = strtok(NULL, " \n");
1682 desc = strtok(NULL, " \n");
1685 if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL)
1686 || (class == NULL) || (meth == NULL) || (desc == NULL))
1688 if ( (class == NULL) || (meth == NULL) || (desc == NULL)) {
1689 log_text("Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc");
1692 SYSADD(class,meth,desc, POLY, missedtxt)
1694 fclose(xtaMissedIn);
1701 /*--------------------------------------------------------*/
1702 /* parseXTAmethod */
1703 /* input: method to be XTA static parsed */
1704 /*--------------------------------------------------------*/
1705 void parseXTAmethod(methodinfo *xta_method) {
1706 if (! ( (xta_method->flags & ACC_NATIVE )
1707 || (xta_method->flags & ACC_ABSTRACT) ) )
1709 /* XTA parse to approxmate....
1710 what classes/methods will really be used during execution */
1711 parseXTA(xta_method);
1714 if (xta_method->flags & ACC_NATIVE )
1716 METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
1717 /* parseXTApseudo(xta_method); */
1720 printf("Abstract method in XTA Work List: ");
1721 METHINFOx(xta_method);
1722 log_text("Abstract method in XTA Work List.");
1728 void XTAprintCallgraph (list *xtaWorkList, char * txt);
1730 /*-- XTA -- *******************************************************/
1731 int XTA_jit_parse(methodinfo *m)
1734 methodinfo *mainmeth;
1736 /* Should only be called once */
1739 /*----- XTA initializations --------*/
1741 log_text("XTA static analysis started.\n");
1743 mainmeth = initializeXTAworklist(m);
1744 /** XTAprintCallgraph (xtaWorkList, "after init1"); **/
1745 firstCall = false; /* turn flag off */
1747 if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
1748 printf("CACAO - xtaMissed file: cant open file to write\n");
1750 /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
1752 /*------ process XTA call work list --------*/
1753 for (xta =list_first(xtaWorkList);
1755 xta =list_next(xtaWorkList,xta))
1757 parseXTAmethod(xta->method);
1758 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
1760 missedXTAworklist();
1761 /** XTAprintCallgraph (xtaWorkList, "after missed"); **/
1762 for (xta =list_first(xtaWorkList);
1764 xta =list_next(xtaWorkList,xta))
1766 parseXTAmethod(xta->method);
1767 /** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
1773 printf("printXTAhierarchyInfo(m); not yet there\n");
1775 XTAprintCallgraph (xtaWorkList, "After all XTA parses");
1779 log_text("XTA static analysis done.\n");
1785 /*--------------------------------------------------------------*/
1786 void XTAprintCallgraph (list *xtaWorkList, char * txt)
1790 methodinfo *xta_meth;
1792 printf("\n%s\n",txt);
1793 #if defined(ENABLE_STATISTICS)
1794 printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
1797 for (xta =list_first(xtaWorkList);
1799 xta =list_next(xtaWorkList,xta))
1801 xta_meth = xta->method;
1803 printf(" (%i): ",i++);
1804 method_println(xta_meth);
1813 * These are local overrides for various environment variables in Emacs.
1814 * Please do not remove this and leave it at the end of the file, where
1815 * Emacs will automagically detect them.
1816 * ---------------------------------------------------------------------
1819 * indent-tabs-mode: t