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