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