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