rta update to get rid of debug print
[cacao.git] / src / vm / jit / inline / parseRT.c
1 /* jit/parseRT.c - parser and print functions for Rapid Type Analyis
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Carolyn Oates
28
29    $Id: parseRT.c 1419 2004-10-21 09:59:33Z carolyn $
30
31 Changes:
32 opcode put into functions
33 changed class_findmethod class_fetchmethod
34
35 */
36
37 /***************
38
39  USAGE:
40  Methods called by NATIVE methods and classes loaded dynamically
41  cannot be found by parsing. The following files supply missing methods:
42
43  rtMissedIn0 - (provided) has the methods missed by every java program
44  rtMissed||mainClassName - is program specific.
45
46  A file rtMissed will be written by RT analysis of any methods missed.
47
48  This file can be renamed to rtMissed concatenated with the main class name.
49
50  Example:
51  ./cacao -rt hello
52
53  inlining with virtuals should fail if the returned rtMissed is not empty.
54  so...
55  mv rtMissed rtMissedhello
56  ./cacao hello
57
58 Results: (currently) with -stat see # methods marked used
59  
60 TODO: end analysis if mono- or polymorphic call (in parseRTstats)
61 ****************/
62
63 #include <stdio.h>
64 #include <string.h>
65 #include "tables.h"
66
67 #include "statistics.h"
68 #include "loader.h"
69 #include "main.h"
70 #include "options.h"
71 #include "jit/jit.h"
72 #include "jit/parse.h"
73 #include "toolbox/list.h"
74 #include "toolbox/memory.h"   
75 #include "parseRT.h"
76
77 static bool firstCall= true;
78 static list *rtaWorkList;
79 FILE *rtMissed;   /* Methods missed during RTA parse of Main  */
80  
81 #define LAZYLOADING(class) { \
82         if (!class_load(class)) \
83                 return 0; \
84         if (!class_link(class)) \
85                 return 0; }
86
87 bool DEBUGr = false;
88 bool DEBUGopcodes = false;
89
90 #define METHINFO(mm) \
91 if (DEBUGr == true) { \
92         printf("<c%i/m%i>\t",mm->class->classUsed,mm->methodUsed); \
93         utf_display(mm->class->name); printf("."); fflush(stdout); \
94         method_display(mm); fflush(stdout); }
95
96 #define METHINFOt(mm,TXT) \
97 if (DEBUGr == true) { \
98                 printf(TXT); \
99                 printf("<c%i/m%i>\t",mm->class->classUsed,mm->methodUsed); \
100                 utf_display(mm->class->name); printf("."); fflush(stdout); \
101                 method_display(mm); fflush(stdout); }
102
103 #define CLASSNAME1(cls,TXT) \
104 if (DEBUGr == true) {printf(TXT); \
105         printf("<c%i>\t",cls->classUsed); \
106         utf_display(cls->name); fflush(stdout);}
107
108 #define CLASSNAMEop(cls) \
109 if (DEBUGr == true) {printf("\t%s: ",opcode_names[opcode]);\
110         printf("<c%i>\t",cls->classUsed); \
111         utf_display(cls->name); printf("\n");fflush(stdout);}
112
113 #define CLASSNAME(cls,TXT) \
114 if (DEBUGr == true) { printf(TXT); \
115                 printf("<c%i>\t",cls->classUsed); \
116                 utf_display(cls->name); printf("\n");fflush(stdout);} 
117
118 #define SHOWOPCODE \
119 if (DEBUGopcodes == true) {printf("Parse p=%i<%i<   opcode=<%i> %s\n", \
120                            p, m->jcodelength,opcode,opcode_names[opcode]);}
121
122 /*********************************************************************/
123
124 void addToRtaWorkList(methodinfo *meth, char *info) {
125     rtaNode    *rta;
126
127 if (meth->methodUsed == USED) return;
128
129 if (!(meth->flags & ACC_ABSTRACT))  {
130     count_methods_marked_used++;
131     METHINFOt(meth,info)
132     meth ->methodUsed = USED;
133     rta = NEW(rtaNode);
134     rta->method = meth ;
135     list_addlast(rtaWorkList,rta);
136     }
137 /***
138 else {
139      printf("Method not added to work list!!!<%i> : ",
140      meth->methodUsed); fflush(stdout);
141      METHINFO(meth)
142      }
143 ***/
144 }
145
146 /**************************************************************************/
147 /* Add Marked methods for input class ci                                  */
148 /* Add methods with the same name and descriptor as implemented interfaces*/
149 /*   with the same method name                                            */
150 /*                                                                        */
151 /*------------------------------------------------------------------------*/
152 void rtaAddMarkedMethods(classinfo *ci) {
153 int ii,jj,mm;
154
155 /* add marked methods to callgraph */ 
156 for (ii=0; ii<ci->methodscount; ii++) { 
157         methodinfo *mi = &(ci->methods[ii]);
158
159         if (mi->methodUsed == MARKED) { 
160                 addToRtaWorkList(mi,
161                                 "addTo was MARKED:");
162                 }
163         else    {
164                 for (jj=0; jj < ci -> interfacescount; jj++) {
165                         classinfo *ici = ci -> interfaces [jj];
166                         /*  use resolve method....!!!! */
167                         if (ici -> classUsed != NOTUSED) {
168                                 for (mm=0; mm< ici->methodscount; mm++) {
169                                         methodinfo *imi = &(ici->methods[mm]);
170                                       /*if interface method=method is used*/
171                                         if  (      (imi->methodUsed == USED)
172                            &&    ( (imi->name == mi->name) 
173                            &&      (imi->descriptor == mi->descriptor))) {
174                                           addToRtaWorkList(mi,
175                                      "addTo was interfaced used/MARKED:");
176                                           }
177                                         } /*end for */  
178                                 }
179                         }
180                 }
181         }
182 }    
183
184
185 /*********************************************************************/
186 void addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark)
187 {
188   methodinfo *mi;
189
190   if (addmark)
191         ci->classUsed = USED;
192         
193   if (clinits) { /* No <clinit>  available - ignore */
194     mi = class_findmethod(ci, 
195                         utf_new_char("<clinit>"), 
196                         utf_new_char("()V"));
197     if (mi) { 
198         if (ci->classUsed != USED)
199             ci->classUsed = PARTUSED;
200         addToRtaWorkList(mi,"addTo CLINIT added:");
201       }     
202     }        
203
204   /*Special Case for System class init:
205     add java/lang/initializeSystemClass to callgraph */
206   if (ci->name == utf_new_char("initializeSystemClass")) {
207     /* ?? what is name of method ?? */ 
208     } 
209
210   if (finalizes) {
211     mi = class_findmethod(ci, 
212                         utf_new_char("finalize"), 
213                         utf_new_char("()V"));
214     if (mi) { 
215         if (ci->classUsed != USED)
216             ci->classUsed = PARTUSED;
217         addToRtaWorkList(mi,"addTo FINALIZE added:");
218       }     
219     }        
220
221   if (addmark) {
222     /* rtaAddMarkedMethods(ci); */
223     }
224
225 }
226
227
228 /*--------------------------------------------------------------*/
229 /* Mark the method with same name /descriptor in topmethod      */
230 /* in class                                                     */
231 /*                                                              */
232 /* Class marked USED and method defined in this class ->        */
233 /*    -> mark method as USED                                    */
234 /* Class not marked USED and method defined in this class ->    */
235 /*    -> if Method NOTUSED mark method as MARKED                */
236 /*                                                              */
237 /* Class USED, but method not defined in this class ->          */
238 /* -> 1) search up the heirarchy and mark method where defined  */
239 /*    2) if class where method is defined is not USED ->        */
240 /*       -> mark class with defined method as PARTUSED          */
241 /*--------------------------------------------------------------*/
242
243 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
244
245 utf *name       = topmethod->name; 
246 utf *descriptor = topmethod->descriptor;
247 methodinfo *submeth;
248
249 /* See if method defined in class heirarchy */
250 submeth = class_resolvemethod(class, name, descriptor); 
251 if (submeth == NULL)
252         panic("parse RT: Method not found in class hierarchy");
253 if (submeth->methodUsed == USED) return;
254   
255 #undef CTA 
256 #ifdef CTA
257   /* Class Type Analysis if class.method in virt cone marks it used */
258   /*   very inexact, too many extra methods */
259   addClassInit( submeth->class,
260                 true,true,true);
261   addToRtaWorkList(submeth,
262                    "addTo RTA VIRT CONE:");
263   return;
264 #endif
265
266   if (submeth->class == class) { 
267
268         /*--- Method defined in class -----------------------------*/
269         if (  submeth->class->classUsed == USED) { 
270                 /* method defined in this class -> */
271                 /* Class IS  marked USED           */ 
272                 /*    -> mark method as USED       */
273                 addToRtaWorkList(submeth,
274                         "addTo VIRT CONE 1:");
275                 }
276         else    {
277                 /* method defined in this class -> */
278                 /* Class IS NOT  marked USED (PART or NOTUSED) */ 
279                 /* -> if Method NOTUSED mark method as  MARKED */
280                 METHINFOt(submeth,
281                         "\tmarked VIRT CONE 2:");
282                 submeth->methodUsed = MARKED;
283                 /* Note: if class NOTUSED and subclass is used handled  */
284                 /*       by subsequent calls to rtaMarkMethods for cone */
285                 }
286         } /* end defined in class */
287
288   else {
289         /*--- Method NOT defined in class ---------------*/
290         /* first mark classes if needed */
291         if (submeth->class->classUsed == NOTUSED) {
292                 submeth->class->classUsed = PARTUSED;
293                 if (class->classUsed != USED) {
294                         submeth->methodUsed = MARKED;
295                         METHINFOt(submeth,"JUST MARKED :");
296                         }
297                 }
298         /* add method to rta work list if conditions met */
299         //if ( (submeth->class->classUsed == USED) ||
300         if (class->classUsed == USED) {
301                 addToRtaWorkList(submeth,
302                                 "addTo VIRT CONE 3:");
303                 }
304         } /* end NOT defined in class */
305
306
307
308 /*----------------------------------------------------------------------*/
309 /* Mark the method with the same name and descriptor as topmethod       */
310 /*   and any subclass where the method is defined and/or class is used  */
311 /*                                                                      */
312 /*----------------------------------------------------------------------*/
313 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
314
315   /* Mark method in class  */
316   CLASSNAME1(class," MARKSUBS ");
317   METHINFOt(topmethod," TOP ");
318   rtaMarkMethod(class, topmethod);  
319
320   /* Mark method in subclasses */
321   if (class->sub != NULL) {
322      classinfo *subs;
323         
324      if (!(topmethod->flags & ACC_FINAL )) {
325         for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
326           CLASSNAME1(subs," SUBS ");
327           rtaMarkSubs(subs, topmethod); 
328           }
329         }
330      }
331   return;
332 }
333
334
335 /*********************************************************************/
336
337 void rtaMarkInterfaceSubs(methodinfo *mi) {                             
338         classSetNode *subs;
339         if (mi->class->classUsed == NOTUSED) {
340                 mi->class->classUsed = USED; 
341                 class_java_lang_Object->impldBy =  addElement(class_java_lang_Object -> impldBy,  mi->class);
342                 }
343
344         /* add interface class to list kept in Object */
345         mi->methodUsed = USED;
346         mi->monoPoly   = POLY;
347
348         subs =  mi->class->impldBy; 
349             /*RTAPRINT08invokeInterface1*/
350         while (subs != NULL) {                  
351                 classinfo * isubs = subs->classType;
352            /*RTAPRINT09invokeInterface2*/
353                 /* Mark method (mark/used) in classes that implement the method */
354                 if (isubs->classUsed != NOTUSED) {
355                         methodinfo *submeth;
356                                                 
357                         submeth = class_findmethod(isubs,mi->name, mi->descriptor); 
358                         if (submeth != NULL)
359                                 submeth->monoPoly = POLY; /*  poly even if nosubs */
360                         rtaMarkSubs(isubs, mi);  
361                         }
362                                 
363                 subs = subs->nextClass;
364                 } /* end while */
365
366
367
368 /*********************************************************************/
369
370 int parseRT(methodinfo *m)
371 {
372         int  p;                     /* java instruction counter */ 
373         int  nextp;                 /* start of next java instruction */
374         int  opcode;                /* java opcode */
375         int  i;                     /* temp for different uses (counters)*/
376         bool iswide = false;        /* true if last instruction was a wide*/
377         int rc = 1;
378
379 METHINFOt(m,"\n----RT PARSING:"); 
380 if (DEBUGr) printf("\n");
381
382 /* scan all java instructions */
383         for (p = 0; p < m->jcodelength; p = nextp) {
384
385                 opcode = code_get_u1(p,m);            /* fetch op code  */
386                 SHOWOPCODE
387
388                 nextp = p + jcommandsize[opcode];   /* compute next instrtart */
389                 if (nextp > m->jcodelength)
390                         panic("Unexpected end of bytecode");
391
392                 switch (opcode) {
393
394                 case JAVA_ILOAD:
395                 case JAVA_LLOAD:
396                 case JAVA_FLOAD:
397                 case JAVA_DLOAD:
398                 case JAVA_ALOAD:
399
400                 case JAVA_ISTORE:
401                 case JAVA_LSTORE:
402                 case JAVA_FSTORE:
403                 case JAVA_DSTORE:
404                 case JAVA_ASTORE:
405
406                         if (iswide) {
407                                 nextp = p + 3;
408                                 iswide = false;
409                         }
410                         break;
411
412                 case JAVA_IINC: 
413                         {
414                                 
415                                 if (iswide) {
416                                         iswide = false;
417                                         nextp = p + 5;
418                                 }
419                         }
420                         break;
421
422                         /* wider index for loading, storing and incrementing */
423
424                 case JAVA_WIDE:
425                         iswide = true;
426                         nextp = p + 1;
427                         break;
428
429                 case JAVA_RET:
430                         if (iswide) {
431                                 nextp = p + 3;
432                                 iswide = false;
433                         }
434                         break;
435
436                 case JAVA_LOOKUPSWITCH:
437                         {
438                         s4 num;
439                         nextp = ALIGN((p + 1), 4) + 4;
440                         num = code_get_u4(nextp,m);
441                         nextp += (code_get_u4(nextp,m)) * 8 + 4;
442                         break;
443                         }
444
445
446                 case JAVA_TABLESWITCH:
447                        {
448                                 s4 num;
449                                 nextp = ALIGN ((p + 1),4);
450                                 num = code_get_s4(nextp + 4, m);
451                                 num = code_get_s4(nextp + 8, m) - num;
452                                 nextp = nextp + 16 + 4 * num;
453                                 break;
454                         }
455  /*********************/
456                 case JAVA_PUTSTATIC:
457                 case JAVA_GETSTATIC:
458
459                         i = code_get_u2(p + 1,m);
460                         {
461                                 constant_FMIref *fr;
462                                 fieldinfo *fi;
463
464                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
465                                 LAZYLOADING(fr->class)
466
467                                 fi = class_resolvefield(fr->class,
468                                                         fr->name,
469                                                         fr->descriptor,
470                                                         m->class,
471                                                         true);
472
473                                 if (!fi)
474                                         return 0; // was NULL
475
476                                 CLASSNAME(fi->class,"\tPUTSTATIC: ");
477                                 if (!fi->class->initialized) {
478                                         m->isleafmethod = false;
479                                         }       
480                                 addClassInit(   fi->class,
481                                                 true,true,false);
482                         }
483                         break;
484
485                 case JAVA_INVOKESTATIC:
486                 case JAVA_INVOKESPECIAL:
487                         i = code_get_u2(p + 1,m);
488                         {
489                                 constant_FMIref *mr;
490                                 methodinfo *mi;
491
492                                 m->isleafmethod = false;
493                                 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
494                                 LAZYLOADING(mr->class) 
495                                 mi = class_resolveclassmethod(mr->class,
496                                                 mr->name,
497                                                 mr->descriptor,
498                                                 m->class,
499                                                 false);
500
501
502                                 if (mi) 
503                                    {
504                                    if ((opcode == JAVA_INVOKESTATIC)       
505                                      || (mi->flags & ACC_STATIC)  
506                                      || (mi->flags & ACC_PRIVATE)  
507                                      || (mi->flags & ACC_FINAL) )  
508                                      {
509                                      if (mi->class->classUsed == NOTUSED){
510                                         addClassInit(   mi->class,
511                                                         true,true,false);
512                                         }
513                                      if (opcode == JAVA_INVOKESTATIC)      
514                                        addToRtaWorkList(mi,
515                                                      "addTo INVOKESTATIC ");
516                                      else
517                                        addToRtaWorkList(mi,
518                                                     "addTo INVOKESPECIAL ");
519                                      } 
520                                    else {
521                                      /* Handle special <init> calls */
522                                      /* RTA special case:
523                                       call of super's <init> then
524                                       methods of super class not all used */
525                                         
526                                      /* for now same as rest */
527                                      if (mi->class->classUsed == NOTUSED){
528                                        if (utf_new_char("<init>")==mi->name)
529                                           addClassInit( mi->class,
530                                                         true,true,true);
531                                        if (utf_new_char("<clinit>")==mi->name)
532                                           addClassInit( mi->class,
533                                                         true,true,false);
534                                        if (!((utf_new_char("<init>")==mi->name))
535                                        ||   (utf_new_char("<clinit>")==mi->name))
536                                           METHINFOt(mi,"SPECIAL not init:")
537                                           addClassInit( mi->class,
538                                                         true,true,true);
539                                            
540                                        }
541
542                                      addToRtaWorkList(mi,
543                                                     "addTo INVOKESPECIALi ");
544                                      }
545                                    } 
546 /***  assume if method can't be resolved won't actually be called or
547       there is a real error in classpath and in normal parse an exception
548       will be thrown. Following debug print can verify this
549 else  from if (mi) {
550 CLASSNAME1(mr->class,"CouldNOT Resolve method:");printf(".");fflush(stdout);
551 utf_display(mr->name); printf(" "); fflush(stdout);
552 utf_display(mr->descriptor); printf("\n");fflush(stdout);
553 ***/
554                         }
555                         break;
556
557                 case JAVA_INVOKEVIRTUAL:
558                         i = code_get_u2(p + 1,m);
559                         {
560                                 constant_FMIref *mr;
561                                 methodinfo *mi;
562
563                                 m->isleafmethod = false;
564                                 mr = m->class->cpinfos[i];
565                                 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
566                                 LAZYLOADING(mr->class) 
567                                 mi = class_resolveclassmethod(mr->class,
568                                                 mr->name,
569                                                 mr->descriptor,
570                                                 m->class,
571                                                 false);
572
573
574                                 if (mi) 
575                                    {
576                                    METHINFOt(mi,"INVOKEVIRTUAL ::");
577                                    if ((mi->flags & ACC_STATIC) 
578                                    ||  (mi->flags & ACC_PRIVATE)  
579                                    ||  (mi->flags & ACC_FINAL) )  
580                                      {
581                                      if (mi->class->classUsed == NOTUSED){
582                                        addClassInit(mi->class,
583                                                     true,true,true);
584                                        }
585                                       addToRtaWorkList(mi,
586                                                     "addTo INVOKEVIRTUAL ");
587                                       } 
588                                    else {
589                                      mi->monoPoly = POLY;
590                                      rtaMarkSubs(mi->class,mi);
591                                      }
592                                    } 
593                                 else {
594 CLASSNAME1(mr->class,"CouldNOT Resolve virt meth:");printf(".");fflush(stdout);
595 utf_display(mr->name); printf(" "); fflush(stdout);
596 utf_display(mr->descriptor); printf("\n");fflush(stdout);
597                                    }
598                                 }
599                                 break;
600
601                 case JAVA_INVOKEINTERFACE:
602                         i = code_get_u2(p + 1,m);
603                         {
604                                 constant_FMIref *mr;
605                                 methodinfo *mi;
606
607                                 m->isleafmethod = false;
608
609                                 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
610                                 LAZYLOADING(mr->class)
611
612                                 mi = class_resolveinterfacemethod(mr->class,
613                                                           mr->name,
614                                                           mr->descriptor,
615                                                           m->class,
616                                                           false);
617                                         if (mi)
618                                            {
619                                            METHINFOt(mi,"\tINVOKEINTERFACE: ")
620                                            rtaMarkInterfaceSubs(mi);
621                                            }
622                                 /* see INVOKESTATIC for explanation about */
623                                 /*   case when Interface is not resolved  */
624                                 //descriptor2types(mi); ?? do need paramcnt?
625                         }
626                         break;
627
628                 case JAVA_NEW:
629                 /* means class is at least passed as a parameter */
630                 /* class is really instantiated when class.<init> called*/
631                         i = code_get_u2(p + 1,m);
632                         {
633                         classinfo *ci;
634                         ci = class_getconstant(m->class, i, CONSTANT_Class);
635                         m->isleafmethod = false; /* why for new ? */
636                         // s_count++; look for s_counts for VTA
637                         //ci->classUsed=USED;
638                         /* add marked methods */
639                         CLASSNAME(ci,"NEW : do nothing");
640                         }
641                         break;
642
643                 case JAVA_CHECKCAST:
644                 case JAVA_INSTANCEOF:
645                 /* class used */
646                         i = code_get_u2(p + 1,m);
647                         {
648                         classinfo *cls =
649                                 (classinfo *)
650                              class_getconstant(m->class, i, CONSTANT_Class);
651                         LAZYLOADING(cls)
652                         CLASSNAMEop(cls);
653                         }
654                         break;
655
656                 default:
657                         break;
658                                 
659                 } /* end switch */
660
661                 } /* end for */
662
663         return rc;
664 }
665
666 /* Helper fn for initialize **********************************************/
667
668 int getline(char *line, int max, FILE *inFP) {
669 if (fgets(line, max, inFP) == NULL) 
670   return 0;
671 else
672   return strlen((const char *) line);
673 }
674
675 /* Initialize RTA Work list ***********************************************/
676
677 /*-- Get meth ptr for class.meth desc and add to RTA worklist --*/
678 #define SYSADD(cls,meth,desc,txt) \
679         c = class_new(utf_new_char(cls)); \
680         LAZYLOADING(c) \
681         callmeth = class_resolveclassmethod(c, \
682               utf_new_char(meth), \
683               utf_new_char(desc), \
684               c, \
685               false); \
686         if (callmeth->class->classUsed != USED) {  \
687               addClassInit(callmeth->class, \
688                            true,true,true);\
689               } \
690         addToRtaWorkList(callmeth,txt);
691
692
693 /*--  
694     Initialize RTA work list with methods/classes from:  
695       System calls 
696         and 
697       rtMissedIn list (missed becaused called from NATIVE &/or dynamic calls
698 --*/
699 int initializeRTAworklist(methodinfo *m) {
700         classinfo  *c;
701         methodinfo* callmeth;
702         char systxt[]    = "System     Call :";
703         char missedtxt[] = "rtMissedIn Call :";
704
705         FILE *rtMissedIn; /* Methods missed during previous RTA parse */
706         char line[256];
707         char* class, *meth, *desc;
708         char filename[256] = "rtMissed";
709
710         /* Create RTA call work list */
711         rtaWorkList = NEW(list);
712         list_init(rtaWorkList, OFFSET(rtaNode,linkage) );
713
714         /* Add first method to call list */
715         m->class->classUsed = USED; 
716         addToRtaWorkList(m,systxt);
717
718         /* Add system called methods */
719         SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt)
720         SYSADD("java/lang/Runtime","getRuntime","()Ljava/lang/Runtime;",systxt)
721         SYSADD("java/lang/Runtime","exit","(I)V",systxt)
722
723         /*----- rtMissedIn 0 */
724         if ( (rtMissedIn = fopen("rtMissedIn0", "r")) == NULL) {
725                 //if (verbose) 
726                     {printf("No rtMissedIn0 file\n");fflush(stdout);} 
727                 return 0;
728                 }
729         while (getline(line,256,rtMissedIn)) {
730             class = strtok(line, " \n");
731             meth  = strtok(NULL, " \n");
732             desc  = strtok(NULL, " \n");
733                 SYSADD(class,meth,desc,missedtxt)
734                 }
735         fclose(rtMissedIn);
736
737         /*----- rtMissedIn pgm specific */
738         strcat(filename, (const char *)mainstring);  
739         if ( (rtMissedIn = fopen(filename, "r")) == NULL) {
740                 //if (verbose) 
741                     {printf("No rtMissedIn=%s file\n",filename);fflush(stdout);} 
742                 return 0;
743                 }
744         while (getline(line,256,rtMissedIn)) {
745             class = strtok(line, " \n");
746             meth  = strtok(NULL, " \n");
747             desc  = strtok(NULL, " \n");
748                 SYSADD(class,meth,desc,missedtxt)
749                 }
750         fclose(rtMissedIn);
751         return 0;
752 }
753 /*- end initializeRTAworklist-------- */
754
755
756
757 /*-- RTA -- *******************************************************/
758 int RT_jit_parse(methodinfo *m)
759 {
760   methodinfo *rt_method;
761   rtaNode    *rta;
762
763   /* Should only be called once */
764   if (firstCall) {
765         firstCall = false; /* turn flag off */
766
767         /*----- RTA initializations --------*/
768         if (verbose) 
769             log_text("RTA static analysis started.\n");
770
771         initializeRTAworklist(m);
772
773     if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
774         printf("CACAO - rtMissed file: cant open file to write\n");
775         }
776     /* Note: rtMissed must be renamed to rtMissedIn to be used as input */
777         
778     /*------ process RTA call work list --------*/
779     for (rta =list_first(rtaWorkList); 
780          rta != NULL; 
781          rta =list_next(rtaWorkList,rta)) 
782         { 
783         rt_method = rta->method;
784         if (! (  (rt_method->flags & ACC_NATIVE  )
785             ||   (rt_method->flags & ACC_ABSTRACT) ) )  
786             {
787             /* RTA parse to approxmate....
788                 what classes/methods will really be used during execution */
789             parseRT(rt_method);  
790             }
791         else {
792             if (rt_method->flags & ACC_NATIVE  )
793                 {
794                 METHINFOt(rt_method,"TO BE NATIVE RTA PARSED :")
795                 /* parseRTpseudo(rt_method); */
796                 }   
797             else {
798                printf("Abstract method in RTA Work List: ");
799                METHINFO(rt_method);
800                panic("Abstract method in RTA Work List.");
801                }
802             }                   
803         }       
804     fclose(rtMissed);
805     if (verbose) {
806       log_text("RTA static analysis done.\n");
807       }
808   }
809 return 0;
810 }
811
812 /*
813  * These are local overrides for various environment variables in Emacs.
814  * Please do not remove this and leave it at the end of the file, where
815  * Emacs will automagically detect them.
816  * ---------------------------------------------------------------------
817  * Local variables:
818  * mode: c
819  * indent-tabs-mode: t
820  * c-basic-offset: 4
821  * tab-width: 4
822  * End:
823  */