added field and method resolution
[cacao.git] / jit / parseRT.c
1 /* jit/parseRT.c - parser and print functions for Rapid Type Analyis
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Carolyn Oates
28
29    $Id: parseRT.c 1009 2004-03-31 22:44:07Z edwin $
30
31 Changes:
32 opcode put into functions
33 changed class_findmethod class_fetchmethod
34
35 */
36
37
38 #include "parseRT.h"
39
40  
41 /*------------ global variables -----------------------------------------*/
42 #define MAXCALLGRAPH 5000
43
44 #include "parseRTflags.h"
45
46
47 bool NATIVE = false;  // Dez version chasing Native problems
48
49 int callgraphAddedBy[MAXCALLGRAPH];   // add comment
50
51 int methRT = 0;
52 int methRTlast = -1;
53 int methRTmax = MAXCALLGRAPH;
54 methodinfo **callgraph;
55 /*methodinfo *callgraph[MAXCALLGRAPH];*/ 
56         
57  
58 int methXTA = 0;            
59 int methXTAlast = -1;
60 int methXTAmax = MAXCALLGRAPH;        
61 methodinfo **XTAcallgraph;
62 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
63
64 static bool nativecallcompdone=0 ;
65
66 static bool firstCall= true;
67 static bool parse1 = true;
68 static bool AfterMain = false;
69 static FILE *rtMissed;   /* Methods missed during RTA parse of Main  */
70 /*   so easier to build dynmanic calls file */
71 static FILE *appldynm;  /* Methods dynamically loaded by application */
72
73 static utf *utf_OBJECT;   /*  utf_new_char("Object"); */
74 static utf *utf_MAIN;   /*  utf_new_char("main"); */
75 static utf *INIT    ;   /*  utf_new_char("<init>"); */
76 static utf *CLINIT  ;   /*  utf_new_char("<clinit>"); */
77 static utf *FINALIZE;   /*  utf_new_char("finalize"); */
78 static utf *EMPTY_DESC; /*  utf_new_char("V()");  */
79 static int missedCnt = 0;
80
81
82 /*--------------------------------------------------------------*/
83 /* addToCallgraph - adds to RTA callgraph and                   */ 
84 /*                  sets  meth->methodUsed  to USED             */
85 /*--------------------------------------------------------------*/  
86 //  if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { 
87 #define ADDTOCALLGRAPH(meth)  if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
88         if (opt_rt) {  \
89         callgraph[++methRTlast] = meth ; \
90         meth->methodUsed = USED; \
91                         if(pWhenMarked>=1) \
92                                 {printf("\n Added to Call Graph #%i:",  \
93                                          methRTlast); \
94                                 printf("\t <used flags c/m> <%i/%i> %i\t",  \
95                                   meth->class->classUsed, \
96                                   meth->methodUsed, \
97                                   USED);  \
98                                 printf(" method name =");   \
99                                 utf_display(meth->class->name);printf("."); \
100                                 method_display(meth);fflush(stdout);} \
101         } } 
102
103 /*--------------------------------------------------------------*/
104 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
105         classinfo *subs;
106
107         for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
108                 if (subs->classUsed == USED) {
109                         if (class_findmethod_w(class, meth->name, meth->descriptor,"rtaSubUsed") == NULL)
110                                 return false;
111                         else    
112                                 return true;
113                 }
114                 if (rtaSubUsed(subs, meth)) 
115                         return false;
116         }
117         return false;
118 }
119
120
121 /*--------------------------------------------------------------*/
122 /* Mark the method with same name /descriptor in topmethod      */
123 /* in class                                                     */
124 /*                                                              */
125 /* Class not marked USED and method defined in this class ->    */
126 /*    -> if Method NOTUSED mark method as MARKED                */
127 /* Class marked USED and method defined in this class ->        */
128 /*    -> mark method as USED                                    */
129 /*                                                              */
130 /* Class USED, but method not defined in this class ->          */
131 /*    -> search up the heirarchy and mark method where defined  */
132 /*       if class where method is defined is not USED ->        */
133 /*       -> mark class with defined method as PARTUSED          */
134 /*--------------------------------------------------------------*/
135
136 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
137
138         utf *name = topmethod -> name; 
139         utf *descriptor = topmethod -> descriptor;
140         methodinfo *submeth;
141
142         submeth = class_resolvemethod(class, name, descriptor); 
143         if (submeth == NULL)
144                 panic("parse RT: Method not found in class hierarchy");
145         if (submeth->methodUsed == USED) return;
146   
147         if (submeth->class == class) { 
148
149                 /*--- Method defined in class -----------------------------*/
150         if (submeth->class->classUsed != USED) { 
151                         if (submeth->methodUsed == NOTUSED) { 
152
153                 /* Class NOT marked USED and method defined in this class -> */
154                                 /*    -> if Method NOTUSED mark method as  MARKED            */
155                                 if (pWhenMarked >= 1) {
156                                         printf("MARKED class.method\t"); 
157                                         utf_display(submeth->class->name);printf(".");method_display(submeth);
158                                 }
159                                 if (rtaSubUsed(submeth->class,submeth)) {
160                                         submeth->class->classUsed = PARTUSED;
161                                         ADDTOCALLGRAPH(submeth) 
162                                                 }
163                                 else    {
164                                         submeth->methodUsed = MARKED;
165                                         RTAPRINTmarkMethod1
166                                                 }
167                 } }
168         else    {
169                         /* Class IS  marked USED and method defined in this class -> */
170                         /*    -> mark method as USED  */
171                         ADDTOCALLGRAPH(submeth) 
172                                 }
173         } /* end defined in class */
174
175         else {
176                 /*--- Method NOT defined in class -----------------------------*/
177                 if (submeth->class->classUsed == NOTUSED) {
178                         submeth->class->classUsed = PARTUSED;
179                         if (class->classUsed != USED) {
180                                 submeth->methodUsed = MARKED;
181                         }
182                 }
183                 if ( (submeth->class->classUsed == USED) 
184                          || (class->classUsed == USED)) {
185                         ADDTOCALLGRAPH(submeth)
186                                 }
187         } /* end NOT defined in class */
188
189
190 /*-------------------------------------------------------------------------------*/
191 /* Mark the method with the same name and descriptor as topmethod                */
192 /*   and any subclass where the method is defined and/or class is used           */
193 /*                                                                               */
194 /*-------------------------------------------------------------------------------*/
195 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
196                 RTAPRINTmarkSubs1
197         rtaMarkMethod(class, topmethod);   /* Mark method in class where it was found */
198         if (class->sub != NULL) {
199                 classinfo *subs;
200         
201                 if (!(topmethod->flags & ACC_FINAL )) {
202                         for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
203                                         RTAPRINTmarkSubs1
204                                 rtaMarkSubs(subs, topmethod); 
205                                 }
206                         }
207                 }
208         return;
209 }
210
211 /*-------------------------------------------------------------------------------*/
212 /* Add Marked methods for input class ci                                         */
213 /* Add methods with the same name and descriptor as implemented interfaces       */
214 /*   with the same method name                                                   */
215 /*                                                                               */
216 /*-------------------------------------------------------------------------------*/
217 void rtaAddMarkedMethods(classinfo *ci) {
218         int ii,jj,mm;
219
220         /* add marked methods to callgraph */ 
221         for (ii=0; ii<ci->methodscount; ii++) { 
222                 methodinfo *mi = &(ci->methods[ii]);
223                 if (mi->methodUsed == MARKED) { 
224                         if (pWhenMarked >= 1) {
225                                 printf("ADDED a method that was MARKED\n");
226                                 }
227                         ADDTOCALLGRAPH(mi)  
228                         }
229                 else {
230 // from Dez                         if (NATIVE == true) { printf("NOT MARKED: "); method_display(mi);}
231
232                         for (jj=0; jj < ci -> interfacescount; jj++) {
233                                 classinfo *ici = ci -> interfaces [jj];
234                                 /*  use resolve method....!!!! */
235                                 if (ici -> classUsed != NOTUSED) {
236                                         for (mm=0; mm< ici->methodscount; mm++) {
237                                                 methodinfo *imi = &(ici->methods[mm]);
238
239                                                 if  (      (imi->methodUsed == USED) 
240                                                                    &&    ( (imi->name == mi->name) 
241                                                                                    &&      (imi->descriptor == mi->descriptor))) {
242                                                         if (pWhenMarked >= 1) 
243                                                                 printf("ADDED a method that was used by an interface\n");
244                                                         ADDTOCALLGRAPH(mi)  
245                                                                 }
246                                         }
247                                 }
248                         }
249                 }
250         }
251 }    
252 /*-------------------------------------------------------------------------------*/
253 /*  XTA Functions                                                                */
254 /*-------------------------------------------------------------------------------*/
255
256 xtainfo *xtainfoInit(methodinfo *m)
257 {
258         if (m->xta != NULL)
259                 return m->xta;
260         m ->xta = (xtainfo *) NEW(xtainfo); 
261         m ->xta-> XTAmethodUsed = NOTUSED;
262         m ->xta-> XTAclassSet   = NULL;
263         m ->xta-> XTAclassSet   = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
264
265         /* PartClassSet */
266         m->xta->paramClassSet = NULL;
267         m->xta->calls         = NULL;
268         m->xta->calledBy      = NULL;
269
270         m->xta->marked        = NULL; /* comment out*/
271         m ->xta->markedBy     = NULL; 
272         m->xta->fldsUsed      = NULL;
273         /*m ->xta->interfaceCalls    = NULL*/
274         m->xta->chgdSinceLastParse = false;
275         return m->xta;
276 }
277
278
279 xtafldinfo * xtafldinfoInit (fieldinfo *f)
280 {
281         if (f->xta != NULL)
282                 return f->xta;
283
284         f->xta = NEW(xtafldinfo);
285
286         f->xta->fieldChecked = false;   /*XTA*/
287         f->xta->fldClassType = NULL;    /*XTA*/
288         f->xta->XTAclassSet = NULL;     /*XTA*/
289
290         return f->xta;
291 }
292
293
294 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
295 {
296         classSetNode *p;
297         classSetNode *c;
298         classSetNode *c1;
299         classSetNode *cprev;
300         bool          rc = false;
301
302         if (XTAdebug >= 1) {
303                 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
304
305                 printf("\tIN SmCalled set : "); 
306                 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
307                 printClassSet(SmCalled->xta->XTAclassSet); printf("\n"); 
308
309                 printf("\tIN SmCalls set: "); 
310                 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
311                 printClassSet(SmCalls->xta->XTAclassSet); printf("\n"); 
312                 
313                 printf("\tIN lastptrInto : (");
314                 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
315                         utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
316                 }
317                 else {printf("NULL) ");}
318                 fflush(stdout);
319                 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
320                 method_display(lastptrInto->methRef); fflush(stdout);
321                 printf("\n");fflush(stdout);
322         }
323
324         /* Get SmCalled ParamType set if null */
325         if (SmCalled->xta->paramClassSet == NULL) {
326                 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); 
327         }
328         if (XTAdebug >= 1) {
329                 printf("\tParamPassed\n"); fflush(stdout);
330                 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
331                 printf("\n"); fflush(stdout);
332         }
333
334         if (lastptrInto->lastptrIntoClassSet2 == NULL) {
335                 if (SmCalls->xta->XTAclassSet != NULL) 
336                         c1 = SmCalls->xta->XTAclassSet->head;
337                 else
338                         c1 = NULL;
339         }
340         else    {
341                 /* start with type where left off */
342                 c1 = lastptrInto->lastptrIntoClassSet2;  
343                 c1 = c1 -> nextClass;  /* even if NULL */
344         }
345         cprev = NULL;
346         if (XTAdebug >= 1) {
347                 if (c1 == NULL){
348                         printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
349                 }
350                 else    {
351                         printf("\tIN SmCalls ... start with :");fflush(stdout);
352                         utf_display(c1->classType->name); printf("\n");
353                 }
354         }
355
356         /* for each Param Class */
357         for (   p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
358
359                 /* for each SmCalls class */
360                 for (c=c1; c != NULL; c = c->nextClass) {
361                         vftbl *p_cl_vt = p->classType->vftbl; 
362                         vftbl *c_cl_vt = c->classType->vftbl; 
363
364                         /* if SmCalls class is in the Params Class range */
365                         if (  (p_cl_vt->baseval <=  c_cl_vt->baseval)
366                                   && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
367
368                                 /*    add SmCalls class to SmCalledBy Class set */
369                                 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType); 
370                                 rc = true;
371                         }
372                         cprev = c;
373                 }       
374         }
375         lastptrInto->lastptrIntoClassSet2 = cprev;
376         if (XTAdebug >= 1) {
377                 printf("\tOUT SmCalled set: ");fflush(stdout);
378                 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
379
380                 printf("\tOUT SmCalls set: ");fflush(stdout);
381                 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
382
383                 printf("\tOUT  lastptrInto="); fflush(stdout);
384                 if (lastptrInto->lastptrIntoClassSet2 != NULL)
385                         utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
386
387                 printf("<rc=%i>\n",rc);fflush(stdout);
388         }
389         return rc;
390 }
391
392 /*-------------------------------------------------------------------------------*/
393 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
394
395         classSetNode* cs;
396         classSetNode* cs1;
397         bool          rc = false;
398
399         if (XTAdebug >= 1)
400                 printf("xtaPassReturnType \n");
401
402         /* Get SmCalled return class is null */
403         if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
404                 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); 
405         }
406
407         if (SmCalled->returnclass == NULL) {
408                 if (XTAdebug >= 1)
409                         printf("\tReturn type is NULL\n");
410                 return rc;
411         }
412         
413         if (XTAdebug >= 1) {
414                 printf("\tReturn type is: ");
415                 utf_display(SmCalled->returnclass->name);
416                 printf("\n");
417
418                 printf("\tIN SmCalls set: ");
419                 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
420                 printClassSet(SmCalls->xta->XTAclassSet);
421
422                 printf("\tIN SmCalled set: ");
423                 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
424                 printClassSet(SmCalled->xta->XTAclassSet);
425         }
426
427
428         if (SmCalled->xta->XTAclassSet == NULL) 
429                 cs1 = NULL;
430         else
431                 cs1 =  SmCalled->xta->XTAclassSet->head;
432         for (cs =cs1; cs != NULL; cs = cs->nextClass) {
433                 classinfo *c = cs->classType;
434                 vftbl *r_cl_vt = SmCalled->returnclass->vftbl; 
435                 vftbl *c_cl_vt = c->vftbl; 
436
437                 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
438                 if (  (r_cl_vt->baseval <=  r_cl_vt->baseval)
439                           && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
440                         SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);  
441                         rc = true;
442                 }
443         } 
444
445         if (XTAdebug >= 1) {
446                 printf("\tOUT SmCalls set: ");
447                 printClassSet(SmCalls->xta->XTAclassSet);
448         }
449         return rc;
450 }
451
452 /*-------------------------------------------------------------------------------*/
453 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
454
455         if (mi->xta == NULL)
456                 mi->xta = xtainfoInit(mi);
457         if (mi->xta->XTAmethodUsed  != USED) {  /* if static method not in callgraph */
458                 mi->xta->XTAmethodUsed = USED;
459                 if (!(mi->flags & ACC_ABSTRACT)) { 
460                         if (mi->methodUsed != USED) {
461                                 XTAcallgraph[++methXTAlast] = mi;
462                                 mi->methodUsed = USED;
463                                         /*RTprint*/ if (pClassHeir >= 1) {
464                                                 XTAPRINTcallgraph2
465                                                 }
466                                 }
467                         }
468
469                 }
470                         /*RTAprint*/ if(pWhenMarked>=1) {  
471                                 /*RTAprint*/ printf("\nxxxxxxxxxxxxxxxxx XTA set Used or Added to Call Graph #%i:", 
472                                 /*RTAprint*/       methXTAlast); 
473                                 /*RTAprint*/ printf(" method name ="); fflush(stdout);
474                                 /*RTAprint*/ utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout); 
475                                 /*RTAprint*/ method_display(mi);fflush(stdout); 
476                                 /*RTAprint*/ printf("\t\t\t\tcalledBy:");
477                                 /*RTAprint*/ utf_display(rt_method->class->name);fflush(stdout); printf(".");fflush(stdout); 
478                                 /*RTAprint*/ method_display(rt_method);fflush(stdout); 
479                                 /*RTAprint*/ }
480         /* add call edges */
481         rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
482         rt_method->xta->calls->tail->monoPoly = monoPoly;
483         mi->xta->calledBy     = add2MethSet(mi->xta->calledBy,     rt_method); 
484         if (mi->xta->calledBy     == NULL) panic("mi->xta->calledBy is NULL!!!");
485         if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
486 }
487
488
489 /*--------------------------------------------------------------*/
490 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
491         classinfo *subs;
492
493         for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
494                 /* if class used */
495                 if (inSet(subtypesUsedSet,subs)) {
496                         if (class_findmethod_w(class, meth->name, meth->descriptor, "xtaSubUsed") == NULL) 
497                                 return false;
498                         else    {
499                                 if (class_findmethod_w(subs, meth->name, meth->descriptor, "xtaSubUsed") == NULL) 
500                                         return true;
501                                 }
502                 }
503                 if (xtaSubUsed(subs, meth,  subtypesUsedSet)) 
504                         return false;
505         }
506         return false;
507 }
508
509
510 /*-------------------------------------------------------------------------------*/
511 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
512 {
513         methodinfo *submeth;
514
515         utf *name = topmethod -> name;
516         utf *descriptor = topmethod -> descriptor;
517         /****/
518                  printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout); 
519                  method_display(topmethod);
520         /**/
521
522         submeth = class_resolvemethod(class, name, descriptor);
523
524         /***/
525                 printf(" def: "); utf_display(submeth->class->name); printf("\n");fflush(stdout);
526         /****/
527
528         /* Basic checks */
529         if (submeth == NULL)
530                 panic("parse XTA: Method not found in class hierarchy");
531         if (submeth->xta == NULL) 
532                 submeth->xta = xtainfoInit(submeth);
533
534         if (rt_method->xta->calls != NULL) {
535                 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
536         }
537         /*----*/
538         if (submeth->class == class) {
539
540         /*--- Method defined in class -----------------------------*/
541                 if (inSet(subtypesUsedSet,submeth->class)) {
542                         xtaAddCallEdges(submeth,POLY);  
543                 }
544                 else    {
545                         if (subtypesUsedSet != NULL) {  
546                                 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
547                                         xtaAddCallEdges(submeth,POLY);
548                                         return; //Dez
549                                 }
550                         submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
551                                 /****
552                                         printf("\t(defd) Added to MarkBy Set\n"); fflush(stdout);
553                                         utf_display(submeth->class->name); printf("."); fflush(stdout);
554                                         method_display(submeth);
555                                         printMethodSet(submeth->xta->markedBy);
556                                 ****/
557
558                         }
559                 }
560         }
561         else  {
562         /*--- Method NOT defined in class -----------------------------*/
563                 if (!(inSet(subtypesUsedSet,submeth->class) )){  /* class with method def     is not used */
564                         if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */ 
565                                 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
566                                 submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,rt_method);
567                                 /****
568                                         printf("\t(^^defd) Added to MarkBy Set\n"); fflush(stdout);
569                                         utf_display(submeth->class->name); printf("."); fflush(stdout);
570                                         method_display(submeth);
571                                         printMethodSet(submeth->xta->markedBy);
572                                 ****/
573                         }
574                 }
575                 if ( (inSet(subtypesUsedSet,submeth->class))  /* class with method def     is used */
576                          || (inSet(subtypesUsedSet,class)) ) {       /* class currently resolving is used */ 
577                         xtaAddCallEdges(submeth,POLY);
578                 }
579
580         } /* end defined in class */
581
582 }
583 /*-------------------------------------------------------------------------------*/
584 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
585         /* xtaPRINTmarkSubs1*/
586         xtaMarkMethod(class, topmethod,subtypesUsedSet);   /* Mark method in class where it was found */
587         if (class->sub != NULL) {
588                 classinfo *subs;
589
590                 if (!(topmethod->flags & ACC_FINAL )) {
591                         for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
592                                 /* xtaPRINTmarkSubs1 */
593                                 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
594                                 }
595                         }
596                 }
597 }
598
599 /*-------------------------------------------------------------------------------*/
600 /* Add Marked methods for input class ci                                         */
601 /* Add methods with the same name and descriptor as implemented interfaces       */
602 /*   with the same method name                                                   */
603 /*                                                                               */
604 /*-------------------------------------------------------------------------------*/
605 void xtaAddMarkedMethods(classinfo *ci) {
606         int ii,jj,mm;
607
608         /* add marked methods to callgraph */
609         for (ii=0; ii<ci->methodscount; ii++) {
610                 methodinfo *mi = &(ci->methods[ii]);
611           if (mi->xta != NULL) {
612                 if (mi->xta->markedBy != NULL) {
613                         methSetNode *mcnode;
614                         for (mcnode = mi->xta->markedBy->head; mcnode  != NULL; mcnode  = mcnode ->nextmethRef) {
615                                 methodinfo *mc = mcnode->methRef;
616                                 if (pWhenMarked >= 1) {
617                                         printf("ADDED a method that was MARKED\n");
618                                         }
619                                 xtaAddCallEdges(mi,POLY);
620                                 }
621                         }
622                 {
623                         for (jj=0; jj < ci -> interfacescount; jj++) {
624                                 classinfo *ici = ci -> interfaces [jj];
625                                 /*  use resolve method....!!!! */
626                                 if (ici -> classUsed != NOTUSED) {
627                                         for (mm=0; mm< ici->methodscount; mm++) {
628                                                 methodinfo *imi = &(ici->methods[mm]);
629                                                 if (imi->xta != NULL) {
630                                                 if      ((imi->xta->XTAmethodUsed == USED)
631                                                            &&    ( (imi->name == mi->name)
632                                                            &&      (imi->descriptor == mi->descriptor))) {
633                                                         if (pWhenMarked >= 1)
634                                                                 printf("ADDED a method that was used by an interface\n");
635                                                         xtaAddCallEdges(mi,POLY);
636                                                         }
637                                                         }
638                                                 }
639                                         }
640                                 }
641                         }
642                   }
643                 }
644 }
645
646 /*-------------------------------------------------------------------------------*/
647 /* Both RTA and XTA */
648 /*-------------------------------------------------------------------------------*/
649
650 int addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark) {
651         /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
652          */
653
654         utf* utf_java_lang_system = utf_new_char("java/lang/System"); 
655         utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass"); 
656         utf* utf_java_lang_Object = utf_new_char("java/lang/Object"); 
657
658         int m, m1=-1, m2=-1, mf=-1;
659         methodinfo *mi;
660
661         if (clinits) { /* No <clinit>  available - ignore */  
662
663                 /* Get clinit methodinfo ptr */
664                 if ((mi = class_resolvemethod(ci,CLINIT, EMPTY_DESC)) !=NULL) {
665                         if (mi->class != ci) {
666                                 printf("WARNING:::::<clinit> method not found in class requested: ");
667                                 utf_display(ci->name); printf(" found in:"); utf_display(mi->class->name);
668                                 printf("\n");
669                                 }
670                         /*--- RTA ---*/
671                         if ( mi->methodUsed != USED) {
672                                 mi->class->classUsed = PARTUSED;  
673                                 ADDTOCALLGRAPH(mi)  
674                                 }
675
676                         /*--- XTA ---*/
677                         if ((XTAOPTbypass) || (opt_xta)) {
678                                 xtaAddCallEdges(mi,MONO); 
679                                 }
680                         }
681                 else    {
682                         printf("class=");utf_display(ci->name);
683                         printf(" super="); 
684                         if (ci->super != NULL)
685                                 utf_display(ci->super->name);
686                         else
687                                 printf("NULL");
688                         if ( (ci->super->name != utf_OBJECT) && (ci->name != utf_OBJECT)  )
689                                 panic("<clinit> method not found");
690                         }
691                 }
692
693         if (finalizes) {   
694
695                 /* Get finalize methodinfo ptr */
696                 if ( (mi = class_findmethod (ci,FINALIZE, EMPTY_DESC)) != NULL) { 
697                         /*--- RTA ---*/
698                         if ( mi->methodUsed != USED) {
699                                 mi->class->classUsed = PARTUSED;  
700                                 ADDTOCALLGRAPH(mi)  
701                                 }
702
703                         /*--- XTA ---*/
704                         if ((XTAOPTbypass) || (opt_xta)) {
705                                 xtaAddCallEdges(mi,MONO); 
706                                 }
707                         }
708                 }
709
710         /*Special Case for System class init:  
711         add java/lang/initializeSystemClass to callgraph */
712         if (class->name == utf_initializeSystemClass) {
713                 /* Get clinit methodinfo ptr */
714                 if ((mi = class_findmethod (ci,utf_initializeSystemClass, EMPTY_DESC)) != NULL) {
715                         /*--- RTA ---*/
716                         if ( mi->methodUsed != USED) {
717                                 mi->class->classUsed = PARTUSED;
718                                 ADDTOCALLGRAPH(mi)  
719                                 }
720
721                         /*--- XTA ---*/
722                         if ((XTAOPTbypass) || (opt_xta)) {
723                                 xtaAddCallEdges(mi,MONO);
724                                 }
725                         }
726                 }
727         if (addmark) {
728                 /* add marked methods to callgraph */ 
729                 if ((XTAOPTbypass) || (opt_xta))
730                         xtaAddMarkedMethods(ci);
731                 else
732                         rtaAddMarkedMethods(ci);
733                 }
734                 
735         return m;
736
737
738
739 #define rt_code_get_u1(p)  rt_jcode[p]
740 #define rt_code_get_s1(p)  ((s1)rt_jcode[p])
741 #define rt_code_get_u2(p)  ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
742 #define rt_code_get_s2(p)  ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
743 #define rt_code_get_u4(p)  ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
744                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
745 #define rt_code_get_s4(p)  ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
746                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
747
748
749
750 /*-------------------------------------------------------------------------------*/
751 void rtaAddUsedInterfaceMethods(classinfo *ci) {
752         int jj,mm;
753
754         /* add used interfaces methods to callgraph */
755         for (jj=0; jj < ci -> interfacescount; jj++) {
756                 classinfo *ici = ci -> interfaces [jj];
757         
758                 if (pWhenMarked >= 1) { 
759                         printf("BInterface used: ");fflush(stdout); 
760                         utf_display(ici->name);
761                         printf("<%i>\t",ici -> classUsed ); fflush(stdout); 
762                         if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
763                         if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
764                         if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
765                         fflush(stdout);
766                 }
767                 /* add class to interfaces list of classes that implement it */
768                 ici -> impldBy =  addElement(ici -> impldBy,  ci);
769
770                 /* if interface class is used */
771         if (ici -> classUsed != NOTUSED) {
772
773                         /* for each interface method implementation that has already been used */
774                         for (mm=0; mm< ici->methodscount; mm++) {
775                                 methodinfo *imi = &(ici->methods[mm]);
776                                 if (pWhenMarked >= 1) { 
777                                         if  (imi->methodUsed != USED) {
778                                                 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: "); 
779                                                 if (imi->methodUsed == MARKED) printf("Interface Method marked: "); 
780                                                 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
781                                         }
782                                 } 
783                                 if  (imi->methodUsed == USED) {
784                                         if (pWhenMarked >= 1) { 
785                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
786
787                                                 /* Mark this method used in the (used) implementing class and its subclasses */
788                                                 printf("rMAY ADD methods that was used by an interface\n");
789                                         }
790                                         rtaMarkSubs(ci,imi);
791                                 }
792                         }
793                 }
794         }
795
796 }
797 /*-------------------------------------------------------------------------------*/
798 void rtaMarkInterfaceSubs(methodinfo *mi) {                             
799         classSetNode *subs;
800         if (mi->class->classUsed == NOTUSED) {
801                 mi->class->classUsed = USED; 
802                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
803                 }
804
805         /* add interface class to list kept in Object */
806         mi->methodUsed = USED;
807         mi->monoPoly   = POLY;
808
809         subs =  mi->class->impldBy; 
810                                                 RTAPRINT08invokeInterface1
811         while (subs != NULL) {                  
812                 classinfo * isubs = subs->classType;
813                                                         RTAPRINT09invokeInterface2
814                 /* Mark method (mark/used) in classes that implement the method */
815                 if (isubs->classUsed != NOTUSED) {
816                         methodinfo *submeth;
817                                                 
818                         submeth = class_findmethod(isubs,mi->name, mi->descriptor); 
819                         if (submeth != NULL)
820                                 submeth->monoPoly = POLY; /*  poly even if nosubs */
821                         rtaMarkSubs(isubs, mi);  
822                         }
823                                 
824                 subs = subs->nextClass;
825                 } /* end while */
826
827
828 /*-------------------------------------------------------------------------------*/
829 /*-------------------------------------------------------------------------------*/
830
831
832
833 /*-------------------------------------------------------------------------------*/
834 void xtaAddUsedInterfaceMethods(classinfo *ci) {
835         int jj,mm;
836
837 /* add used interfaces methods to callgraph */
838 for (jj=0; jj < ci -> interfacescount; jj++) {
839         classinfo *ici = ci -> interfaces [jj];
840         
841         if (pWhenMarked >= 1) { 
842                         printf("XInterface used: ");fflush(stdout); 
843                         utf_display(ici->name);
844                         printf("<%i>\t",ici -> classUsed ); fflush(stdout); 
845                         if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
846                         if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
847                         if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
848                         fflush(stdout);
849                         }
850         /* add class to interfaces list of classes that implement it */
851         ici -> impldBy =  addElement(ici -> impldBy,  ci);
852
853         /* if interface class is used */
854         if (ici -> classUsed != NOTUSED) {
855
856                 /* for each interface method implementation that has already been used */
857                 for (mm=0; mm< ici->methodscount; mm++) {
858                         methodinfo *imi = &(ici->methods[mm]);  /*interface method */
859 printf("==%i==%i\n",ici->methodscount,mm);
860                         if (imi->xta == NULL)
861                                 xtainfoInit (imi); 
862                                         /*RTAprint*/if (pWhenMarked >= 1) { 
863                                         /*RTAprint*/  if  (imi->xta->XTAmethodUsed != USED) {
864                                         /*RTAprint*/    if (imi->xta->XTAmethodUsed==NOTUSED) 
865                                                                 printf("Interface Method notused: "); 
866                                         /*RTAprint*/    if (imi->xta->XTAmethodUsed==MARKED) 
867                                                                 printf("Interface Method marked: "); 
868                                         /*RTAprint*/    utf_display(ici->name);printf(".");
869                                         /*RTAprint*/    method_display(imi);fflush(stdout);
870                                         /*RTAprint*/    }
871                                         /*RTAprint*/  } 
872                         if  (imi->xta->XTAmethodUsed == USED) {
873                                 methSetNode *mCalledBy = NULL;
874                                         if (pWhenMarked >= 1) { 
875                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");
876                                                 method_display(imi);fflush(stdout);
877
878                                                 /* Mark this method used in the (used) implementing class &its subclasses */
879                                                 printf("xMAY ADD methods that was used by an interface\n"); fflush(stdout);
880                                                 }
881                                         if (pWhenMarked >= 1) {
882                                                 printf("calledBy set ="); fflush(stdout);
883                                                 printMethodSet(imi->xta->calledBy);
884                                                 }
885                                 if (imi->xta->calledBy != NULL) { 
886                                         /* for each calledBy method */
887                                         for (   mCalledBy = imi->xta->calledBy->head; 
888                                                 mCalledBy != NULL; 
889                                                 mCalledBy = mCalledBy->nextmethRef) {
890                                                 if (pWhenMarked >= 1) {
891                                                                 printf("xtaMarkSubs(");
892                                                                 utf_display(ci->name); printf("."); fflush(stdout);
893                                                                 method_display(imi);
894                                                                 printf("mCalledBy method class set BEFORE\n"); fflush(stdout);
895                                                                 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
896                                                 }
897                                                 xtaMarkSubs(ci,imi,mCalledBy->methRef->xta->XTAclassSet->head);
898                                                         if (pWhenMarked >= 1) {
899                                                                 printf("mCalledBy method class set AFTER \n"); fflush(stdout);
900                                                                 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
901                                                         }
902                                                 }
903                                         }
904                                 }
905                         } 
906                 }
907         } /* end for */
908 }
909
910 /*-------------------------------------------------------------------------------*/
911
912 /*-------------------------------------------------------------------------------*/
913 void xtaMarkInterfaceSubs(methodinfo *mi) {
914         classSetNode *subs;
915         classSetNode * Si;
916
917         if (mi->xta == NULL)
918                 xtainfoInit (mi); 
919                                         
920         if (mi->class->classUsed != USED) {
921                 mi->class->classUsed = USED; 
922                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
923                 }
924
925         /* add interface class to list kept in Object */
926                                 if (pWhenMarked >= 1) {
927                                         printf("Marking Interface Method: "); fflush(stdout);
928                                         }
929         xtaAddCallEdges(mi,POLY);       
930
931         subs =  mi->class->impldBy; 
932                                                 RTAPRINT08invokeInterface1
933         while (subs != NULL) { 
934                 classinfo * isubs = subs->classType;
935                                                         RTAPRINT09invokeInterface2
936                 /* Mark method (mark/used) in classes that implement the method */
937                 if (isubs->classUsed != NOTUSED) {
938                         methodinfo *submeth;
939                                                 
940                         submeth = class_resolvemethod(isubs,mi->name, mi->descriptor); 
941                         if (submeth != NULL)    ///+1
942                                 {
943                                 classSetNode *subtypesUsedSet = NULL;
944                                 submeth->monoPoly = POLY; /*  poly even if nosubs */
945                                                         
946                                 mi->xta->XTAmethodUsed = USED;
947                                 if (rt_method->xta->XTAclassSet != NULL)
948                                         subtypesUsedSet =
949                                                 intersectSubtypesWithSet
950                                                         (subs->classType, rt_method->xta->XTAclassSet->head);
951
952                                                         if (pWhenMarked >= 1) {
953                                                                 /*RTAprint*/ printf(" \nXTA subtypesUsedSet: ");
954                                                                 /*RTAprint*/ fflush(stdout);
955                                                                 /*RTAprint*/ printSet(subtypesUsedSet);
956                                                         }
957                                 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
958                                 }
959                         }
960                 subs = subs->nextClass;
961                 }
962 }
963 /*-------------------------------------------------------------------------------*/
964
965 /*-------------------------------------------------------------------------------*/
966 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
967
968         bool rc = false;
969
970         if (fi->xta->fieldChecked) {
971                 if (fi->xta->fldClassType != NULL)
972                         return true;  /* field has a class type */
973                 else
974                         return false;
975         }
976         fi->xta->fieldChecked = true;
977
978         if (fi->type == TYPE_ADDRESS) {
979                 char *utf_ptr = fi->descriptor->text;  /* current position in utf text */
980
981                 if (*utf_ptr != 'L') {
982                         while (*utf_ptr++ =='[') ;
983                 }
984
985                 if (*utf_ptr =='L') {
986                         rc = true;
987                         if  (fi->xta->fldClassType== NULL) {
988                                 char *desc;
989                                 char *cname;
990                                 classinfo * class;
991
992                                 desc = MNEW(char, 256);
993                                 strcpy(desc,++utf_ptr);
994                                 cname = strtok(desc,";");
995                                 if (XTAdebug >= 1) {
996                                         printf("STATIC fields type is: %s\n",cname);
997                                         fflush(stdout);
998                                 }
999                                 class = class_get(utf_new_char(cname));
1000                                 fi->xta->fldClassType= class;    /* save field's type class ptr */      
1001                         } 
1002                 }
1003         }
1004         return rc;
1005 }
1006
1007 /*-------------------------------------------------------------------------------*/
1008 void xtaPassFldPUT(fldSetNode *fN)
1009 {
1010         /* Field type is a class */
1011         classSetNode *c;
1012         classSetNode *c1 = NULL;
1013         classSetNode *cp = NULL;
1014         classSetNode *cprev= NULL;
1015
1016         fieldinfo *fi;
1017         if (fN != NULL)
1018                 fi = fN->fldRef;
1019         else
1020                 return;
1021
1022 /* Use lastptr  so don't check whole XTA class set each time */
1023         cp = fN->lastptrPUT;
1024         if (cp != NULL) {
1025                 if (cp->nextClass != NULL)
1026                         c1 = cp -> nextClass;
1027         } 
1028         else    {
1029                 if (rt_method->xta->XTAclassSet != NULL)
1030                         c1  = rt_method->xta->XTAclassSet->head;
1031
1032                 if (XTAfld >=1 ) {
1033                         printf("rt XTA class set =");fflush(stdout);
1034                         printClassSet(rt_method->xta->XTAclassSet);
1035                         printf("\t\tField class type = ");fflush(stdout);
1036                         utf_display(fi->xta->fldClassType->name); printf("\n");
1037                 }
1038         }
1039
1040         /*--- PUTSTATIC specific ---*/
1041         /* Sx = intersection of type+subtypes(field x)   */
1042         /*   and Sm (where putstatic code is)            */
1043         for (c=c1; c != NULL; c=c->nextClass) {
1044                 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
1045                 vftbl *c_cl_vt =  c->   classType->vftbl;
1046                 if (XTAfld >=2 ) {
1047                         printf("\tXTA class = ");fflush(stdout);
1048                         utf_display(c->classType->name);
1049                         printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
1050                         if (c->nextClass == NULL) {
1051                                 printf("next=NULL ");fflush(stdout);
1052                         }
1053                         else    {
1054                                 printf("next="); fflush(stdout);
1055                                 utf_display(c->nextClass->classType->name);
1056                                 printf("\n"); fflush(stdout);
1057                         }
1058
1059                         printf("\t\tField class type = ");fflush(stdout);
1060                         utf_display(fi->xta->fldClassType->name);
1061                         printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
1062                 }
1063
1064                 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
1065                         && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
1066                         fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
1067                 }
1068                 cprev = c;
1069         }
1070         fN->lastptrPUT = cprev;
1071 }
1072 /*-------------------------------------------------------------------------------*/
1073 void xtaPassFldGET(fldSetNode *fN)
1074 {
1075         /* Field type is a class */
1076         classSetNode *c;
1077         classSetNode *c1 = NULL;
1078         classSetNode *cp = NULL;
1079         classSetNode *cprev= NULL;
1080
1081         fieldinfo *fi;
1082         if (fN != NULL)
1083                 fi = fN->fldRef;
1084         else
1085                 return;
1086
1087 /* Use lastptr  so don't check whole XTA class set each time */
1088         cp = fN->lastptrGET;
1089         if (cp != NULL) {
1090                 if (cp->nextClass != NULL)
1091                         c1 = cp -> nextClass;
1092         } 
1093         else    {
1094                 if (fi->xta->XTAclassSet != NULL)
1095                         c1  = fi->xta->XTAclassSet->head;
1096
1097                 if (XTAfld >=1 ) {
1098                         printf("fld XTA class set =");fflush(stdout);
1099                         printClassSet(fi->xta->XTAclassSet);
1100                         printf("\t\tField class type = ");fflush(stdout);
1101                         utf_display(fi->xta->fldClassType->name); printf("\n");
1102                 }
1103         }
1104
1105         /*--- GETSTATIC specific ---*/
1106         /* Sm = union of Sm and Sx */
1107         for (c=c1; c != NULL; c=c->nextClass) {
1108                 bool addFlg = false;
1109                 if (rt_method->xta->XTAclassSet ==NULL) 
1110                         addFlg = true;
1111                 else    {
1112                         if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) )) 
1113                                 addFlg = true;
1114                         }
1115                 if (addFlg) {
1116                         rt_method->xta->XTAclassSet 
1117                                 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
1118                 }
1119                 cprev = c;
1120         }
1121
1122         fN->lastptrGET = cprev;
1123
1124 }
1125
1126 /*-------------------------------------------------------------------------------*/
1127 void xtaPassAllCalledByParams () {
1128         methSetNode *SmCalled;
1129         methSetNode *s1;
1130         if (XTAdebug >= 1) {
1131                 printf("xta->calledBy method set: "); fflush(stdout);
1132                 
1133                 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
1134                 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
1135                 }
1136         if (rt_method->xta->calledBy == NULL)
1137                 s1 = NULL;
1138         else
1139                 s1 = rt_method->xta->calledBy->head;
1140         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1141                 if (XTAdebug >= 1) {
1142                         printf("SmCalled = "); fflush(stdout);
1143                         utf_display(SmCalled->methRef->class->name); fflush(stdout);
1144                         printf(".");fflush(stdout); method_display(SmCalled->methRef);
1145                 }
1146                                 
1147                 rt_method->xta->chgdSinceLastParse = false;             
1148                 xtaPassParams(rt_method, SmCalled->methRef,SmCalled);   /* chg flag output ignored for 1st regular parse */
1149         }
1150 }
1151
1152 /*-------------------------------------------------------------------------------*/
1153 void xtaAllFldsUsed ( ){
1154         fldSetNode  *f;
1155         fldSetNode *f1=NULL; 
1156         /*      bool chgd = false */
1157
1158         if (rt_method->xta->fldsUsed == NULL) return;
1159
1160         /* for each field that this method uses */
1161         f1 = rt_method->xta->fldsUsed->head;
1162
1163         for (f=f1; f != NULL; f = f->nextfldRef) {
1164
1165                 if (f->writePUT)
1166                         xtaPassFldPUT(f);
1167                 if (f->readGET)
1168                         xtaPassFldGET(f);
1169         }
1170 }
1171 /*-------------------------------------------------------------------------------*/
1172 void  xtaMethodCalls_and_sendReturnType() 
1173 {
1174         methSetNode *SmCalled;  /* for return type       */
1175         methSetNode *SmCalls;   /* for calls param types */
1176         methSetNode *s1=NULL; 
1177         bool chgd = false;
1178         if (XTAdebug >= 1) {
1179                 printf("calls method set Return type: ");
1180                 printMethodSet(rt_method->xta->calls);
1181         }
1182         xtaAllFldsUsed ( );
1183
1184         /* for each method that this method calls */
1185         if (rt_method->xta->calls == NULL)
1186                 s1 = NULL;
1187         else
1188                 s1 = SmCalls=rt_method->xta->calls->head;
1189
1190         for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
1191                 /*    pass param types  */
1192                 bool chgd = false;
1193                 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);  
1194                 /* if true chgd after its own parse */
1195                 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
1196                         SmCalls->methRef->xta->chgdSinceLastParse = true;
1197                 }
1198         }
1199
1200         /* for each calledBy method */
1201         /*    send return type */
1202         if (rt_method->xta->calledBy == NULL)
1203                 s1 = NULL;
1204         else
1205                 s1 = rt_method->xta->calledBy->head;
1206         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1207
1208                 if (XTAdebug >= 1) {
1209                         printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
1210                         printf("."); method_display(SmCalled->methRef);
1211                 }
1212                                 
1213                 chgd = xtaPassReturnType(rt_method, SmCalled->methRef); 
1214                 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1215                         SmCalled->methRef->xta->chgdSinceLastParse = chgd;              
1216                 }
1217         }
1218 }
1219
1220 /*-------------------------------------------------------------------------------*/
1221 /* -- Processes STATIC  & PRIVATE methods
1222
1223 /* -- called for INVOKESTATIC, INVOKESPECIAL - PRIVATE and
1224 /*    STATIC / PRIVATE methods used by NATIVE methods
1225 /*-------------------------------------------------------------------------------*/
1226
1227 // Dez Version but gives too many Missed
1228 void invokestatic2( methodinfo *mi) {
1229
1230 mi->class->classUsed = PARTUSED;
1231 /*-- RTA --*/
1232 addClassInit(mi->class, true, true, true);
1233                 RTAPRINT04invokestatic1
1234
1235 if (opt_rt) {
1236         ADDTOCALLGRAPH(mi)
1237         } /* end RTA */
1238
1239 /*-- XTA --*/
1240 if ((XTAOPTbypass) || (opt_xta)) {
1241         mi->class->classUsed = PARTUSED;
1242         rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,mi->class);
1243         xtaAddCallEdges(mi,MONO);
1244         } /* end XTA */
1245 }
1246
1247
1248
1249 //// from just RTA version before Dez changes
1250 void invokestatic(methodinfo *mi){
1251                 RTAPRINT04invokestatic1
1252 if (mi->class->classUsed == NOTUSED) {
1253         mi->class->classUsed = USED;
1254                         RTAPRINT05invokestatic2
1255         }
1256         addClassInit(mi->class,true, true, true);
1257
1258         if (opt_rt) {
1259                 ADDTOCALLGRAPH(mi)  
1260                 } /* end RTA */
1261         /*-- XTA --*/
1262         if ((XTAOPTbypass) || (opt_xta)) {
1263                 xtaAddCallEdges(mi,MONO); 
1264         } /* end XTA */
1265 }
1266
1267
1268 /*-------------------------------------------------------------------------------*/
1269 /* -- Processes <INIT> methods
1270
1271 /* -- called for INVOKESPECIAL - <init> and
1272 /*    <init> methods used by NATIVE methods
1273 /*-------------------------------------------------------------------------------*/
1274
1275 void initMethods(methodinfo *mi) {
1276
1277 classinfo  *ci = mi->class;
1278
1279 /* new class so add marked methods */
1280 if (opt_rt) {
1281         if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED))  {
1282                 /*--- process NORMAL <init> method ---------------------------------------------*/
1283                 if ( mi->methodUsed != USED) {
1284                         /* Normal <init> 
1285                         - mark class as USED and <init> to callgraph */
1286
1287                         /*-- RTA --*/
1288 //      addClassInit(mi->class,true, true, false);
1289                         ci->classUsed = USED;
1290                         rtaAddMarkedMethods(ci);  /* add to callgraph marked methods */
1291                                         RTAPRINT06Binvoke_spec_init
1292                         rtaAddUsedInterfaceMethods(ci); 
1293                         ADDTOCALLGRAPH(mi)  
1294                         }
1295                 }       
1296         }
1297
1298 /*-- XTA --*/
1299 if ((XTAOPTbypass) || (opt_xta)) { 
1300         if (mi->xta == NULL) {
1301                 mi->xta = xtainfoInit(mi);
1302                 }
1303         if ((mi->xta->XTAmethodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1304                 ci->classUsed = USED;
1305                 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); 
1306                 xtaAddMarkedMethods(ci);  /* add to callgraph marked methods */
1307                 xtaAddUsedInterfaceMethods(ci); 
1308                 xtaAddCallEdges(mi,MONO);
1309                         RTAPRINT06CXTAinvoke_spec_init1
1310                 } /* end XTA */
1311         }
1312 }
1313
1314 /*-------------------------------------------------------------------------------*/
1315 /* -- Processes VIRTUAL methods
1316
1317 /* -- called for INVOKEVIRTUAL and 
1318 /*    virtual methods used by NATIVE methods 
1319 /*-------------------------------------------------------------------------------*/
1320
1321 void invokevirtual(methodinfo *mi) {
1322
1323 /*--- RTA ---*/
1324                         RTAPRINT07invoke_spec_virt2
1325 mi->class->classUsed = USED;  // Should this be later?
1326
1327 if ((mi->flags & ACC_STATIC)  || (mi->flags & ACC_PRIVATE)  || (mi->flags & ACC_FINAL) ) {
1328         invokestatic(mi);
1329         return;
1330         }
1331
1332
1333 mi->monoPoly = POLY;
1334
1335 if (opt_rt) { 
1336         rtaMarkSubs(mi->class,mi); 
1337         }
1338
1339 /*--- XTA ---*/
1340 if ((XTAOPTbypass) || (opt_xta)) { 
1341         classSetNode *subtypesUsedSet = NULL;
1342         if (rt_method->xta->XTAclassSet != NULL)
1343         subtypesUsedSet = 
1344                 intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1345         else
1346                 subtypesUsedSet = addElement(subtypesUsedSet, rt_method->class);
1347         /*****/ 
1348         printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1349         printSet(subtypesUsedSet);
1350         /*****/
1351         xtaMarkSubs(mi->class, mi, subtypesUsedSet);   
1352         } /* end XTA */
1353 }
1354
1355
1356 /*-------------------------------------------------------------------------------*/
1357 void invokeinterface( methodinfo *mi ) {        
1358                                                 /*RTAprint*/ if (pWhenMarked >= 1) {
1359                                                 /*RTAprint*/ printf("\t");fflush(stdout);
1360                                                 /*RTAprint*/ utf_display(mi->class->name); printf(".");fflush(stdout);
1361                                                 /*RTAprint*/ method_display(mi); fflush(stdout); 
1362                                                 /*RTAprint*/ }
1363
1364 if (mi->flags & ACC_STATIC)
1365         panic ("Static/Nonstatic mismatch calling static method");
1366                                                 RTAPRINT08AinvokeInterface0
1367 /*--- RTA ---*/
1368 if (opt_rt) {
1369         rtaMarkInterfaceSubs(mi);
1370         }
1371 /*--- XTA ---*/
1372 if ((XTAOPTbypass2) || (opt_xta)) {
1373         xtaMarkInterfaceSubs(mi);
1374         }
1375 }
1376
1377 /*-------------------------------------------------------------------------------*/
1378 void newClasses(classinfo *ci) {
1379                                         if (pWhenMarked >= 1) {
1380                                                 printf("\tclass=");fflush(stdout);
1381                                                 utf_display(ci->name); fflush(stdout);
1382                                                 printf("=\n");fflush(stdout);
1383                                                 }
1384 /*--- RTA ---*/
1385 if (ci->classUsed != USED) {
1386                                         RTAPRINT10new
1387         ci->classUsed = USED;    /* add to heirarchy    */
1388         /* Add this class to the implemented by list of the abstract interface */
1389         rtaAddUsedInterfaceMethods(ci);
1390         addClassInit(ci, true, true, false);
1391         } 
1392 /*--- XTA ---*/
1393 if ((XTAOPTbypass) || (opt_xta))
1394         {
1395         xtaAddUsedInterfaceMethods(ci);
1396         rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1397                                                 RTAPRINT10newXTA
1398         }
1399 }
1400
1401 /*-------------------------------------------------------------------------------*/
1402 static void parseRT()
1403 {
1404         int  p;                     /* java instruction counter                   */
1405         int  nextp;                 /* start of next java instruction             */
1406         int  opcode;                /* java opcode                                */
1407         int  i;                     /* temporary for different uses (counters)    */
1408         bool iswide = false;        /* true if last instruction was a wide        */
1409
1410         RTAPRINT01method
1411
1412                 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1413                                         printf("XTA parseRT():"); fflush(stdout);
1414                                         method_display(rt_method);
1415                         if (rt_method->xta == NULL)
1416                                 xtainfoInit (rt_method);
1417                         xtaPassAllCalledByParams ();
1418                                         printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1419    
1420                 }
1421
1422         /* scan all java instructions */
1423
1424         for (p = 0; p < rt_jcodelength; p = nextp) {
1425                 opcode = rt_code_get_u1 (p);           /* fetch op code                  */
1426                 RTAPRINT02opcode
1427                         fflush(stdout); 
1428                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
1429                 switch (opcode) {
1430
1431                         /*--------------------------------*/
1432                         /* Code just to get the correct  next instruction */
1433                         /* 21- 25 */
1434                 case JAVA_ILOAD:
1435                 case JAVA_LLOAD:
1436                 case JAVA_FLOAD:
1437                 case JAVA_DLOAD:
1438
1439                 case JAVA_ALOAD:
1440                         if (iswide)
1441                                 {
1442                                         nextp = p+3;
1443                                         iswide = false;
1444                                 }
1445                         break;
1446
1447                         /* 54 -58 */
1448                 case JAVA_ISTORE:
1449                 case JAVA_LSTORE:
1450                 case JAVA_FSTORE:
1451                 case JAVA_DSTORE:
1452
1453                 case JAVA_ASTORE:
1454                         if (iswide)
1455                                 {
1456                                         iswide=false;
1457                                         nextp = p+3;
1458                                 }
1459                         break;
1460
1461                         /* 132 */
1462                 case JAVA_IINC:
1463                         {
1464                                 if (iswide) {
1465                                         iswide = false;
1466                                         nextp = p+5;
1467                                 }
1468                         }
1469                         break;
1470
1471                         /* wider index for loading, storing and incrementing */
1472                         /* 196 */
1473                 case JAVA_WIDE:
1474                         iswide = true;
1475                         nextp = p + 1;
1476                         break;
1477                         /* 169 */
1478                 case JAVA_RET:
1479                         if (iswide) {
1480                                 nextp = p+3;
1481                                 iswide = false;
1482                         }
1483                         break;
1484
1485                         /* table jumps ********************************/
1486
1487                 case JAVA_LOOKUPSWITCH:
1488                         {
1489                                 s4 num;
1490                                 nextp = ALIGN((p + 1), 4);
1491                                 num = rt_code_get_u4(nextp + 4);
1492                                 nextp = nextp + 8 + 8 * num;
1493                                 break;
1494                         }
1495
1496
1497                 case JAVA_TABLESWITCH:
1498                         {
1499                                 s4 num;
1500                                 nextp = ALIGN ((p + 1),4);
1501                                 num = rt_code_get_s4(nextp + 4);
1502                                 num = rt_code_get_s4(nextp + 8) - num;
1503                                 nextp = nextp + 16 + 4 * num;
1504                                 break;
1505                         }
1506
1507                         /*-------------------------------*/
1508                 case JAVA_PUTSTATIC:
1509                         i = rt_code_get_u2(p + 1);
1510                         {
1511                                 constant_FMIref *fr;
1512                                 fieldinfo *fi;
1513
1514                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1515                                 /* descr has type of field ref'd  */
1516                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1517                                 RTAPRINT03putstatic1
1518
1519                                 /*--- RTA ---*/
1520                                 /* class with field - marked in addClassinit */
1521                                 addClassInit(fr->class, true, true, false);
1522
1523                                 /*--- XTA ---*/
1524                                 if   ((XTAOPTbypass) || (opt_xta))
1525                                         {
1526                                                 if (fi->xta == NULL)
1527                                                         fi->xta = xtafldinfoInit(fi);
1528                                                 if (xtaAddFldClassTypeInfo(fi)) {  
1529                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1530                                                 }
1531                                         }
1532                         }
1533                         break;
1534
1535                 case JAVA_GETSTATIC:
1536                         i = rt_code_get_u2(p + 1);
1537                         {
1538                                 constant_FMIref *fr;
1539                                 fieldinfo *fi;
1540
1541                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1542                                 /* descr has type of field ref'd  */
1543                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1544                                 RTAPRINT03putstatic1
1545
1546                                 /*--- RTA ---*/
1547                                 /* class with field - marked in addClassinit */
1548                                 addClassInit(fr->class,true, true, true);
1549
1550                                 /*--- XTA ---*/
1551                                 if  ((XTAOPTbypass) || (opt_xta) ) 
1552                                         {
1553                                                 if (fi->xta == NULL)
1554                                                         fi->xta = xtafldinfoInit(fi);
1555                                                 if (xtaAddFldClassTypeInfo(fi)) {
1556                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1557                                                 }
1558                                         }
1559
1560                         }
1561                         break;
1562
1563
1564                         /*--------------------  method invocation ---------------------*/
1565
1566                 case JAVA_INVOKESTATIC:
1567                         i = rt_code_get_u2(p + 1);
1568                         {
1569                                 constant_FMIref *mr;
1570                                 methodinfo *mi;
1571
1572                                 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1573                                 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1574                                 if (!mi)
1575                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1576                                 /*-- RTA --*/
1577                                 invokestatic(mi);
1578                         }
1579                         break;
1580
1581                 case JAVA_INVOKESPECIAL:
1582                         i = rt_code_get_u2(p + 1);
1583                         {
1584                         constant_FMIref *mr;
1585                         methodinfo *mi;
1586                                 
1587                         mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1588                         mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1589                         if (!mi)
1590                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1591                                                 RTAPRINT06invoke_spec_virt1
1592                         /*--- PRIVATE Method -----------------------------------------------------*/ 
1593                         if (mi->name        != INIT) {     /* if method called is PRIVATE */ 
1594                                                         RTAPRINT07invoke_spec_virt2
1595                                                         RTAPRINT04invokestatic1
1596                                 invokestatic(mi);
1597                                 }
1598
1599                         else    {
1600                                 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1601                                 initMethods(mi);
1602                                 }
1603                         }                                                
1604                         break;
1605
1606
1607                 case JAVA_INVOKEVIRTUAL:
1608                         i = rt_code_get_u2(p + 1);
1609                         {
1610                         constant_FMIref *mr;
1611                         methodinfo *mi;
1612                                 
1613                         mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1614                         mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, class, true);
1615                         if (!mi)
1616                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1617
1618                         invokevirtual(mi);
1619                         }
1620                         break;
1621
1622                 case JAVA_INVOKEINTERFACE:
1623                         i = rt_code_get_u2(p + 1);
1624                         {
1625                         constant_FMIref *mr;
1626                         methodinfo *mi;
1627
1628                         mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1629                         mi = class_resolveinterfacemethod (mr->class, mr->name, mr->descriptor, class, true);
1630                         if (!mi)
1631                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1632                         invokeinterface(mi);
1633                         }
1634                         break;
1635
1636                         /* miscellaneous object operations *******/
1637
1638                 case JAVA_NEW:
1639                         i = rt_code_get_u2 (p+1);
1640                         {
1641                                 classinfo *ci;
1642
1643                                 ci = class_getconstant (rt_class, i, CONSTANT_Class); 
1644                                 newClasses(ci);
1645                         }
1646                         break;
1647
1648                 default:
1649                         break;
1650
1651                 } /* end switch */
1652
1653
1654         } /* end for */
1655
1656         if (p != rt_jcodelength)
1657                 panic("Command-sequence crosses code-boundary");
1658
1659         if ((XTAOPTbypass) || (opt_xta))
1660                 xtaMethodCalls_and_sendReturnType();
1661
1662
1663 }
1664
1665 /*-------------------------------------------------------------------------------*/
1666 /* RTA add Native Methods/ Class functions  */
1667 /*-------------------------------------------------------------------------------*/
1668 void   findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1669
1670         classinfo  *class;
1671         methodinfo *meth;
1672
1673         class = class_get(c1);
1674         if (class == NULL)  {
1675                 utf_display(c1);
1676                 printf("  WARNING: CLASS used by NATIVE method is NULL so loaded\n");
1677                 loader_load_sysclass(NULL, c1); 
1678                 class = class_get(c1);
1679                 if (class == NULL)  {
1680                         panic("CLASS used by NATIVE method is NULL and loading didn't help\n");
1681                         return;    /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1682                         }
1683         }
1684
1685         if (class->classUsed == NOTUSED) {
1686 printf("NATIVE_MARKED CLASS USED "); utf_display(class->name); printf("\n");
1687                 class->classUsed = USED; /* MARK CLASS USED */
1688                 /* add marked methods to callgraph */ 
1689                 rtaAddMarkedMethods(class);
1690         }
1691
1692         meth = class_findmethod_w (class, m1, d1,"findMarkNativeUsedMeth");
1693         if (meth == NULL) {
1694                 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1695                 panic("WARNING from parseRT:  Method given is used by Native method call, but NOT FOUND\n");
1696         }
1697         else
1698                 rtaMarkSubs(class,meth);
1699 }
1700
1701 /*-------------------------------------------------------------------------------*/
1702
1703 void   findMarkNativeUsedClass (utf * c) {
1704         classinfo  *class;
1705
1706         class = class_get(c);
1707         if (class == NULL)  panic("parseRT: Class used by Native method called not loaded!!!");
1708         class->classUsed = USED;
1709
1710         /* add marked methods to callgraph */
1711         rtaAddMarkedMethods(class);
1712 }
1713
1714
1715 /*-------------------------------------------------------------------------------*/
1716
1717 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1718         int i,j,k;
1719         bool found = false;
1720
1721         nativecallcompdone = natcall2utf(nativecallcompdone); 
1722
1723         for (i=0; i<NATIVECALLSSIZE; i++) {
1724                 if (rt_class  == nativeCompCalls[i].classname) {
1725         
1726                         /* find native class.method invoked */
1727                         for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1728
1729                                 if ( (rt_method     == nativeCompCalls[i].methods[j].methodname)
1730                                          && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1731
1732                                         found=true;
1733 printf("#%i#\n",nativeCompCalls[i].callCnt[j]);
1734                                         /* mark methods and classes used by this native class.method */
1735                                         for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1736                                                 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1737                                                         /* mark method used */
1738                                                         findMarkNativeUsedMeth(
1739                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].classname,
1740                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1741                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].descriptor); 
1742
1743                                                         /*RTprint 
1744                                                           printf("\nmark method used: "); fflush(stdout);
1745                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1746                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1747                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1748                                                         */
1749                                                 }
1750                                                 else {
1751                                                         /* mark class used */
1752                                                         findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1753                                                 } /* if-else k  */ 
1754
1755                                         }  /* for k */ 
1756
1757                                 }  /* if j */
1758                         }  /* for j */
1759
1760                 }  /* if i */  
1761         }  /* for i */
1762
1763 }
1764
1765
1766
1767 /*-------------------------------------------------------------------------------*/
1768 /*-------------------------------------------------------------------------------*/
1769 /* still need to look at field sets in 2nd pass and clinit .....  */
1770 void XTA_jit_parse2(methodinfo *m)
1771 {
1772 int methRT; /* local */
1773         if (XTAdebug >= 1) 
1774                 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1775
1776         /* for each method in XTA worklist = callgraph (use RTA for now) */
1777         methRT=0;
1778         //while (methRT <= methRTlast) {
1779         while (methRT <= methXTAlast) {
1780                 rt_method      = XTAcallgraph[methRT];
1781                 rt_class       = rt_method->class;
1782                 rt_descriptor  = rt_method->descriptor;
1783                 rt_jcodelength = rt_method->jcodelength;
1784                 rt_jcode       = rt_method->jcode;
1785
1786                 if (! (  (rt_method->flags & ACC_NATIVE  )
1787                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1788                         if (XTAdebug >= 1) {
1789                                 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1790                                 utf_display(rt_class->name); printf("."); fflush(stdout);
1791                                 method_display(rt_method);
1792                         }
1793                         /*   if XTA type set changed since last parse */
1794                         if (rt_method->xta->chgdSinceLastParse) {
1795
1796                                 /*     get types from methods it is calledBy */
1797                                 xtaPassAllCalledByParams ();
1798
1799                                 /* Pass parameter types to methods it calls and  send the return type those called by  */
1800                                 xtaMethodCalls_and_sendReturnType();
1801                         }
1802                 }
1803                 methRT++;
1804         }
1805         if (XTAdebug >= 1) {
1806
1807                 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1808                 printXTACallgraph ();
1809         }
1810         
1811         RTAPRINT14CallgraphLast  /*was >=2 */
1812                 RTAPRINT15HeirarchyiLast /*was >= 2 */
1813                 }
1814
1815
1816 /*-------------------------------------------------------------------------------*/
1817 /*-------------------------------------------------------------------------------*/
1818 void mainRTAparseInit (methodinfo *m )
1819 {
1820         /*printf("MAIN_NOT_STARTED \n");*/ 
1821         if (class_java_lang_Object->sub != NULL) { 
1822                 RTAPRINT16stats1;
1823         }
1824
1825         if (firstCall) {
1826                 firstCall=false;
1827
1828                 /* Frequently used utf strings */
1829                 utf_OBJECT = utf_new_char("java/lang/Object");
1830                 utf_MAIN  = utf_new_char("main");
1831                 INIT      = utf_new_char("<init>");
1832                 CLINIT    = utf_new_char("<clinit>");
1833                 FINALIZE  = utf_new_char("finalize");
1834                 EMPTY_DESC= utf_new_char("()V");
1835
1836                 /* open file for list of methods parsed before main method or missed and parsed after main */
1837                 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1838                         printf("CACAO - rtMissed file: cant open file to write\n");
1839                 }
1840                 else {
1841                         fprintf(rtMissed,"To Help User create a dymLoad file \n");
1842                         fprintf(rtMissed,
1843                 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1844                         fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1845                         fflush(rtMissed);
1846                         fclose(rtMissed);
1847                 }
1848                 /* Allocate callgraph */
1849                 if (opt_rt) {
1850                         callgraph = MNEW (methodinfo*, MAXCALLGRAPH);   /****/
1851                         }
1852                 if ((XTAOPTbypass) || (opt_xta)) {
1853                         printf("XTAXTA  CALLGRAPHS allocated\n");
1854                         XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1855                         }
1856                 }
1857
1858         if (m->name == utf_MAIN) {
1859                 rtMissed = fopen("rtMissed","a");
1860                 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1861                 fclose(rtMissed);
1862                 AfterMain = true;
1863         }
1864         else {  
1865                 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1866                         printf("CACAO - rtMissed file: cant open file to write\n");
1867                 }
1868                 else {
1869                         fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1870                         utf_fprint(rtMissed,m->class->name);
1871                         fprintf(rtMissed," ");
1872                         fprintflags(rtMissed,m->flags);
1873                         fprintf(rtMissed," ");
1874                         utf_fprint(rtMissed,m->name);
1875                         fprintf(rtMissed," ");
1876                         utf_fprint(rtMissed,m->descriptor);
1877                         fprintf(rtMissed,"\n");
1878                         fflush(rtMissed);
1879                         fclose(rtMissed);
1880                 }
1881                 if (AfterMain) {
1882                         printf("#%i : ",methRT);
1883                         printf("Method missed by static analysis Main parse. See ./rtMissed file\n");
1884                         /***    panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1885                 }
1886         }
1887
1888         /* At moment start RTA before main when parsed                      */
1889         /* Will definitely use flag with to know if ok to apply in-lining.  */
1890 }
1891
1892
1893 /*-------------------------------------------------------------------------------*/
1894 /*-------------------------------------------------------------------------------*/
1895
1896 void RTparseCGWorklist (methodinfo *m) {  
1897 printf("IIIIIIIIIIIIIIIIIIIIn RTparseCGWorklist\n"); fflush(stdout);
1898         if (m->methodUsed == USED) return;
1899         if ((firstCall) || (parse1) || (m->name == utf_MAIN))
1900                 mainRTAparseInit (m);
1901         parse1= false;
1902         m->methodUsed = USED;
1903
1904         /* initialise parameter type descriptor */
1905         callgraph[++methRTlast] = m;          /*-- RTA --*/
1906                 RTAPRINT11addedtoCallgraph 
1907         /* <init> then like a new class so add marked methods to callgraph */
1908         if (m->name == INIT)  {  /* need for <init>s parsed efore Main */
1909                 classinfo *ci;
1910                 ci = m->class;
1911                 ci->classUsed = USED;
1912                         if (pWhenMarked >= 1) {
1913                                 printf("Class=");utf_display(ci->name);
1914                         }
1915                         /* add marked methods to callgraph */
1916                         RTAPRINT11addedtoCallgraph2
1917                 rtaAddMarkedMethods(ci);
1918                 } /* if */
1919
1920         /*---- RTA call graph worklist -----***/
1921         while (methRT <= methRTlast) {
1922                 rt_method      = callgraph[methRT];
1923                 rt_class       = rt_method->class;
1924                 rt_descriptor  = rt_method->descriptor;
1925                 rt_jcodelength = rt_method->jcodelength;
1926                 rt_jcode       = rt_method->jcode;
1927
1928                 if (! (  (rt_method->flags & ACC_NATIVE  )
1929                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1930                         parseRT();
1931                         }
1932                 //if (true == false) {   // At moment nativecalls.h is not current and neither helps nor hinders
1933                 else    {
1934                                 RTAPRINT12bAbstractNative
1935                         if (rt_method->flags & ACC_NATIVE ) {
1936                                         RTAPRINT12aNative
1937                                                 /* mark used and add to callgraph methods and classes used by NATIVE method */
1938                                                 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);                
1939                                 }
1940                         if (rt_method->flags & ACC_ABSTRACT) {
1941                                 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n"); 
1942                                 }
1943                         }
1944                 methRT++;
1945                                 RTAPRINT12Callgraph 
1946                                 RTAPRINT13Heirarchy 
1947                 } /* while */
1948
1949         if (m->class->classUsed == NOTUSED)
1950                 m->class->classUsed = USED; /* say Main's class has a method used ??*/ 
1951 }
1952
1953
1954 /*-------------------------------------------------------------------------------*/
1955 /*--------------------------------------------------------*/
1956 int getdymline(char *line, int max, FILE *inFP) {
1957 if (fgets(line, max, inFP) == NULL)
1958   return 0;
1959 else {
1960   return strlen((const char *)line);
1961   }
1962 }
1963
1964 /*-------------------------------------------------------------------------------*/
1965
1966 methodinfo *getApplicationDynamics ( ) {
1967 char line[512]="";
1968 char *classname;
1969 char *methname ;
1970 char *desc;
1971 int rc;
1972
1973 classinfo  *class;
1974 methodinfo *mi;
1975
1976 if ( (appldynm = fopen("appldynm", "r")) == NULL) {
1977         printf("parseRT - appldynm file: no appldynm file - ok if nothing in rtMissed after Main\n");
1978         return NULL;
1979 }
1980
1981 if ( getdymline(line,512,appldynm) != 0)
1982         {
1983         printf("line=%s\n",line); fflush(stdout);
1984
1985         classname = strtok(line," \n");
1986         methname  = strtok(NULL," \n");
1987         if (methname == NULL) {  /* if no meth */
1988                 panic("parseRT - dynamic loaded class/method/desc in appldynm has no method");
1989                 }
1990         desc = strtok(NULL," \n");
1991         if (desc == NULL) {  /* if no desc */
1992                 panic("parseRT - dynamic loaded class/method/desc in appldynm has no descriptor");
1993                 }
1994         printf("appldynm class=%s meth=%s desc=%s\n",classname, methname,desc); fflush(stdout);
1995
1996         class = class_get(utf_new_char(classname));
1997         if (class == NULL) {
1998                 class = loader_load_sysclass(NULL,  utf_new_char(classname));   
1999                 }
2000         mi = class_fetchmethod(class,utf_new_char(methname), utf_new_char(desc)) ;
2001         printf("+++++--3--+++++\t");
2002         RTparseCGWorklist (mi) ;  
2003
2004         }
2005
2006 fclose(appldynm);
2007 return NULL;
2008 }
2009
2010 /*-------------------------------------------------------------------------------*/
2011
2012 void RT_jit_parse(methodinfo *m)
2013 {
2014 classinfo  *class;
2015 methodinfo * mi;
2016 classinfo *topclass;
2017
2018 /*-- RTA -- *******************************************************/
2019     if (opt_rt) 
2020        {
2021         /*---- java/lang/Object.<clinit> ----*/
2022  if ((firstCall == false) || (true == false))  
2023         {
2024         parse1 = true;
2025         if (m->methodUsed == USED) return;
2026         printf("MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2027         RTparseCGWorklist (m) ;  
2028                                         /*RTAprint*/ if (pCallgraph >= 1) {
2029                                         /*RTAprint*/    printCallgraph ();}
2030                                         /*RTprint*/ //if (pClassHeir >= 1) {
2031                                         /*RTprint*/ //    printRThierarchyInfo(m);
2032                                         /*RTprint*/ //    }
2033                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2034                                                 fflush(stdout);
2035         printf("END MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2036         return;
2037         }
2038  else
2039         {
2040         parse1 = true;
2041         printf("SSSSSSSSSSSSSSSSSSSSSStatic Analysis \n"); fflush(stdout);
2042         printf("+++++--1--+++++\t");
2043         RTparseCGWorklist (m) ;  
2044
2045         class = class_get(utf_new_char("java/lang/Thread"));
2046         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2047         printf("+++++--2--+++++\t");
2048         RTparseCGWorklist (mi) ;  
2049
2050         class = class_get(utf_new_char("java/lang/ThreadGroup"));
2051         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2052         printf("+++++--3--+++++\t");
2053         RTparseCGWorklist (mi) ;  
2054
2055
2056         class = class_get(utf_new_char("java/lang/Throwable"));
2057         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2058         printf("+++++--4--+++++\t");
2059         RTparseCGWorklist (mi) ;  
2060
2061         printf("mainString=%s=\n",mainString);fflush(stdout);
2062         class = loader_load_sysclass(NULL,  utf_new_char(mainString));  
2063         mi = class_fetchmethod( class,
2064                                 utf_new_char("main"),
2065                                 utf_new_char("([Ljava/lang/String;)V")
2066                                );
2067         printf("+++++--5--+++++\t");
2068         RTparseCGWorklist (mi) ;  
2069
2070         printf("+++++--6--+++++\t");
2071         getApplicationDynamics();
2072
2073 printf("-+-+-+-+-+-+-+-+-+-+-33"); fflush(stdout);
2074
2075                                         /*RTAprint*/ if (pCallgraph >= 1) {
2076                                         /*RTAprint*/    printCallgraph ();}
2077                                         /*RTprint*/ //if (pClassHeir >= 1) {
2078                                         /*RTprint*/ //    printRThierarchyInfo(m);
2079                                         /*RTprint*/ //    }
2080                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2081                                                 fflush(stdout);
2082 printf("-+-+-+-+-+-+-+-+-+-+-44"); fflush(stdout);
2083         /** MFREE(callgraph,methodinfo*,MAXCALLGRAPH);  causes stack overflow **/
2084         }
2085      } /*  end opt_rt */
2086
2087 /*-- XTA -- *******************************************************/
2088         if ((XTAOPTbypass) || (opt_xta)) {
2089                 if (m->xta != NULL) {
2090                         if (m->xta->XTAmethodUsed == USED) return;
2091                         }
2092                 mainRTAparseInit (m);
2093
2094                 XTAcallgraph[++methXTAlast] = m;
2095                 if (m->xta == NULL) {
2096                         m->xta = xtainfoInit(m);
2097                         }
2098                 m->xta->XTAmethodUsed = USED;
2099                         {methodinfo *mi = m;
2100                         printf("<");fflush(stdout);
2101                         XTAPRINTcallgraph2
2102                         }
2103                 }
2104
2105         /*-- Call graph work list loop -----------------*/
2106         /*---- XTA call graph worklist -----***/
2107                                                         useXTAcallgraph = true;
2108         if ((useXTAcallgraph) && (opt_xta)) {
2109                                                         printf("USING XTA call graph>>>>>>>>>><<\n");
2110
2111           while (methXTA <= methXTAlast) {
2112                 rt_method      = XTAcallgraph[methXTA];
2113                                                         printf("xTA CALLGRAPH #%i:",methXTA); fflush(stdout);
2114                                                         method_display(rt_method);
2115                 rt_class       = rt_method->class;
2116                 rt_descriptor  = rt_method->descriptor;
2117                 rt_jcodelength = rt_method->jcodelength;
2118                 rt_jcode       = rt_method->jcode;
2119
2120                 if (! (  (rt_method->flags & ACC_NATIVE  )
2121                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
2122                         parseRT();
2123                         }
2124                 else    {
2125                                 RTAPRINT12bAbstractNative
2126                         if (rt_method->flags & ACC_NATIVE ) {
2127                                         RTAPRINT12aNative
2128                                 /* mark used and add to callgraph methods and classes used by NATIVE method */
2129                                 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
2130                                 }
2131                         if (rt_method->flags & ACC_ABSTRACT) {
2132                                 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
2133                                 }
2134                         }
2135                 methXTA++;
2136                                 RTAPRINT12Callgraph
2137                                 RTAPRINT13Heirarchy
2138                 } /* while */
2139         if (m->class->classUsed == NOTUSED)
2140                 m->class->classUsed = USED; /* say Main's class has a method used ??*/ 
2141         printXTACallgraph ();
2142
2143         if (m->name == utf_MAIN) { /*-- MAIN specific -- */
2144                                         /*RTAprint*/ if (pCallgraph >= 1) {
2145                                         /*RTAprint*/    printXTACallgraph (); }
2146                                         /*RTprint*/ if (pClassHeir >= 1) {
2147                                         /*RTprint*/     printf("Last RTA Info -+-+-");
2148                                         /*RTprint*/     printRThierarchyInfo(m);
2149                                         /*RTprint*/     }
2150                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2151                                                 fflush(stdout);
2152                 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
2153                 XTA_jit_parse2(m);
2154                 printf("XTAXTA  CALLGRAPHS -SHOULD BE BUT ISNT- returned \n");
2155                 //MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
2156                 }
2157         } /*  end opt_xta */
2158
2159         RTAPRINT14CallgraphLast  /*  was >=2*/
2160                 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
2161
2162         return;
2163 }
2164
2165
2166 /*
2167  * These are local overrides for various environment variables in Emacs.
2168  * Please do not remove this and leave it at the end of the file, where
2169  * Emacs will automagically detect them.
2170  * ---------------------------------------------------------------------
2171  * Local variables:
2172  * mode: c
2173  * indent-tabs-mode: t
2174  * c-basic-offset: 4
2175  * tab-width: 4
2176  * End:
2177  */
2178