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