Removed jit.c global variables. Most of them were already in methodinfo,
[cacao.git] / src / vm / jit / inline / 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 1203 2004-06-22 23:14:55Z twisti $
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         /* XXX TWISTI */
713 /*      if (class->name == utf_initializeSystemClass) { */
714         if (mi->class->name == utf_initializeSystemClass) {
715                 /* Get clinit methodinfo ptr */
716                 if ((mi = class_findmethod (ci,utf_initializeSystemClass, EMPTY_DESC)) != NULL) {
717                         /*--- RTA ---*/
718                         if ( mi->methodUsed != USED) {
719                                 mi->class->classUsed = PARTUSED;
720                                 ADDTOCALLGRAPH(mi)  
721                                 }
722
723                         /*--- XTA ---*/
724                         if ((XTAOPTbypass) || (opt_xta)) {
725                                 xtaAddCallEdges(mi,MONO);
726                                 }
727                         }
728                 }
729         if (addmark) {
730                 /* add marked methods to callgraph */ 
731                 if ((XTAOPTbypass) || (opt_xta))
732                         xtaAddMarkedMethods(ci);
733                 else
734                         rtaAddMarkedMethods(ci);
735                 }
736                 
737         return m;
738
739
740
741 #define rt_code_get_u1(p)  rt_jcode[p]
742 #define rt_code_get_s1(p)  ((s1)rt_jcode[p])
743 #define rt_code_get_u2(p)  ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
744 #define rt_code_get_s2(p)  ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
745 #define rt_code_get_u4(p)  ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
746                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
747 #define rt_code_get_s4(p)  ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
748                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
749
750
751
752 /*-------------------------------------------------------------------------------*/
753 void rtaAddUsedInterfaceMethods(classinfo *ci) {
754         int jj,mm;
755
756         /* add used interfaces methods to callgraph */
757         for (jj=0; jj < ci -> interfacescount; jj++) {
758                 classinfo *ici = ci -> interfaces [jj];
759         
760                 if (pWhenMarked >= 1) { 
761                         printf("BInterface used: ");fflush(stdout); 
762                         utf_display(ici->name);
763                         printf("<%i>\t",ici -> classUsed ); fflush(stdout); 
764                         if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
765                         if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
766                         if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
767                         fflush(stdout);
768                 }
769                 /* add class to interfaces list of classes that implement it */
770                 ici -> impldBy =  addElement(ici -> impldBy,  ci);
771
772                 /* if interface class is used */
773         if (ici -> classUsed != NOTUSED) {
774
775                         /* for each interface method implementation that has already been used */
776                         for (mm=0; mm< ici->methodscount; mm++) {
777                                 methodinfo *imi = &(ici->methods[mm]);
778                                 if (pWhenMarked >= 1) { 
779                                         if  (imi->methodUsed != USED) {
780                                                 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: "); 
781                                                 if (imi->methodUsed == MARKED) printf("Interface Method marked: "); 
782                                                 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
783                                         }
784                                 } 
785                                 if  (imi->methodUsed == USED) {
786                                         if (pWhenMarked >= 1) { 
787                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
788
789                                                 /* Mark this method used in the (used) implementing class and its subclasses */
790                                                 printf("rMAY ADD methods that was used by an interface\n");
791                                         }
792                                         rtaMarkSubs(ci,imi);
793                                 }
794                         }
795                 }
796         }
797
798 }
799 /*-------------------------------------------------------------------------------*/
800 void rtaMarkInterfaceSubs(methodinfo *mi) {                             
801         classSetNode *subs;
802         if (mi->class->classUsed == NOTUSED) {
803                 mi->class->classUsed = USED; 
804                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
805                 }
806
807         /* add interface class to list kept in Object */
808         mi->methodUsed = USED;
809         mi->monoPoly   = POLY;
810
811         subs =  mi->class->impldBy; 
812                                                 RTAPRINT08invokeInterface1
813         while (subs != NULL) {                  
814                 classinfo * isubs = subs->classType;
815                                                         RTAPRINT09invokeInterface2
816                 /* Mark method (mark/used) in classes that implement the method */
817                 if (isubs->classUsed != NOTUSED) {
818                         methodinfo *submeth;
819                                                 
820                         submeth = class_findmethod(isubs,mi->name, mi->descriptor); 
821                         if (submeth != NULL)
822                                 submeth->monoPoly = POLY; /*  poly even if nosubs */
823                         rtaMarkSubs(isubs, mi);  
824                         }
825                                 
826                 subs = subs->nextClass;
827                 } /* end while */
828
829
830 /*-------------------------------------------------------------------------------*/
831 /*-------------------------------------------------------------------------------*/
832
833
834
835 /*-------------------------------------------------------------------------------*/
836 void xtaAddUsedInterfaceMethods(classinfo *ci) {
837         int jj,mm;
838
839 /* add used interfaces methods to callgraph */
840 for (jj=0; jj < ci -> interfacescount; jj++) {
841         classinfo *ici = ci -> interfaces [jj];
842         
843         if (pWhenMarked >= 1) { 
844                         printf("XInterface used: ");fflush(stdout); 
845                         utf_display(ici->name);
846                         printf("<%i>\t",ici -> classUsed ); fflush(stdout); 
847                         if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
848                         if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
849                         if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
850                         fflush(stdout);
851                         }
852         /* add class to interfaces list of classes that implement it */
853         ici -> impldBy =  addElement(ici -> impldBy,  ci);
854
855         /* if interface class is used */
856         if (ici -> classUsed != NOTUSED) {
857
858                 /* for each interface method implementation that has already been used */
859                 for (mm=0; mm< ici->methodscount; mm++) {
860                         methodinfo *imi = &(ici->methods[mm]);  /*interface method */
861 printf("==%i==%i\n",ici->methodscount,mm);
862                         if (imi->xta == NULL)
863                                 xtainfoInit (imi); 
864                                         /*RTAprint*/if (pWhenMarked >= 1) { 
865                                         /*RTAprint*/  if  (imi->xta->XTAmethodUsed != USED) {
866                                         /*RTAprint*/    if (imi->xta->XTAmethodUsed==NOTUSED) 
867                                                                 printf("Interface Method notused: "); 
868                                         /*RTAprint*/    if (imi->xta->XTAmethodUsed==MARKED) 
869                                                                 printf("Interface Method marked: "); 
870                                         /*RTAprint*/    utf_display(ici->name);printf(".");
871                                         /*RTAprint*/    method_display(imi);fflush(stdout);
872                                         /*RTAprint*/    }
873                                         /*RTAprint*/  } 
874                         if  (imi->xta->XTAmethodUsed == USED) {
875                                 methSetNode *mCalledBy = NULL;
876                                         if (pWhenMarked >= 1) { 
877                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");
878                                                 method_display(imi);fflush(stdout);
879
880                                                 /* Mark this method used in the (used) implementing class &its subclasses */
881                                                 printf("xMAY ADD methods that was used by an interface\n"); fflush(stdout);
882                                                 }
883                                         if (pWhenMarked >= 1) {
884                                                 printf("calledBy set ="); fflush(stdout);
885                                                 printMethodSet(imi->xta->calledBy);
886                                                 }
887                                 if (imi->xta->calledBy != NULL) { 
888                                         /* for each calledBy method */
889                                         for (   mCalledBy = imi->xta->calledBy->head; 
890                                                 mCalledBy != NULL; 
891                                                 mCalledBy = mCalledBy->nextmethRef) {
892                                                 if (pWhenMarked >= 1) {
893                                                                 printf("xtaMarkSubs(");
894                                                                 utf_display(ci->name); printf("."); fflush(stdout);
895                                                                 method_display(imi);
896                                                                 printf("mCalledBy method class set BEFORE\n"); fflush(stdout);
897                                                                 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
898                                                 }
899                                                 xtaMarkSubs(ci,imi,mCalledBy->methRef->xta->XTAclassSet->head);
900                                                         if (pWhenMarked >= 1) {
901                                                                 printf("mCalledBy method class set AFTER \n"); fflush(stdout);
902                                                                 printSet(mCalledBy->methRef->xta->XTAclassSet->head);
903                                                         }
904                                                 }
905                                         }
906                                 }
907                         } 
908                 }
909         } /* end for */
910 }
911
912 /*-------------------------------------------------------------------------------*/
913
914 /*-------------------------------------------------------------------------------*/
915 void xtaMarkInterfaceSubs(methodinfo *mi) {
916         classSetNode *subs;
917         classSetNode * Si;
918
919         if (mi->xta == NULL)
920                 xtainfoInit (mi); 
921                                         
922         if (mi->class->classUsed != USED) {
923                 mi->class->classUsed = USED; 
924                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
925                 }
926
927         /* add interface class to list kept in Object */
928                                 if (pWhenMarked >= 1) {
929                                         printf("Marking Interface Method: "); fflush(stdout);
930                                         }
931         xtaAddCallEdges(mi,POLY);       
932
933         subs =  mi->class->impldBy; 
934                                                 RTAPRINT08invokeInterface1
935         while (subs != NULL) { 
936                 classinfo * isubs = subs->classType;
937                                                         RTAPRINT09invokeInterface2
938                 /* Mark method (mark/used) in classes that implement the method */
939                 if (isubs->classUsed != NOTUSED) {
940                         methodinfo *submeth;
941                                                 
942                         submeth = class_resolvemethod(isubs,mi->name, mi->descriptor); 
943                         if (submeth != NULL)    ///+1
944                                 {
945                                 classSetNode *subtypesUsedSet = NULL;
946                                 submeth->monoPoly = POLY; /*  poly even if nosubs */
947                                                         
948                                 mi->xta->XTAmethodUsed = USED;
949                                 if (rt_method->xta->XTAclassSet != NULL)
950                                         subtypesUsedSet =
951                                                 intersectSubtypesWithSet
952                                                         (subs->classType, rt_method->xta->XTAclassSet->head);
953
954                                                         if (pWhenMarked >= 1) {
955                                                                 /*RTAprint*/ printf(" \nXTA subtypesUsedSet: ");
956                                                                 /*RTAprint*/ fflush(stdout);
957                                                                 /*RTAprint*/ printSet(subtypesUsedSet);
958                                                         }
959                                 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
960                                 }
961                         }
962                 subs = subs->nextClass;
963                 }
964 }
965 /*-------------------------------------------------------------------------------*/
966
967 /*-------------------------------------------------------------------------------*/
968 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
969
970         bool rc = false;
971
972         if (fi->xta->fieldChecked) {
973                 if (fi->xta->fldClassType != NULL)
974                         return true;  /* field has a class type */
975                 else
976                         return false;
977         }
978         fi->xta->fieldChecked = true;
979
980         if (fi->type == TYPE_ADDRESS) {
981                 char *utf_ptr = fi->descriptor->text;  /* current position in utf text */
982
983                 if (*utf_ptr != 'L') {
984                         while (*utf_ptr++ =='[') ;
985                 }
986
987                 if (*utf_ptr =='L') {
988                         rc = true;
989                         if  (fi->xta->fldClassType== NULL) {
990                                 char *desc;
991                                 char *cname;
992                                 classinfo * class;
993
994                                 desc = MNEW(char, 256);
995                                 strcpy(desc,++utf_ptr);
996                                 cname = strtok(desc,";");
997                                 if (XTAdebug >= 1) {
998                                         printf("STATIC fields type is: %s\n",cname);
999                                         fflush(stdout);
1000                                 }
1001                                 class = class_get(utf_new_char(cname));
1002                                 fi->xta->fldClassType= class;    /* save field's type class ptr */      
1003                         } 
1004                 }
1005         }
1006         return rc;
1007 }
1008
1009 /*-------------------------------------------------------------------------------*/
1010 void xtaPassFldPUT(fldSetNode *fN)
1011 {
1012         /* Field type is a class */
1013         classSetNode *c;
1014         classSetNode *c1 = NULL;
1015         classSetNode *cp = NULL;
1016         classSetNode *cprev= NULL;
1017
1018         fieldinfo *fi;
1019         if (fN != NULL)
1020                 fi = fN->fldRef;
1021         else
1022                 return;
1023
1024 /* Use lastptr  so don't check whole XTA class set each time */
1025         cp = fN->lastptrPUT;
1026         if (cp != NULL) {
1027                 if (cp->nextClass != NULL)
1028                         c1 = cp -> nextClass;
1029         } 
1030         else    {
1031                 if (rt_method->xta->XTAclassSet != NULL)
1032                         c1  = rt_method->xta->XTAclassSet->head;
1033
1034                 if (XTAfld >=1 ) {
1035                         printf("rt XTA class set =");fflush(stdout);
1036                         printClassSet(rt_method->xta->XTAclassSet);
1037                         printf("\t\tField class type = ");fflush(stdout);
1038                         utf_display(fi->xta->fldClassType->name); printf("\n");
1039                 }
1040         }
1041
1042         /*--- PUTSTATIC specific ---*/
1043         /* Sx = intersection of type+subtypes(field x)   */
1044         /*   and Sm (where putstatic code is)            */
1045         for (c=c1; c != NULL; c=c->nextClass) {
1046                 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
1047                 vftbl *c_cl_vt =  c->   classType->vftbl;
1048                 if (XTAfld >=2 ) {
1049                         printf("\tXTA class = ");fflush(stdout);
1050                         utf_display(c->classType->name);
1051                         printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
1052                         if (c->nextClass == NULL) {
1053                                 printf("next=NULL ");fflush(stdout);
1054                         }
1055                         else    {
1056                                 printf("next="); fflush(stdout);
1057                                 utf_display(c->nextClass->classType->name);
1058                                 printf("\n"); fflush(stdout);
1059                         }
1060
1061                         printf("\t\tField class type = ");fflush(stdout);
1062                         utf_display(fi->xta->fldClassType->name);
1063                         printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
1064                 }
1065
1066                 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
1067                         && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
1068                         fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
1069                 }
1070                 cprev = c;
1071         }
1072         fN->lastptrPUT = cprev;
1073 }
1074 /*-------------------------------------------------------------------------------*/
1075 void xtaPassFldGET(fldSetNode *fN)
1076 {
1077         /* Field type is a class */
1078         classSetNode *c;
1079         classSetNode *c1 = NULL;
1080         classSetNode *cp = NULL;
1081         classSetNode *cprev= NULL;
1082
1083         fieldinfo *fi;
1084         if (fN != NULL)
1085                 fi = fN->fldRef;
1086         else
1087                 return;
1088
1089 /* Use lastptr  so don't check whole XTA class set each time */
1090         cp = fN->lastptrGET;
1091         if (cp != NULL) {
1092                 if (cp->nextClass != NULL)
1093                         c1 = cp -> nextClass;
1094         } 
1095         else    {
1096                 if (fi->xta->XTAclassSet != NULL)
1097                         c1  = fi->xta->XTAclassSet->head;
1098
1099                 if (XTAfld >=1 ) {
1100                         printf("fld XTA class set =");fflush(stdout);
1101                         printClassSet(fi->xta->XTAclassSet);
1102                         printf("\t\tField class type = ");fflush(stdout);
1103                         utf_display(fi->xta->fldClassType->name); printf("\n");
1104                 }
1105         }
1106
1107         /*--- GETSTATIC specific ---*/
1108         /* Sm = union of Sm and Sx */
1109         for (c=c1; c != NULL; c=c->nextClass) {
1110                 bool addFlg = false;
1111                 if (rt_method->xta->XTAclassSet ==NULL) 
1112                         addFlg = true;
1113                 else    {
1114                         if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) )) 
1115                                 addFlg = true;
1116                         }
1117                 if (addFlg) {
1118                         rt_method->xta->XTAclassSet 
1119                                 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
1120                 }
1121                 cprev = c;
1122         }
1123
1124         fN->lastptrGET = cprev;
1125
1126 }
1127
1128 /*-------------------------------------------------------------------------------*/
1129 void xtaPassAllCalledByParams () {
1130         methSetNode *SmCalled;
1131         methSetNode *s1;
1132         if (XTAdebug >= 1) {
1133                 printf("xta->calledBy method set: "); fflush(stdout);
1134                 
1135                 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
1136                 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
1137                 }
1138         if (rt_method->xta->calledBy == NULL)
1139                 s1 = NULL;
1140         else
1141                 s1 = rt_method->xta->calledBy->head;
1142         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1143                 if (XTAdebug >= 1) {
1144                         printf("SmCalled = "); fflush(stdout);
1145                         utf_display(SmCalled->methRef->class->name); fflush(stdout);
1146                         printf(".");fflush(stdout); method_display(SmCalled->methRef);
1147                 }
1148                                 
1149                 rt_method->xta->chgdSinceLastParse = false;             
1150                 xtaPassParams(rt_method, SmCalled->methRef,SmCalled);   /* chg flag output ignored for 1st regular parse */
1151         }
1152 }
1153
1154 /*-------------------------------------------------------------------------------*/
1155 void xtaAllFldsUsed ( ){
1156         fldSetNode  *f;
1157         fldSetNode *f1=NULL; 
1158         /*      bool chgd = false */
1159
1160         if (rt_method->xta->fldsUsed == NULL) return;
1161
1162         /* for each field that this method uses */
1163         f1 = rt_method->xta->fldsUsed->head;
1164
1165         for (f=f1; f != NULL; f = f->nextfldRef) {
1166
1167                 if (f->writePUT)
1168                         xtaPassFldPUT(f);
1169                 if (f->readGET)
1170                         xtaPassFldGET(f);
1171         }
1172 }
1173 /*-------------------------------------------------------------------------------*/
1174 void  xtaMethodCalls_and_sendReturnType() 
1175 {
1176         methSetNode *SmCalled;  /* for return type       */
1177         methSetNode *SmCalls;   /* for calls param types */
1178         methSetNode *s1=NULL; 
1179         bool chgd = false;
1180         if (XTAdebug >= 1) {
1181                 printf("calls method set Return type: ");
1182                 printMethodSet(rt_method->xta->calls);
1183         }
1184         xtaAllFldsUsed ( );
1185
1186         /* for each method that this method calls */
1187         if (rt_method->xta->calls == NULL)
1188                 s1 = NULL;
1189         else
1190                 s1 = SmCalls=rt_method->xta->calls->head;
1191
1192         for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
1193                 /*    pass param types  */
1194                 bool chgd = false;
1195                 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);  
1196                 /* if true chgd after its own parse */
1197                 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
1198                         SmCalls->methRef->xta->chgdSinceLastParse = true;
1199                 }
1200         }
1201
1202         /* for each calledBy method */
1203         /*    send return type */
1204         if (rt_method->xta->calledBy == NULL)
1205                 s1 = NULL;
1206         else
1207                 s1 = rt_method->xta->calledBy->head;
1208         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
1209
1210                 if (XTAdebug >= 1) {
1211                         printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
1212                         printf("."); method_display(SmCalled->methRef);
1213                 }
1214                                 
1215                 chgd = xtaPassReturnType(rt_method, SmCalled->methRef); 
1216                 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1217                         SmCalled->methRef->xta->chgdSinceLastParse = chgd;              
1218                 }
1219         }
1220 }
1221
1222 /*-------------------------------------------------------------------------------*/
1223 /* -- Processes STATIC  & PRIVATE methods
1224
1225  * -- called for INVOKESTATIC, INVOKESPECIAL - PRIVATE and
1226  *    STATIC / PRIVATE methods used by NATIVE methods
1227  *-------------------------------------------------------------------------------*/
1228
1229 // Dez Version but gives too many Missed
1230 void invokestatic2( methodinfo *mi) {
1231
1232 mi->class->classUsed = PARTUSED;
1233 /*-- RTA --*/
1234 addClassInit(mi->class, true, true, true);
1235                 RTAPRINT04invokestatic1
1236
1237 if (opt_rt) {
1238         ADDTOCALLGRAPH(mi)
1239         } /* end RTA */
1240
1241 /*-- XTA --*/
1242 if ((XTAOPTbypass) || (opt_xta)) {
1243         mi->class->classUsed = PARTUSED;
1244         rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,mi->class);
1245         xtaAddCallEdges(mi,MONO);
1246         } /* end XTA */
1247 }
1248
1249
1250
1251 //// from just RTA version before Dez changes
1252 void invokestatic(methodinfo *mi){
1253                 RTAPRINT04invokestatic1
1254 if (mi->class->classUsed == NOTUSED) {
1255         mi->class->classUsed = USED;
1256                         RTAPRINT05invokestatic2
1257         }
1258         addClassInit(mi->class,true, true, true);
1259
1260         if (opt_rt) {
1261                 ADDTOCALLGRAPH(mi)  
1262                 } /* end RTA */
1263         /*-- XTA --*/
1264         if ((XTAOPTbypass) || (opt_xta)) {
1265                 xtaAddCallEdges(mi,MONO); 
1266         } /* end XTA */
1267 }
1268
1269
1270 /*-------------------------------------------------------------------------------*/
1271 /* -- Processes <INIT> methods
1272
1273  * -- called for INVOKESPECIAL - <init> and
1274  *    <init> methods used by NATIVE methods
1275  *-------------------------------------------------------------------------------*/
1276
1277 void initMethods(methodinfo *mi) {
1278
1279 classinfo  *ci = mi->class;
1280
1281 /* new class so add marked methods */
1282 if (opt_rt) {
1283         if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED))  {
1284                 /*--- process NORMAL <init> method ---------------------------------------------*/
1285                 if ( mi->methodUsed != USED) {
1286                         /* Normal <init> 
1287                         - mark class as USED and <init> to callgraph */
1288
1289                         /*-- RTA --*/
1290 //      addClassInit(mi->class,true, true, false);
1291                         ci->classUsed = USED;
1292                         rtaAddMarkedMethods(ci);  /* add to callgraph marked methods */
1293                                         RTAPRINT06Binvoke_spec_init
1294                         rtaAddUsedInterfaceMethods(ci); 
1295                         ADDTOCALLGRAPH(mi)  
1296                         }
1297                 }       
1298         }
1299
1300 /*-- XTA --*/
1301 if ((XTAOPTbypass) || (opt_xta)) { 
1302         if (mi->xta == NULL) {
1303                 mi->xta = xtainfoInit(mi);
1304                 }
1305         if ((mi->xta->XTAmethodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
1306                 ci->classUsed = USED;
1307                 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); 
1308                 xtaAddMarkedMethods(ci);  /* add to callgraph marked methods */
1309                 xtaAddUsedInterfaceMethods(ci); 
1310                 xtaAddCallEdges(mi,MONO);
1311                         RTAPRINT06CXTAinvoke_spec_init1
1312                 } /* end XTA */
1313         }
1314 }
1315
1316 /*-------------------------------------------------------------------------------*/
1317 /* -- Processes VIRTUAL methods
1318
1319  * -- called for INVOKEVIRTUAL and 
1320  *    virtual methods used by NATIVE methods 
1321  *-------------------------------------------------------------------------------*/
1322
1323 void invokevirtual(methodinfo *mi) {
1324
1325 /*--- RTA ---*/
1326                         RTAPRINT07invoke_spec_virt2
1327 mi->class->classUsed = USED;  // Should this be later?
1328
1329 if ((mi->flags & ACC_STATIC)  || (mi->flags & ACC_PRIVATE)  || (mi->flags & ACC_FINAL) ) {
1330         invokestatic(mi);
1331         return;
1332         }
1333
1334
1335 mi->monoPoly = POLY;
1336
1337 if (opt_rt) { 
1338         rtaMarkSubs(mi->class,mi); 
1339         }
1340
1341 /*--- XTA ---*/
1342 if ((XTAOPTbypass) || (opt_xta)) { 
1343         classSetNode *subtypesUsedSet = NULL;
1344         if (rt_method->xta->XTAclassSet != NULL)
1345         subtypesUsedSet = 
1346                 intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1347         else
1348                 subtypesUsedSet = addElement(subtypesUsedSet, rt_method->class);
1349         /*****/ 
1350         printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1351         printSet(subtypesUsedSet);
1352         /*****/
1353         xtaMarkSubs(mi->class, mi, subtypesUsedSet);   
1354         } /* end XTA */
1355 }
1356
1357
1358 /*-------------------------------------------------------------------------------*/
1359 void invokeinterface( methodinfo *mi ) {        
1360                                                 /*RTAprint*/ if (pWhenMarked >= 1) {
1361                                                 /*RTAprint*/ printf("\t");fflush(stdout);
1362                                                 /*RTAprint*/ utf_display(mi->class->name); printf(".");fflush(stdout);
1363                                                 /*RTAprint*/ method_display(mi); fflush(stdout); 
1364                                                 /*RTAprint*/ }
1365
1366 if (mi->flags & ACC_STATIC)
1367         panic ("Static/Nonstatic mismatch calling static method");
1368                                                 RTAPRINT08AinvokeInterface0
1369 /*--- RTA ---*/
1370 if (opt_rt) {
1371         rtaMarkInterfaceSubs(mi);
1372         }
1373 /*--- XTA ---*/
1374 if ((XTAOPTbypass2) || (opt_xta)) {
1375         xtaMarkInterfaceSubs(mi);
1376         }
1377 }
1378
1379 /*-------------------------------------------------------------------------------*/
1380 void newClasses(classinfo *ci) {
1381                                         if (pWhenMarked >= 1) {
1382                                                 printf("\tclass=");fflush(stdout);
1383                                                 utf_display(ci->name); fflush(stdout);
1384                                                 printf("=\n");fflush(stdout);
1385                                                 }
1386 /*--- RTA ---*/
1387 if (ci->classUsed != USED) {
1388                                         RTAPRINT10new
1389         ci->classUsed = USED;    /* add to heirarchy    */
1390         /* Add this class to the implemented by list of the abstract interface */
1391         rtaAddUsedInterfaceMethods(ci);
1392         addClassInit(ci, true, true, false);
1393         } 
1394 /*--- XTA ---*/
1395 if ((XTAOPTbypass) || (opt_xta))
1396         {
1397         xtaAddUsedInterfaceMethods(ci);
1398         rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1399                                                 RTAPRINT10newXTA
1400         }
1401 }
1402
1403 /*-------------------------------------------------------------------------------*/
1404 static void parseRT(methodinfo *m)
1405 {
1406         int  p;                     /* java instruction counter                   */
1407         int  nextp;                 /* start of next java instruction             */
1408         int  opcode;                /* java opcode                                */
1409         int  i;                     /* temporary for different uses (counters)    */
1410         bool iswide = false;        /* true if last instruction was a wide        */
1411
1412         RTAPRINT01method
1413
1414                 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1415                                         printf("XTA parseRT():"); fflush(stdout);
1416                                         method_display(rt_method);
1417                         if (rt_method->xta == NULL)
1418                                 xtainfoInit (rt_method);
1419                         xtaPassAllCalledByParams ();
1420                                         printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1421    
1422                 }
1423
1424         /* scan all java instructions */
1425
1426         for (p = 0; p < rt_jcodelength; p = nextp) {
1427                 opcode = rt_code_get_u1 (p);           /* fetch op code                  */
1428                 RTAPRINT02opcode
1429                         fflush(stdout); 
1430                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
1431                 switch (opcode) {
1432
1433                         /*--------------------------------*/
1434                         /* Code just to get the correct  next instruction */
1435                         /* 21- 25 */
1436                 case JAVA_ILOAD:
1437                 case JAVA_LLOAD:
1438                 case JAVA_FLOAD:
1439                 case JAVA_DLOAD:
1440
1441                 case JAVA_ALOAD:
1442                         if (iswide)
1443                                 {
1444                                         nextp = p+3;
1445                                         iswide = false;
1446                                 }
1447                         break;
1448
1449                         /* 54 -58 */
1450                 case JAVA_ISTORE:
1451                 case JAVA_LSTORE:
1452                 case JAVA_FSTORE:
1453                 case JAVA_DSTORE:
1454
1455                 case JAVA_ASTORE:
1456                         if (iswide)
1457                                 {
1458                                         iswide=false;
1459                                         nextp = p+3;
1460                                 }
1461                         break;
1462
1463                         /* 132 */
1464                 case JAVA_IINC:
1465                         {
1466                                 if (iswide) {
1467                                         iswide = false;
1468                                         nextp = p+5;
1469                                 }
1470                         }
1471                         break;
1472
1473                         /* wider index for loading, storing and incrementing */
1474                         /* 196 */
1475                 case JAVA_WIDE:
1476                         iswide = true;
1477                         nextp = p + 1;
1478                         break;
1479                         /* 169 */
1480                 case JAVA_RET:
1481                         if (iswide) {
1482                                 nextp = p+3;
1483                                 iswide = false;
1484                         }
1485                         break;
1486
1487                         /* table jumps ********************************/
1488
1489                 case JAVA_LOOKUPSWITCH:
1490                         {
1491                                 s4 num;
1492                                 nextp = ALIGN((p + 1), 4);
1493                                 num = rt_code_get_u4(nextp + 4);
1494                                 nextp = nextp + 8 + 8 * num;
1495                                 break;
1496                         }
1497
1498
1499                 case JAVA_TABLESWITCH:
1500                         {
1501                                 s4 num;
1502                                 nextp = ALIGN ((p + 1),4);
1503                                 num = rt_code_get_s4(nextp + 4);
1504                                 num = rt_code_get_s4(nextp + 8) - num;
1505                                 nextp = nextp + 16 + 4 * num;
1506                                 break;
1507                         }
1508
1509                         /*-------------------------------*/
1510                 case JAVA_PUTSTATIC:
1511                         i = rt_code_get_u2(p + 1);
1512                         {
1513                                 constant_FMIref *fr;
1514                                 fieldinfo *fi;
1515
1516                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1517                                 /* descr has type of field ref'd  */
1518                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1519                                 RTAPRINT03putstatic1
1520
1521                                 /*--- RTA ---*/
1522                                 /* class with field - marked in addClassinit */
1523                                 addClassInit(fr->class, true, true, false);
1524
1525                                 /*--- XTA ---*/
1526                                 if   ((XTAOPTbypass) || (opt_xta))
1527                                         {
1528                                                 if (fi->xta == NULL)
1529                                                         fi->xta = xtafldinfoInit(fi);
1530                                                 if (xtaAddFldClassTypeInfo(fi)) {  
1531                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1532                                                 }
1533                                         }
1534                         }
1535                         break;
1536
1537                 case JAVA_GETSTATIC:
1538                         i = rt_code_get_u2(p + 1);
1539                         {
1540                                 constant_FMIref *fr;
1541                                 fieldinfo *fi;
1542
1543                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1544                                 /* descr has type of field ref'd  */
1545                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1546                                 RTAPRINT03putstatic1
1547
1548                                 /*--- RTA ---*/
1549                                 /* class with field - marked in addClassinit */
1550                                 addClassInit(fr->class,true, true, true);
1551
1552                                 /*--- XTA ---*/
1553                                 if  ((XTAOPTbypass) || (opt_xta) ) 
1554                                         {
1555                                                 if (fi->xta == NULL)
1556                                                         fi->xta = xtafldinfoInit(fi);
1557                                                 if (xtaAddFldClassTypeInfo(fi)) {
1558                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1559                                                 }
1560                                         }
1561
1562                         }
1563                         break;
1564
1565
1566                         /*--------------------  method invocation ---------------------*/
1567
1568                 case JAVA_INVOKESTATIC:
1569                         i = rt_code_get_u2(p + 1);
1570                         {
1571                                 constant_FMIref *mr;
1572                                 methodinfo *mi;
1573
1574                                 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1575                                 mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1576                                 if (!mi)
1577                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1578                                 /*-- RTA --*/
1579                                 invokestatic(mi);
1580                         }
1581                         break;
1582
1583                 case JAVA_INVOKESPECIAL:
1584                         i = rt_code_get_u2(p + 1);
1585                         {
1586                         constant_FMIref *mr;
1587                         methodinfo *mi;
1588                                 
1589                         mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1590                         mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1591                         if (!mi)
1592                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1593                                                 RTAPRINT06invoke_spec_virt1
1594                         /*--- PRIVATE Method -----------------------------------------------------*/ 
1595                         if (mi->name        != INIT) {     /* if method called is PRIVATE */ 
1596                                                         RTAPRINT07invoke_spec_virt2
1597                                                         RTAPRINT04invokestatic1
1598                                 invokestatic(mi);
1599                                 }
1600
1601                         else    {
1602                                 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1603                                 initMethods(mi);
1604                                 }
1605                         }                                                
1606                         break;
1607
1608
1609                 case JAVA_INVOKEVIRTUAL:
1610                         i = rt_code_get_u2(p + 1);
1611                         {
1612                         constant_FMIref *mr;
1613                         methodinfo *mi;
1614                                 
1615                         mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1616                         mi = class_resolveclassmethod (mr->class, mr->name, mr->descriptor, m->class, true);
1617                         if (!mi)
1618                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1619
1620                         invokevirtual(mi);
1621                         }
1622                         break;
1623
1624                 case JAVA_INVOKEINTERFACE:
1625                         i = rt_code_get_u2(p + 1);
1626                         {
1627                         constant_FMIref *mr;
1628                         methodinfo *mi;
1629
1630                         mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1631                         mi = class_resolveinterfacemethod (mr->class, mr->name, mr->descriptor, m->class, true);
1632                         if (!mi)
1633                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1634                         invokeinterface(mi);
1635                         }
1636                         break;
1637
1638                         /* miscellaneous object operations *******/
1639
1640                 case JAVA_NEW:
1641                         i = rt_code_get_u2 (p+1);
1642                         {
1643                                 classinfo *ci;
1644
1645                                 ci = class_getconstant (rt_class, i, CONSTANT_Class); 
1646                                 newClasses(ci);
1647                         }
1648                         break;
1649
1650                 default:
1651                         break;
1652
1653                 } /* end switch */
1654
1655
1656         } /* end for */
1657
1658         if (p != rt_jcodelength)
1659                 panic("Command-sequence crosses code-boundary");
1660
1661         if ((XTAOPTbypass) || (opt_xta))
1662                 xtaMethodCalls_and_sendReturnType();
1663
1664
1665 }
1666
1667 /*-------------------------------------------------------------------------------*/
1668 /* RTA add Native Methods/ Class functions  */
1669 /*-------------------------------------------------------------------------------*/
1670 void   findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1671
1672         classinfo  *class;
1673         methodinfo *meth;
1674
1675         class = class_get(c1);
1676         if (class == NULL)  {
1677                 utf_display(c1);
1678                 printf("  WARNING: CLASS used by NATIVE method is NULL so loaded\n");
1679 /*              loader_load_sysclass(NULL, c1);  */
1680 /*              class = class_get(c1); */
1681                 class = class_new(c1);
1682                 if (class == NULL)  {
1683                         panic("CLASS used by NATIVE method is NULL and loading didn't help\n");
1684                         return;    /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1685                         }
1686         }
1687
1688         if (class->classUsed == NOTUSED) {
1689 printf("NATIVE_MARKED CLASS USED "); utf_display(class->name); printf("\n");
1690                 class->classUsed = USED; /* MARK CLASS USED */
1691                 /* add marked methods to callgraph */ 
1692                 rtaAddMarkedMethods(class);
1693         }
1694
1695         meth = class_findmethod_w (class, m1, d1,"findMarkNativeUsedMeth");
1696         if (meth == NULL) {
1697                 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1698                 panic("WARNING from parseRT:  Method given is used by Native method call, but NOT FOUND\n");
1699         }
1700         else
1701                 rtaMarkSubs(class,meth);
1702 }
1703
1704 /*-------------------------------------------------------------------------------*/
1705
1706 void   findMarkNativeUsedClass (utf * c) {
1707         classinfo  *class;
1708
1709         class = class_get(c);
1710         if (class == NULL)  panic("parseRT: Class used by Native method called not loaded!!!");
1711         class->classUsed = USED;
1712
1713         /* add marked methods to callgraph */
1714         rtaAddMarkedMethods(class);
1715 }
1716
1717
1718 /*-------------------------------------------------------------------------------*/
1719
1720 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1721         int i,j,k;
1722         bool found = false;
1723
1724         nativecallcompdone = natcall2utf(nativecallcompdone); 
1725
1726         for (i=0; i<NATIVECALLSSIZE; i++) {
1727                 if (rt_class  == nativeCompCalls[i].classname) {
1728         
1729                         /* find native class.method invoked */
1730                         for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1731
1732                                 if ( (rt_method     == nativeCompCalls[i].methods[j].methodname)
1733                                          && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1734
1735                                         found=true;
1736 printf("#%i#\n",nativeCompCalls[i].callCnt[j]);
1737                                         /* mark methods and classes used by this native class.method */
1738                                         for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1739                                                 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1740                                                         /* mark method used */
1741                                                         findMarkNativeUsedMeth(
1742                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].classname,
1743                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1744                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].descriptor); 
1745
1746                                                         /*RTprint 
1747                                                           printf("\nmark method used: "); fflush(stdout);
1748                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1749                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1750                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1751                                                         */
1752                                                 }
1753                                                 else {
1754                                                         /* mark class used */
1755                                                         findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1756                                                 } /* if-else k  */ 
1757
1758                                         }  /* for k */ 
1759
1760                                 }  /* if j */
1761                         }  /* for j */
1762
1763                 }  /* if i */  
1764         }  /* for i */
1765
1766 }
1767
1768
1769
1770 /*-------------------------------------------------------------------------------*/
1771 /*-------------------------------------------------------------------------------*/
1772 /* still need to look at field sets in 2nd pass and clinit .....  */
1773 void XTA_jit_parse2(methodinfo *m)
1774 {
1775 int methRT; /* local */
1776         if (XTAdebug >= 1) 
1777                 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1778
1779         /* for each method in XTA worklist = callgraph (use RTA for now) */
1780         methRT=0;
1781         //while (methRT <= methRTlast) {
1782         while (methRT <= methXTAlast) {
1783                 rt_method      = XTAcallgraph[methRT];
1784                 rt_class       = rt_method->class;
1785                 rt_descriptor  = rt_method->descriptor;
1786                 rt_jcodelength = rt_method->jcodelength;
1787                 rt_jcode       = rt_method->jcode;
1788
1789                 if (! (  (rt_method->flags & ACC_NATIVE  )
1790                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1791                         if (XTAdebug >= 1) {
1792                                 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1793                                 utf_display(rt_class->name); printf("."); fflush(stdout);
1794                                 method_display(rt_method);
1795                         }
1796                         /*   if XTA type set changed since last parse */
1797                         if (rt_method->xta->chgdSinceLastParse) {
1798
1799                                 /*     get types from methods it is calledBy */
1800                                 xtaPassAllCalledByParams ();
1801
1802                                 /* Pass parameter types to methods it calls and  send the return type those called by  */
1803                                 xtaMethodCalls_and_sendReturnType();
1804                         }
1805                 }
1806                 methRT++;
1807         }
1808         if (XTAdebug >= 1) {
1809
1810                 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1811                 printXTACallgraph ();
1812         }
1813         
1814         RTAPRINT14CallgraphLast  /*was >=2 */
1815                 RTAPRINT15HeirarchyiLast /*was >= 2 */
1816                 }
1817
1818
1819 /*-------------------------------------------------------------------------------*/
1820 /*-------------------------------------------------------------------------------*/
1821 void mainRTAparseInit (methodinfo *m )
1822 {
1823         /*printf("MAIN_NOT_STARTED \n");*/ 
1824         if (class_java_lang_Object->sub != NULL) { 
1825                 RTAPRINT16stats1;
1826         }
1827
1828         if (firstCall) {
1829                 firstCall=false;
1830
1831                 /* Frequently used utf strings */
1832                 utf_OBJECT = utf_new_char("java/lang/Object");
1833                 utf_MAIN  = utf_new_char("main");
1834                 INIT      = utf_new_char("<init>");
1835                 CLINIT    = utf_new_char("<clinit>");
1836                 FINALIZE  = utf_new_char("finalize");
1837                 EMPTY_DESC= utf_new_char("()V");
1838
1839                 /* open file for list of methods parsed before main method or missed and parsed after main */
1840                 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1841                         printf("CACAO - rtMissed file: cant open file to write\n");
1842                 }
1843                 else {
1844                         fprintf(rtMissed,"To Help User create a dymLoad file \n");
1845                         fprintf(rtMissed,
1846                 "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1847                         fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1848                         fflush(rtMissed);
1849                         fclose(rtMissed);
1850                 }
1851                 /* Allocate callgraph */
1852                 if (opt_rt) {
1853                         callgraph = MNEW (methodinfo*, MAXCALLGRAPH);   /****/
1854                         }
1855                 if ((XTAOPTbypass) || (opt_xta)) {
1856                         printf("XTAXTA  CALLGRAPHS allocated\n");
1857                         XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1858                         }
1859                 }
1860
1861         if (m->name == utf_MAIN) {
1862                 rtMissed = fopen("rtMissed","a");
1863                 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1864                 fclose(rtMissed);
1865                 AfterMain = true;
1866         }
1867         else {  
1868                 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1869                         printf("CACAO - rtMissed file: cant open file to write\n");
1870                 }
1871                 else {
1872                         fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1873                         utf_fprint(rtMissed,m->class->name);
1874                         fprintf(rtMissed," ");
1875                         fprintflags(rtMissed,m->flags);
1876                         fprintf(rtMissed," ");
1877                         utf_fprint(rtMissed,m->name);
1878                         fprintf(rtMissed," ");
1879                         utf_fprint(rtMissed,m->descriptor);
1880                         fprintf(rtMissed,"\n");
1881                         fflush(rtMissed);
1882                         fclose(rtMissed);
1883                 }
1884                 if (AfterMain) {
1885                         printf("#%i : ",methRT);
1886                         printf("Method missed by static analysis Main parse. See ./rtMissed file\n");
1887                         /***    panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1888                 }
1889         }
1890
1891         /* At moment start RTA before main when parsed                      */
1892         /* Will definitely use flag with to know if ok to apply in-lining.  */
1893 }
1894
1895
1896 /*-------------------------------------------------------------------------------*/
1897 /*-------------------------------------------------------------------------------*/
1898
1899 void RTparseCGWorklist (methodinfo *m) {  
1900 printf("IIIIIIIIIIIIIIIIIIIIn RTparseCGWorklist\n"); fflush(stdout);
1901         if (m->methodUsed == USED) return;
1902         if ((firstCall) || (parse1) || (m->name == utf_MAIN))
1903                 mainRTAparseInit (m);
1904         parse1= false;
1905         m->methodUsed = USED;
1906
1907         /* initialise parameter type descriptor */
1908         callgraph[++methRTlast] = m;          /*-- RTA --*/
1909                 RTAPRINT11addedtoCallgraph 
1910         /* <init> then like a new class so add marked methods to callgraph */
1911         if (m->name == INIT)  {  /* need for <init>s parsed efore Main */
1912                 classinfo *ci;
1913                 ci = m->class;
1914                 ci->classUsed = USED;
1915                         if (pWhenMarked >= 1) {
1916                                 printf("Class=");utf_display(ci->name);
1917                         }
1918                         /* add marked methods to callgraph */
1919                         RTAPRINT11addedtoCallgraph2
1920                 rtaAddMarkedMethods(ci);
1921                 } /* if */
1922
1923         /*---- RTA call graph worklist -----***/
1924         while (methRT <= methRTlast) {
1925                 rt_method      = callgraph[methRT];
1926                 rt_class       = rt_method->class;
1927                 rt_descriptor  = rt_method->descriptor;
1928                 rt_jcodelength = rt_method->jcodelength;
1929                 rt_jcode       = rt_method->jcode;
1930
1931                 if (! (  (rt_method->flags & ACC_NATIVE  )
1932                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1933                         parseRT(m);
1934                         }
1935                 //if (true == false) {   // At moment nativecalls.h is not current and neither helps nor hinders
1936                 else    {
1937                                 RTAPRINT12bAbstractNative
1938                         if (rt_method->flags & ACC_NATIVE ) {
1939                                         RTAPRINT12aNative
1940                                                 /* mark used and add to callgraph methods and classes used by NATIVE method */
1941                                                 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);                
1942                                 }
1943                         if (rt_method->flags & ACC_ABSTRACT) {
1944                                 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n"); 
1945                                 }
1946                         }
1947                 methRT++;
1948                                 RTAPRINT12Callgraph 
1949                                 RTAPRINT13Heirarchy 
1950                 } /* while */
1951
1952         if (m->class->classUsed == NOTUSED)
1953                 m->class->classUsed = USED; /* say Main's class has a method used ??*/ 
1954 }
1955
1956
1957 /*-------------------------------------------------------------------------------*/
1958 /*--------------------------------------------------------*/
1959 int getdymline(char *line, int max, FILE *inFP) {
1960 if (fgets(line, max, inFP) == NULL)
1961   return 0;
1962 else {
1963   return strlen((const char *)line);
1964   }
1965 }
1966
1967 /*-------------------------------------------------------------------------------*/
1968
1969 methodinfo *getApplicationDynamics ( ) {
1970 char line[512]="";
1971 char *classname;
1972 char *methname ;
1973 char *desc;
1974 int rc;
1975
1976 classinfo  *class;
1977 methodinfo *mi;
1978
1979 if ( (appldynm = fopen("appldynm", "r")) == NULL) {
1980         printf("parseRT - appldynm file: no appldynm file - ok if nothing in rtMissed after Main\n");
1981         return NULL;
1982 }
1983
1984 if ( getdymline(line,512,appldynm) != 0)
1985         {
1986         printf("line=%s\n",line); fflush(stdout);
1987
1988         classname = strtok(line," \n");
1989         methname  = strtok(NULL," \n");
1990         if (methname == NULL) {  /* if no meth */
1991                 panic("parseRT - dynamic loaded class/method/desc in appldynm has no method");
1992                 }
1993         desc = strtok(NULL," \n");
1994         if (desc == NULL) {  /* if no desc */
1995                 panic("parseRT - dynamic loaded class/method/desc in appldynm has no descriptor");
1996                 }
1997         printf("appldynm class=%s meth=%s desc=%s\n",classname, methname,desc); fflush(stdout);
1998
1999         class = class_get(utf_new_char(classname));
2000         if (class == NULL) {
2001 /*              class = loader_load_sysclass(NULL,  utf_new_char(classname));    */
2002                 class = class_new(utf_new_char(classname));
2003                 }
2004         mi = class_fetchmethod(class,utf_new_char(methname), utf_new_char(desc)) ;
2005         printf("+++++--3--+++++\t");
2006         RTparseCGWorklist (mi) ;  
2007
2008         }
2009
2010 fclose(appldynm);
2011 return NULL;
2012 }
2013
2014 /*-------------------------------------------------------------------------------*/
2015
2016 void RT_jit_parse(methodinfo *m)
2017 {
2018 classinfo  *class;
2019 methodinfo * mi;
2020 classinfo *topclass;
2021
2022 /*-- RTA -- *******************************************************/
2023     if (opt_rt) 
2024        {
2025         /*---- java/lang/Object.<clinit> ----*/
2026  if ((firstCall == false) || (true == false))  
2027         {
2028         parse1 = true;
2029         if (m->methodUsed == USED) return;
2030         printf("MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2031         RTparseCGWorklist (m) ;  
2032                                         /*RTAprint*/ if (pCallgraph >= 1) {
2033                                         /*RTAprint*/    printCallgraph ();}
2034                                         /*RTprint*/ //if (pClassHeir >= 1) {
2035                                         /*RTprint*/ //    printRThierarchyInfo(m);
2036                                         /*RTprint*/ //    }
2037                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2038                                                 fflush(stdout);
2039         printf("END MMMMMMMMMMMMMMMMMMMMMMMMMMMMissed\n"); fflush(stdout);
2040         return;
2041         }
2042  else
2043         {
2044         parse1 = true;
2045         printf("SSSSSSSSSSSSSSSSSSSSSStatic Analysis \n"); fflush(stdout);
2046         printf("+++++--1--+++++\t");
2047         RTparseCGWorklist (m) ;  
2048
2049         class = class_get(utf_new_char("java/lang/Thread"));
2050         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2051         printf("+++++--2--+++++\t");
2052         RTparseCGWorklist (mi) ;  
2053
2054         class = class_get(utf_new_char("java/lang/ThreadGroup"));
2055         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2056         printf("+++++--3--+++++\t");
2057         RTparseCGWorklist (mi) ;  
2058
2059
2060         class = class_get(utf_new_char("java/lang/Throwable"));
2061         mi = class_fetchmethod(class,clinit_name(),clinit_desc()) ;
2062         printf("+++++--4--+++++\t");
2063         RTparseCGWorklist (mi) ;  
2064
2065         printf("mainstring=%s=\n",mainstring);fflush(stdout);
2066 /*      class = loader_load_sysclass(NULL,  utf_new_char(mainString));   */
2067         class = class_new(utf_new_char(mainstring));
2068         mi = class_fetchmethod( class,
2069                                 utf_new_char("main"),
2070                                 utf_new_char("([Ljava/lang/String;)V")
2071                                );
2072         printf("+++++--5--+++++\t");
2073         RTparseCGWorklist (mi) ;  
2074
2075         printf("+++++--6--+++++\t");
2076         getApplicationDynamics();
2077
2078 printf("-+-+-+-+-+-+-+-+-+-+-33"); fflush(stdout);
2079
2080                                         /*RTAprint*/ if (pCallgraph >= 1) {
2081                                         /*RTAprint*/    printCallgraph ();}
2082                                         /*RTprint*/ //if (pClassHeir >= 1) {
2083                                         /*RTprint*/ //    printRThierarchyInfo(m);
2084                                         /*RTprint*/ //    }
2085                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2086                                                 fflush(stdout);
2087 printf("-+-+-+-+-+-+-+-+-+-+-44"); fflush(stdout);
2088         /** MFREE(callgraph,methodinfo*,MAXCALLGRAPH);  causes stack overflow **/
2089         }
2090      } /*  end opt_rt */
2091
2092 /*-- XTA -- *******************************************************/
2093         if ((XTAOPTbypass) || (opt_xta)) {
2094                 if (m->xta != NULL) {
2095                         if (m->xta->XTAmethodUsed == USED) return;
2096                         }
2097                 mainRTAparseInit (m);
2098
2099                 XTAcallgraph[++methXTAlast] = m;
2100                 if (m->xta == NULL) {
2101                         m->xta = xtainfoInit(m);
2102                         }
2103                 m->xta->XTAmethodUsed = USED;
2104                         {methodinfo *mi = m;
2105                         printf("<");fflush(stdout);
2106                         XTAPRINTcallgraph2
2107                         }
2108                 }
2109
2110         /*-- Call graph work list loop -----------------*/
2111         /*---- XTA call graph worklist -----***/
2112                                                         useXTAcallgraph = true;
2113         if ((useXTAcallgraph) && (opt_xta)) {
2114                                                         printf("USING XTA call graph>>>>>>>>>><<\n");
2115
2116           while (methXTA <= methXTAlast) {
2117                 rt_method      = XTAcallgraph[methXTA];
2118                                                         printf("xTA CALLGRAPH #%i:",methXTA); fflush(stdout);
2119                                                         method_display(rt_method);
2120                 rt_class       = rt_method->class;
2121                 rt_descriptor  = rt_method->descriptor;
2122                 rt_jcodelength = rt_method->jcodelength;
2123                 rt_jcode       = rt_method->jcode;
2124
2125                 if (! (  (rt_method->flags & ACC_NATIVE  )
2126                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
2127                         parseRT(m);
2128                         }
2129                 else    {
2130                                 RTAPRINT12bAbstractNative
2131                         if (rt_method->flags & ACC_NATIVE ) {
2132                                         RTAPRINT12aNative
2133                                 /* mark used and add to callgraph methods and classes used by NATIVE method */
2134                                 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
2135                                 }
2136                         if (rt_method->flags & ACC_ABSTRACT) {
2137                                 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
2138                                 }
2139                         }
2140                 methXTA++;
2141                                 RTAPRINT12Callgraph
2142                                 RTAPRINT13Heirarchy
2143                 } /* while */
2144         if (m->class->classUsed == NOTUSED)
2145                 m->class->classUsed = USED; /* say Main's class has a method used ??*/ 
2146         printXTACallgraph ();
2147
2148         if (m->name == utf_MAIN) { /*-- MAIN specific -- */
2149                                         /*RTAprint*/ if (pCallgraph >= 1) {
2150                                         /*RTAprint*/    printXTACallgraph (); }
2151                                         /*RTprint*/ if (pClassHeir >= 1) {
2152                                         /*RTprint*/     printf("Last RTA Info -+-+-");
2153                                         /*RTprint*/     printRThierarchyInfo(m);
2154                                         /*RTprint*/     }
2155                                         /*RTprint*/     /**printObjectClassHeirarchyAll( );**/
2156                                                 fflush(stdout);
2157                 /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
2158                 XTA_jit_parse2(m);
2159                 printf("XTAXTA  CALLGRAPHS -SHOULD BE BUT ISNT- returned \n");
2160                 //MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
2161                 }
2162         } /*  end opt_xta */
2163
2164         RTAPRINT14CallgraphLast  /*  was >=2*/
2165                 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
2166
2167         return;
2168 }
2169
2170
2171 /*
2172  * These are local overrides for various environment variables in Emacs.
2173  * Please do not remove this and leave it at the end of the file, where
2174  * Emacs will automagically detect them.
2175  * ---------------------------------------------------------------------
2176  * Local variables:
2177  * mode: c
2178  * indent-tabs-mode: t
2179  * c-basic-offset: 4
2180  * tab-width: 4
2181  * End:
2182  */
2183