Code indent.
[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 619 2003-11-13 13:49:23Z twisti $
30
31 */
32
33
34 #include "parseRT.h"
35  
36 /*------------ global variables -----------------------------------------*/
37 #define MAXCALLGRAPH 5000
38
39 bool XTAOPTbypass = false;
40 bool XTAOPTbypass2 = false;   /* for now  invokeinterface     */
41 bool XTAOPTbypass3 = false;   /* print XTA classsets in stats */
42 int  XTAdebug = 0;
43 int  XTAfld = 0;
44
45 int methRT = 0;
46 int methRTlast = -1;
47 int methRTmax = MAXCALLGRAPH;
48 methodinfo **callgraph;
49 /*methodinfo *callgraph[MAXCALLGRAPH];*/ 
50
51  
52 int methXTA = 0;            
53 int methXTAlast = -1;
54 int methXTAmax = MAXCALLGRAPH;        
55 methodinfo **XTAcallgraph;
56 /*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/
57
58 static bool nativecallcompdone=0 ;
59
60 static bool firstCall= true;
61 static bool AfterMain = false;
62 static FILE *rtMissed;   /* Methods missed during RTA parse of Main  */
63 /*   so easier to build dynmanic calls file */
64
65 static utf *utf_MAIN;   /*  utf_new_char("main"); */
66 static utf *INIT    ;   /*  utf_new_char("<init>"); */
67 static utf *CLINIT  ;   /*  utf_new_char("<clinit>"); */
68 static utf *FINALIZE;   /*  utf_new_char("finalize"); */
69 static utf *EMPTY_DESC; /*  utf_new_char("V()");  */
70 static int missedCnt = 0;
71
72
73 /*--------------------------------------------------------------*/
74 /* addToCallgraph - adds to RTA callgraph and                   */ 
75 /*                  sets  meth->methodUsed  to USED             */
76 /*--------------------------------------------------------------*/  
77 #define ADDTOCALLGRAPH(meth)  if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \
78         callgraph[++methRTlast] = meth ; \
79         meth->methodUsed = USED; \
80                         if(pWhenMarked>=1) \
81                                 {printf("\n Added to Call Graph #%i:",  \
82                                 methRTlast); \
83                                 printf("\t <used flags c/m> <%i/%i> %i\t",  \
84                                   meth->class->classUsed, \
85                                   meth->methodUsed, \
86                                   USED);  \
87                                 printf(" method name =");   \
88                                 utf_display(meth->class->name);printf("."); \
89                                 method_display(meth);fflush(stdout);} \
90         }
91
92
93 /*--------------------------------------------------------------*/
94 bool rtaSubUsed(classinfo *class, methodinfo *meth) {
95         classinfo *subs;
96
97         for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
98                 if (subs->classUsed == USED) {
99                         if (class_findmethod(class, meth->name, meth->descriptor) == NULL)
100                                 return false;
101                         else    
102                                 return true;
103                 }
104                 if (rtaSubUsed(subs, meth)) 
105                         return false;
106         }
107         return false;
108 }
109
110
111 /*--------------------------------------------------------------*/
112 /* Mark the method with same name /descriptor in topmethod      */
113 /* in class                                                     */
114 /*                                                              */
115 /* Class not marked USED and method defined in this class ->    */
116 /*    -> if Method NOTUSED mark method as MARKED                */
117 /* Class marked USED and method defined in this class ->        */
118 /*    -> mark method as USED                                    */
119 /*                                                              */
120 /* Class USED, but method not defined in this class ->          */
121 /*    -> search up the heirarchy and mark method where defined  */
122 /*       if class where method is defined is not USED ->        */
123 /*       -> mark class with defined method as PARTUSED          */
124 /*--------------------------------------------------------------*/
125
126 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
127
128         utf *name = topmethod -> name; 
129         utf *descriptor = topmethod -> descriptor;
130         methodinfo *submeth;
131
132         submeth = class_resolvemethod(class, name, descriptor); 
133         if (submeth == NULL)
134                 panic("parse RT: Method not found in class hierarchy");
135         if (submeth->methodUsed == USED) return;
136   
137         if (submeth->class == class) { 
138
139                 /*--- Method defined in class -----------------------------*/
140         if (submeth->class->classUsed != USED) { 
141                         if (submeth->methodUsed == NOTUSED) { 
142
143                 /* Class NOT marked USED and method defined in this class -> */
144                                 /*    -> if Method NOTUSED mark method as  MARKED            */
145                                 if (pWhenMarked >= 1) {
146                                         printf("MARKED class.method\t"); 
147                                         utf_display(submeth->class->name);printf(".");method_display(submeth);
148                                 }
149                                 if (rtaSubUsed(submeth->class,submeth)) {
150                                         submeth->class->classUsed = PARTUSED;
151                                         ADDTOCALLGRAPH(submeth) 
152                                                 }
153                                 else    {
154                                         submeth->methodUsed = MARKED;
155                                         RTAPRINTmarkMethod1
156                                                 }
157                 } }
158         else    {
159                         /* Class IS  marked USED and method defined in this class -> */
160                         /*    -> mark method as USED  */
161                         ADDTOCALLGRAPH(submeth) 
162                                 }
163         } /* end defined in class */
164
165         else {
166                 /*--- Method NOT defined in class -----------------------------*/
167                 if (submeth->class->classUsed == NOTUSED) {
168                         submeth->class->classUsed = PARTUSED;
169                         if (class->classUsed != USED) {
170                                 submeth->methodUsed = MARKED;
171                         }
172                 }
173                 if ( (submeth->class->classUsed == USED) 
174                          || (class->classUsed == USED)) {
175                         ADDTOCALLGRAPH(submeth)
176                                 }
177         } /* end NOT defined in class */
178
179
180 /*-------------------------------------------------------------------------------*/
181 /* Mark the method with the same name and descriptor as topmethod                */
182 /*   and any subclass where the method is defined and/or class is used           */
183 /*                                                                               */
184 /*-------------------------------------------------------------------------------*/
185 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
186                 RTAPRINTmarkSubs1
187         rtaMarkMethod(class, topmethod);   /* Mark method in class where it was found */
188         if (class->sub != NULL) {
189                 classinfo *subs;
190         
191                 if (!(topmethod->flags & ACC_FINAL )) {
192                         for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
193                                         RTAPRINTmarkSubs1
194                                 rtaMarkSubs(subs, topmethod); 
195                                 }
196                         }
197                 }
198         return;
199 }
200
201 /*-------------------------------------------------------------------------------*/
202 /* Add Marked methods for input class ci                                         */
203 /* Add methods with the same name and descriptor as implemented interfaces       */
204 /*   with the same method name                                                   */
205 /*                                                                               */
206 /*-------------------------------------------------------------------------------*/
207 void addMarkedMethods(classinfo *ci) {
208         int ii,jj,mm;
209
210         /* add marked methods to callgraph */ 
211         for (ii=0; ii<ci->methodscount; ii++) { 
212                 methodinfo *mi = &(ci->methods[ii]);
213                 if (mi->methodUsed == MARKED) { 
214                         if (pWhenMarked >= 1) {
215                                 printf("ADDED a method that was MARKED\n");
216                                 }
217                         ADDTOCALLGRAPH(mi)  
218                         }
219                 else {
220         
221                         for (jj=0; jj < ci -> interfacescount; jj++) {
222                                 classinfo *ici = ci -> interfaces [jj];
223                                 /*  use resolve method....!!!! */
224                                 if (ici -> classUsed != NOTUSED) {
225                                         for (mm=0; mm< ici->methodscount; mm++) {
226                                                 methodinfo *imi = &(ici->methods[mm]);
227
228                                                 if  (      (imi->methodUsed == USED) 
229                                                                    &&    ( (imi->name == mi->name) 
230                                                                                    &&      (imi->descriptor == mi->descriptor))) {
231                                                         if (pWhenMarked >= 1) 
232                                                                 printf("ADDED a method that was used by an interface\n");
233                                                         ADDTOCALLGRAPH(mi)  
234                                                                 }
235                                         }
236                                 }
237                         }
238                 }
239         }
240 }    
241 /*-------------------------------------------------------------------------------*/
242 /*  XTA Functions                                                                */
243 /*-------------------------------------------------------------------------------*/
244
245 xtainfo *xtainfoInit(methodinfo *m)
246 {
247         if (m->xta != NULL)
248                 return m->xta;
249
250         if (m->xta != NULL)
251                 return m->xta;
252
253         m ->xta = (xtainfo *) NEW(xtainfo); 
254         m ->xta-> XTAmethodUsed = NOTUSED;
255         m ->xta-> XTAclassSet   = NULL;
256         /* PartClassSet */
257         m->xta->paramClassSet = NULL;
258         m->xta->calls         = NULL;
259         m->xta->calledBy      = NULL;
260
261         m->xta->marked        = NULL;
262         /*m ->xta->markedBy     = NULL */
263         m->xta->fldsUsed      = NULL;
264         /*m ->xta->interfaceCalls    = NULL*/
265         m->xta->chgdSinceLastParse = false;
266         return m->xta;
267 }
268
269
270 xtafldinfo * xtafldinfoInit (fieldinfo *f)
271 {
272         if (f->xta != NULL)
273                 return f->xta;
274
275         f->xta = NEW(xtafldinfo);
276
277         f->xta->fieldChecked = false;   /*XTA*/
278         f->xta->fldClassType = NULL;    /*XTA*/
279         f->xta->XTAclassSet = NULL;     /*XTA*/
280
281         return f->xta;
282 }
283
284
285 bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto)
286 {
287         classSetNode *p;
288         classSetNode *c;
289         classSetNode *c1;
290         classSetNode *cprev;
291         bool          rc = false;
292
293         if (XTAdebug >= 1) {
294                 printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
295
296                 printf("\tIN SmCalled set : "); 
297                 utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
298                 printClassSet(SmCalled->xta->XTAclassSet); printf("\n"); 
299
300                 printf("\tIN SmCalls set: "); 
301                 utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
302                 printClassSet(SmCalls->xta->XTAclassSet); printf("\n"); 
303                 
304                 printf("\tIN lastptrInto : (");
305                 if (lastptrInto->lastptrIntoClassSet2 != NULL) {
306                         utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") ");
307                 }
308                 else {printf("NULL) ");}
309                 fflush(stdout);
310                 utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout);
311                 method_display(lastptrInto->methRef); fflush(stdout);
312                 printf("\n");fflush(stdout);
313         }
314
315         /* Get SmCalled ParamType set if null */
316         if (SmCalled->xta->paramClassSet == NULL) {
317                 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); 
318         }
319         if (XTAdebug >= 1) {
320                 printf("\tParamPassed\n"); fflush(stdout);
321                 printSet(SmCalled->xta->paramClassSet);fflush(stdout);
322                 printf("\n"); fflush(stdout);
323         }
324
325         if (lastptrInto->lastptrIntoClassSet2 == NULL) {
326                 if (SmCalls->xta->XTAclassSet != NULL) 
327                         c1 = SmCalls->xta->XTAclassSet->head;
328                 else
329                         c1 = NULL;
330         }
331         else    {
332                 /* start with type where left off */
333                 c1 = lastptrInto->lastptrIntoClassSet2;  
334                 c1 = c1 -> nextClass;  /* even if NULL */
335         }
336         cprev = NULL;
337         if (XTAdebug >= 1) {
338                 if (c1 == NULL){
339                         printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout);
340                 }
341                 else    {
342                         printf("\tIN SmCalls ... start with :");fflush(stdout);
343                         utf_display(c1->classType->name); printf("\n");
344                 }
345         }
346
347         /* for each Param Class */
348         for (   p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) {
349
350                 /* for each SmCalls class */
351                 for (c=c1; c != NULL; c = c->nextClass) {
352                         vftbl *p_cl_vt = p->classType->vftbl; 
353                         vftbl *c_cl_vt = c->classType->vftbl; 
354
355                         /* if SmCalls class is in the Params Class range */
356                         if (  (p_cl_vt->baseval <=  c_cl_vt->baseval)
357                                   && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) {
358
359                                 /*    add SmCalls class to SmCalledBy Class set */
360                                 SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType); 
361                                 rc = true;
362                         }
363                         cprev = c;
364                 }       
365         }
366         lastptrInto->lastptrIntoClassSet2 = cprev;
367         if (XTAdebug >= 1) {
368                 printf("\tOUT SmCalled set: ");fflush(stdout);
369                 printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout);
370
371                 printf("\tOUT SmCalls set: ");fflush(stdout);
372                 printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout);
373
374                 printf("\tOUT  lastptrInto="); fflush(stdout);
375                 if (lastptrInto->lastptrIntoClassSet2 != NULL)
376                         utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
377
378                 printf("<rc=%i>\n",rc);fflush(stdout);
379         }
380         return rc;
381 }
382
383 /*-------------------------------------------------------------------------------*/
384 bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) {
385
386         classSetNode* cs;
387         classSetNode* cs1;
388         bool          rc = false;
389
390         if (XTAdebug >= 1)
391                 printf("xtaPassReturnType \n");
392
393         /* Get SmCalled return class is null */
394         if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) {
395                 SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); 
396         }
397
398         if (SmCalled->returnclass == NULL) {
399                 if (XTAdebug >= 1)
400                         printf("\tReturn type is NULL\n");
401                 return rc;
402         }
403         
404         if (XTAdebug >= 1) {
405                 printf("\tReturn type is: ");
406                 utf_display(SmCalled->returnclass->name);
407                 printf("\n");
408
409                 printf("\tIN SmCalls set: ");
410                 utf_display(SmCalls->class->name); printf("."); method_display(SmCalls);
411                 printClassSet(SmCalls->xta->XTAclassSet);
412
413                 printf("\tIN SmCalled set: ");
414                 utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
415                 printClassSet(SmCalled->xta->XTAclassSet);
416         }
417
418
419         if (SmCalled->xta->XTAclassSet == NULL) 
420                 cs1 = NULL;
421         else
422                 cs1 =  SmCalled->xta->XTAclassSet->head;
423         for (cs =cs1; cs != NULL; cs = cs->nextClass) {
424                 classinfo *c = cs->classType;
425                 vftbl *r_cl_vt = SmCalled->returnclass->vftbl; 
426                 vftbl *c_cl_vt = c->vftbl; 
427
428                 /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/
429                 if (  (r_cl_vt->baseval <=  r_cl_vt->baseval)
430                           && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) {
431                         SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c);  
432                         rc = true;
433                 }
434         } 
435
436         if (XTAdebug >= 1) {
437                 printf("\tOUT SmCalls set: ");
438                 printClassSet(SmCalls->xta->XTAclassSet);
439         }
440         return rc;
441 }
442
443 /*-------------------------------------------------------------------------------*/
444 void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
445
446         if (mi->xta == NULL)
447                 mi->xta = xtainfoInit(mi);
448         if (mi->xta->XTAmethodUsed  != USED) {  /* if static method not in callgraph */
449                 XTAcallgraph[++methXTAlast] = mi;
450                 mi->xta->XTAmethodUsed = USED;
451                 /**                             XTAPRINTcallgraph2 */
452
453                 if(pWhenMarked>=1) {  
454                         printf("\n XTA Added to Call Graph #%i:", 
455                                    methXTAlast); 
456                         printf(" method name ="); fflush(stdout);
457                         if (mi == NULL) panic ("Method ptr NULL!!!");
458                         if (mi->class == NULL) panic ("Method class ptr NULL!!!");
459                         if (mi->class->name == NULL) panic ("Method class name ptr NULL!!!");
460                         utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout); 
461                         method_display(mi);fflush(stdout); 
462         }
463
464         }
465         /* add call edges */
466         rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi);
467         rt_method->xta->calls->tail->monoPoly = monoPoly;
468         mi->xta->calledBy     = add2MethSet(mi->xta->calledBy,     rt_method); 
469         if (mi->xta->calledBy     == NULL) panic("mi->xta->calledBy is NULL!!!");
470         if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!");
471 }
472
473
474 /*--------------------------------------------------------------*/
475 bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) {
476         classinfo *subs;
477
478         for (subs=class->sub; subs != NULL; subs = subs->nextsub) {
479                 /* if class used */
480                 if (inSet(subtypesUsedSet,subs)) {
481                         if (class_findmethod(class, meth->name, meth->descriptor) == NULL) 
482                                 return false;
483                         else    
484                                 return true;
485                 }
486                 if (xtaSubUsed(subs, meth,  subtypesUsedSet)) 
487                         return false;
488         }
489         return false;
490 }
491
492
493 /*-------------------------------------------------------------------------------*/
494 void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
495 {
496         methodinfo *submeth;
497
498         utf *name = topmethod -> name;
499         utf *descriptor = topmethod -> descriptor;
500         /****
501                  printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout); 
502                  method_display(topmethod);
503         **/
504
505         submeth = class_resolvemethod(class, name, descriptor);
506
507         /***
508                 printf(" def: "); utf_display(submeth->class->name);fflush(stdout);
509                 method_display(submeth);
510         ****/
511
512         /* Basic checks */
513         if (submeth == NULL)
514         panic("parse XTA: Method not found in class hierarchy");
515         if (submeth->xta == NULL) 
516                 submeth->xta = xtainfoInit(submeth);
517
518         if (rt_method->xta->calls != NULL) {
519                 if (inMethSet(rt_method->xta->calls->head,submeth)) return;
520         }
521         /*----*/
522         if (submeth->class == class) {
523
524         /*--- Method defined in class -----------------------------*/
525                 if (inSet(subtypesUsedSet,submeth->class)) {
526                         xtaAddCallEdges(submeth,POLY);  
527                 }
528                 else    {
529                         if (subtypesUsedSet != NULL) {  
530                                 if (xtaSubUsed (class,submeth,subtypesUsedSet)) {
531                                         xtaAddCallEdges(submeth,POLY);
532                                 }
533                         }
534                         else    {
535                                 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
536                         }
537                 }
538         }
539         else  {
540         /*--- Method NOT defined in class -----------------------------*/
541                 if (!(inSet(subtypesUsedSet,submeth->class) )){  /* class with method def     is not used */
542                         if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */ 
543                                 rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth);
544                                 /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/
545                         }
546                 }
547                 if ( (inSet(subtypesUsedSet,submeth->class))  /* class with method def     is used */
548                          || (inSet(subtypesUsedSet,class)) ) {       /* class currently resolving is used */ 
549                         xtaAddCallEdges(submeth,POLY);
550                 }
551
552         } /* end defined in class */
553
554 }
555 /*-------------------------------------------------------------------------------*/
556 void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
557         /* xtaPRINTmarkSubs1*/
558         xtaMarkMethod(class, topmethod,subtypesUsedSet);   /* Mark method in class where it was found */
559         if (class->sub != NULL) {
560                 classinfo *subs;
561
562                 if (!(topmethod->flags & ACC_FINAL )) {
563                         for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
564                                 /* xtaPRINTmarkSubs1 */
565                                 xtaMarkSubs(subs, topmethod, subtypesUsedSet);
566                         }
567                 }
568     }
569         return;
570 }
571
572 /*-------------------------------------------------------------------------------*/
573 /*-------------------------------------------------------------------------------*/
574
575 int addClassInit(classinfo *ci) {
576         /* CHANGE to a kind of table look-up for a list of class/methods (currently 3)
577          */
578
579         utf* utf_java_lang_system = utf_new_char("java/lang/System"); 
580         utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass"); 
581         utf* utf_java_lang_Object = utf_new_char("java/lang/Object"); 
582
583         int m, m1=-1, m2=-1, mf=-1;
584         methodinfo *mi;
585
586         for  (m=0; m < ci->methodscount; m++) {
587                 /*<clnit> class init method */
588                 if (ci->methods[m].name == CLINIT) {
589                         m1=m;
590                 }
591                 /* Special case: System class has an extra initializer method */
592                 if        ((utf_java_lang_system == ci->name) 
593                            && (utf_initializeSystemClass == ci->methods[m].name)) {
594                         m2=m;  
595         }
596
597                 /* Finalize methods */
598                 if    ((ci->methods[m].name == FINALIZE) 
599                            && (ci->name != utf_java_lang_Object)) {
600                         mf=m;  
601         }
602
603     }
604
605         if (m1 >= 0) { /* No <clinit>  available - ignore */  
606
607                 /* Get clinit methodinfo ptr */
608                 mi = class_findmethod (ci,ci->methods[m1].name , NULL); 
609
610                 /*--- RTA ---*/
611                 if ( mi->methodUsed != USED) {
612                         mi->class->classUsed = PARTUSED;  
613                         ADDTOCALLGRAPH(mi)  
614                                 }
615
616                 /*--- XTA ---*/
617                 if ((XTAOPTbypass) || (opt_xta)) {
618                         xtaAddCallEdges(mi,MONO); 
619                 }
620
621         }
622
623         if (mf >= 0) {   
624
625                 /* Get finalize methodinfo ptr */
626                 mi = class_findmethod (ci,ci->methods[mf].name , NULL); 
627
628                 /*--- RTA ---*/
629                 if ( mi->methodUsed != USED) {
630                         mi->class->classUsed = PARTUSED;  
631                         ADDTOCALLGRAPH(mi)  
632                                 }
633
634                 /*--- XTA ---*/
635                 if ((XTAOPTbypass) || (opt_xta)) {
636                         xtaAddCallEdges(mi,MONO); 
637                 }
638         }
639
640         /*Special Case for System class init:  
641         add java/lang/initializeSystemClass to callgraph */
642         if (m2 >= 0) {
643                 /* Get clinit methodinfo ptr */
644                 mi = class_findmethod (ci,ci->methods[m2].name , NULL); 
645
646                 /*--- RTA ---*/
647                 if ( mi->methodUsed != USED) {
648                         mi->class->classUsed = PARTUSED;
649                         ADDTOCALLGRAPH(mi)  
650                                 }
651
652                 /*--- XTA ---*/
653                 if ((XTAOPTbypass) || (opt_xta)) {
654                         xtaAddCallEdges(mi,MONO);
655                 }
656         }
657
658         /* add marked methods to callgraph */ 
659         addMarkedMethods(ci); 
660                 
661         return m;
662
663
664
665 #define rt_code_get_u1(p)  rt_jcode[p]
666 #define rt_code_get_s1(p)  ((s1)rt_jcode[p])
667 #define rt_code_get_u2(p)  ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])
668 #define rt_code_get_s2(p)  ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]))
669 #define rt_code_get_u4(p)  ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
670                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])
671 #define rt_code_get_s4(p)  ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\
672                            +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
673
674
675
676 /*-------------------------------------------------------------------------------*/
677 /*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
678         int jj,mm;
679
680         /* add used interfaces methods to callgraph */
681         for (jj=0; jj < ci -> interfacescount; jj++) {
682                 classinfo *ici = ci -> interfaces [jj];
683         
684                 if (pWhenMarked >= 1) { 
685                         printf("BInterface used: ");fflush(stdout); 
686                         utf_display(ici->name);
687                         printf("<%i>\t",ici -> classUsed ); fflush(stdout); 
688                         if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
689                         if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
690                         if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
691                         fflush(stdout);
692                 }
693                 /* add class to interfaces list of classes that implement it */
694                 ici -> impldBy =  addElement(ici -> impldBy,  ci);
695
696                 /* if interface class is used */
697         if (ici -> classUsed != NOTUSED) {
698
699                         /* for each interface method implementation that has already been used */
700                         for (mm=0; mm< ici->methodscount; mm++) {
701                                 methodinfo *imi = &(ici->methods[mm]);
702                                 if (pWhenMarked >= 1) { 
703                                         if  (imi->methodUsed != USED) {
704                                                 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: "); 
705                                                 if (imi->methodUsed == MARKED) printf("Interface Method marked: "); 
706                                                 utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
707                                         }
708                                 } 
709                                 if  (imi->methodUsed == USED) {
710                                         if (pWhenMarked >= 1) { 
711                                                 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
712
713                                                 /* Mark this method used in the (used) implementing class and its subclasses */
714                                                 printf("MAY ADD methods that was used by an interface\n");
715                                         }
716                                         rtaMarkSubs(ci,imi);
717                                 }
718                         }
719                 }
720         }
721
722 }
723 /*-------------------------------------------------------------------------------*/
724 /*-------------------------------------------------------------------------------*/
725
726
727 /*-------------------------------------------------------------------------------*/
728 void xtaMarkInterfaceSubs(methodinfo *mCalled) {
729         classSetNode * Si;
730         
731         /* for every class that implements the interface of the method called */
732         for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) {
733                 /* add all definitions of this method for this interface */
734                 methodinfo *submeth;
735                 classSetNode *subtypesUsedSet = NULL;
736
737                 submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor); 
738                 if (submeth == NULL) { /* search up the heir - ignore for now!!! */
739                        submeth = class_resolvemethod(Si->classType, mCalled->name, mCalled->descriptor);
740                         }
741
742                 if (rt_method->xta->XTAclassSet != NULL)
743                         subtypesUsedSet = intersectSubtypesWithSet(Si->classType, rt_method->xta->XTAclassSet->head);
744                                 
745                                 printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
746                                 printSet(subtypesUsedSet);
747                         xtaMarkSubs(Si->classType, submeth, subtypesUsedSet);   
748         }
749 }
750
751 /*-------------------------------------------------------------------------------*/
752 bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
753
754         bool rc = false;
755
756         if (fi->xta->fieldChecked) {
757                 if (fi->xta->fldClassType != NULL)
758                         return true;  /* field has a class type */
759                 else
760                         return false;
761         }
762         fi->xta->fieldChecked = true;
763
764         if (fi->type == TYPE_ADDRESS) {
765                 char *utf_ptr = fi->descriptor->text;  /* current position in utf text */
766
767                 if (*utf_ptr != 'L') {
768                         while (*utf_ptr++ =='[') ;
769                 }
770
771                 if (*utf_ptr =='L') {
772                         rc = true;
773                         if  (fi->xta->fldClassType== NULL) {
774                                 char *desc;
775                                 char *cname;
776                                 classinfo * class;
777
778                                 desc = MNEW(char, 256);
779                                 strcpy(desc,++utf_ptr);
780                                 cname = strtok(desc,";");
781                                 if (XTAdebug >= 1) {
782                                         printf("STATIC field's type is: %s\n",cname);
783                                         fflush(stdout);
784                                 }
785                                 class = class_get(utf_new_char(cname));
786                                 fi->xta->fldClassType= class;    /* save field's type class ptr */      
787                         } 
788                 }
789         }
790         return rc;
791 }
792
793 /*-------------------------------------------------------------------------------*/
794 void xtaPassFldPUT(fldSetNode *fN)
795 {
796         /* Field type is a class */
797         classSetNode *c;
798         classSetNode *c1 = NULL;
799         classSetNode *cp = NULL;
800         classSetNode *cprev= NULL;
801
802         fieldinfo *fi;
803         if (fN != NULL)
804                 fi = fN->fldRef;
805         else
806                 return;
807
808 /* Use lastptr  so don't check whole XTA class set each time */
809         cp = fN->lastptrPUT;
810         if (cp != NULL) {
811                 if (cp->nextClass != NULL)
812                         c1 = cp -> nextClass;
813         } 
814         else    {
815                 if (rt_method->xta->XTAclassSet != NULL)
816                         c1  = rt_method->xta->XTAclassSet->head;
817
818                 if (XTAfld >=1 ) {
819                         printf("rt XTA class set =");fflush(stdout);
820                         printClassSet(rt_method->xta->XTAclassSet);
821                         printf("\t\tField class type = ");fflush(stdout);
822                         utf_display(fi->xta->fldClassType->name); printf("\n");
823                 }
824         }
825
826         /*--- PUTSTATIC specific ---*/
827         /* Sx = intersection of type+subtypes(field x)   */
828         /*   and Sm (where putstatic code is)            */
829         for (c=c1; c != NULL; c=c->nextClass) {
830                 vftbl *f_cl_vt = fi->xta->fldClassType->vftbl;
831                 vftbl *c_cl_vt =  c->   classType->vftbl;
832                 if (XTAfld >=2 ) {
833                         printf("\tXTA class = ");fflush(stdout);
834                         utf_display(c->classType->name);
835                         printf("<b=%i> ",c_cl_vt->baseval); fflush(stdout);
836                         if (c->nextClass == NULL) {
837                                 printf("next=NULL ");fflush(stdout);
838                         }
839                         else    {
840                                 printf("next="); fflush(stdout);
841                                 utf_display(c->nextClass->classType->name);
842                                 printf("\n"); fflush(stdout);
843                         }
844
845                         printf("\t\tField class type = ");fflush(stdout);
846                         utf_display(fi->xta->fldClassType->name);
847                         printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
848                 }
849
850                 if ((f_cl_vt->baseval <= c_cl_vt->baseval)
851                         && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
852                         fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
853                 }
854                 cprev = c;
855         }
856         fN->lastptrPUT = cprev;
857 }
858 /*-------------------------------------------------------------------------------*/
859 void xtaPassFldGET(fldSetNode *fN)
860 {
861         /* Field type is a class */
862         classSetNode *c;
863         classSetNode *c1 = NULL;
864         classSetNode *cp = NULL;
865         classSetNode *cprev= NULL;
866
867         fieldinfo *fi;
868         if (fN != NULL)
869                 fi = fN->fldRef;
870         else
871                 return;
872
873 /* Use lastptr  so don't check whole XTA class set each time */
874         cp = fN->lastptrGET;
875         if (cp != NULL) {
876                 if (cp->nextClass != NULL)
877                         c1 = cp -> nextClass;
878         } 
879         else    {
880                 if (fi->xta->XTAclassSet != NULL)
881                         c1  = fi->xta->XTAclassSet->head;
882
883                 if (XTAfld >=1 ) {
884                         printf("fld XTA class set =");fflush(stdout);
885                         printClassSet(fi->xta->XTAclassSet);
886                         printf("\t\tField class type = ");fflush(stdout);
887                         utf_display(fi->xta->fldClassType->name); printf("\n");
888                 }
889         }
890
891         /*--- GETSTATIC specific ---*/
892         /* Sm = union of Sm and Sx */
893         for (c=c1; c != NULL; c=c->nextClass) {
894                 bool addFlg = false;
895                 if (rt_method->xta->XTAclassSet ==NULL) 
896                         addFlg = true;
897                 else    {
898                         if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) )) 
899                                 addFlg = true;
900                         }
901                 if (addFlg) {
902                         rt_method->xta->XTAclassSet 
903                                 = add2ClassSet(rt_method->xta->XTAclassSet,c->classType);
904                 }
905                 cprev = c;
906         }
907
908         fN->lastptrGET = cprev;
909
910 }
911
912 /*-------------------------------------------------------------------------------*/
913 void xtaPassAllCalledByParams () {
914         methSetNode *SmCalled;
915         methSetNode *s1;
916         if (XTAdebug >= 1) {
917                 printf("xta->calledBy method set: "); fflush(stdout);
918                 
919                 if (rt_method->xta == NULL) panic ("rt_method->xta == NULL!!!!\n");
920                 printMethodSet(rt_method->xta->calledBy); fflush(stdout);
921                 }
922         if (rt_method->xta->calledBy == NULL)
923                 s1 = NULL;
924         else
925                 s1 = rt_method->xta->calledBy->head;
926         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
927                 if (XTAdebug >= 1) {
928                         printf("SmCalled = "); fflush(stdout);
929                         utf_display(SmCalled->methRef->class->name); fflush(stdout);
930                         printf(".");fflush(stdout); method_display(SmCalled->methRef);
931                 }
932                                 
933                 rt_method->xta->chgdSinceLastParse = false;             
934                 xtaPassParams(rt_method, SmCalled->methRef,SmCalled);   /* chg flag output ignored for 1st regular parse */
935         }
936 }
937
938 /*-------------------------------------------------------------------------------*/
939 void xtaAllFldsUsed ( ){
940         fldSetNode  *f;
941         fldSetNode *f1=NULL; 
942         /*      bool chgd = false */
943
944         if (rt_method->xta->fldsUsed == NULL) return;
945
946         /* for each field that this method uses */
947         f1 = rt_method->xta->fldsUsed->head;
948
949         for (f=f1; f != NULL; f = f->nextfldRef) {
950
951                 if (f->writePUT)
952                         xtaPassFldPUT(f);
953                 if (f->readGET)
954                         xtaPassFldGET(f);
955         }
956 }
957 /*-------------------------------------------------------------------------------*/
958 void  xtaMethodCalls_and_sendReturnType() 
959 {
960         methSetNode *SmCalled;  /* for return type       */
961         methSetNode *SmCalls;   /* for calls param types */
962         methSetNode *s1=NULL; 
963         bool chgd = false;
964         if (XTAdebug >= 1) {
965                 printf("calls method set Return type: ");
966                 printMethodSet(rt_method->xta->calls);
967         }
968         xtaAllFldsUsed ( );
969
970         /* for each method that this method calls */
971         if (rt_method->xta->calls == NULL)
972                 s1 = NULL;
973         else
974                 s1 = SmCalls=rt_method->xta->calls->head;
975
976         for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
977                 /*    pass param types  */
978                 bool chgd = false;
979                 chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls);  
980                 /* if true chgd after its own parse */
981                 if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
982                         SmCalls->methRef->xta->chgdSinceLastParse = true;
983                 }
984         }
985
986         /* for each calledBy method */
987         /*    send return type */
988         if (rt_method->xta->calledBy == NULL)
989                 s1 = NULL;
990         else
991                 s1 = rt_method->xta->calledBy->head;
992         for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
993
994                 if (XTAdebug >= 1) {
995                         printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name);
996                         printf("."); method_display(SmCalled->methRef);
997                 }
998                                 
999                 chgd = xtaPassReturnType(rt_method, SmCalled->methRef); 
1000                 if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
1001                         SmCalled->methRef->xta->chgdSinceLastParse = chgd;              
1002                 }
1003         }
1004 }
1005
1006
1007 /*-------------------------------------------------------------------------------*/
1008 static void parseRT()
1009 {
1010         int  p;                     /* java instruction counter                   */
1011         int  nextp;                 /* start of next java instruction             */
1012         int  opcode;                /* java opcode                                */
1013         int  i;                     /* temporary for different uses (counters)    */
1014         bool iswide = false;        /* true if last instruction was a wide        */
1015
1016         RTAPRINT01method
1017
1018                 if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
1019                                         printf("XTA parseRT():"); fflush(stdout);
1020                                         method_display(rt_method);
1021                         if (rt_method->xta == NULL)
1022                                 xtainfoInit (rt_method);
1023                         xtaPassAllCalledByParams ();
1024                                         printf("XTA parseRT() after xtaPassAll...\n");fflush(stdout);
1025    
1026                 }
1027
1028         /* scan all java instructions */
1029
1030         for (p = 0; p < rt_jcodelength; p = nextp) {
1031                 opcode = rt_code_get_u1 (p);           /* fetch op code                  */
1032                 RTAPRINT02opcode
1033                         fflush(stdout); 
1034                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
1035                 switch (opcode) {
1036
1037                         /*--------------------------------*/
1038                         /* Code just to get the correct  next instruction */
1039                         /* 21- 25 */
1040                 case JAVA_ILOAD:
1041                 case JAVA_LLOAD:
1042                 case JAVA_FLOAD:
1043                 case JAVA_DLOAD:
1044
1045                 case JAVA_ALOAD:
1046                         if (iswide)
1047                                 {
1048                                         nextp = p+3;
1049                                         iswide = false;
1050                                 }
1051                         break;
1052
1053                         /* 54 -58 */
1054                 case JAVA_ISTORE:
1055                 case JAVA_LSTORE:
1056                 case JAVA_FSTORE:
1057                 case JAVA_DSTORE:
1058
1059                 case JAVA_ASTORE:
1060                         if (iswide)
1061                                 {
1062                                         iswide=false;
1063                                         nextp = p+3;
1064                                 }
1065                         break;
1066
1067                         /* 132 */
1068                 case JAVA_IINC:
1069                         {
1070                                 if (iswide) {
1071                                         iswide = false;
1072                                         nextp = p+5;
1073                                 }
1074                         }
1075                         break;
1076
1077                         /* wider index for loading, storing and incrementing */
1078                         /* 196 */
1079                 case JAVA_WIDE:
1080                         iswide = true;
1081                         nextp = p + 1;
1082                         break;
1083                         /* 169 */
1084                 case JAVA_RET:
1085                         if (iswide) {
1086                                 nextp = p+3;
1087                                 iswide = false;
1088                         }
1089                         break;
1090
1091                         /* table jumps ********************************/
1092
1093                 case JAVA_LOOKUPSWITCH:
1094                         {
1095                                 s4 num;
1096                                 nextp = ALIGN((p + 1), 4);
1097                                 num = rt_code_get_u4(nextp + 4);
1098                                 nextp = nextp + 8 + 8 * num;
1099                                 break;
1100                         }
1101
1102
1103                 case JAVA_TABLESWITCH:
1104                         {
1105                                 s4 num;
1106                                 nextp = ALIGN ((p + 1),4);
1107                                 num = rt_code_get_s4(nextp + 4);
1108                                 num = rt_code_get_s4(nextp + 8) - num;
1109                                 nextp = nextp + 16 + 4 * num;
1110                                 break;
1111                         }
1112
1113                         /*-------------------------------*/
1114                 case JAVA_PUTSTATIC:
1115                         i = rt_code_get_u2(p + 1);
1116                         {
1117                                 constant_FMIref *fr;
1118                                 fieldinfo *fi;
1119
1120                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1121                                 /* descr has type of field ref'd  */
1122                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1123                                 RTAPRINT03putstatic1
1124
1125                                         /*--- RTA ---*/
1126                                 /* class with field - marked in addClassinit */
1127                                         addClassInit(fr->class);
1128
1129                                 /*--- XTA ---*/
1130                                 if   ((XTAOPTbypass) || (opt_xta))
1131                                         {
1132                                                 if (fi->xta == NULL)
1133                                                         fi->xta = xtafldinfoInit(fi);
1134                                                 if (xtaAddFldClassTypeInfo(fi)) {  
1135                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false);
1136                                                 }
1137                                         }
1138                         }
1139                         break;
1140
1141                 case JAVA_GETSTATIC:
1142                         i = rt_code_get_u2(p + 1);
1143                         {
1144                                 constant_FMIref *fr;
1145                                 fieldinfo *fi;
1146
1147                                 fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
1148                                 /* descr has type of field ref'd  */
1149                                 fi = class_findfield (fr->class,fr->name, fr->descriptor);
1150                                 RTAPRINT03putstatic1
1151
1152                                         /*--- RTA ---*/
1153                                 /* class with field - marked in addClassinit */
1154                                         addClassInit(fr->class);
1155
1156                                 /*--- XTA ---*/
1157                                 if  ((XTAOPTbypass) || (opt_xta) ) 
1158                                         {
1159                                                 if (fi->xta == NULL)
1160                                                         fi->xta = xtafldinfoInit(fi);
1161                                                 if (xtaAddFldClassTypeInfo(fi)) {
1162                                                         rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true);
1163                                                 }
1164                                         }
1165
1166                         }
1167                         break;
1168
1169
1170                         /*--------------------  method invocation ---------------------*/
1171
1172                 case JAVA_INVOKESTATIC:
1173                         i = rt_code_get_u2(p + 1);
1174                         {
1175                                 constant_FMIref *mr;
1176                                 methodinfo *mi;
1177
1178                                 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1179                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1180                                 /*-- RTA --*/
1181                                 RTAPRINT04invokestatic1
1182                                         if (mi->class->classUsed == NOTUSED) {
1183                                                 mi->class->classUsed = USED;
1184                                                 RTAPRINT05invokestatic2
1185                                                         }
1186                                 addClassInit(mi->class);
1187         
1188                                 ADDTOCALLGRAPH(mi)  
1189                                         fflush(stdout);
1190                                 /*-- XTA --*/
1191                                 if ((XTAOPTbypass) || (opt_xta)) {
1192                                         xtaAddCallEdges(mi,MONO); 
1193                                 } /* end XTA */
1194                         }
1195                         break;
1196
1197                 case JAVA_INVOKESPECIAL:
1198                         i = rt_code_get_u2(p + 1);
1199                         {
1200                                 constant_FMIref *mr;
1201                                 methodinfo *mi;
1202                                 classinfo  *ci;
1203                                 
1204                                 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1205                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1206                                 ci = mi->class;
1207                                 RTAPRINT06invoke_spec_virt1
1208                                         /*--- PRIVATE Method -----------------------------------------------------*/ 
1209                                         if (mi->name        != INIT) {     /* if method called is PRIVATE */ 
1210                                                 RTAPRINT07invoke_spec_virt2
1211                                                         RTAPRINT04invokestatic1
1212                                                         /*-- RTA --*/   /* was just markSubs(mi); */
1213                                                         ADDTOCALLGRAPH(mi)  
1214
1215                                                         /*--- XTA ---*/
1216                                                         if ((XTAOPTbypass) || (opt_xta)) {
1217                                                                 xtaAddCallEdges(mi,MONO);
1218                                                         } /* end XTA */
1219                                         }
1220
1221                                         else    {
1222                                                 /*--- Test for super <init> which is: <init> calling its super class <init> -*/
1223
1224                                                 /* new class so add marked methods */
1225                                                 if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED))  {
1226                                                         /*--- process NORMAL <init> method ---------------------------------------------*/
1227                                                         if ( mi->methodUsed != USED) {
1228                                                                 /* Normal <init> 
1229                                                                    - mark class as USED and <init> to callgraph */
1230                                 
1231                                                                 /*-- RTA --*/
1232                                                                 ci->classUsed = USED;
1233                                                                 addMarkedMethods(ci);    /* add to callgraph marked methods */
1234                                                                 RTAPRINT06Binvoke_spec_init
1235                                                                         addUsedInterfaceMethods(ci); 
1236                                                         ADDTOCALLGRAPH(mi)  
1237
1238                                                                         /*-- XTA --*/
1239                                                                         if ((XTAOPTbypass) || (opt_xta)) { 
1240                                                                                 rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); 
1241                                                                                 xtaAddCallEdges(mi,MONO);
1242                                                                                 RTAPRINT06CXTAinvoke_spec_init1
1243                                                                                         } /* end XTA */
1244                                                         }
1245                                                 }
1246                                         }
1247
1248                         }                                                
1249                         break;
1250
1251
1252                 case JAVA_INVOKEVIRTUAL:
1253                         i = rt_code_get_u2(p + 1);
1254                         {
1255                                 constant_FMIref *mr;
1256                                 methodinfo *mi;
1257                                 
1258                                 mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
1259                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1260
1261                                 /*--- RTA ---*/
1262                                 RTAPRINT07invoke_spec_virt2
1263                                         mi->monoPoly = POLY;
1264                                 rtaMarkSubs(mi->class,mi); 
1265
1266                                 /*--- XTA ---*/
1267                                 if ((XTAOPTbypass) || (opt_xta)) { 
1268                                         classSetNode *subtypesUsedSet = NULL;
1269                                         if (rt_method->xta->XTAclassSet != NULL)
1270                                                 subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head);
1271                                         /*****  
1272                                                         printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
1273                                                         printSet(subtypesUsedSet);
1274                                         *****/
1275                                         xtaMarkSubs(mi->class, mi, subtypesUsedSet);   
1276                                 } /* end XTA */
1277                         }
1278                         break;
1279
1280                 case JAVA_INVOKEINTERFACE:
1281                         i = rt_code_get_u2(p + 1);
1282                         {
1283                                 constant_FMIref *mr;
1284                                 methodinfo *mi;
1285                                 classSetNode *subs;
1286                                 classSetNode *subtypesUsedSet = NULL;
1287
1288                                 mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
1289                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
1290
1291                                 if (mi->flags & ACC_STATIC)
1292                                         panic ("Static/Nonstatic mismatch calling static method");
1293
1294                                 /*--- RTA ---*/
1295                                         RTAPRINT08AinvokeInterface0
1296                                 if (mi->class->classUsed == NOTUSED) {
1297                                         mi->class->classUsed = USED; /*??PARTUSED;*/
1298                                         class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
1299                                         }
1300
1301                                 /* add interface class to list kept in Object */
1302                                 mi->methodUsed = USED;
1303                                 mi->monoPoly   = POLY;
1304
1305                                 subs =  mi->class->impldBy; 
1306                                         RTAPRINT08invokeInterface1
1307                                 while (subs != NULL) { 
1308                                         classinfo * isubs = subs->classType;
1309                                                 RTAPRINT09invokeInterface2
1310                                         /* Mark method (mark/used) in classes that implement the method */
1311                                         if (isubs->classUsed != NOTUSED) {
1312                                                 methodinfo *submeth;
1313                                                 
1314                                                 submeth = class_findmethod(isubs,mi->name, mi->descriptor); 
1315                                                 if (submeth != NULL)
1316                                                         submeth->monoPoly = POLY; /*  poly even if nosubs */
1317                                                 rtaMarkSubs(isubs, mi);  
1318                                                 }
1319                                           /* XTA */
1320                                           if ((XTAOPTbypass) || (opt_xta))
1321                                                 {
1322                                                 if (rt_method->xta->XTAclassSet != NULL)
1323                                                         subtypesUsedSet =
1324                                                           intersectSubtypesWithSet
1325                                                              (subs->classType, rt_method->xta->XTAclassSet->head);
1326
1327                                                                                 printf(" \nXTA subtypesUsedSet: ");
1328                                                                                 fflush(stdout);
1329                                                                                 printSet(subtypesUsedSet);
1330                                                 xtaMarkSubs(subs->classType, mi, subtypesUsedSet);
1331                                                 }
1332
1333                                         subs = subs->nextClass;
1334                                         }
1335
1336                                 /*--- XTA ---*/
1337                                 if ((XTAOPTbypass2) || (opt_xta))
1338                                         {
1339                                         xtaMarkInterfaceSubs(mi);
1340                                         }
1341                         }
1342                         break;
1343
1344                         /* miscellaneous object operations *******/
1345
1346                 case JAVA_NEW:
1347                         i = rt_code_get_u2 (p+1);
1348                         {
1349                                 classinfo *ci;
1350
1351                                 ci = class_getconstant (rt_class, i, CONSTANT_Class); 
1352                                         if (pWhenMarked >= 1) {
1353                                                 printf("\tclass=");fflush(stdout);
1354                                                 utf_display(ci->name); fflush(stdout);
1355                                                 printf("=\n");fflush(stdout);
1356                                                 }
1357                                 /*--- RTA ---*/
1358                                 if (ci->classUsed != USED) {
1359                                         RTAPRINT10new
1360                                                 ci->classUsed = USED;    /* add to heirarchy    */
1361                                         /* Add this class to the implemented by list of the abstract interface */
1362                                         addUsedInterfaceMethods(ci);
1363                                         addClassInit(ci);
1364                                         } 
1365                                 /*--- XTA ---*/
1366                                 if ((XTAOPTbypass) || (opt_xta))
1367                                         {
1368                                         rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/
1369                                                 RTAPRINT10newXTA
1370                                         }
1371                         }
1372                         break;
1373
1374                 default:
1375                         break;
1376
1377                 } /* end switch */
1378
1379
1380         } /* end for */
1381
1382         if (p != rt_jcodelength)
1383                 panic("Command-sequence crosses code-boundary");
1384
1385         if ((XTAOPTbypass) || (opt_xta))
1386                 xtaMethodCalls_and_sendReturnType();
1387
1388
1389 }
1390
1391 /*-------------------------------------------------------------------------------*/
1392 /* RTA add Native Methods/ Class functions  */
1393 /*-------------------------------------------------------------------------------*/
1394 void   findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
1395
1396         classinfo  *class;
1397         methodinfo *meth;
1398
1399         class = class_get(c1);
1400         if (class == NULL)  {
1401                 return;    /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */
1402         }
1403
1404         if (class->classUsed == NOTUSED) {
1405                 class->classUsed = USED; /* MARK CLASS USED */
1406                 /* add marked methods to callgraph */ 
1407                 addMarkedMethods(class);
1408         }
1409
1410         meth = class_findmethod (class, m1, d1);
1411         if (meth == NULL) {
1412                 utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
1413                 printf("WARNING from parseRT:  Method given is used by Native method call, but NOT FOUND\n");
1414         }
1415         else
1416                 rtaMarkSubs(class,meth);
1417 }
1418
1419 /*-------------------------------------------------------------------------------*/
1420
1421 void   findMarkNativeUsedClass (utf * c) {
1422         classinfo  *class;
1423
1424         class = class_get(c);
1425         if (class == NULL)  panic("parseRT: Class used by Native method called not loaded!!!");
1426         class->classUsed = USED;
1427
1428         /* add marked methods to callgraph */
1429         addMarkedMethods(class);
1430 }
1431
1432
1433 /*-------------------------------------------------------------------------------*/
1434
1435 void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) {
1436         int i,j,k;
1437         bool found = false;
1438
1439         nativecallcompdone = natcall2utf(nativecallcompdone); 
1440
1441         for (i=0; i<NATIVECALLSSIZE; i++) {
1442                 if (rt_class  == nativeCompCalls[i].classname) {
1443         
1444                         /* find native class.method invoked */
1445                         for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
1446
1447                                 if ( (rt_method     == nativeCompCalls[i].methods[j].methodname)
1448                                          && (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
1449
1450                                         found=true;
1451
1452                                         /* mark methods and classes used by this native class.method */
1453                                         for (k=0; k < nativeCompCalls[i].callCnt[j]; k++) {
1454                                                 if (nativeCompCalls[i].methods[j].methodCalls[k].methodname != NULL) {
1455                                                         /* mark method used */
1456                                                         findMarkNativeUsedMeth(
1457                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].classname,
1458                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].methodname,
1459                                                                                                    nativeCompCalls[i].methods[j].methodCalls[k].descriptor); 
1460
1461                                                         /*RTprint 
1462                                                           printf("\nmark method used: "); fflush(stdout);
1463                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
1464                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
1465                                                           utf_display(nativeCompCalls[i].methods[j].methodCalls[k].descriptor); printf("==\n"); fflush(stdout);
1466                                                         */
1467                                                 }
1468                                                 else {
1469                                                         /* mark class used */
1470                                                         findMarkNativeUsedClass( nativeCompCalls[i].methods[j].methodCalls[k].classname);
1471                                                 } /* if-else k  */ 
1472
1473                                         }  /* for k */ 
1474
1475                                 }  /* if j */
1476                         }  /* for j */
1477
1478                 }  /* if i */  
1479         }  /* for i */
1480
1481 }
1482
1483
1484 /*-------------------------------------------------------------------------------*/
1485 /*-------------------------------------------------------------------------------*/
1486 void mainRTAparseInit (methodinfo *m )
1487 {
1488         /*printf("MAIN_NOT_STARTED \n");*/ 
1489         if (class_java_lang_Object->sub != NULL) { 
1490                 RTAPRINT16stats1;
1491         }
1492
1493         if (firstCall) {
1494                 firstCall=false;
1495
1496                 utf_MAIN  = utf_new_char("main");
1497                 INIT      = utf_new_char("<init>");
1498                 CLINIT    = utf_new_char("<clinit>");
1499                 FINALIZE  = utf_new_char("finalize");
1500                 EMPTY_DESC= utf_new_char("()V");
1501
1502                 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
1503                 printf("CACAO - rtMissed file: can't open file to write\n");
1504                 }
1505                 else {
1506                         fprintf(rtMissed,"To Help User create a dymLoad file \n");
1507                         fprintf(rtMissed,
1508                                         "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n");
1509                         fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n");
1510                         fflush(rtMissed);
1511                         fclose(rtMissed);
1512                 }
1513                 callgraph = MNEW (methodinfo*, MAXCALLGRAPH);   /****/
1514                 if ((XTAOPTbypass) || (opt_xta)) {
1515                         printf("XTAXTA  CALLGRAPHS allocated\n");
1516                         XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH);
1517                 }
1518         }
1519
1520         if (m->name == utf_MAIN) {
1521                 rtMissed = fopen("rtMissed","a");
1522                 fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
1523                 fclose(rtMissed);
1524                 AfterMain = true;
1525         }
1526         else {  
1527                 if ( (rtMissed = fopen("rtMissed", "a")) == NULL) {
1528                         printf("CACAO - rtMissed file: can't open file to write\n");
1529                 }
1530                 else {
1531                         fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ );
1532                         utf_fprint(rtMissed,m->class->name);
1533                         fprintf(rtMissed," ");
1534                         fprintflags(rtMissed,m->flags);
1535                         fprintf(rtMissed," ");
1536                         utf_fprint(rtMissed,m->name);
1537                         fprintf(rtMissed," ");
1538                         utf_fprint(rtMissed,m->descriptor);
1539                         fprintf(rtMissed,"\n");
1540                         fflush(rtMissed);
1541                         fclose(rtMissed);
1542                 }
1543                 if (AfterMain) {
1544                         printf("#%i : ",methRT);
1545                         printf("Method missed by static analysis Main parse. See rtMissed file");
1546                         /***    panic ("Method missed by static analysis Main parse. See rtMissed file");**/
1547                 }
1548         }
1549
1550         /* At moment start RTA before main when parsed                      */
1551         /* Will definitely use flag with to know if ok to apply in-lining.  */
1552 }
1553
1554
1555 /*-------------------------------------------------------------------------------*/
1556 /*-------------------------------------------------------------------------------*/
1557 /* still need to look at field sets in 2nd pass and clinit .....  */
1558 void XTA_jit_parse2(methodinfo *m)
1559 {
1560         if (XTAdebug >= 1) 
1561                 printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n");
1562
1563         /* for each method in XTA worklist = callgraph (use RTA for now) */
1564         methRT=0;
1565         while (methRT <= methRTlast) {
1566                 rt_method      = callgraph[methRT];
1567                 rt_class       = rt_method->class;
1568                 rt_descriptor  = rt_method->descriptor;
1569                 rt_jcodelength = rt_method->jcodelength;
1570                 rt_jcode       = rt_method->jcode;
1571
1572                 if (! (  (rt_method->flags & ACC_NATIVE  )
1573                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1574                         if (XTAdebug >= 1) {
1575                                 printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout);
1576                                 utf_display(rt_class->name); printf("."); fflush(stdout);
1577                                 method_display(rt_method);
1578                         }
1579                         /*   if XTA type set changed since last parse */
1580                         if (rt_method->xta->chgdSinceLastParse) {
1581
1582                                 /*     get types from methods it is calledBy */
1583                                 xtaPassAllCalledByParams ();
1584
1585                                 /* Pass parameter types to methods it calls and  send the return type those called by  */
1586                                 xtaMethodCalls_and_sendReturnType();
1587                         }
1588                 }
1589                 methRT++;
1590         }
1591         if (XTAdebug >= 1) {
1592
1593                 printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n");
1594                 printXTACallgraph ();
1595         }
1596         
1597         RTAPRINT14CallgraphLast  /*was >=2 */
1598                 RTAPRINT15HeirarchyiLast /*was >= 2 */
1599                 }
1600
1601
1602 /*-------------------------------------------------------------------------------*/
1603
1604 void RT_jit_parse(methodinfo *m)
1605 {
1606         /*-- RTA --*/
1607         if (m->methodUsed == USED) return;
1608         mainRTAparseInit (m);
1609                 
1610         /* initialise parameter type descriptor */
1611         callgraph[++methRTlast] = m;          /*-- RTA --*/
1612         m->methodUsed = USED;
1613         RTAPRINT11addedtoCallgraph 
1614                 /* <init> then like a new class so add marked methods to callgraph */
1615                 if (m->name == INIT)  {  /* need for <init>s parsed efore Main */
1616                         classinfo *ci;
1617                         ci = m->class;
1618                         ci->classUsed = USED;
1619                         if (pWhenMarked >= 1) {
1620                                 printf("Class=");utf_display(ci->name);
1621                         }
1622                         /* add marked methods to callgraph */
1623                         RTAPRINT11addedtoCallgraph2
1624                                 addMarkedMethods(ci);
1625                 } /* if */
1626
1627         /*-- XTA --*/
1628         if ((XTAOPTbypass) || (opt_xta)) {
1629                 XTAcallgraph[++methXTAlast] = m;
1630                 if (m->xta == NULL) {
1631                         m->xta = xtainfoInit(m);
1632                 }
1633                 m->xta->XTAmethodUsed = USED;
1634                 {methodinfo *mi = m;
1635                 XTAPRINTcallgraph2
1636                         }
1637         }
1638
1639         /*-- Call graph work list loop -----------------*/
1640
1641         while (methRT <= methRTlast) {
1642                 rt_method      = callgraph[methRT];
1643             rt_class       = rt_method->class;
1644             rt_descriptor  = rt_method->descriptor;
1645             rt_jcodelength = rt_method->jcodelength;
1646             rt_jcode       = rt_method->jcode;
1647
1648                 if (! (  (rt_method->flags & ACC_NATIVE  )
1649                                  ||   (rt_method->flags & ACC_ABSTRACT) ) ) {
1650                         parseRT();
1651                 }
1652             else {
1653                         RTAPRINT12bAbstractNative
1654                 if (rt_method->flags & ACC_NATIVE ) {
1655                                         RTAPRINT12aNative
1656                                                 /* mark used and add to callgraph methods and classes used by NATIVE method */
1657                                                 markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);                
1658                                 }
1659                         if (rt_method->flags & ACC_ABSTRACT) {
1660                                 panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n"); 
1661                         }
1662                 }
1663                 methRT++;
1664                 RTAPRINT12Callgraph 
1665                         RTAPRINT13Heirarchy 
1666                         } /* while */
1667
1668
1669         if (m->class->classUsed == NOTUSED)
1670                 m->class->classUsed = USED; /* say Main's class has a method used ??*/ 
1671         printXTACallgraph ();
1672         RTAPRINT14CallgraphLast  /*  was >=2*/
1673                 /***RTAPRINT15HeirarchyiLast **/ /*was >= 2 */
1674
1675         if (m->name == utf_MAIN) {
1676                                         /*RTAprint*/ if ((pCallgraph >= 1) && (opt_rt)) {
1677                                         /*RTAprint*/    printCallgraph (); }
1678
1679                                         /*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
1680                                         /*RTprint*/     printf("Last RTA Info -");
1681                                         /*RTprint*/     printRThierarchyInfo(m);
1682                                         /*RTprint*/     }
1683                                         /*RTprint*/     printObjectClassHeirarchy1( );
1684                                                 fflush(stdout);
1685
1686                 if ((XTAOPTbypass) || (opt_xta)) {
1687                         /*--- XTA round 2+ "parse" - use info structures only so not a real parse */
1688                         XTA_jit_parse2(m);
1689                 }
1690         MFREE(callgraph,methodinfo*,MAXCALLGRAPH);
1691         if ((XTAOPTbypass) || (opt_xta)) {
1692                 printf("XTAXTA  CALLGRAPHS returned \n");
1693                 MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH);
1694                 }
1695         }
1696
1697         return;
1698 }
1699
1700
1701 /*
1702  * These are local overrides for various environment variables in Emacs.
1703  * Please do not remove this and leave it at the end of the file, where
1704  * Emacs will automagically detect them.
1705  * ---------------------------------------------------------------------
1706  * Local variables:
1707  * mode: c
1708  * indent-tabs-mode: t
1709  * c-basic-offset: 4
1710  * tab-width: 4
1711  * End:
1712  */
1713