1 /* src/vm/jit/inline/parseRT.c - parser and print functions for Rapid Type
4 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
5 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
6 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
7 J. Wenninger, Institut f. Computersprachen - TU Wien
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 Contact: cacao@cacaojvm.org
28 Authors: Carolyn Oates
30 Changes: Christian Thalinger
32 $Id: parseRT.c 4357 2006-01-22 23:33:38Z twisti $
37 Rapid Type Static Analysis of Java program
38 used -rt option is turned on either explicitly
39 or automatically with inlining of virtuals.
42 Methods called by NATIVE methods and classes loaded dynamically
43 cannot be found by parsing. The following files supply missing methods:
45 rtMissedIn0 - (provided) has the methods missed by every java program
46 rtMissed||mainClassName - is program specific.
48 A file rtMissed will be written by RT analysis of any methods missed.
50 This file can be renamed to rtMissed concatenated with the main class name.
55 inlining with virtuals should fail if the returned rtMissed is not empty.
57 mv rtMissed rtMissedhello
60 Results: (currently) with -stat see # methods marked used
70 #include "cacao/cacao.h"
71 #include "mm/memory.h"
72 #include "toolbox/list.h"
73 #include "toolbox/logging.h"
75 #include "vm/linker.h"
76 #include "vm/loader.h"
77 #include "vm/resolve.h"
78 #include "vm/options.h"
79 #include "vm/statistics.h"
80 #include "vm/jit/jit.h"
81 #include "vm/jit/parse.h"
82 #include "vm/jit/inline/parseRT.h"
83 #include "vm/jit/inline/parseRTstats.h"
84 #include "vm/jit/inline/parseRTprint.h"
88 static bool firstCall= true;
89 static list *rtaWorkList;
90 FILE *rtMissed; /* Methods missed during RTA parse of Main */
92 bool RTA_DEBUGinf = false;
93 bool RTA_DEBUGr = false;
94 bool RTA_DEBUGopcodes = false;
98 /*********************************************************************/
100 void addToRtaWorkList(methodinfo *meth, char *info) {
103 if (meth->methodUsed == USED) return;
105 if (!(meth->flags & ACC_ABSTRACT)) {
106 #if defined(ENABLE_STATISTICS)
107 count_methods_marked_used++;
109 METHINFOt(meth,info,RTA_DEBUGopcodes)
110 if (meth->class->super.cls != NULL) {
111 CLASSNAME(meth->class->super.cls,"\tsuper=",RTA_DEBUGr)
114 if (RTA_DEBUGr) printf("\tsuper=NULL\n");}
116 meth ->methodUsed = USED;
119 list_addlast(rtaWorkList,rta);
120 if (meth->class->classUsed == NOTUSED) {
122 printf("\nADDED method in class not used at all!\n");
128 printf("Method not added to work list!!!<%i> : ",
129 meth->methodUsed); fflush(stdout);
135 /**************************************************************************/
136 void rtaMarkSubs(classinfo *class, methodinfo *topmethod);
138 /*------------------------------------------------------------------------*/
139 void rtaAddUsedInterfaceMethods(classinfo *ci) {
142 /* add used interfaces methods to callgraph */
143 for (jj=0; jj < ci -> interfacescount; jj++) {
144 classinfo *ici = ci -> interfaces [jj].cls;
147 printf("BInterface used: ");fflush(stdout);
148 utf_display(ici->name);
149 printf("<%i>\t",ici -> classUsed ); fflush(stdout);
150 if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
151 if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
152 if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
155 /* add class to interfaces list of classes that implement it */
156 ici -> impldBy = addElement(ici -> impldBy, ci);
158 /* if interface class is used */
159 if (ici -> classUsed != NOTUSED) {
161 /* for each interface method implementation that has already been used */
162 for (mm=0; mm< ici->methodscount; mm++) {
163 methodinfo *imi = &(ici->methods[mm]);
165 if (imi->methodUsed != USED) {
166 if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
167 if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
168 utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
171 if (imi->methodUsed == USED) {
173 printf("Interface Method used: "); utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
175 /* Mark this method used in the (used) implementing class and its subclasses */
176 printf("rMAY ADD methods that was used by an interface\n");
178 if ((utf_clinit != imi->name) &&
179 (utf_init != imi->name))
189 /**************************************************************************/
190 /* Add Marked methods for input class ci */
191 /* Add methods with the same name and descriptor as implemented interfaces*/
192 /* with the same method name */
194 /*------------------------------------------------------------------------*/
195 void rtaAddMarkedMethods(classinfo *ci) {
198 /* add marked methods to callgraph */
199 for (ii=0; ii<ci->methodscount; ii++) {
200 methodinfo *mi = &(ci->methods[ii]);
202 if (mi->methodUsed == MARKED) {
204 "addTo was MARKED:");
206 else { /*** ??? Should this be an else or ??? */
207 for (jj=0; jj < ci -> interfacescount; jj++) {
208 classinfo *ici = ci -> interfaces [jj].cls;
209 /* use resolve method....!!!! */
210 if (ici -> classUsed != NOTUSED) {
211 for (mm=0; mm< ici->methodscount; mm++) {
212 methodinfo *imi = &(ici->methods[mm]);
213 METHINFOt(imi,"NEW IMPD INTERFACE:",RTA_DEBUGinf)
214 /*if interface method=method is used*/
215 if ( (imi->methodUsed == USED)
216 && ( (imi->name == mi->name)
217 && (imi->descriptor == mi->descriptor))) {
219 "addTo was interfaced used/MARKED:");
228 #define CLINITS_T true
229 #define FINALIZE_T true
230 #define ADDMARKED_T true
232 #define CLINITS_F false
233 #define FINALIZE_F false
234 #define ADDMARKED_F false
235 /*********************************************************************/
236 void RTAaddClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark)
241 ci->classUsed = USED;
243 if (clinits) { /* No <clinit> available - ignore */
244 mi = class_findmethod(ci,
248 if (ci->classUsed != USED)
249 ci->classUsed = PARTUSED;
251 addToRtaWorkList(mi,"addTo CLINIT added:");
255 /*Special Case for System class init:
256 add java/lang/initializeSystemClass to callgraph */
257 if (ci->name == utf_new_char("initializeSystemClass")) {
258 /* ?? what is name of method ?? */
262 mi = class_findmethod(ci,
263 utf_new_char("finalize"),
266 if (ci->classUsed != USED)
267 ci->classUsed = PARTUSED;
269 addToRtaWorkList(mi,"addTo FINALIZE added:");
274 rtaAddMarkedMethods(ci);
276 rtaAddUsedInterfaceMethods(ci);
281 /*--------------------------------------------------------------*/
282 /* Mark the method with same name /descriptor in topmethod */
285 /* Class marked USED and method defined in this class -> */
286 /* -> mark method as USED */
287 /* Class not marked USED and method defined in this class -> */
288 /* -> if Method NOTUSED mark method as MARKED */
290 /* Class USED, but method not defined in this class -> */
291 /* -> 1) search up the heirarchy and mark method where defined */
292 /* 2) if class where method is defined is not USED -> */
293 /* -> mark class with defined method as PARTUSED */
294 /*--------------------------------------------------------------*/
296 void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
298 utf *name = topmethod->name;
299 utf *descriptor = topmethod->descriptor;
302 /* See if method defined in class heirarchy */
303 submeth = class_resolvemethod(class, name, descriptor);
304 METHINFOt(submeth,"rtaMarkMethod submeth:",RTA_DEBUGr);
305 if (submeth == NULL) {
306 utf_display(class->name); printf(".");
307 METHINFOx(topmethod);
308 printf("parse RT: Method not found in class hierarchy");fflush(stdout);
311 if (submeth->methodUsed == USED) return;
315 /* Class Type Analysis if class.method in virt cone marks it used */
316 /* very inexact, too many extra methods */
317 RTAaddClassInit( submeth->class,
318 CLINITS_T,FINALIZE_T,ADDMARKED_T);
319 submeth->monoPoly = POLY;
320 addToRtaWorkList(submeth,
321 "addTo RTA VIRT CONE:");
325 if (submeth->class == class) {
327 /*--- Method defined in class -----------------------------*/
328 if ( submeth->class->classUsed == USED) {
329 /* method defined in this class -> */
330 /* Class IS marked USED */
331 /* -> mark method as USED */
332 submeth->monoPoly = POLY;
333 addToRtaWorkList(submeth,
334 "addTo VIRT CONE 1:");
337 /* method defined in this class -> */
338 /* Class IS NOT marked USED (PART or NOTUSED) */
339 /* -> if Method NOTUSED mark method as MARKED */
341 "\tmarked VIRT CONE 2:",RTA_DEBUGr);
342 submeth->monoPoly = POLY;
343 submeth->methodUsed = MARKED;
344 /* Note: if class NOTUSED and subclass is used handled */
345 /* by subsequent calls to rtaMarkMethods for cone */
347 } /* end defined in class */
350 /*--- Method NOT defined in class ---------------*/
351 /* then check class the method could be called with */
353 /* first mark classes if needed */
354 if (submeth->class->classUsed == NOTUSED) {
355 submeth->class->classUsed = PARTUSED;
356 if (class->classUsed != USED) {
357 submeth->monoPoly = POLY;
358 submeth->methodUsed = MARKED;
359 METHINFOt(submeth,"JUST MARKED :",RTA_DEBUGr);
362 /* add method to rta work list if conditions met */
363 /*??if ( (submeth->class->classUsed == USED) || */
364 if (class->classUsed == USED) {
365 submeth->monoPoly = POLY;
366 addToRtaWorkList(submeth,
367 "addTo VIRT CONE 3:");
369 } /* end NOT defined in class */
373 /*----------------------------------------------------------------------*/
374 /* Mark the method with the same name and descriptor as topmethod */
375 /* and any subclass where the method is defined and/or class is used */
377 /*----------------------------------------------------------------------*/
378 void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
380 /* Mark method in class */
381 CLASSNAME1(class," MARKSUBS ",RTA_DEBUGr);
382 METHINFOt(topmethod," TOP ",RTA_DEBUGr);
383 rtaMarkMethod(class, topmethod);
385 /* Mark method in subclasses */
386 if (class->sub != NULL) {
389 if (!(topmethod->flags & ACC_FINAL )) {
390 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
391 CLASSNAME1(subs," SUBS ",RTA_DEBUGr);
392 rtaMarkSubs(subs, topmethod);
400 /*********************************************************************/
402 void rtaMarkInterfaceSubs(methodinfo *mi) {
404 if (mi->class->classUsed == NOTUSED) {
405 mi->class->classUsed = USED;
406 class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
409 /* add interface class to list kept in Object */
410 mi->methodUsed = USED;
413 subs = mi->class->impldBy;
414 /*RTAPRINT08invokeInterface1*/
416 METHINFO(mi,RTA_DEBUGinf)
417 printf("Implemented By classes :\n");fflush(stdout);
418 if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n");
421 while (subs != NULL) {
422 classinfo * isubs = subs->classType;
425 printf("\t");utf_display(isubs->name);fflush(stdout);
426 printf(" <%i>\n",isubs->classUsed);fflush(stdout);
428 /*Mark method (mark/used) in classes that implement method*/
430 submeth = class_findmethod(isubs,mi->name, mi->descriptor);
432 submeth->monoPoly = POLY; /* poly even if nosubs */
433 rtaMarkSubs(isubs, mi);
435 subs = subs->nextClass;
439 /*********************************************************************/
441 int parseRT(methodinfo *m)
443 int p; /* java instruction counter */
444 int nextp; /* start of next java instruction */
445 int opcode; /* java opcode */
446 int i; /* temp for different uses (counters)*/
447 bool iswide = false; /* true if last instruction was a wide*/
450 METHINFOt(m,"\n----RT PARSING:",RTA_DEBUGopcodes);
451 if ((RTA_DEBUGr)||(RTA_DEBUGopcodes)) printf("\n");
453 /* scan all java instructions */
454 for (p = 0; p < m->jcodelength; p = nextp) {
456 opcode = code_get_u1(p,m); /* fetch op code */
457 SHOWOPCODE(RTA_DEBUGopcodes)
459 nextp = p + jcommandsize[opcode]; /* compute next instrtart */
460 if (nextp > m->jcodelength) {
461 log_text("Unexpected end of bytecode");
495 /* wider index for loading, storing and incrementing */
509 case JAVA_LOOKUPSWITCH:
512 nextp = ALIGN((p + 1), 4) + 4;
513 num = code_get_u4(nextp,m);
514 nextp += (code_get_u4(nextp,m)) * 8 + 4;
519 case JAVA_TABLESWITCH:
522 nextp = ALIGN ((p + 1),4);
523 num = code_get_s4(nextp + 4, m);
524 num = code_get_s4(nextp + 8, m) - num;
525 nextp = nextp + 16 + 4 * num;
528 /*********************/
532 i = code_get_u2(p + 1,m);
538 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
541 if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
542 log_text("Could not resolve class reference");
546 LAZYLOADING(frclass);
548 fi = class_resolvefield(frclass,
555 return 0; /* was NULL */
557 CLASSNAME(fi->class,"\tPUT/GETSTATIC: ",RTA_DEBUGr);
558 RTAaddClassInit( fi->class,
559 CLINITS_T,FINALIZE_T,ADDMARKED_F);
565 case JAVA_INVOKESTATIC:
566 case JAVA_INVOKESPECIAL:
567 i = code_get_u2(p + 1,m);
573 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
576 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
577 log_text("Could not resolve class reference");
582 mi = class_resolveclassmethod( mrclass,
590 METHINFOt(mi,"INVOKESTAT/SPEC:: ",RTA_DEBUGopcodes)
593 /*---- Handle "leaf" = static, private, final calls----------------------------*/
594 if ((opcode == JAVA_INVOKESTATIC)
595 || (mi->flags & ACC_STATIC)
596 || (mi->flags & ACC_PRIVATE)
597 || (mi->flags & ACC_FINAL) )
599 if (mi->class->classUsed != USED){ /* = NOTUSED or PARTUSED */
600 RTAaddClassInit(mi->class,
601 CLINITS_T,FINALIZE_T,ADDMARKED_T);
602 /* Leaf methods are used whether class is or not */
603 /* so mark class as PARTlyUSED */
604 mi->class->classUsed = PARTUSED;
606 /* Add to RTA working list/set of reachable methods */
607 if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
609 "addTo INVOKESTATIC ");
612 "addTo INVOKESPECIAL ");
616 /*---- Handle special <init> calls ---------------------------------------------*/
618 if (mi->class->classUsed != USED) {
620 call of super's <init> then
621 methods of super class not all used */
623 /*--- <init> ()V is equivalent to "new"
624 indicating a class is used = instaniated ---- */
625 if (utf_init==mi->name) {
626 if ((m->class->super.cls == mi->class)
627 && (m->descriptor == utf_void__void) )
629 METHINFOt(mi,"SUPER INIT:",RTA_DEBUGopcodes);
630 /* super init so class may be only used because of its sub-class */
631 RTAaddClassInit(mi->class,
632 CLINITS_T,FINALIZE_T,ADDMARKED_F);
633 if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
636 /* since <init> indicates classes is used, then add marked methods, too */
637 METHINFOt(mi,"NORMAL INIT:",RTA_DEBUGopcodes);
638 RTAaddClassInit(mi->class,
639 CLINITS_T,FINALIZE_T,ADDMARKED_T);
643 } /* end just for <init> ()V */
645 /* <clinit> for class inits do not add marked methods; class not yet instaniated */
646 if (utf_clinit==mi->name)
647 RTAaddClassInit( mi->class,
648 CLINITS_T,FINALIZE_T,ADDMARKED_F);
650 if (!((utf_init==mi->name))
651 || (utf_clinit==mi->name)) {
652 METHINFOt(mi,"SPECIAL not init:",RTA_DEBUGopcodes)
653 if (mi->class->classUsed !=USED)
654 mi->class->classUsed = PARTUSED;
656 "addTo SPEC notINIT ");
659 } /* end init'd class not used = class init process was needed */
661 /* add method to RTA list = set of reachable methods */
663 "addTo SPEC whymissed ");
666 /*** assume if method can't be resolved won't actually be called or
667 there is a real error in classpath and in normal parse an exception
668 will be thrown. Following debug print can verify this
670 CLASSNAME1(mr->class,"CouldNOT Resolve method:",,RTA_DEBUGr);printf(".");fflush(stdout);
671 utf_display(mr->name); printf(" "); fflush(stdout);
672 utf_display(mr->descriptor); printf("\n");fflush(stdout);
677 case JAVA_INVOKEVIRTUAL:
678 i = code_get_u2(p + 1,m);
684 /* XXX why this direct access, this should not be! */
685 mr = m->class->cpinfos[i];
686 /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
687 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
688 log_text("Could not resolve class reference");
693 mi = class_resolveclassmethod(mrclass,
702 METHINFOt(mi,"INVOKEVIRTUAL ::",RTA_DEBUGopcodes);
703 if ((mi->flags & ACC_STATIC)
704 || (mi->flags & ACC_PRIVATE)
705 || (mi->flags & ACC_FINAL) )
707 if (mi->class->classUsed == NOTUSED){
708 RTAaddClassInit(mi->class,
709 CLINITS_T,FINALIZE_T,ADDMARKED_T);
713 "addTo INVOKEVIRTUAL ");
717 rtaMarkSubs(mi->class,mi);
721 CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",RTA_DEBUGr);printf(".");fflush(stdout);
722 utf_display(mr->name); printf(" "); fflush(stdout);
723 utf_display(mr->descriptor); printf("\n");fflush(stdout);
728 case JAVA_INVOKEINTERFACE:
729 i = code_get_u2(p + 1,m);
735 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
738 if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
739 log_text("Could not resolve class reference");
745 mi = class_resolveinterfacemethod(mrclass,
752 METHINFOt(mi,"\tINVOKEINTERFACE: ",RTA_DEBUGopcodes)
753 rtaMarkInterfaceSubs(mi);
755 /* see INVOKESTATIC for explanation about */
756 /* case when Interface is not resolved */
757 /*method_descriptor2types(mi);
758 ?? do need paramcnt? for RTA (or just XTA)*/
763 /* means class is at least passed as a parameter */
764 /* class is really instantiated when class.<init> called*/
765 i = code_get_u2(p + 1,m);
767 constant_classref *cr;
769 cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
772 resolve_classref(NULL,cr,resolveEager,true, false,&ci);
773 /*** s_count++; look for s_counts for VTA */
774 /* add marked methods */
775 CLASSNAME(ci,"NEW : do nothing",RTA_DEBUGr);
776 RTAaddClassInit(ci, CLINITS_T, FINALIZE_T,ADDMARKED_T);
781 case JAVA_INSTANCEOF:
783 i = code_get_u2(p + 1,m);
785 constant_classref *cr;
788 cr = (constant_classref*) class_getconstant(m->class, i, CONSTANT_Class);
791 resolve_classref(NULL,cr,resolveEager,true, false,&cls);
794 CLASSNAMEop(cls,RTA_DEBUGr);
795 if (cls->classUsed == NOTUSED){
797 CLINITS_T,FINALIZE_T,ADDMARKED_T);
812 /* Helper fn for initialize **********************************************/
814 int RTAgetline(char *line, int max, FILE *inFP) {
815 if (fgets(line, max, inFP) == NULL)
818 return strlen((const char *) line);
821 /* Initialize RTA Work list ***********************************************/
823 /*-- Get meth ptr for class.meth desc and add to RTA worklist --*/
824 #define SYSADD(cls,meth,desc,txt) \
825 c = load_class_bootstrap(utf_new_char(cls)); \
827 callmeth = class_resolveclassmethod(c, \
828 utf_new_char(meth), \
829 utf_new_char(desc), \
832 if (callmeth->class->classUsed != USED) { \
833 c->classUsed = PARTUSED; \
834 RTAaddClassInit(callmeth->class, \
835 CLINITS_T,FINALIZE_T,ADDMARKED_T);\
837 callmeth->monoPoly = POLY; \
838 addToRtaWorkList(callmeth,txt);
841 /*-- -----------------------------------------------------------------------------
844 rtMissedIn list (missed becaused called from NATIVE &/or dynamic calls
845 *-- -----------------------------------------------------------------------------*/
846 methodinfo *initializeRTAworklist(methodinfo *m) {
848 methodinfo* callmeth;
849 char systxt[] = "System Call :";
850 char missedtxt[] = "rtMissedIn Call :";
852 FILE *rtMissedIn; /* Methods missed during previous RTA parse */
854 char* class, *meth, *desc;
855 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
858 /* Create RTA call work list */
859 rtaWorkList = NEW(list);
860 list_init(rtaWorkList, OFFSET(rtaNode,linkage) );
862 /* Add first method to call list */
863 m->class->classUsed = USED;
864 addToRtaWorkList(m,systxt);
865 /* Add system called methods */
866 /*** SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt) ***/
867 SYSADD(MAINCLASS, MAINMETH, MAINDESC,systxt)
869 /*** SYSADD("java/lang/System","exit","(I)V",systxt) ***/
870 SYSADD(EXITCLASS, EXITMETH, EXITDESC, systxt)
871 /*----- rtMissedIn 0 */
872 if ( (rtMissedIn = fopen("rtMissedIn0", "r")) == NULL) {
873 /*if (opt_verbose) */
874 {printf("No rtMissedIn0 file\n");fflush(stdout);}
877 while (RTAgetline(line,256,rtMissedIn)) {
878 class = strtok(line, " \n");
879 meth = strtok(NULL, " \n");
880 desc = strtok(NULL, " \n");
881 SYSADD(class,meth,desc,missedtxt)
892 /*- end initializeRTAworklist-------- */
896 /*-------------------------------------------------------------------------------*/
897 methodinfo *missedRTAworklist()
899 FILE *rtMissedIn; /* Methods missed during previous RTA parse */
900 char filenameIn[256] = "rtIn/";
902 char* class, *meth, *desc;
903 char missedtxt[] = "rtIn/ missed Call :";
905 methodinfo* callmeth;
907 methodinfo *rm =NULL; /* return methodinfo ptr to main method */
910 #if defined(USE_THREADS)
911 SYSADD(THREADCLASS, THREADMETH, THREADDESC, "systxt2")
912 SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, "systxt2")
914 /*----- rtMissedIn pgm specific */
915 strcat(filenameIn, (const char *)mainstring);
916 if ( (rtMissedIn = fopen(filenameIn, "r")) == NULL) {
918 {printf("No rtIn/=%s file\n",filenameIn);fflush(stdout);}
921 while (RTAgetline(line,256,rtMissedIn)) {
922 class = strtok(line, " \n");
923 meth = strtok(NULL, " \n");
924 desc = strtok(NULL, " \n");
925 if ((class == NULL) || (meth == NULL) || (desc == NULL)) {
926 log_text("Error in rtMissedIn file for: class.meth, desc");
929 SYSADD(class,meth,desc,missedtxt)
938 /*--------------------------------------------------------*/
940 /* input: method to be RTA static parsed */
941 /*--------------------------------------------------------*/
942 void parseRTmethod(methodinfo *rt_method) {
943 if (! ( (rt_method->flags & ACC_NATIVE )
944 || (rt_method->flags & ACC_ABSTRACT) ) )
946 /* RTA parse to approxmate....
947 what classes/methods will really be used during execution */
951 if (rt_method->flags & ACC_NATIVE )
953 METHINFOt(rt_method,"TO BE NATIVE RTA PARSED :",RTA_DEBUGopcodes);
954 /* parseRTpseudo(rt_method); */
957 printf("Abstract method in RTA Work List: ");
958 METHINFOx(rt_method);
959 log_text("Abstract method in RTA Work List.");
966 /*-- RTA -- *******************************************************/
967 int RT_jit_parse(methodinfo *m)
970 methodinfo *mainmeth;
972 /* Should only be called once */
975 /*----- RTA initializations --------*/
977 log_text("RTA static analysis started.\n");
979 mainmeth = initializeRTAworklist(m);
980 firstCall = false; /* turn flag off */
982 if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
983 printf("CACAO - rtMissed file: cant open file to write\n");
985 /* Note: rtMissed must be renamed to rtMissedIn to be used as input */
987 /*------ process RTA call work list --------*/
988 for (rta =list_first(rtaWorkList);
990 rta =list_next(rtaWorkList,rta))
992 parseRTmethod(rta->method);
995 for (rta =list_first(rtaWorkList);
997 rta =list_next(rtaWorkList,rta))
999 parseRTmethod(rta->method);
1005 printRThierarchyInfo(m);
1007 printCallgraph(rtaWorkList);
1011 log_text("RTA static analysis done.\n");
1018 * These are local overrides for various environment variables in Emacs.
1019 * Please do not remove this and leave it at the end of the file, where
1020 * Emacs will automagically detect them.
1021 * ---------------------------------------------------------------------
1024 * indent-tabs-mode: t