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