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