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