Changed some includes.
[cacao.git] / src / vm / jit / inline / parseXTA.c
1 /*****
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
4    what about clinits?
5 Check initialization... need at least a dummy called by ...
6
7 ... why no error now????
8
9 What about recursion???  x.a calls x.a
10
11 Now wondering if there is a memory corruption because XTA seems to finish ok
12 ****/
13
14 /* jit/parseXTA.c - parser and print functions for Rapid Type Analyis
15
16    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
17    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
18    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
19    Institut f. Computersprachen - TU Wien
20
21    This file is part of CACAO.
22
23    This program is free software; you can redistribute it and/or
24    modify it under the terms of the GNU General Public License as
25    published by the Free Software Foundation; either version 2, or (at
26    your option) any later version.
27
28    This program is distributed in the hope that it will be useful, but
29    WITHOUT ANY WARRANTY; without even the implied warranty of
30    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31    General Public License for more details.
32
33    You should have received a copy of the GNU General Public License
34    along with this program; if not, write to the Free Software
35    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
36    02111-1307, USA.
37
38    Contact: cacao@complang.tuwien.ac.at
39
40    Authors: Carolyn Oates
41
42    $Id: parseXTA.c 2107 2005-03-28 22:44:28Z twisti $
43
44 */
45
46 /*--------------------------------------
47 XTA so far
48 static
49 fields
50 virtual 
51 interfaces - started
52 clinit / final
53 general initialization 
54 ----
55 interfaces
56 + hand coded calls for system
57 2nd interation (want to try it in inlining)
58
59 Testing
60
61 ?? PARTUSED???
62 ----------------------------------*/
63
64 /***************
65  XTA Type Static Analysis of Java program
66    used -xta option is turned on either explicitly 
67  or automatically with inlining of virtuals.
68
69  XTA is called for reachable methods and keeps sets for each Method and Field used as follows:
70 1. Work list of reachable methods is initialized to main + JVM called methods 
71                                                 + missed methods
72 2. For virtual method call from M of e.m then
73   a. Add all static lookup of m in the cone of e = ce.mi to reachable worklist
74         JAVA_INVOKESTATIC/ JAVA_INVOKESPECIAL - xtaAddCallEdges
75         JAVA_INVOKEVIRTUAL - xtaMarkSubs 
76         JAVA_INVOKEINTERFACES
77   b. Add mi's parameters class + subtypes that are used by M to mi used classes
78         When XTA parsed follow the calls list (beg. parseXTA)
79   c. Add mi's return type + subtypes used by mi to M's used classes
80         When XTA parsed follow the calledBy list (end parseXTA)
81   d. Add ce of mi to mi's used classes
82         static/special  - addXTAcalledges
83         virtual - xtaMarkSubs if subclass used     -> xtaAddCallEdges
84                               if subclass not used -> add ce.mi to markedby temp set 
85
86 3. new C (new, <init>, & similiar) then add  C to M's used classes
87         JAVA_NEW, INVOKE_SPECIAL <init>, JAVA_CHECKCAST / JAVA_INSTANCEOF - classinit 
88 4. read Field X.f: add X to M's used classes
89         JAVA_GETSTATIC
90 5. write Field X.f: add X+subtypes that are used by M to X's classes
91         JAVA_PUTSTATIC
92
93  
94  If M calls 
95  USAGE:
96  Methods called by NATIVE methods and classes loaded dynamically
97  cannot be found by parsing. The following files supply missing methods:
98
99  xtaMissedIn0 - (provided) has the methods missed by every java program
100  xtaMissed||mainClassName - is program specific.
101
102  A file xtaMissed will be written by XTA analysis of any methods missed.
103
104  This file can be renamed to xtaMissed concatenated with the main class name.
105
106  Example:
107  ./cacao -xta hello
108
109  inlining with virtuals should fail if the returned xtaMissed is not empty.
110  so...
111  mv xtaMissed xtaMissedhello
112  ./cacao hello
113
114 Results: (currently) with -stat see # methods marked used
115  
116 ****************/
117
118 #include <stdio.h>
119 #include <string.h>
120
121 #include "config.h"
122 #include "cacao/cacao.h"
123 #include "mm/memory.h"   
124 #include "toolbox/list.h"
125 #include "vm/class.h"
126 #include "vm/linker.h"
127 #include "vm/loader.h"
128 #include "vm/options.h"
129 #include "vm/statistics.h"
130 #include "vm/tables.h"
131 #include "vm/jit/jit.h"
132 #include "vm/jit/parse.h"
133 #include "vm/jit/inline/parseXTA.h"
134 #include "vm/jit/inline/parseRTstats.h"
135 #include "vm/jit/inline/parseRTprint.h"
136
137
138
139 static bool firstCall= true;
140 static list *xtaWorkList;
141 FILE *xtaMissed;   /* Methods missed during XTA parse of Main  */
142
143 bool XTA_DEBUGinf = false;
144 bool XTA_DEBUGr = false;
145 bool XTA_DEBUGopcodes = false;
146
147 char * clsFlgs  [] = {"NOTUSED", "PARTUSED", "USED"};
148 char * methFlgs [] = {"NOTUSED", "MARKED",   "USED"};
149
150 /*********************************************************************/
151 /*********************************************************************/
152
153 /*-------------------------------------------------------------------------------*/
154
155 xtafldinfo * xtafldinfoInit (fieldinfo *f)
156 {
157         if (f->xta != NULL)
158                 return f->xta;
159
160         f->xta = NEW(xtafldinfo);
161
162         f->xta->fieldChecked = false;
163         f->xta->fldClassType = NULL;
164         f->xta->XTAclassSet = NULL;
165
166         return f->xta;
167 }
168
169 /*-------------------------------------------------------------------------------*/
170
171 xtainfo *xtainfoInit(methodinfo *m)
172 {
173         if (m->xta != NULL)
174                 return m->xta; /* already initialized */
175
176 #if defined(STATISTICS)
177         count_methods_marked_used++;
178 #endif
179
180         m ->xta = (xtainfo *) NEW(xtainfo);
181         m ->xta-> XTAmethodUsed = NOTUSED;
182
183         /* xta sets for a method */
184         m->xta->fldsUsed        = NULL;
185         m ->xta-> XTAclassSet   = NULL;
186                                 /* Methods's have access to the class they are a part of */
187         m ->xta-> XTAclassSet   = add2ClassSet ( m ->xta-> XTAclassSet, m->class);  
188         /* cone set of methods parameters */ 
189                  /* what if no param?? is it NULL then, too? */ 
190    /****** class not loaded so take param info from superclass ??? */
191         m->xta->paramClassSet = descriptor2typesL(m); 
192
193         /* Edges */
194         m->xta->calls         = NULL;
195         m->xta->calledBy      = NULL;
196         m ->xta->markedBy     = NULL; 
197
198         m->xta->chgdSinceLastParse = false;
199         return m->xta;
200
201         /* thought needed at some earlier point */
202         /*m ->xta->interfaceCalls    = NULL*/
203 }
204
205 /*-------------------------------------------------------------------------------*/
206 void xtaAddCallEdges(methodinfo *mCalls, methodinfo *mCalled, s4 monoPoly, char *info) {
207     xtaNode    *xta = NULL;
208
209
210 if (mCalled->flags & ACC_ABSTRACT) return;
211 /* First call to this method initializations */
212                 /******
213 printf("mCalled->methodUsed =%i != %i = USED is ",mCalled->methodUsed, USED); fflush(stdout);
214 printf(" <%i> T%i/%iF\n",(mCalled->methodUsed!= USED), true,false); fflush(stdout);
215                 ******/
216
217 if (mCalled->methodUsed != USED) {
218                 /******
219                 printf("\n>>>>>>%s:\n",info); fflush(stdout);
220                 printf("Add to Worklist mCalls_=");fflush(stdout);
221                 if (mCalls!=NULL) {
222                         printf("<"); fflush(stdout);
223                         METHINFOx(mCalls)
224                         printf("> "); fflush(stdout);
225                         }
226                 else
227                         {
228                         printf("NULL\n");fflush(stdout);
229                         }
230
231                 printf("mCalled=");fflush(stdout);
232                 if (mCalled!=NULL) {
233                         printf("<"); fflush(stdout);
234                         METHINFOx(mCalled)
235                         printf("> "); fflush(stdout);
236                         }
237                 else
238                         {printf("NULL\n");fflush(stdout);}
239                 ****/
240     mCalled->xta = xtainfoInit(mCalled);
241     mCalled ->methodUsed = USED; /* used to see if method in the work list of methods */ 
242     xta = NEW(xtaNode);
243     xta->method = mCalled ;
244     list_addlast(xtaWorkList,xta);  
245     }
246
247 if ((mCalls == NULL) && (!(monoPoly == SYSCALL)) ) {} /* panic when init file correct is */
248
249 if ((mCalls == mCalled)  /* recursion doesn't change class set nor field set so ignore */
250   || (mCalls == NULL)) {return; }  
251
252
253 /***            printf(" AddCallEdges\n"); fflush(stdout); ***/
254 /* Add call edges */
255 mCalls->xta = xtainfoInit(mCalls);
256 mCalls->xta->calls = add2MethSet(mCalls->xta->calls, mCalled);
257                         /* mono if static, private, final else virtual so poly */
258 mCalls->xta->calls->tail->monoPoly = monoPoly;  
259
260 mCalled->xta->calledBy = add2MethSet(mCalled->xta->calledBy, mCalls);
261
262 /* IS THIS REALLY NEEDED???? */
263 if (mCalled->xta->calledBy == NULL) panic("mCalled->xta->calledBy is NULL!!!");
264 if (mCalls->xta->calls == NULL) panic("mCalls->xta->calls is NULL!!!");
265
266 }
267
268
269 /*-------------------------------------------------------------------------------*/
270 bool xtaPassParams (methodinfo *Called, methodinfo *Calls, methSetNode *lastptrInto)
271 {
272         classSetNode *p;
273         classSetNode *c;
274         classSetNode *c1;
275         classSetNode *cprev;
276         bool          chgd = false;
277
278         if (lastptrInto->lastptrIntoClassSet2 == NULL) {
279                 if (Calls->xta->XTAclassSet != NULL)
280                         c1 = Calls->xta->XTAclassSet->head;
281                  /*else already c1 = NULL; */
282         }
283         else    {
284                 /* start with type where left off */
285                 c1 = lastptrInto->lastptrIntoClassSet2;
286                 c1 = c1 -> nextClass;  /* even if NULL */
287         }
288         if (c1 == NULL) return false;
289
290         cprev = NULL;
291        /* for each Param Class */
292         for (   p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
293
294                 /* for each SmCalls class */
295                 for (c=c1; c != NULL; c = c->nextClass) {
296                         vftbl_t *p_cl_vt;
297                         vftbl_t *c_cl_vt;
298
299                         LAZYLOADING(c->classType)  /* if not loaded is it really needed ??? */
300
301                         p_cl_vt = p->classType->vftbl;
302                         c_cl_vt = c->classType->vftbl;
303
304                         /* if SmCalls class is in the Params Class range */
305                         if (  (p_cl_vt->baseval <=  c_cl_vt->baseval)
306                                   && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
307
308                                 /*    add Calls class to CalledBy Class set */
309                                 Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
310                               chgd = true;
311                         }
312                         cprev = c;
313                 }
314         }
315         lastptrInto->lastptrIntoClassSet2 = cprev;
316         return chgd;
317 }
318
319
320 /*-------------------------------------------------------------------------------*/
321 void xtaPassAllCalledByParams (methodinfo *m) {
322         methSetNode *SmCalled;
323         if (m->xta->calledBy == NULL)
324                 return;
325         for (SmCalled  = m->xta->calledBy->head; 
326              SmCalled != NULL; 
327              SmCalled = SmCalled->nextmethRef) {
328                 m->xta->chgdSinceLastParse = false;             /* re'init flag */
329                 xtaPassParams(m, SmCalled->methRef,SmCalled);   /* chg flag output ignored for 1st regular parse */
330         }
331 }
332
333
334 /*-------------------------------------------------------------------------------*/
335 void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
336 {
337         /* Field type is a class */
338         classSetNode *c;
339         classSetNode *c1 = NULL;
340         classSetNode *cp = NULL;
341         classSetNode *cprev= NULL;
342
343         fieldinfo *fi;
344                 
345         if (fN != NULL)
346                 fi = fN->fldRef;
347         else
348                 return;
349         
350 /* Use lastptr  so don't check whole XTA class set each time */
351         cp = fN->lastptrPUT;
352         if (cp != NULL) {
353                 if (cp->nextClass != NULL)
354                         c1 = cp -> nextClass;
355         } 
356         else    {
357                 if (m->xta->XTAclassSet != NULL)
358                         c1  = m->xta->XTAclassSet->head;
359         }
360
361         /*--- PUTSTATIC specific ---*/
362         /* Sx = intersection of type+subtypes(field x)   */
363         /*   and Sm (where putstatic code is)            */
364         for (c=c1; c != NULL; c=c->nextClass) {
365                 vftbl_t *f_cl_vt;
366                 vftbl_t *c_cl_vt;
367
368                 LAZYLOADING1(fi->xta->fldClassType)
369
370                 f_cl_vt = fi->xta->fldClassType->vftbl;
371                 c_cl_vt = c->   classType->vftbl;
372                 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
373                         && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
374                         fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
375                 }
376                 cprev = c;
377         }
378         fN->lastptrPUT = cprev;
379 }
380 /*-------------------------------------------------------------------------------*/
381 void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
382 {
383         /* Field type is a class */
384         classSetNode *c;
385         classSetNode *c1 = NULL;
386         classSetNode *cp = NULL;
387         classSetNode *cprev= NULL;
388
389         fieldinfo *fi;
390         if (fN != NULL)
391                 fi = fN->fldRef;
392         else
393                 return;
394
395 /* Use lastptr  so don't check whole XTA class set each time */
396         cp = fN->lastptrGET;
397         if (cp != NULL) {
398                 if (cp->nextClass != NULL)
399                         c1 = cp -> nextClass;
400         } 
401         else    {
402                 if (fi->xta->XTAclassSet != NULL)
403                         c1  = fi->xta->XTAclassSet->head;
404         }
405
406         /*--- GETSTATIC specific ---*/
407         /* Sm = union of Sm and Sx */
408         for (c=c1; c != NULL; c=c->nextClass) {
409                 bool addFlg = false;
410                 if (m->xta->XTAclassSet ==NULL) 
411                         addFlg = true;
412                 else    {
413                         if (!(inSet (m->xta->XTAclassSet->head, c->classType) )) 
414                                 addFlg = true;
415                         }
416                 if (addFlg) {
417                         m->xta->XTAclassSet 
418                                 = add2ClassSet(m->xta->XTAclassSet,c->classType);
419                 }
420                 cprev = c;
421         }
422
423         fN->lastptrGET = cprev;
424 }
425
426
427 /*-------------------------------------------------------------------------------*/
428 void xtaAllFldsUsed (methodinfo *m) {
429         fldSetNode  *f;
430         fldSetNode *f1=NULL;
431         /*      bool chgd = false */
432
433         if (m->xta->fldsUsed == NULL) return;
434
435         /* for each field that this method uses */
436         f1 = m->xta->fldsUsed->head;
437
438         for (f=f1; f != NULL; f = f->nextfldRef) {
439
440                 if (f->writePUT)
441                         xtaPassFldPUT(m,f);
442                 if (f->readGET)
443                         xtaPassFldGET(m,f);
444         }
445 }
446
447 /*-------------------------------------------------------------------------------*/
448 bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
449
450         classSetNode* cs;
451         classSetNode* cs1;
452         bool          fchgd = false;
453
454         /* Get Called return class is null */
455         if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
456                 Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */ 
457         }
458
459         if (Called->returnclass == NULL) {
460                 return fchgd;
461         }
462         
463         if (Called->xta->XTAclassSet == NULL) 
464                 cs1 = NULL;
465         else
466                 cs1 =  Called->xta->XTAclassSet->head;
467
468         for (cs =cs1; cs != NULL; cs = cs->nextClass) {
469                 classinfo *c = cs->classType;
470                 vftbl_t *r_cl_vt; 
471                 vftbl_t *c_cl_vt; 
472                 LAZYLOADING(c)
473                 LAZYLOADING(Called->returnclass)
474                 r_cl_vt = Called->returnclass->vftbl; 
475                 c_cl_vt = c->vftbl; 
476
477                 /* if class is a subtype of the return type, then add to Calls class set (ie.interscection)*/
478                 if (  (r_cl_vt->baseval <=  r_cl_vt->baseval)
479                           && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
480                         Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);  
481                         fchgd = true;
482                 }
483         } 
484
485         return fchgd; 
486 }
487
488
489 /*-------------------------------------------------------------------------------*/
490 void  xtaMethodCalls_and_sendReturnType(methodinfo *m)
491 {
492         methSetNode *SmCalled;  /* for return type       */
493         methSetNode *SmCalls;   /* for calls param types */
494         methSetNode *s1=NULL;
495         bool chgd = false;
496
497         xtaAllFldsUsed (m);
498
499         if (m->xta == NULL) panic("m->xta null for return type\n");
500         /* for each method that this method calls */
501         if (m->xta->calls == NULL)
502                 s1 = NULL;
503         else
504                 s1 = SmCalls=m->xta->calls->head;
505
506         for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
507                 /*    pass param types  */
508                 bool chgd = false;
509                 chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
510                 /* if true chgd after its own parse */
511                 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
512                         SmCalls->methRef->xta->chgdSinceLastParse = true;
513                 }
514         }
515
516         /* for each calledBy method */
517         /*    send return type */
518         if (m->xta->calledBy == NULL)
519                 s1 = NULL;
520         else
521                 s1 = m->xta->calledBy->head;
522         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
523
524                 chgd = xtaPassReturnType(m, SmCalled->methRef);
525                 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
526                         SmCalled->methRef->xta->chgdSinceLastParse = chgd;
527                 }
528         }
529
530 }
531
532 /*-------------------------------------------------------------------------------*/
533 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
534
535         bool is_classtype = false; /* return value */
536
537         if (fi->xta->fieldChecked) {
538                 if (fi->xta->fldClassType != NULL)
539                         return true;  /* field has a class type */
540                 else
541                         return false;
542         }
543         fi->xta->fieldChecked = true;
544
545         if (fi->type == TYPE_ADDRESS) {
546                 char *utf_ptr = fi->descriptor->text;  /* current position in utf text */
547
548                 if (*utf_ptr != 'L') {
549                         while (*utf_ptr++ =='[') ;
550                 }
551
552                 if (*utf_ptr =='L') {
553                         is_classtype = true;
554                         if  (fi->xta->fldClassType== NULL) {
555                                 char *desc;
556                                 char *cname;
557                                 classinfo * class;
558
559                                 desc = MNEW(char, 256);
560                                 strcpy(desc,++utf_ptr);
561                                 cname = strtok(desc,";");
562                                 class = class_get(utf_new_char(cname));
563                                 fi->xta->fldClassType= class;    /* save field's type class ptr */      
564                         } 
565                 }
566         }
567         return is_classtype;
568 }
569
570 /*--------------------------------------------------------------*/
571 /* Mark the method with same name /descriptor in topmethod      */
572 /* in class                                                     */
573 /*                                                              */
574 /* Class marked USED and method defined in this class ->        */
575 /*    -> add call edges = USED                                  */
576 /* Class not marked USED and method defined in this class ->    */
577 /*    -> if Method NOTUSED mark method as MARKED                */
578 /*                                                              */
579 /* Class USED, but method not defined in this class ->          */
580 /* -> 1) search up the heirarchy and mark method where defined  */
581 /*    2) if class where method is defined is not USED ->        */
582 /*       -> ????mark class with defined method as PARTUSED          */
583 /*--------------------------------------------------------------*/
584
585
586 void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
587
588 utf *name       = topmethod->name; 
589 utf *descriptor = topmethod->descriptor;
590 methodinfo *submeth;
591
592 /* See if method defined in class heirarchy */
593 submeth = class_resolvemethod(class, name, descriptor); 
594 METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
595 if (submeth == NULL) {
596         utf_display(class->name); printf(".");
597         METHINFOx(topmethod);
598         printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
599         panic("parse XTA: Method not found in class hierarchy");
600         }
601
602 /* if submeth called previously from this method then return */
603 if (mCalls->xta->calls != NULL) {
604         if (inMethSet(mCalls->xta->calls->head,submeth)) return;
605         }
606
607 #undef CTA 
608 #ifdef CTA
609   XTAaddClassInit(submeth,      submeth->class,
610                 CLINITS_T,FINALIZE_T,ADDMARKED_T);
611   if (inSet(subtypesUsedSet,submeth->class)) {
612       submeth->monoPoly = POLY;
613       xtaAddCallEdges(mCalls, submeth, submeth->monoPoly, 
614                       "00addTo XTA VIRT CONE:");
615       }
616   return;
617 #endif
618
619   if (submeth->class == class) { 
620
621         /*--- Method defined in class -----------------------------*/
622         if (inSet(subtypesUsedSet,submeth->class)) {
623                 /* method defined in this class -> */
624                 /* Class IS  marked USED           */ 
625                 /*    -> mark method as USED       */
626                 submeth->monoPoly = POLY;
627                 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly, 
628                         "01addTo VIRT CONE 1:");
629                 }
630         else    {
631                 /* method defined in this class -> */
632                 /* Class IS NOT  marked USED (PART or NOTUSED) */ 
633                 /* -> if Method NOTUSED mark method as  MARKED */
634                 METHINFOt(submeth,
635                         "\tmarked VIRT CONE 2:",XTA_DEBUGr);
636                 submeth->monoPoly = POLY;
637                 if (submeth->xta == NULL) {
638                         submeth->xta = xtainfoInit(submeth);
639                         }
640                 submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */ 
641                 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
642                 /* Note: if class NOTUSED and subclass is used handled  */
643                 /*       by subsequent calls to xtaMarkMethods for cone */
644                 }
645         } /* end defined in class */
646
647   else {
648         /*--- Method NOT defined in class  - defined up the heirarchy ---------------*/
649         /* then check class the method could be called with */
650
651         /* first mark classes if needed */
652         if (!(inSet(subtypesUsedSet,submeth->class))) {
653                 submeth->class->classUsed = PARTUSED; 
654                 if (!(inSet(subtypesUsedSet,class))) {
655                         submeth->monoPoly = POLY;
656                         if (submeth->xta == NULL)
657                                 submeth->xta = xtainfoInit(submeth);
658                         submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */ 
659                         submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
660                         METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
661                         }
662                 }
663         /* add method to xta work list if conditions met */
664         if (inSet(subtypesUsedSet,class)) {
665                 submeth->monoPoly = POLY;
666                 xtaAddCallEdges(mCalls, submeth, submeth->monoPoly, 
667                                 "02addTo VIRT CONE 3:");
668                 }
669         } /* end NOT defined in class */
670
671
672
673 /*----------------------------------------------------------------------*/
674 /* Mark the method with the same name and descriptor as topmethod       */
675 /*   and any subclass where the method is defined and/or class is used  */
676 /*                                                                      */
677 /*----------------------------------------------------------------------*/
678
679 void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
680         /* xtaPRINTmarkSubs1*/
681         xtaMarkMethod(class, mCalls, topmethod, subtypesUsedSet);   /* Mark method in class where it was found */
682         if (class->sub != NULL) {
683                 classinfo *subs;
684
685                 if (!(topmethod->flags & ACC_FINAL )) {
686                         for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
687                                 xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
688                                 }
689                         }
690                 }
691 }
692
693
694 /**************************************************************************/
695 /* Add Marked methods for input class ci                                  */
696 /* Add methods with the same name and descriptor as implemented interfaces*/
697 /*   with the same method name                                            */
698 /*  ??? interface part not XTA checked                                    */
699 /*------------------------------------------------------------------------*/
700 void xtaAddMarkedMethods(methodinfo *mCalls, classinfo *ci) {
701 int ii,jj,mm;
702
703 /* add marked methods to callgraph */ 
704 for (ii=0; ii<ci->methodscount; ii++) { 
705         methodinfo *mi = &(ci->methods[ii]);
706
707         if (mi->xta != NULL) {
708                 if (mi->xta->markedBy != NULL) {
709                         methSetNode *mcnode;
710                         for (mcnode = mi->xta->markedBy->head; mcnode  != NULL; mcnode  = mcnode ->nextmethRef) {
711                                 methodinfo *mCalls = mcnode->methRef;
712                                 xtaAddCallEdges(mCalls, mi, mi->monoPoly, 
713                                         "03addToInit was Marked added:");
714                                 }
715                         }
716
717                 else    { /* NOT XTA checked yet */
718                         for (jj=0; jj < ci -> interfacescount; jj++) {
719                                 classinfo *ici = ci -> interfaces [jj];
720                                 /*  use resolve method....!!!! */
721                                 if (ici -> classUsed != NOTUSED) {
722                                         for (mm=0; mm< ici->methodscount; mm++) {
723                                                 methodinfo *imi = &(ici->methods[mm]);
724                                                 METHINFOt(imi,"NEW IMPD INTERFACE:",XTA_DEBUGinf)
725                                               /*if interface method=method is used*/
726                                                 if  (      (imi->methodUsed == USED)
727                                                    &&    ( (imi->name == mi->name) 
728                                                    &&      (imi->descriptor == mi->descriptor))) {
729                                                         xtaAddCallEdges(mCalls, mi, mi->monoPoly, 
730                                                                  "04addTo was interfaced used/MARKED:");
731                                                         } 
732                                                 } /*end for */  
733                                         }
734                                 }
735                         }
736                 }       
737         }
738 }    
739
740
741 /*------------------------------------------------------------------------*/
742 void xtaAddUsedInterfaceMethods(methodinfo *m, classinfo *ci) {
743         int jj,mm;
744
745         /* add used interfaces methods to callgraph */
746         for (jj=0; jj < ci -> interfacescount; jj++) {
747                 classinfo *ici = ci -> interfaces [jj];
748         
749                 if (XTA_DEBUGinf) { 
750                         printf("BInterface used: ");fflush(stdout); 
751                         utf_display(ici->name);
752                         printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); fflush(stdout); 
753                         }
754                 /* add class to interfaces list of classes that implement it */
755                 ici -> impldBy =  addElement(ici -> impldBy,  ci);
756
757                 /* if interface class is used */
758                  if (ici -> classUsed != NOTUSED) {
759
760                         /* for each interface method implementation that has already been used */
761                         for (mm=0; mm< ici->methodscount; mm++) {
762                                 methodinfo *imi = &(ici->methods[mm]);
763                                         if  ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
764                                                 printf("Interface Method %s: ", methFlgs[imi->methodUsed]); 
765                                                 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
766                                         }
767                                 if  (imi->methodUsed == USED) {
768                                             if (XTA_DEBUGinf) { 
769                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
770                                                 /* Mark this method used in the (used) implementing class &its subclasses */
771                                                 printf("rMAY ADD methods that was used by an interface\n");
772                                                 }
773                                         if ((utf_clinit != imi->name) &&
774                                             (utf_init   != imi->name))
775                                                 {
776                                                 classSetNode *subtypesUsedSet = NULL;
777                                                 if (m->xta->XTAclassSet != NULL) {
778                                                         subtypesUsedSet =
779                                                                 intersectSubtypesWithSet
780                                                                 (imi->class, m->xta->XTAclassSet->head);
781                                                         }
782                                                 else /* can any methods be added if 1 set is NULL ??? */
783                                                         subtypesUsedSet = addElement(subtypesUsedSet, m->class);
784                                                 xtaMarkSubs(m, ci, imi, subtypesUsedSet); 
785                                                 imi->monoPoly = POLY;
786
787                                                 }
788                                         }       
789                                 } /* end for method */
790                         } /* end != NOTUSED */
791                 } /* end for interface */
792
793 }
794
795
796 /*----------------------------------------------------------------------*/
797
798 #define CLINITS_T   true
799 #define FINALIZE_T  true
800 #define ADDMARKED_T true
801
802 #define CLINITS_F   false 
803 #define FINALIZE_F  false 
804 #define ADDMARKED_F false
805 /*-----------------------*/
806
807 void XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
808 {
809   methodinfo *mi;
810
811   if (addmark)
812         ci->classUsed = USED;
813         
814   if (clinits) { /* No <clinit>  available - ignore */
815     mi = class_findmethod(ci, utf_clinit, utf_void__void); 
816     if (mi) { 
817         if (ci->classUsed != USED)
818             ci->classUsed = PARTUSED;
819         mi->monoPoly = MONO;
820         xtaAddCallEdges(mCalls, mi, mi->monoPoly, 
821                         "05addTo CLINIT added:");
822       }     
823     }        
824
825   /*Special Case for System class init:
826     add java/lang/initializeSystemClass to callgraph */
827   if (ci->name == utf_new_char("initializeSystemClass")) {
828     /* ?? what is name of method ?? */ 
829     } 
830
831   if (finalizes) {
832     mi = class_findmethod(ci, utf_finalize, utf_void__void);
833     if (mi) { 
834         if (ci->classUsed != USED)
835             ci->classUsed = PARTUSED;
836         mi->monoPoly = MONO;
837         xtaAddCallEdges(mCalls, mi, mi->monoPoly, 
838                         "06addTo FINALIZE added:");
839       }     
840     }        
841
842   if (addmark) {
843     xtaAddMarkedMethods(mCalls, ci);
844     }
845
846   /* always so know have access to the interface methods */
847   xtaAddUsedInterfaceMethods(mCalls,ci);
848
849 }
850
851 /*-------------------------------------------------------------------------------*/
852
853 /*********************************************************************/
854 /*********************************************************************/
855
856 /*-------------------------------------------------------------------*/
857
858 void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {                              
859         classSetNode *subs;
860         if (mi->class->classUsed == NOTUSED) {
861                 mi->class->classUsed = USED; 
862                 /* add interface class to list kept in Object */
863                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
864                 }
865
866         mi->methodUsed = USED;
867         mi->monoPoly   = POLY;
868
869                    /*XTAPRINT08invokeInterface1*/
870                    if (XTA_DEBUGinf) {
871                         subs =  mi->class->impldBy; 
872                         METHINFO(mi,XTA_DEBUGinf)
873                         printf("Implemented By classes :\n");fflush(stdout);
874                         if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
875                         }
876         for (subs =  mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
877                 methodinfo *submeth;
878                    if (XTA_DEBUGinf) {
879                        printf("\t");utf_display(subs->classType->name);fflush(stdout);
880                         printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
881                         }
882
883                 /*Mark method (mark/used) in classes that implement method*/
884                 submeth = class_findmethod(subs->classType, mi->name, mi->descriptor); 
885                 if (submeth != NULL) {
886                         classSetNode *subtypesUsedSet = NULL;
887                         submeth->monoPoly = POLY; /*  poly even if nosubs */
888                         submeth->xta = xtainfoInit(submeth);
889                         
890                         submeth->xta->XTAmethodUsed = USED;
891                         if (m->xta->XTAclassSet != NULL) {
892                                 subtypesUsedSet =     /* interface classes cone */
893                                 intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
894                                 }
895                          else {  /* can any methods be added if 1 set is NULL ??? */
896                                  subtypesUsedSet = addElement(subtypesUsedSet, m->class);
897                                 }
898                          xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
899                          }
900                                 
901                 } /* end for */
902
903
904                                 
905
906 /*********************************************************************/
907
908 int parseXTA(methodinfo *m)
909 {
910         int  p;                     /* java instruction counter */ 
911         int  nextp;                 /* start of next java instruction */
912         int  opcode;                /* java opcode */
913         int  i;                     /* temp for different uses (counters)*/
914         bool iswide = false;        /* true if last instruction was a wide*/
915         int rc = 1;
916
917 if (m->methodXTAparsed) return 0;
918 else m->methodXTAparsed = true;
919
920 /***XTA_DEBUGopcodes=false;***/
921 /***printf("\n-----------------------------------\n"); **/
922 METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes); 
923 if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
924 /***XTA_DEBUGopcodes=false;***/
925         if (m->xta == NULL) {
926                 xtainfoInit (m);
927                 }
928         else    {
929                 xtaPassAllCalledByParams (m); 
930                 }
931
932 /* scan all java instructions */
933         for (p = 0; p < m->jcodelength; p = nextp) {
934
935                 opcode = code_get_u1(p,m);            /* fetch op code  */
936                 SHOWOPCODE(XTA_DEBUGopcodes)
937
938                 nextp = p + jcommandsize[opcode];   /* compute next instr start */
939                 if (nextp > m->jcodelength)
940                         panic("Unexpected end of bytecode");
941
942                 switch (opcode) {
943
944                 case JAVA_ILOAD:
945                 case JAVA_LLOAD:
946                 case JAVA_FLOAD:
947                 case JAVA_DLOAD:
948                 case JAVA_ALOAD:
949
950                 case JAVA_ISTORE:
951                 case JAVA_LSTORE:
952                 case JAVA_FSTORE:
953                 case JAVA_DSTORE:
954                 case JAVA_ASTORE:
955
956                         if (iswide) {
957                                 nextp = p + 3;
958                                 iswide = false;
959                         }
960                         break;
961
962                 case JAVA_IINC: 
963                         {
964                                 
965                                 if (iswide) {
966                                         iswide = false;
967                                         nextp = p + 5;
968                                 }
969                         }
970                         break;
971
972                         /* wider index for loading, storing and incrementing */
973
974                 case JAVA_WIDE:
975                         iswide = true;
976                         nextp = p + 1;
977                         break;
978
979                 case JAVA_RET:
980                         if (iswide) {
981                                 nextp = p + 3;
982                                 iswide = false;
983                         }
984                         break;
985
986                 case JAVA_LOOKUPSWITCH:
987                         {
988                         s4 num;
989                         nextp = ALIGN((p + 1), 4) + 4;
990                         num = code_get_u4(nextp,m);
991                         nextp += (code_get_u4(nextp,m)) * 8 + 4;
992                         break;
993                         }
994
995
996                 case JAVA_TABLESWITCH:
997                        {
998                                 s4 num;
999                                 nextp = ALIGN ((p + 1),4);
1000                                 num = code_get_s4(nextp + 4, m);
1001                                 num = code_get_s4(nextp + 8, m) - num;
1002                                 nextp = nextp + 16 + 4 * num;
1003                                 break;
1004                         }
1005  /*********************/
1006
1007                 case JAVA_PUTSTATIC: /* write */
1008
1009                         i = code_get_u2(p + 1,m);
1010                         {
1011                                 constant_FMIref *fr;
1012                                 fieldinfo *fi;
1013
1014                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1015                                 LAZYLOADING(fr->class)
1016
1017                                 fi = class_resolvefield(fr->class,
1018                                                         fr->name,
1019                                                         fr->descriptor,
1020                                                         m->class,
1021                                                         true);
1022
1023                                 if (!fi)
1024                                         return 0; /* was NULL */
1025 /***
1026 printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1027                                       utf_display(fi->name);printf("\n");fflush(stdout);
1028 ***/
1029                                 fi->xta = xtafldinfoInit(fi);
1030                                 XTAaddClassInit(m,      fi->class,
1031                                                 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1032                                 if (xtaAddFldClassTypeInfo(fi)) {
1033                                         m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
1034                                         }
1035                         }
1036                         break;
1037
1038
1039                 case JAVA_GETSTATIC: /* read */
1040
1041                         i = code_get_u2(p + 1,m);
1042                         {
1043                                 constant_FMIref *fr;
1044                                 fieldinfo *fi;
1045
1046                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1047                                 LAZYLOADING(fr->class)
1048
1049                                 fi = class_resolvefield(fr->class,
1050                                                         fr->name,
1051                                                         fr->descriptor,
1052                                                         m->class,
1053                                                         true);
1054
1055                                 if (!fi)
1056                                         return 0; /* was NULL */
1057
1058 /***
1059 printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
1060                                       utf_display(fi->name);printf("\n");fflush(stdout);
1061 ***/
1062                                 fi->xta = xtafldinfoInit(fi);
1063                                 XTAaddClassInit(m,      fi->class,
1064                                                 CLINITS_T,FINALIZE_T,ADDMARKED_F);
1065                                 if (xtaAddFldClassTypeInfo(fi)) {
1066                                         m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
1067                                         }
1068
1069                         }
1070                         break;
1071
1072
1073                                                                 
1074                         case JAVA_INVOKESTATIC:
1075                         case JAVA_INVOKESPECIAL:
1076                                 i = code_get_u2(p + 1,m);
1077                                 {
1078                                 constant_FMIref *mr;
1079                                 methodinfo *mi;
1080
1081                                 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1082                                 LAZYLOADING(mr->class) 
1083                                 mi = class_resolveclassmethod(  mr->class,
1084                                                                                                 mr->name,
1085                                                                                                 mr->descriptor,
1086                                                                                                 m->class,
1087                                                                                                 false);
1088
1089                                 if (mi) 
1090                                    {
1091                                    METHINFOt(mi,"INVOKESTAT/SPEC:: ",XTA_DEBUGopcodes)
1092                                    mi->monoPoly = MONO;
1093                                    
1094                                    /*---- Handle "leaf" = static, private, final calls-------------*/
1095                                    if ((opcode == JAVA_INVOKESTATIC)       
1096                                      || (mi->flags & ACC_STATIC)  
1097                                      || (mi->flags & ACC_PRIVATE)  
1098                                      || (mi->flags & ACC_FINAL) )  
1099                                         {
1100                                         if (mi->class->classUsed != USED) { /* = NOTUSED or PARTUSED */ 
1101                                                 XTAaddClassInit(m, mi->class, 
1102                                                                 CLINITS_T,FINALIZE_T,ADDMARKED_T); 
1103                                                                 /* Leaf methods are used whether class is or not */
1104                                                                 /*   so mark class as PARTlyUSED                 */
1105                                                 mi->class->classUsed = PARTUSED; 
1106                                                 } 
1107                                         /* Add to XTA working list/set of reachable methods     */
1108                                         if (opcode == JAVA_INVOKESTATIC)  /* if stmt just for debug tracing */     
1109                                                              /* calls , called */
1110                                                 xtaAddCallEdges(m, mi, MONO, 
1111                                                         "07addTo INVOKESTATIC "); 
1112                                         else 
1113                                                 xtaAddCallEdges(m, mi, MONO, 
1114                                                         "08addTo INVOKESPECIAL ");      
1115                                         } /* end STATIC, PRIVATE, FINAL */ 
1116                                         
1117                                    else {
1118                                         /*---- Handle special <init> calls ---------------------------------------------*/
1119                                    
1120                                         if (mi->class->classUsed != USED) {
1121                                         /* XTA special case:
1122                                                 call of super's <init> then
1123                                                 methods of super class not all used */
1124                                                         
1125                                                 /*--- <init>  ()V  is equivalent to "new" 
1126                                                         indicating a class is used = instaniated ---- */        
1127                                                 if (utf_init==mi->name) {
1128                                                         if ((m->class->super == mi->class) 
1129                                                         &&  (m->descriptor == utf_void__void) ) 
1130                                                                 {
1131                                                                 METHINFOt(mi,"SUPER INIT:",XTA_DEBUGopcodes);
1132                                                                 /* super init so class may be only used because of its sub-class */
1133                                                                 XTAaddClassInit(m,mi->class,
1134                                                                         CLINITS_T,FINALIZE_T,ADDMARKED_F);
1135                                                                 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
1136                                                                 }
1137                                                         else {
1138                                                                 /* since <init> indicates classes is used, then add marked methods, too */
1139                                                                         METHINFOt(mi,"NORMAL INIT:",XTA_DEBUGopcodes);
1140                                                                 XTAaddClassInit(m, mi->class,
1141                                                                                 CLINITS_T,FINALIZE_T,ADDMARKED_T);
1142                                                                 }
1143                                                         xtaAddCallEdges(m, mi, MONO, 
1144                                                                         "09addTo INIT ");
1145                                                         } /* end just for <init> ()V */
1146                                                         
1147                                                 /* <clinit> for class inits do not add marked methods; 
1148                                                                 class not yet instaniated */ 
1149                                                 if (utf_clinit==mi->name)
1150                                                         XTAaddClassInit(m,      mi->class,
1151                                                                         CLINITS_T,FINALIZE_T,ADDMARKED_F);
1152
1153                                                 if (!((utf_init==mi->name))
1154                                                 ||   (utf_clinit==mi->name)) {
1155                                                         METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
1156                                                         if (mi->class->classUsed !=USED)
1157                                                                 mi->class->classUsed = PARTUSED;
1158                                                         xtaAddCallEdges(m, mi, MONO, 
1159                                                                 "10addTo SPEC notINIT ");
1160                                                         } 
1161                                                                 
1162                                                 } /* end init'd class not used = class init process was needed */ 
1163                                                         
1164                                         /* add method to XTA list = set of reachable methods */ 
1165                                         xtaAddCallEdges(m, mi, MONO, 
1166                                                 "11addTo SPEC whymissed ");
1167                                         } /* end inits */
1168                                 } 
1169 /***  assume if method can't be resolved won't actually be called or
1170       there is a real error in classpath and in normal parse an exception
1171       will be thrown. Following debug print can verify this
1172 else  from if (mi) {
1173 CLASSNAME1(mr->class,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
1174 utf_display(mr->name); printf(" "); fflush(stdout);
1175 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1176 ***/
1177                         }
1178                         break;
1179
1180                 case JAVA_INVOKEVIRTUAL:
1181                         i = code_get_u2(p + 1,m);
1182                         {
1183                                 constant_FMIref *mr;
1184                                 methodinfo *mi;
1185
1186                                 mr = m->class->cpinfos[i];
1187                                 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
1188                                 LAZYLOADING(mr->class) 
1189                                 mi = class_resolveclassmethod(mr->class,
1190                                                 mr->name,
1191                                                 mr->descriptor,
1192                                                 m->class,
1193                                                 false);
1194
1195
1196                                 if (mi) 
1197                                    {
1198                                    METHINFOt(mi,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
1199                                    if ((mi->flags & ACC_STATIC) 
1200                                    ||  (mi->flags & ACC_PRIVATE)  
1201                                    ||  (mi->flags & ACC_FINAL) )  
1202                                      { /*** DOES THIS EVER OCCUR ??? */
1203                                      if (mi->class->classUsed == NOTUSED){
1204                                        XTAaddClassInit(m, mi->class,
1205                                                     CLINITS_T,FINALIZE_T,ADDMARKED_T);
1206                                        }
1207                                       mi->monoPoly = MONO;
1208                                       xtaAddCallEdges(m, mi, MONO, 
1209                                                     "12addTo INVOKEVIRTUAL ");
1210                                       } 
1211                                    else { /* normal virtual */
1212                                           /* get the set of used subtypes if none at least the current methods class */
1213                                         classSetNode *subtypesUsedSet = NULL;
1214                                         if (m->xta->XTAclassSet != NULL) {
1215                                                 subtypesUsedSet =
1216                                                 intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
1217                                                 }
1218                                         else { /* can any methods be added if 1 set is NULL ??? */
1219                                                 subtypesUsedSet = addElement(subtypesUsedSet, m->class);
1220                                                 }
1221                                        mi->monoPoly = POLY;
1222                                        xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
1223                                        }
1224                                    } 
1225                                 else {
1226 CLASSNAME1(mr->class,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
1227 utf_display(mr->name); printf(" "); fflush(stdout);
1228 utf_display(mr->descriptor); printf("\n");fflush(stdout);
1229                                    }
1230                                 }
1231                                 break;
1232
1233                 case JAVA_INVOKEINTERFACE:
1234                         i = code_get_u2(p + 1,m);
1235                         {
1236                                 constant_FMIref *mr;
1237                                 methodinfo *mi;
1238
1239                                 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1240                                 LAZYLOADING(mr->class)
1241
1242                                 mi = class_resolveinterfacemethod(mr->class,
1243                                                           mr->name,
1244                                                           mr->descriptor,
1245                                                           m->class,
1246                                                           false);
1247                                         if (mi)
1248                                            {
1249                                            METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
1250                                            xtaMarkInterfaceSubs(m,mi);
1251                                            }
1252                                 /* see INVOKESTATIC for explanation about */
1253                                 /*   case when Interface is not resolved  */
1254                                 /*descriptor2types(mi); 
1255                                 ?? do need paramcnt? for XTA (or just XTA)*/
1256                         }
1257                         break;
1258
1259                 case JAVA_NEW:
1260                 /* means class is at least passed as a parameter */
1261                 /* class is really instantiated when class.<init> called*/
1262                         i = code_get_u2(p + 1,m);
1263                         {
1264                         classinfo *cls;
1265                         cls = class_getconstant(m->class, i, CONSTANT_Class);
1266                         /*** s_count++; look for s_counts for VTA */
1267                         /* add marked methods */
1268                         CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
1269                         XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T); 
1270                         m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1271                         }
1272                         break;
1273
1274                 case JAVA_CHECKCAST:
1275                 case JAVA_INSTANCEOF:
1276                 /* class used */
1277                         i = code_get_u2(p + 1,m);
1278                         {
1279                         classinfo *cls =
1280                                 (classinfo *)
1281                              class_getconstant(m->class, i, CONSTANT_Class);
1282                         LAZYLOADING(cls)
1283                         CLASSNAMEop(cls,XTA_DEBUGr);
1284                         if (cls->classUsed == NOTUSED){
1285                                 XTAaddClassInit(m, cls,
1286                                             CLINITS_T,FINALIZE_T,ADDMARKED_T);
1287                                 m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
1288                                 }
1289                         }
1290                         break;
1291
1292                 default:
1293                         break;
1294                                 
1295                 } /* end switch */
1296
1297                 } /* end for */
1298         xtaMethodCalls_and_sendReturnType(m);
1299
1300         return rc;
1301 }
1302
1303 /* Helper fn for initialize **********************************************/
1304
1305 int XTAgetline(char *line, int max, FILE *inFP) {
1306 if (fgets(line, max, inFP) == NULL) 
1307   return 0;
1308 else
1309   return strlen((const char *) line);
1310 }
1311
1312 /* Initialize XTA Work list ***********************************************/
1313
1314 /*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
1315 #define SYSADD(cls,meth,desc, is_mono_poly, txt) \
1316   c = class_new(utf_new_char(cls)); \
1317   LAZYLOADING(c) \
1318   callmeth = class_resolveclassmethod(c, \
1319     utf_new_char(meth), \
1320     utf_new_char(desc), \
1321     c, \
1322     false); \
1323   if (callmeth->class->classUsed != USED) {  \
1324       c->classUsed = PARTUSED; \
1325       XTAaddClassInit(callmeth, callmeth->class, \
1326                    CLINITS_T,FINALIZE_T,ADDMARKED_T);\
1327       } \
1328   callmeth->monoPoly = is_mono_poly; \
1329   xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt); 
1330
1331 /*-- ---------------------------------------------------------------------------- 
1332     Initialize XTA work list with methods/classes from:  
1333       System calls 
1334         and 
1335       xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
1336 -------------------------------------------------------------------------------*/
1337 methodinfo *initializeXTAworklist(methodinfo *m) {
1338         classinfo  *c;
1339         methodinfo* callmeth;
1340         char systxt[]    = "2S addTo System     Call :";
1341         char missedtxt[] = "2M addTo xtaMissedIn Call :";
1342
1343         FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1344         char line[256];
1345         char* class, *meth, *desc;
1346         methodinfo *rm =NULL;  /* return methodinfo ptr to main method */
1347
1348
1349         /* Create XTA call work list */
1350         xtaWorkList = NEW(list);
1351         list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
1352
1353         /* Add first method to call list */
1354         m->class->classUsed = USED; 
1355         xtaAddCallEdges(NULL, m, SYSCALL, systxt); 
1356
1357         /* Add system called methods */
1358 /***    SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
1359         SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
1360         rm = callmeth;  
1361 /***    SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
1362         SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
1363         /*----- xtaMissedIn 0 */
1364         if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
1365                 /*if (opt_verbose) */
1366                     {printf("No xtaMissedIn0 file\n");fflush(stdout);} 
1367                 return  rm;
1368                 }
1369         while (XTAgetline(line,256,xtaMissedIn)) {
1370             class = strtok(line, " \n");
1371             meth  = strtok(NULL, " \n");
1372             desc  = strtok(NULL, " \n");
1373                 SYSADD(class,meth,desc, POLY, missedtxt)
1374                 /* ??? Need to hand / hard code who calls it ??? */
1375                 }
1376         fclose(xtaMissedIn);
1377
1378
1379
1380
1381         return rm;
1382
1383 }
1384
1385 /*- end initializeXTAworklist-------- */
1386
1387
1388 /*-------------------------------------------------------------------------------*/
1389 methodinfo *missedXTAworklist()  
1390 {
1391         FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
1392         char filenameIn[256] = "xtaIn/";
1393         char line[256];
1394         char* class, *meth, *desc;
1395         /****
1396         char* calls_class, *calls_meth, *calls_desc;
1397         ****/
1398         char missedtxt[] = "xtaIn/ missed Call :";
1399         classinfo  *c;
1400         methodinfo* callmeth;
1401
1402         methodinfo *rm =NULL;  /* return methodinfo ptr to main method */
1403
1404
1405 #if defined(USE_THREADS)
1406         SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
1407         SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
1408 #endif
1409         /*----- xtaMissedIn pgm specific */
1410         strcat(filenameIn, (const char *)mainstring);  
1411         if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
1412                 /*if (opt_verbose)*/ 
1413                     {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);} 
1414                 return rm;
1415                 }
1416         while (XTAgetline(line,256,xtaMissedIn)) {
1417         /****
1418             calls_class = strtok(line, " \n");
1419             calls_meth  = strtok(NULL, " \n");
1420             calls_desc  = strtok(NULL, " \n");
1421             
1422             class = strtok(NULL, " \n");
1423         ****/
1424             class = strtok(line, " \n");
1425             meth  = strtok(NULL, " \n");
1426             desc  = strtok(NULL, " \n");
1427             
1428         /****
1429             if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL) 
1430             ||        (class == NULL) ||       (meth == NULL) ||       (desc == NULL))  
1431         ****/
1432             if (        (class == NULL) ||       (meth == NULL) ||       (desc == NULL))  
1433                 panic (
1434                 "Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc \n"); 
1435             SYSADD(class,meth,desc, POLY, missedtxt)
1436             }
1437         fclose(xtaMissedIn);
1438
1439         return rm;
1440 }
1441
1442
1443
1444 /*--------------------------------------------------------*/
1445 /* parseXTAmethod                                          */
1446 /* input: method to be XTA static parsed                  */
1447 /*--------------------------------------------------------*/
1448 void parseXTAmethod(methodinfo *xta_method) {
1449         if (! (  (xta_method->flags & ACC_NATIVE  )
1450             ||   (xta_method->flags & ACC_ABSTRACT) ) ) 
1451             {
1452             /* XTA parse to approxmate....
1453                 what classes/methods will really be used during execution */
1454             parseXTA(xta_method);  
1455             }
1456         else {
1457             if (xta_method->flags & ACC_NATIVE  )
1458                 {
1459                METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
1460                 /* parseXTApseudo(xta_method); */
1461                 }   
1462             else {
1463                printf("Abstract method in XTA Work List: ");
1464                METHINFOx(xta_method);
1465                panic("Abstract method in XTA Work List.");
1466                }
1467             }                   
1468 }
1469
1470 void XTAprintCallgraph (list *xtaWorkList, char * txt);
1471
1472 /*-- XTA -- *******************************************************/
1473 int XTA_jit_parse(methodinfo *m)
1474 {
1475   xtaNode    *xta;
1476   methodinfo *mainmeth;
1477
1478   /* Should only be called once */
1479   if (firstCall) {
1480
1481     /*----- XTA initializations --------*/
1482     if (opt_verbose) 
1483             log_text("XTA static analysis started.\n");
1484
1485     mainmeth = initializeXTAworklist(m);
1486 /**     XTAprintCallgraph (xtaWorkList, "after init1"); **/
1487     firstCall = false; /* turn flag off */
1488
1489     if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
1490         printf("CACAO - xtaMissed file: cant open file to write\n");
1491         }
1492     /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
1493         
1494     /*------ process XTA call work list --------*/
1495     for (xta =list_first(xtaWorkList); 
1496          xta != NULL; 
1497          xta =list_next(xtaWorkList,xta)) 
1498         { 
1499         parseXTAmethod(xta->method);
1500 /**     XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
1501         }       
1502     missedXTAworklist();  
1503 /**     XTAprintCallgraph (xtaWorkList, "after missed"); **/
1504     for (xta =list_first(xtaWorkList); 
1505          xta != NULL; 
1506          xta =list_next(xtaWorkList,xta)) 
1507         { 
1508         parseXTAmethod(xta->method);
1509 /**     XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
1510         }       
1511
1512     fclose(xtaMissed);
1513     if (opt_verbose) {
1514         if (opt_stat) {
1515           printf("printXTAhierarchyInfo(m); not yet there\n");
1516           }
1517         XTAprintCallgraph (xtaWorkList, "After all XTA parses");
1518       }
1519
1520     if (opt_verbose) {
1521       log_text("XTA static analysis done.\n");
1522       }
1523   }
1524 return 0;
1525 }
1526
1527 /*--------------------------------------------------------------*/
1528 void XTAprintCallgraph (list *xtaWorkList, char * txt)
1529 {
1530     int i = 1;
1531     xtaNode    *xta;
1532     methodinfo *xta_meth;
1533
1534  printf("\n%s\n",txt);
1535 #if defined(STATISTICS)
1536  printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
1537 #endif
1538
1539    for (xta =list_first(xtaWorkList);
1540          xta != NULL;
1541          xta =list_next(xtaWorkList,xta))
1542         {
1543          xta_meth = xta->method;
1544
1545          printf("  (%i): ",i++);
1546          method_display_w_class(xta_meth);
1547         }
1548
1549  printf("\n\n");
1550
1551 }
1552
1553
1554 /*
1555  * These are local overrides for various environment variables in Emacs.
1556  * Please do not remove this and leave it at the end of the file, where
1557  * Emacs will automagically detect them.
1558  * ---------------------------------------------------------------------
1559  * Local variables:
1560  * mode: c
1561  * indent-tabs-mode: t
1562  * c-basic-offset: 4
1563  * tab-width: 4
1564  * End:
1565  */
1566