X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Finline%2FparseRT.c;h=1c802ba87c7282e400682f27c5fe76a4ee1eeb76;hb=d75b6037acf17c342166b9c9bd6e657dfdd12cd9;hp=f0bf40b4d17bcb6dce24076ff5ef24fe80d91074;hpb=5bc68e8c5cb6809f0fe7cd1c7cf2a647605d56d1;p=cacao.git diff --git a/src/vm/jit/inline/parseRT.c b/src/vm/jit/inline/parseRT.c index f0bf40b4d..1c802ba87 100644 --- a/src/vm/jit/inline/parseRT.c +++ b/src/vm/jit/inline/parseRT.c @@ -1,9 +1,9 @@ /* jit/parseRT.c - parser and print functions for Rapid Type Analyis - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, - M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, - P. Tomsich, J. Wenninger + Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, + R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, + C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, + Institut f. Computersprachen - TU Wien This file is part of CACAO. @@ -26,665 +26,109 @@ Authors: Carolyn Oates - $Id: parseRT.c 557 2003-11-02 22:51:59Z twisti $ + $Id: parseRT.c 1735 2004-12-07 14:33:27Z twisti $ */ +/*************** + Rapid Type Static Analysis of Java program + used -rt option is turned on either explicitly + or automatically with inlining of virtuals. -#include -#include -#include "jit.h" -#include "parse.h" -#include "loader.h" -#include "natcalls.h" -#include "parseRTprint.h" -#include "parseRTstats.h" -#include "sets.h" -#include "tables.h" -#include "toolbox/loging.h" -#include "toolbox/memory.h" - - -/*------------ global variables -----------------------------------------*/ -#define MAXCALLGRAPH 5000 + USAGE: + Methods called by NATIVE methods and classes loaded dynamically + cannot be found by parsing. The following files supply missing methods: -bool XTAOPTbypass = false; -bool XTAOPTbypass2 = false; /* for now invokeinterface */ -bool XTAOPTbypass3 = false; /* print XTA classsets in stats */ -int XTAdebug = 0; -int XTAfld = 0; - -int methRT = 0; -int methRTlast = -1; -int methRTmax = MAXCALLGRAPH; -methodinfo **callgraph; -/*methodinfo *callgraph[MAXCALLGRAPH];*/ - - -int methXTA = 0; -int methXTAlast = -1;; -int methXTAmax=MAXCALLGRAPH; -methodinfo **XTAcallgraph; -/*methodinfo *XTAcallgraph[MAXCALLGRAPH];*/ + rtMissedIn0 - (provided) has the methods missed by every java program + rtMissed||mainClassName - is program specific. -static bool nativecallcompdone=0 ; - -static bool firstCall= true; -static bool AfterMain = false; -static FILE *rtMissed; /* Methods missed during RTA parse of Main */ -/* so easier to build dynmanic calls file */ - -static utf *utf_MAIN; /* utf_new_char("main"); */ -static utf *INIT ; /* utf_new_char(""); */ -static utf *CLINIT ; /* utf_new_char(""); */ -static utf *FINALIZE; /* utf_new_char("finalize"); */ -static utf *EMPTY_DESC; /* utf_new_char("V()"); */ -static int missedCnt = 0; - - -/*--------------------------------------------------------------*/ -/* addToCallgraph - adds to RTA callgraph and */ -/* sets meth->methodUsed to USED */ -/*--------------------------------------------------------------*/ -#define ADDTOCALLGRAPH(meth) if ((meth->methodUsed != USED) && (!(meth->flags & ACC_ABSTRACT)) ) { \ - callgraph[++methRTlast] = meth ; \ - meth->methodUsed = USED; \ - if(pWhenMarked>=1) \ - {printf("\n Added to Call Graph #%i:", \ - methRTlast); \ - printf("\t <%i/%i> %i\t", \ - meth->class->classUsed, \ - meth->methodUsed, \ - USED); \ - printf(" method name ="); \ - utf_display(meth->class->name);printf("."); \ - method_display(meth);fflush(stdout);} \ - } + A file rtMissed will be written by RT analysis of any methods missed. + This file can be renamed to rtMissed concatenated with the main class name. -/*--------------------------------------------------------------*/ -bool rtaSubUsed(classinfo *class, methodinfo *meth) { - classinfo *subs; - - for (subs=class->sub; subs != NULL; subs = subs->nextsub) { - if (subs->classUsed == USED) { - if (class_findmethod(class, meth->name, meth->descriptor) == NULL) - return false; - else - return true; - } - if (rtaSubUsed(subs, meth)) - return false; - } - return false; -} + Example: + ./cacao -rt hello + inlining with virtuals should fail if the returned rtMissed is not empty. + so... + mv rtMissed rtMissedhello + ./cacao hello -/*--------------------------------------------------------------*/ -/* Mark the method with same name /descriptor in topmethod */ -/* in class */ -/* */ -/* Class not marked USED and method defined in this class -> */ -/* -> if Method NOTUSED mark method as MARKED */ -/* Class marked USED and method defined in this class -> */ -/* -> mark method as USED */ -/* */ -/* Class USED, but method not defined in this class -> */ -/* -> search up the heirarchy and mark method where defined */ -/* if class where method is defined is not USED -> */ -/* -> mark class with defined method as PARTUSED */ -/*--------------------------------------------------------------*/ - -void rtaMarkMethod(classinfo *class, methodinfo *topmethod) { - - utf *name = topmethod -> name; - utf *descriptor = topmethod -> descriptor; - methodinfo *submeth; - - submeth = class_resolvemethod(class, name, descriptor); - if (submeth == NULL) - panic("parse RT: Method not found in class hierarchy"); - if (submeth->methodUsed == USED) return; - - if (submeth->class == class) { - - /*--- Method defined in class -----------------------------*/ - if (submeth->class->classUsed != USED) { - if (submeth->methodUsed == NOTUSED) { - - /* Class NOT marked USED and method defined in this class -> */ - /* -> if Method NOTUSED mark method as MARKED */ - if (pWhenMarked >= 1) { - printf("MARKED class.method\t"); - utf_display(submeth->class->name);printf(".");method_display(submeth); - } - if (rtaSubUsed(submeth->class,submeth)) { - submeth->class->classUsed = PARTUSED; - ADDTOCALLGRAPH(submeth) - } - else { - submeth->methodUsed = MARKED; - RTAPRINTmarkMethod1 - } - } } - else { - /* Class IS marked USED and method defined in this class -> */ - /* -> mark method as USED */ - ADDTOCALLGRAPH(submeth) - } - } /* end defined in class */ - - else { - /*--- Method NOT defined in class -----------------------------*/ - if (submeth->class->classUsed == NOTUSED) { - submeth->class->classUsed = PARTUSED; - if (class->classUsed != USED) { - submeth->methodUsed = MARKED; - } - } - if ( (submeth->class->classUsed == USED) - || (class->classUsed == USED)) { - ADDTOCALLGRAPH(submeth) - } - } /* end NOT defined in class */ -} - -/*-------------------------------------------------------------------------------*/ -/* Mark the method with the same name and descriptor as topmethod */ -/* and any subclass where the method is defined and/or class is used */ -/* */ -/*-------------------------------------------------------------------------------*/ -void rtaMarkSubs(classinfo *class, methodinfo *topmethod) { - RTAPRINTmarkSubs1 - rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */ - if (class->sub != NULL) { - classinfo *subs; - - if (!(topmethod->flags & ACC_FINAL )) { - for (subs = class->sub;subs != NULL;subs = subs->nextsub) { - RTAPRINTmarkSubs1 - rtaMarkSubs(subs, topmethod); - } - } - } - return; -} - -/*-------------------------------------------------------------------------------*/ -/* Add Marked methods for input class ci */ -/* Add methods with the same name and descriptor as implemented interfaces */ -/* with the same method name */ -/* */ -/*-------------------------------------------------------------------------------*/ -void addMarkedMethods(classinfo *ci) { - int ii,jj,mm; - - /* add marked methods to callgraph */ - for (ii=0; iimethodscount; ii++) { - methodinfo *mi = &(ci->methods[ii]); - if (mi->methodUsed == MARKED) { - if (pWhenMarked >= 1) { - printf("ADDED a method that was MARKED\n"); - } - ADDTOCALLGRAPH(mi) - } - else { - - for (jj=0; jj < ci -> interfacescount; jj++) { - classinfo *ici = ci -> interfaces [jj]; - /* use resolve method....!!!! */ - if (ici -> classUsed != NOTUSED) { - for (mm=0; mm< ici->methodscount; mm++) { - methodinfo *imi = &(ici->methods[mm]); - - if ( (imi->methodUsed == USED) - && ( (imi->name == mi->name) - && (imi->descriptor == mi->descriptor))) { - if (pWhenMarked >= 1) - printf("ADDED a method that was used by an interface\n"); - ADDTOCALLGRAPH(mi) - } - } - } - } - } - } -} -/*-------------------------------------------------------------------------------*/ -/* XTA Functions */ -/*-------------------------------------------------------------------------------*/ - -xtainfo * xtainfoInit (methodinfo *m) { - - if (m->xta != NULL) return m->xta; - m ->xta = (xtainfo *)malloc(sizeof(xtainfo)); - m ->xta-> XTAmethodUsed = NOTUSED; - m ->xta-> XTAclassSet = NULL; - /* PartClassSet */ - m ->xta-> paramClassSet = NULL; - m ->xta-> calls = NULL; - m ->xta-> calledBy = NULL; - - m ->xta-> marked = NULL; - /*m ->xta-> markedBy = NULL */ - m ->xta-> fldsUsed = NULL; - /*m ->xta-> interfaceCalls = NULL*/ - m ->xta-> chgdSinceLastParse = false; - return m->xta; -} - -xtafldinfo * xtafldinfoInit (fieldinfo *f) { - - if (f->xta != NULL) return f->xta; - - f ->xta = (xtafldinfo *)malloc(sizeof(xtafldinfo)); - f -> xta-> fieldChecked = false; /*XTA*/ - f -> xta-> fldClassType = NULL; /*XTA*/ - f -> xta-> XTAclassSet = NULL; /*XTA*/ - return f->xta; - -} -bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) { - - classSetNode *p; - classSetNode *c; - classSetNode *c1; - classSetNode *cprev; - bool rc = false; - - if (XTAdebug >= 1) { - printf("\n>>>>>>>>>>>>>>>>><<class->name);printf("."); method_display(SmCalled); - printClassSet(SmCalled->xta->XTAclassSet); printf("\n"); - - printf("\tIN SmCalls set: "); - utf_display(SmCalls->class->name);printf("."); method_display(SmCalls); - printClassSet(SmCalls->xta->XTAclassSet); printf("\n"); - - printf("\tIN lastptrInto : ("); - if (lastptrInto->lastptrIntoClassSet2 != NULL) { - utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); printf(") "); - } - else {printf("NULL) ");} - fflush(stdout); - utf_display(lastptrInto->methRef->class->name);printf("."); fflush(stdout); - method_display(lastptrInto->methRef); fflush(stdout); - printf("\n");fflush(stdout); - } - - /* Get SmCalled ParamType set if null */ - if (SmCalled->xta->paramClassSet == NULL) { - SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); - } - if (XTAdebug >= 1) { - printf("\tParamPassed\n"); fflush(stdout); - printSet(SmCalled->xta->paramClassSet);fflush(stdout); - printf("\n"); fflush(stdout); - } - - if (lastptrInto->lastptrIntoClassSet2 == NULL) { - if (SmCalls->xta->XTAclassSet != NULL) - c1 = SmCalls->xta->XTAclassSet->head; - else - c1 = NULL; - } - else { - /* start with type where left off */ - c1 = lastptrInto->lastptrIntoClassSet2; - c1 = c1 -> nextClass; /* even if NULL */ - } - cprev = NULL; - if (XTAdebug >= 1) { - if (c1 == NULL){ - printf("\tIN SmCalls ... start with NULL\n"); fflush(stdout); - } - else { - printf("\tIN SmCalls ... start with :");fflush(stdout); - utf_display(c1->classType->name); printf("\n"); - } - } - - /* for each Param Class */ - for ( p=SmCalled->xta->paramClassSet; p != NULL; p = p->nextClass) { - - /* for each SmCalls class */ - for (c=c1; c != NULL; c = c->nextClass) { - vftbl *p_cl_vt = p->classType->vftbl; - vftbl *c_cl_vt = c->classType->vftbl; - - /* if SmCalls class is in the Params Class range */ - if ( (p_cl_vt->baseval <= c_cl_vt->baseval) - && (c_cl_vt->baseval <= (p_cl_vt->baseval+p_cl_vt->diffval)) ) { - - /* add SmCalls class to SmCalledBy Class set */ - SmCalled->xta->XTAclassSet = SmCalled->xta->XTAclassSet = add2ClassSet(SmCalled->xta->XTAclassSet, c->classType); - rc = true; - } - cprev = c; - } - } - lastptrInto->lastptrIntoClassSet2 = cprev; - if (XTAdebug >= 1) { - printf("\tOUT SmCalled set: ");fflush(stdout); - printClassSet(SmCalled->xta->XTAclassSet);fflush(stdout); - - printf("\tOUT SmCalls set: ");fflush(stdout); - printClassSet(SmCalls->xta->XTAclassSet);fflush(stdout); - - printf("\tOUT lastptrInto="); fflush(stdout); - if (lastptrInto->lastptrIntoClassSet2 != NULL) - utf_display(lastptrInto->lastptrIntoClassSet2->classType->name); - - printf("\n",rc);fflush(stdout); - } - return rc; -} - -/*-------------------------------------------------------------------------------*/ -bool xtaPassReturnType(methodinfo *SmCalled, methodinfo *SmCalls) { - - classSetNode* cs; - classSetNode* cs1; - bool rc = false; - - if (XTAdebug >= 1) - printf("xtaPassReturnType \n"); - - /* Get SmCalled return class is null */ - if ((SmCalled->returnclass == NULL) && (SmCalled->xta->paramClassSet == NULL)) { - SmCalled->xta->paramClassSet = descriptor2typesL(SmCalled); - } - - if (SmCalled->returnclass == NULL) { - if (XTAdebug >= 1) - printf("\tReturn type is NULL\n"); - return rc; - } - - if (XTAdebug >= 1) { - printf("\tReturn type is: "); - utf_display(SmCalled->returnclass->name); - printf("\n"); - - printf("\tIN SmCalls set: "); - utf_display(SmCalls->class->name); printf("."); method_display(SmCalls); - printClassSet(SmCalls->xta->XTAclassSet); - - printf("\tIN SmCalled set: "); - utf_display(SmCalled->class->name); printf("."); method_display(SmCalled); - printClassSet(SmCalled->xta->XTAclassSet); - } +Results: (currently) with -stat see # methods marked used + +****************/ +#include +#include - if (SmCalled->xta->XTAclassSet == NULL) - cs1 = NULL; - else - cs1 = SmCalled->xta->XTAclassSet->head; - for (cs =cs1; cs != NULL; cs = cs->nextClass) { - classinfo *c = cs->classType; - vftbl *r_cl_vt = SmCalled->returnclass->vftbl; - vftbl *c_cl_vt = c->vftbl; - - /* if class is a subtype of the return type, then add to SmCalls class set (ie.interscection)*/ - if ( (r_cl_vt->baseval <= r_cl_vt->baseval) - && (c_cl_vt->baseval <= (r_cl_vt->baseval+r_cl_vt->diffval)) ) { - SmCalls->xta->XTAclassSet = add2ClassSet(SmCalls->xta->XTAclassSet, c); - rc = true; - } - } +#include "cacao/cacao.h" +#include "mm/memory.h" +#include "toolbox/list.h" +#include "vm/tables.h" +#include "vm/statistics.h" +#include "vm/loader.h" +#include "vm/options.h" +#include "vm/jit/jit.h" +#include "vm/jit/parse.h" +#include "vm/jit/inline/parseRT.h" +#include "vm/jit/inline/parseRTstats.h" - if (XTAdebug >= 1) { - printf("\tOUT SmCalls set: "); - printClassSet(SmCalls->xta->XTAclassSet); - } - return rc; -} - -/*-------------------------------------------------------------------------------*/ -void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) { - - if (mi->xta == NULL) - mi->xta = xtainfoInit(mi); - if (mi->xta->XTAmethodUsed != USED) { /* if static method not in callgraph */ - XTAcallgraph[++methXTAlast] = mi; - mi->xta->XTAmethodUsed = USED; - // XTAPRINTcallgraph2 - - if(pWhenMarked>=1) { - printf("\n XTA Added to Call Graph #%i:", - methXTAlast); - printf(" method name ="); fflush(stdout); - if (mi == NULL) panic ("Method ptr NULL!!!"); - if (mi->class == NULL) panic ("Method class ptr NULL!!!"); - if (mi->class->name == NULL) panic ("Method class name ptr NULL!!!"); - utf_display(mi->class->name);fflush(stdout); printf(".");fflush(stdout); - method_display(mi);fflush(stdout); - } - - } - /* add call edges */ - printf("AA1 "); fflush(stdout); - rt_method->xta->calls = add2MethSet(rt_method->xta->calls, mi); - rt_method->xta->calls->tail->monoPoly = monoPoly; - mi->xta->calledBy = add2MethSet(mi->xta->calledBy, rt_method); - if (mi->xta->calledBy == NULL) panic("mi->xta->calledBy is NULL!!!"); - if (rt_method->xta->calls == NULL) panic("rt_method->xta->calls is NULL!!!"); -} +static bool firstCall= true; +static list *rtaWorkList; +FILE *rtMissed; /* Methods missed during RTA parse of Main */ + +bool DEBUGinf = false; +bool DEBUGr = false; +bool DEBUGopcodes = false; -/*--------------------------------------------------------------*/ -bool xtaSubUsed(classinfo *class, methodinfo *meth, classSetNode *subtypesUsedSet) { - classinfo *subs; - - for (subs=class->sub; subs != NULL; subs = subs->nextsub) { - /* if class used */ - if (inSet(subtypesUsedSet,subs)) { - if (class_findmethod(class, meth->name, meth->descriptor) == NULL) - return false; - else - return true; - } - if (xtaSubUsed(subs, meth, subtypesUsedSet)) - return false; - } - return false; -} +/*********************************************************************/ +void addToRtaWorkList(methodinfo *meth, char *info) { + rtaNode *rta; -/*-------------------------------------------------------------------------------*/ -void xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) -{ - methodinfo *submeth; - - utf *name = topmethod -> name; - utf *descriptor = topmethod -> descriptor; - /**** - printf("xtaMarkMethod for:"); utf_display(class->name);fflush(stdout); - method_display(topmethod); - **/ - - submeth = class_resolvemethod(class, name, descriptor); - - /*** - printf(" def: "); utf_display(submeth->class->name);fflush(stdout); - method_display(submeth); - ****/ - - /* Basic checks */ - if (submeth == NULL) - panic("parse XTA: Method not found in class hierarchy"); - if (submeth->xta == NULL) - submeth->xta = xtainfoInit(submeth); - - if (rt_method->xta->calls != NULL) { - if (inMethSet(rt_method->xta->calls->head,submeth)) return; - } - /*----*/ - if (submeth->class == class) { +if (meth->methodUsed == USED) return; - /*--- Method defined in class -----------------------------*/ - if (inSet(subtypesUsedSet,submeth->class)) { - xtaAddCallEdges(submeth,POLY); - } - else { - if (subtypesUsedSet != NULL) { - if (xtaSubUsed (class,submeth,subtypesUsedSet)) { - xtaAddCallEdges(submeth,POLY); - } - } - else { - rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth); - } +if (!(meth->flags & ACC_ABSTRACT)) { + count_methods_marked_used++; + METHINFOt(meth,info,DEBUGopcodes) + if (meth->class->super != NULL) { + CLASSNAME(meth->class->super,"\tsuper=",DEBUGr) } + else { + if (DEBUGr) printf("\tsuper=NULL\n");} + fflush(stdout); + meth ->methodUsed = USED; + rta = NEW(rtaNode); + rta->method = meth ; + list_addlast(rtaWorkList,rta); +if (meth->class->classUsed == NOTUSED) { + METHINFOx(meth) + printf("\nADDED method in class not used at all!\n"); + fflush(stdout); } - else { - /*--- Method NOT defined in class -----------------------------*/ - if (!(inSet(subtypesUsedSet,submeth->class) )){ /* class with method def is not used */ - if (!(inSet(subtypesUsedSet,class) )) { /* class currently resolving is not used */ - rt_method->xta->marked = add2MethSet(rt_method->xta->marked, submeth); - /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->xta->marked);*/ - } - } - if ( (inSet(subtypesUsedSet,submeth->class)) /* class with method def is used */ - || (inSet(subtypesUsedSet,class)) ) { /* class currently resolving is used */ - xtaAddCallEdges(submeth,POLY); - } - - } /* end defined in class */ - -} -/*-------------------------------------------------------------------------------*/ -void xtaMarkSubs(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) { - /* xtaPRINTmarkSubs1*/ - xtaMarkMethod(class, topmethod,subtypesUsedSet); /* Mark method in class where it was found */ - if (class->sub != NULL) { - classinfo *subs; - - if (!(topmethod->flags & ACC_FINAL )) { - for (subs = class->sub; subs != NULL; subs = subs->nextsub) { - /* xtaPRINTmarkSubs1 */ - xtaMarkSubs(subs, topmethod, subtypesUsedSet); - } - } } - return; +/*** +else { + printf("Method not added to work list!!!<%i> : ", + meth->methodUsed); fflush(stdout); + METHINFO(meth,true) + } +***/ } -/*-------------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------------*/ - -int addClassInit(classinfo *ci) { - /* CHANGE to a kind of table look-up for a list of class/methods (currently 3) - */ - - utf* utf_java_lang_system = utf_new_char("java/lang/System"); - utf* utf_initializeSystemClass = utf_new_char("initializeSystemClass"); - utf* utf_java_lang_Object = utf_new_char("java/lang/Object"); - - int m, m1=-1, m2=-1, mf=-1; - methodinfo *mi; - - for (m=0; m < ci->methodscount; m++) { - /* class init method */ - if (ci->methods[m].name == CLINIT) { - m1=m; - } - /* Special case: System class has an extra initializer method */ - if ((utf_java_lang_system == ci->name) - && (utf_initializeSystemClass == ci->methods[m].name)) { - m2=m; - } - - /* Finalize methods */ - if ((ci->methods[m].name == FINALIZE) - && (ci->name != utf_java_lang_Object)) { - mf=m; - } - - } - - if (m1 >= 0) { /* No available - ignore */ - - /* Get clinit methodinfo ptr */ - mi = class_findmethod (ci,ci->methods[m1].name , NULL); - - /*--- RTA ---*/ - if ( mi->methodUsed != USED) { - mi->class->classUsed = PARTUSED; - ADDTOCALLGRAPH(mi) - } - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) { - xtaAddCallEdges(mi,MONO); - } - - } +/**************************************************************************/ +void rtaMarkSubs(classinfo *class, methodinfo *topmethod); - if (mf >= 0) { - - /* Get finalize methodinfo ptr */ - mi = class_findmethod (ci,ci->methods[mf].name , NULL); - - /*--- RTA ---*/ - if ( mi->methodUsed != USED) { - mi->class->classUsed = PARTUSED; - ADDTOCALLGRAPH(mi) - } - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) { - xtaAddCallEdges(mi,MONO); - } - } - - /*Special Case for System class init: - add java/lang/initializeSystemClass to callgraph */ - if (m2 >= 0) { - /* Get clinit methodinfo ptr */ - mi = class_findmethod (ci,ci->methods[m2].name , NULL); - - /*--- RTA ---*/ - if ( mi->methodUsed != USED) { - mi->class->classUsed = PARTUSED; - ADDTOCALLGRAPH(mi) - } - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) { - xtaAddCallEdges(mi,MONO); - } - } - - /* add marked methods to callgraph */ - addMarkedMethods(ci); - - return m; -} - - -#define rt_code_get_u1(p) rt_jcode[p] -#define rt_code_get_s1(p) ((s1)rt_jcode[p]) -#define rt_code_get_u2(p) ((((u2)rt_jcode[p])<<8)+rt_jcode[p+1]) -#define rt_code_get_s2(p) ((s2)((((u2)rt_jcode[p])<<8)+rt_jcode[p+1])) -#define rt_code_get_u4(p) ((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\ - +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]) -#define rt_code_get_s4(p) ((s4)((((u4)rt_jcode[p])<<24)+(((u4)rt_jcode[p+1])<<16)\ - +(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3])) - - - -/*-------------------------------------------------------------------------------*/ -/*xx*/ void addUsedInterfaceMethods(classinfo *ci) { +/*------------------------------------------------------------------------*/ +void rtaAddUsedInterfaceMethods(classinfo *ci) { int jj,mm; /* add used interfaces methods to callgraph */ for (jj=0; jj < ci -> interfacescount; jj++) { classinfo *ici = ci -> interfaces [jj]; - if (pWhenMarked >= 1) { + if (DEBUGinf) { printf("BInterface used: ");fflush(stdout); utf_display(ici->name); printf("<%i>\t",ici -> classUsed ); fflush(stdout); @@ -702,7 +146,7 @@ int addClassInit(classinfo *ci) { /* for each interface method implementation that has already been used */ for (mm=0; mm< ici->methodscount; mm++) { methodinfo *imi = &(ici->methods[mm]); - if (pWhenMarked >= 1) { + if (DEBUGinf) { if (imi->methodUsed != USED) { if (imi->methodUsed == NOTUSED) printf("Interface Method notused: "); if (imi->methodUsed == MARKED) printf("Interface Method marked: "); @@ -710,968 +154,808 @@ int addClassInit(classinfo *ci) { } } if (imi->methodUsed == USED) { - if (pWhenMarked >= 1) { + if (DEBUGinf) { printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout); /* Mark this method used in the (used) implementing class and its subclasses */ - printf("MAY ADD methods that was used by an interface\n"); + printf("rMAY ADD methods that was used by an interface\n"); } - rtaMarkSubs(ci,imi); + if ((utf_new_char("") != imi->name) && + (utf_new_char("") != imi->name)) + rtaMarkSubs(ci,imi); } } } } } -/*-------------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------------*/ -void xtaMarkInterfaceSubs(methodinfo *mCalled) { - classSetNode * Si; - - /* for every class that implements the interface of the method called */ - for (Si = mCalled->class->impldBy; Si != NULL; Si = Si->nextClass) { - /* add all definitions of this method for this interface */ - methodinfo *submeth; +/**************************************************************************/ +/* Add Marked methods for input class ci */ +/* Add methods with the same name and descriptor as implemented interfaces*/ +/* with the same method name */ +/* */ +/*------------------------------------------------------------------------*/ +void rtaAddMarkedMethods(classinfo *ci) { +int ii,jj,mm; - submeth = class_findmethod(Si->classType, mCalled->name, mCalled->descriptor); - if (submeth == NULL) ; /* search up the heir - ignore for now!!! */ - else { - classSetNode *subtypesUsedSet = NULL; - - if (rt_method->xta->XTAclassSet != NULL) - subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->xta->XTAclassSet->head); - - printf(" \nXTA subtypesUsedSet: "); fflush(stdout); - printSet(subtypesUsedSet); - xtaMarkSubs(submeth->class, submeth, subtypesUsedSet); +/* add marked methods to callgraph */ +for (ii=0; iimethodscount; ii++) { + methodinfo *mi = &(ci->methods[ii]); + + if (mi->methodUsed == MARKED) { + addToRtaWorkList(mi, + "addTo was MARKED:"); + } + else { + for (jj=0; jj < ci -> interfacescount; jj++) { + classinfo *ici = ci -> interfaces [jj]; + /* use resolve method....!!!! */ + if (ici -> classUsed != NOTUSED) { + for (mm=0; mm< ici->methodscount; mm++) { + methodinfo *imi = &(ici->methods[mm]); + METHINFOt(imi,"NEW IMPD INTERFACE:",DEBUGinf) + /*if interface method=method is used*/ + if ( (imi->methodUsed == USED) + && ( (imi->name == mi->name) + && (imi->descriptor == mi->descriptor))) { + addToRtaWorkList(mi, + "addTo was interfaced used/MARKED:"); + } + } /*end for */ + } + } } } -} - -/*-------------------------------------------------------------------------------*/ -bool xtaAddFldClassTypeInfo(fieldinfo *fi) { - - bool rc = false; +} - if (fi->xta->fieldChecked) { - if (fi->xta->fldClassType != NULL) - return true; /* field has a class type */ - else - return false; - } - fi->xta->fieldChecked = true; +#define CLINITS_T true +#define FINALIZE_T true +#define ADDMARKED_T true - if (fi->type == TYPE_ADDRESS) { - char *utf_ptr = fi->descriptor->text; /* current position in utf text */ +#define CLINITS_F false +#define FINALIZE_F false +#define ADDMARKED_F false +/*********************************************************************/ +void addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark) +{ + methodinfo *mi; - if (*utf_ptr != 'L') { - while (*utf_ptr++ =='[') ; - } + if (addmark) + ci->classUsed = USED; + + if (clinits) { /* No available - ignore */ + mi = class_findmethod(ci, + utf_new_char(""), + utf_new_char("()V")); + if (mi) { + if (ci->classUsed != USED) + ci->classUsed = PARTUSED; + mi->monoPoly = MONO; + addToRtaWorkList(mi,"addTo CLINIT added:"); + } + } + + /*Special Case for System class init: + add java/lang/initializeSystemClass to callgraph */ + if (ci->name == utf_new_char("initializeSystemClass")) { + /* ?? what is name of method ?? */ + } + + if (finalizes) { + mi = class_findmethod(ci, + utf_new_char("finalize"), + utf_new_char("()V")); + if (mi) { + if (ci->classUsed != USED) + ci->classUsed = PARTUSED; + mi->monoPoly = MONO; + addToRtaWorkList(mi,"addTo FINALIZE added:"); + } + } + + if (addmark) { + rtaAddMarkedMethods(ci); + } + rtaAddUsedInterfaceMethods(ci); - if (*utf_ptr =='L') { - rc = true; - if (fi->xta->fldClassType== NULL) { - char *desc; - char *cname; - classinfo * class; - - desc = MNEW(char, 256); - strcpy(desc,++utf_ptr); - cname = strtok(desc,";"); - if (XTAdebug >= 1) { - printf("STATIC field's type is: %s\n",cname); - fflush(stdout); - } - class = class_get(utf_new_char(cname)); - fi->xta->fldClassType= class; /* save field's type class ptr */ - } - } - } - return rc; } -/*-------------------------------------------------------------------------------*/ -void xtaPassFldPUT(fldSetNode *fN) -{ - /* Field type is a class */ - classSetNode *c; - classSetNode *c1 = NULL; - classSetNode *cp = NULL; - classSetNode *cprev= NULL; - - fieldinfo *fi; - if (fN != NULL) - fi = fN->fldRef; - else - return; - -/* Use lastptr so don't check whole XTA class set each time */ - cp = fN->lastptrPUT; - if (cp != NULL) { - if (cp->nextClass != NULL) - c1 = cp -> nextClass; - } - else { - if (rt_method->xta->XTAclassSet != NULL) - c1 = rt_method->xta->XTAclassSet->head; - - if (XTAfld >=1 ) { - printf("rt XTA class set =");fflush(stdout); - printClassSet(rt_method->xta->XTAclassSet); - printf("\t\tField class type = ");fflush(stdout); - utf_display(fi->xta->fldClassType->name); printf("\n"); - } - } - /*--- PUTSTATIC specific ---*/ - /* Sx = intersection of type+subtypes(field x) */ - /* and Sm (where putstatic code is) */ - for (c=c1; c != NULL; c=c->nextClass) { - vftbl *f_cl_vt = fi->xta->fldClassType->vftbl; - vftbl *c_cl_vt = c-> classType->vftbl; - if (XTAfld >=2 ) { - printf("\tXTA class = ");fflush(stdout); - utf_display(c->classType->name); - printf(" ",c_cl_vt->baseval); fflush(stdout); - if (c->nextClass == NULL) { - printf("next=NULL ");fflush(stdout); - } - else { - printf("next="); fflush(stdout); - utf_display(c->nextClass->classType->name); - printf("\n"); fflush(stdout); - } +/*--------------------------------------------------------------*/ +/* Mark the method with same name /descriptor in topmethod */ +/* in class */ +/* */ +/* Class marked USED and method defined in this class -> */ +/* -> mark method as USED */ +/* Class not marked USED and method defined in this class -> */ +/* -> if Method NOTUSED mark method as MARKED */ +/* */ +/* Class USED, but method not defined in this class -> */ +/* -> 1) search up the heirarchy and mark method where defined */ +/* 2) if class where method is defined is not USED -> */ +/* -> mark class with defined method as PARTUSED */ +/*--------------------------------------------------------------*/ - printf("\t\tField class type = ");fflush(stdout); - utf_display(fi->xta->fldClassType->name); - printf(" \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout); - } +void rtaMarkMethod(classinfo *class, methodinfo *topmethod) { - if ((f_cl_vt->baseval <= c_cl_vt->baseval) - && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) { - fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType); - } - cprev = c; +utf *name = topmethod->name; +utf *descriptor = topmethod->descriptor; +methodinfo *submeth; + +/* See if method defined in class heirarchy */ +submeth = class_resolvemethod(class, name, descriptor); +METHINFOt(submeth,"rtaMarkMethod submeth:",DEBUGr); +if (submeth == NULL) { + utf_display(class->name); printf("."); + METHINFOx(topmethod); + printf("parse RT: Method not found in class hierarchy");fflush(stdout); + panic("parse RT: Method not found in class hierarchy"); } - fN->lastptrPUT = cprev; -} -/*-------------------------------------------------------------------------------*/ -void xtaPassFldGET(fldSetNode *fN) -{ - /* Field type is a class */ - classSetNode *c; - classSetNode *c1 = NULL; - classSetNode *cp = NULL; - classSetNode *cprev= NULL; - - fieldinfo *fi; - if (fN != NULL) - fi = fN->fldRef; - else - return; - -/* Use lastptr so don't check whole XTA class set each time */ - cp = fN->lastptrGET; - if (cp != NULL) { - if (cp->nextClass != NULL) - c1 = cp -> nextClass; - } - else { - if (fi->xta->XTAclassSet != NULL) - c1 = fi->xta->XTAclassSet->head; - - if (XTAfld >=1 ) { - printf("fld XTA class set =");fflush(stdout); - printClassSet(fi->xta->XTAclassSet); - printf("\t\tField class type = ");fflush(stdout); - utf_display(fi->xta->fldClassType->name); printf("\n"); +if (submeth->methodUsed == USED) return; + +#undef CTA +#ifdef CTA + /* Class Type Analysis if class.method in virt cone marks it used */ + /* very inexact, too many extra methods */ + addClassInit( submeth->class, + CLINITS_T,FINALIZE_T,ADDMARKED_T); + submeth->monoPoly = POLY; + addToRtaWorkList(submeth, + "addTo RTA VIRT CONE:"); + return; +#endif + + if (submeth->class == class) { + + /*--- Method defined in class -----------------------------*/ + if ( submeth->class->classUsed == USED) { + /* method defined in this class -> */ + /* Class IS marked USED */ + /* -> mark method as USED */ + submeth->monoPoly = POLY; + addToRtaWorkList(submeth, + "addTo VIRT CONE 1:"); + } + else { + /* method defined in this class -> */ + /* Class IS NOT marked USED (PART or NOTUSED) */ + /* -> if Method NOTUSED mark method as MARKED */ + METHINFOt(submeth, + "\tmarked VIRT CONE 2:",DEBUGr); + submeth->monoPoly = POLY; + submeth->methodUsed = MARKED; + /* Note: if class NOTUSED and subclass is used handled */ + /* by subsequent calls to rtaMarkMethods for cone */ } - } + } /* end defined in class */ - /*--- GETSTATIC specific ---*/ - /* Sm = union of Sm and Sx */ - for (c=c1; c != NULL; c=c->nextClass) { - bool addFlg = false; - if (rt_method->xta->XTAclassSet ==NULL) - addFlg = true; - else { - if (!(inSet (rt_method->xta->XTAclassSet->head, c->classType) )) - addFlg = true; + else { + /*--- Method NOT defined in class ---------------*/ + /* first mark classes if needed */ + if (submeth->class->classUsed == NOTUSED) { + submeth->class->classUsed = PARTUSED; + if (class->classUsed != USED) { + submeth->monoPoly = POLY; + submeth->methodUsed = MARKED; + METHINFOt(submeth,"JUST MARKED :",DEBUGr); + } } - if (addFlg) { - rt_method->xta->XTAclassSet - = add2ClassSet(rt_method->xta->XTAclassSet,c->classType); + /* add method to rta work list if conditions met */ + /*??if ( (submeth->class->classUsed == USED) || */ + if (class->classUsed == USED) { + submeth->monoPoly = POLY; + addToRtaWorkList(submeth, + "addTo VIRT CONE 3:"); } - cprev = c; - } + } /* end NOT defined in class */ + +} + +/*----------------------------------------------------------------------*/ +/* Mark the method with the same name and descriptor as topmethod */ +/* and any subclass where the method is defined and/or class is used */ +/* */ +/*----------------------------------------------------------------------*/ +void rtaMarkSubs(classinfo *class, methodinfo *topmethod) { - fN->lastptrGET = cprev; + /* Mark method in class */ + CLASSNAME1(class," MARKSUBS ",DEBUGr); + METHINFOt(topmethod," TOP ",DEBUGr); + rtaMarkMethod(class, topmethod); + /* Mark method in subclasses */ + if (class->sub != NULL) { + classinfo *subs; + + if (!(topmethod->flags & ACC_FINAL )) { + for (subs = class->sub;subs != NULL;subs = subs->nextsub) { + CLASSNAME1(subs," SUBS ",DEBUGr); + rtaMarkSubs(subs, topmethod); + } + } + } + return; } -/*-------------------------------------------------------------------------------*/ -void xtaPassAllCalledByParams () { - methSetNode *SmCalled; - methSetNode *s1; - if (XTAdebug >= 1) { - printf("xta->calledBy method set: "); fflush(stdout); - printMethodSet(rt_method->xta->calledBy); fflush(stdout); - } - if (rt_method->xta->calledBy == NULL) - s1 = NULL; - else - s1 = rt_method->xta->calledBy->head; - for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) { - if (XTAdebug >= 1) { - printf("SmCalled = "); fflush(stdout); - utf_display(SmCalled->methRef->class->name); fflush(stdout); - printf(".");fflush(stdout); method_display(SmCalled->methRef); + +/*********************************************************************/ + +void rtaMarkInterfaceSubs(methodinfo *mi) { + classSetNode *subs; + if (mi->class->classUsed == NOTUSED) { + mi->class->classUsed = USED; + class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class); } + + /* add interface class to list kept in Object */ + mi->methodUsed = USED; + mi->monoPoly = POLY; + + subs = mi->class->impldBy; + /*RTAPRINT08invokeInterface1*/ + if (DEBUGinf) { + METHINFO(mi,DEBUGinf) + printf("Implemented By classes :\n");fflush(stdout); + if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); + fflush(stdout); + } + while (subs != NULL) { + classinfo * isubs = subs->classType; + methodinfo *submeth; + if (DEBUGinf) { + printf("\t");utf_display(isubs->name);fflush(stdout); + printf(" <%i>\n",isubs->classUsed);fflush(stdout); + } + /*Mark method (mark/used) in classes that implement method*/ + + submeth = class_findmethod(isubs,mi->name, mi->descriptor); + if (submeth != NULL) + submeth->monoPoly = POLY; /* poly even if nosubs */ + rtaMarkSubs(isubs, mi); - rt_method->xta->chgdSinceLastParse = false; - xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */ - } -} + subs = subs->nextClass; + } /* end while */ +} -/*-------------------------------------------------------------------------------*/ -void xtaAllFldsUsed ( ){ - fldSetNode *f; - fldSetNode *f1=NULL; - /* bool chgd = false */ - if (rt_method->xta->fldsUsed == NULL) return; - /* for each field that this method uses */ - f1 = rt_method->xta->fldsUsed->head; - for (f=f1; f != NULL; f = f->nextfldRef) { - if (f->writePUT) - xtaPassFldPUT(f); - if (f->readGET) - xtaPassFldGET(f); - } -} -/*-------------------------------------------------------------------------------*/ -void xtaMethodCalls_and_sendReturnType() -{ - methSetNode *SmCalled; /* for return type */ - methSetNode *SmCalls; /* for calls param types */ - methSetNode *s1=NULL; - bool chgd = false; - if (XTAdebug >= 1) { - printf("calls method set Return type: "); - printMethodSet(rt_method->xta->calls); - printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->xta->calls)\n");fflush(stdout); - } - xtaAllFldsUsed ( ); - - /* for each method that this method calls */ - if (rt_method->xta->calls == NULL) - s1 = NULL; - else - s1 = SmCalls=rt_method->xta->calls->head; - - for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) { - /* pass param types */ - bool chgd = false; - chgd = xtaPassParams (SmCalls->methRef, rt_method, SmCalls); - /* if true chgd after its own parse */ - if (!(SmCalls->methRef->xta->chgdSinceLastParse)) { - SmCalls->methRef->xta->chgdSinceLastParse = true; - } - } - /* for each calledBy method */ - /* send return type */ - if (rt_method->xta->calledBy == NULL) - s1 = NULL; - else - s1 = rt_method->xta->calledBy->head; - for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) { - - if (XTAdebug >= 1) { - printf("\tSmCalled = ");fflush(stdout); utf_display(SmCalled->methRef->class->name); - printf("."); method_display(SmCalled->methRef); - } - - chgd = xtaPassReturnType(rt_method, SmCalled->methRef); - if (!(SmCalled->methRef->xta->chgdSinceLastParse)) { - SmCalled->methRef->xta->chgdSinceLastParse = chgd; - } - } -} +/*********************************************************************/ -/*-------------------------------------------------------------------------------*/ -static void parseRT() +int parseRT(methodinfo *m) { - int p; /* java instruction counter */ - int nextp; /* start of next java instruction */ - int opcode; /* java opcode */ - int i; /* temporary for different uses (counters) */ - bool iswide = false; /* true if last instruction was a wide */ + int p; /* java instruction counter */ + int nextp; /* start of next java instruction */ + int opcode; /* java opcode */ + int i; /* temp for different uses (counters)*/ + bool iswide = false; /* true if last instruction was a wide*/ + int rc = 1; - RTAPRINT01method +METHINFOt(m,"\n----RT PARSING:",DEBUGopcodes); +if ((DEBUGr)||(DEBUGopcodes)) printf("\n"); - if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) { +/* scan all java instructions */ + for (p = 0; p < m->jcodelength; p = nextp) { - xtaPassAllCalledByParams (); - } + opcode = code_get_u1(p,m); /* fetch op code */ + SHOWOPCODE - /* scan all java instructions */ + nextp = p + jcommandsize[opcode]; /* compute next instrtart */ + if (nextp > m->jcodelength) + panic("Unexpected end of bytecode"); - for (p = 0; p < rt_jcodelength; p = nextp) { - opcode = rt_code_get_u1 (p); /* fetch op code */ - RTAPRINT02opcode - fflush(stdout); - nextp = p + jcommandsize[opcode]; /* compute next instruction start */ switch (opcode) { - /*--------------------------------*/ - /* Code just to get the correct next instruction */ - /* 21- 25 */ case JAVA_ILOAD: case JAVA_LLOAD: case JAVA_FLOAD: case JAVA_DLOAD: - case JAVA_ALOAD: - if (iswide) - { - nextp = p+3; - iswide = false; - } - break; - /* 54 -58 */ - case JAVA_ISTORE: - case JAVA_LSTORE: - case JAVA_FSTORE: - case JAVA_DSTORE: - - case JAVA_ASTORE: - if (iswide) - { - iswide=false; - nextp = p+3; - } + case JAVA_ISTORE: + case JAVA_LSTORE: + case JAVA_FSTORE: + case JAVA_DSTORE: + case JAVA_ASTORE: + + if (iswide) { + nextp = p + 3; + iswide = false; + } break; - /* 132 */ - case JAVA_IINC: + case JAVA_IINC: { + if (iswide) { iswide = false; - nextp = p+5; + nextp = p + 5; } } break; /* wider index for loading, storing and incrementing */ - /* 196 */ + case JAVA_WIDE: iswide = true; nextp = p + 1; break; - /* 169 */ + case JAVA_RET: if (iswide) { - nextp = p+3; + nextp = p + 3; iswide = false; } break; - /* table jumps ********************************/ - case JAVA_LOOKUPSWITCH: { - s4 num; - nextp = ALIGN((p + 1), 4); - num = rt_code_get_u4(nextp + 4); - nextp = nextp + 8 + 8 * num; - break; + s4 num; + nextp = ALIGN((p + 1), 4) + 4; + num = code_get_u4(nextp,m); + nextp += (code_get_u4(nextp,m)) * 8 + 4; + break; } case JAVA_TABLESWITCH: - { - s4 num; - nextp = ALIGN ((p + 1),4); - num = rt_code_get_s4(nextp + 4); - num = rt_code_get_s4(nextp + 8) - num; - nextp = nextp + 16 + 4 * num; - break; - } - - /*-------------------------------*/ + { + s4 num; + nextp = ALIGN ((p + 1),4); + num = code_get_s4(nextp + 4, m); + num = code_get_s4(nextp + 8, m) - num; + nextp = nextp + 16 + 4 * num; + break; + } + /*********************/ case JAVA_PUTSTATIC: - i = rt_code_get_u2(p + 1); - { - constant_FMIref *fr; - fieldinfo *fi; - - fr = class_getconstant (rt_class, i, CONSTANT_Fieldref); - /* descr has type of field ref'd */ - fi = class_findfield (fr->class,fr->name, fr->descriptor); - RTAPRINT03putstatic1 - - /*--- RTA ---*/ - /* class with field - marked in addClassinit */ - addClassInit(fr->class); - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) - { - if (fi->xta == NULL) - fi->xta = xtafldinfoInit(fi); - if (xtaAddFldClassTypeInfo(fi)) { - rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, true,false); - } - } - } - break; - case JAVA_GETSTATIC: - i = rt_code_get_u2(p + 1); + + i = code_get_u2(p + 1,m); { constant_FMIref *fr; fieldinfo *fi; - fr = class_getconstant (rt_class, i, CONSTANT_Fieldref); - /* descr has type of field ref'd */ - fi = class_findfield (fr->class,fr->name, fr->descriptor); - RTAPRINT03putstatic1 - - /*--- RTA ---*/ - /* class with field - marked in addClassinit */ - addClassInit(fr->class); - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta) ) - { - if (fi->xta == NULL) - fi->xta = xtafldinfoInit(fi); - if (xtaAddFldClassTypeInfo(fi)) { - rt_method->xta->fldsUsed = add2FldSet(rt_method->xta->fldsUsed, fi, false, true); - } - } - - } - break; + fr = class_getconstant(m->class, i, CONSTANT_Fieldref); + LAZYLOADING(fr->class) + fi = class_resolvefield(fr->class, + fr->name, + fr->descriptor, + m->class, + true); - /*-------------------- method invocation ---------------------*/ + if (!fi) + return 0; /* was NULL */ - case JAVA_INVOKESTATIC: - i = rt_code_get_u2(p + 1); - { - constant_FMIref *mr; - methodinfo *mi; - - mr = class_getconstant (rt_class, i, CONSTANT_Methodref); - mi = class_findmethod (mr->class, mr->name, mr->descriptor); - /*-- RTA --*/ - RTAPRINT04invokestatic1 - if (mi->class->classUsed == NOTUSED) { - mi->class->classUsed = USED; - RTAPRINT05invokestatic2 - } - addClassInit(mi->class); - - ADDTOCALLGRAPH(mi) - fflush(stdout); - /*-- XTA --*/ - if ((XTAOPTbypass) || (opt_xta)) { - xtaAddCallEdges(mi,MONO); - } /* end XTA */ + CLASSNAME(fi->class,"\tPUT/GETSTATIC: ",DEBUGr); + if (!fi->class->initialized) { + m->isleafmethod = false; + } + addClassInit( fi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_F); } break; - case JAVA_INVOKESPECIAL: - i = rt_code_get_u2(p + 1); + case JAVA_INVOKESTATIC: + case JAVA_INVOKESPECIAL: + i = code_get_u2(p + 1,m); { constant_FMIref *mr; - methodinfo *mi; - classinfo *ci; - - mr = class_getconstant (rt_class, i, CONSTANT_Methodref); - mi = class_findmethod (mr->class, mr->name, mr->descriptor); - ci = mi->class; - RTAPRINT06invoke_spec_virt1 - /*--- PRIVATE Method -----------------------------------------------------*/ - if (mi->name != INIT) { /* if method called is PRIVATE */ - RTAPRINT07invoke_spec_virt2 - RTAPRINT04invokestatic1 - /*-- RTA --*/ /* was just markSubs(mi); */ - ADDTOCALLGRAPH(mi) - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) { - xtaAddCallEdges(mi,MONO); - } /* end XTA */ + methodinfo *mi; + + m->isleafmethod = false; + mr = class_getconstant(m->class, i, CONSTANT_Methodref); + LAZYLOADING(mr->class) + mi = class_resolveclassmethod(mr->class, + mr->name, + mr->descriptor, + m->class, + false); + + + if (mi) + { + METHINFOt(mi,"INVOKESTAT/SPEC:: ",DEBUGopcodes) + mi->monoPoly = MONO; + if ((opcode == JAVA_INVOKESTATIC) + || (mi->flags & ACC_STATIC) + || (mi->flags & ACC_PRIVATE) + || (mi->flags & ACC_FINAL) ) + { + if (mi->class->classUsed == PARTUSED){ + addClassInit(mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_T); } - - else { - /*--- Test for super which is: calling its super class -*/ - - /* new class so add marked methods */ - if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) { - /*--- process NORMAL method ---------------------------------------------*/ - if ( mi->methodUsed != USED) { - /* Normal - - mark class as USED and to callgraph */ - - /*-- RTA --*/ - ci->classUsed = USED; - addMarkedMethods(ci); /* add to callgraph marked methods */ - RTAPRINT06Binvoke_spec_init - addUsedInterfaceMethods(ci); - ADDTOCALLGRAPH(mi) - - /*-- XTA --*/ - if ((XTAOPTbypass) || (opt_xta)) { - rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); - xtaAddCallEdges(mi,MONO); - RTAPRINT06CXTAinvoke_spec_init1 - } /* end XTA */ - } - } + else { + if (mi->class->classUsed == NOTUSED){ + addClassInit(mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_T); + if (mi->class->classUsed == NOTUSED){ + mi->class->classUsed = PARTUSED; } + } } - - } - break; - - - case JAVA_INVOKEVIRTUAL: - i = rt_code_get_u2(p + 1); - { - constant_FMIref *mr; - methodinfo *mi; - - mr = class_getconstant (rt_class, i, CONSTANT_Methodref); - mi = class_findmethod (mr->class, mr->name, mr->descriptor); - - /*--- RTA ---*/ - RTAPRINT07invoke_spec_virt2 - mi->monoPoly = POLY; - rtaMarkSubs(mi->class,mi); - - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) { - classSetNode *subtypesUsedSet = NULL; - if (rt_method->xta->XTAclassSet != NULL) - subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->xta->XTAclassSet->head); - /***** - printf(" \nXTA subtypesUsedSet: "); fflush(stdout); - printSet(subtypesUsedSet); - *****/ - xtaMarkSubs(mi->class, mi, subtypesUsedSet); - } /* end XTA */ + if (opcode == JAVA_INVOKESTATIC) + addToRtaWorkList(mi, + "addTo INVOKESTATIC "); + else + addToRtaWorkList(mi, + "addTo INVOKESPECIAL "); + } + else { + /* Handle special calls */ + + /* for now same as rest */ + if (mi->class->classUsed != USED){ + /* RTA special case: + call of super's then + methods of super class not all used */ + if (utf_new_char("")==mi->name) { + if ((m->class->super == mi->class) + && (m->descriptor == utf_new_char("()V")) ) + { + METHINFOt(mi,"SUPER INIT:",DEBUGopcodes); + /* super init */ + addClassInit(mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_F); + if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED; + } + else { + METHINFOt(mi,"NORMAL INIT:",DEBUGopcodes); + addClassInit(mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_T); + } + addToRtaWorkList(mi, + "addTo INIT "); + } + if (utf_new_char("")==mi->name) + addClassInit( mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_F); + + if (!((utf_new_char("")==mi->name)) + || (utf_new_char("")==mi->name)) { + METHINFOt(mi,"SPECIAL not init:",DEBUGopcodes) + if (mi->class->classUsed !=USED) + mi->class->classUsed = PARTUSED; + addToRtaWorkList(mi, + "addTo SPEC notINIT "); + } + } + addToRtaWorkList(mi, + "addTo SPEC whymissed "); + + } + } +/*** assume if method can't be resolved won't actually be called or + there is a real error in classpath and in normal parse an exception + will be thrown. Following debug print can verify this +else from if (mi) { +CLASSNAME1(mr->class,"CouldNOT Resolve method:",,DEBUGr);printf(".");fflush(stdout); +utf_display(mr->name); printf(" "); fflush(stdout); +utf_display(mr->descriptor); printf("\n");fflush(stdout); +***/ } break; - case JAVA_INVOKEINTERFACE: - i = rt_code_get_u2(p + 1); + case JAVA_INVOKEVIRTUAL: + i = code_get_u2(p + 1,m); { constant_FMIref *mr; - methodinfo *mi; - classSetNode *subs; - - mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref); - mi = class_findmethod (mr->class, mr->name, mr->descriptor); - - if (mi->flags & ACC_STATIC) - panic ("Static/Nonstatic mismatch calling static method"); - - /*--- RTA ---*/ - RTAPRINT08AinvokeInterface0 - if (mi->class->classUsed == NOTUSED) { - mi->class->classUsed = USED; /*??PARTUSED;*/ - class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class); - } - - /* add interface class to list kept in Object */ - mi->methodUsed = USED; - mi->monoPoly = POLY; - - subs = mi->class->impldBy; - RTAPRINT08invokeInterface1 - while (subs != NULL) { - classinfo * isubs = subs->classType; - RTAPRINT09invokeInterface2 - /* Mark method (mark/used) in classes that implement the method */ - if (isubs->classUsed != NOTUSED) { - methodinfo *submeth; - - submeth = class_findmethod(isubs,mi->name, mi->descriptor); - if (submeth != NULL) - submeth->monoPoly = POLY; /* poly even if nosubs */ - rtaMarkSubs(isubs, mi); - } - subs = subs->nextClass; - } - - /*--- XTA ---*/ - if ((XTAOPTbypass2) || (opt_xta)) - { - xtaMarkInterfaceSubs(mi); - } - } - break; - - /* miscellaneous object operations *******/ + methodinfo *mi; + + m->isleafmethod = false; + mr = m->class->cpinfos[i]; + /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/ + LAZYLOADING(mr->class) + mi = class_resolveclassmethod(mr->class, + mr->name, + mr->descriptor, + m->class, + false); + + + if (mi) + { + METHINFOt(mi,"INVOKEVIRTUAL ::",DEBUGopcodes); + if ((mi->flags & ACC_STATIC) + || (mi->flags & ACC_PRIVATE) + || (mi->flags & ACC_FINAL) ) + { + if (mi->class->classUsed == NOTUSED){ + addClassInit(mi->class, + CLINITS_T,FINALIZE_T,ADDMARKED_T); + } + mi->monoPoly = MONO; + addToRtaWorkList(mi, + "addTo INVOKEVIRTUAL "); + } + else { + mi->monoPoly = POLY; + rtaMarkSubs(mi->class,mi); + } + } + else { +CLASSNAME1(mr->class,"CouldNOT Resolve virt meth:",DEBUGr);printf(".");fflush(stdout); +utf_display(mr->name); printf(" "); fflush(stdout); +utf_display(mr->descriptor); printf("\n");fflush(stdout); + } + } + break; - case JAVA_NEW: - i = rt_code_get_u2 (p+1); + case JAVA_INVOKEINTERFACE: + i = code_get_u2(p + 1,m); + { + constant_FMIref *mr; + methodinfo *mi; + + m->isleafmethod = false; + + mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref); + LAZYLOADING(mr->class) + + mi = class_resolveinterfacemethod(mr->class, + mr->name, + mr->descriptor, + m->class, + false); + if (mi) + { + METHINFOt(mi,"\tINVOKEINTERFACE: ",DEBUGopcodes) + rtaMarkInterfaceSubs(mi); + } + /* see INVOKESTATIC for explanation about */ + /* case when Interface is not resolved */ + /*descriptor2types(mi); + ?? do need paramcnt? for RTA (or just XTA)*/ + } + break; + + case JAVA_NEW: + /* means class is at least passed as a parameter */ + /* class is really instantiated when class. called*/ + i = code_get_u2(p + 1,m); { - classinfo *ci; - - ci = class_getconstant (rt_class, i, CONSTANT_Class); - if (pWhenMarked >= 1) { - printf("\tclass=");fflush(stdout); - utf_display(ci->name); fflush(stdout); - printf("=\n");fflush(stdout); - } - /*--- RTA ---*/ - if (ci->classUsed != USED) { - RTAPRINT10new - ci->classUsed = USED; /* add to heirarchy */ - /* Add this class to the implemented by list of the abstract interface */ - addUsedInterfaceMethods(ci); - addClassInit(ci); - } - /*--- XTA ---*/ - if ((XTAOPTbypass) || (opt_xta)) - { - rt_method->xta->XTAclassSet = add2ClassSet(rt_method->xta->XTAclassSet,ci ); /*XTA*/ - RTAPRINT10newXTA - } + classinfo *ci; + ci = class_getconstant(m->class, i, CONSTANT_Class); + m->isleafmethod = false; /* why for new ? */ + /*** s_count++; look for s_counts for VTA */ + /***ci->classUsed=USED; */ + /* add marked methods */ + CLASSNAME(ci,"NEW : do nothing",DEBUGr); + addClassInit(ci, CLINITS_T, FINALIZE_T,ADDMARKED_T); } - break; + break; + + case JAVA_CHECKCAST: + case JAVA_INSTANCEOF: + /* class used */ + i = code_get_u2(p + 1,m); + { + classinfo *cls = + (classinfo *) + class_getconstant(m->class, i, CONSTANT_Class); + LAZYLOADING(cls) + CLASSNAMEop(cls,DEBUGr); + if (cls->classUsed == NOTUSED){ + addClassInit(cls, + CLINITS_T,FINALIZE_T,ADDMARKED_T); + } + } + break; default: break; - + } /* end switch */ + } /* end for */ - } /* end for */ - - if (p != rt_jcodelength) - panic("Command-sequence crosses code-boundary"); - - if ((XTAOPTbypass) || (opt_xta)) - xtaMethodCalls_and_sendReturnType(); - - + return rc; } -/*-------------------------------------------------------------------------------*/ -/* RTA add Native Methods/ Class functions */ -/*-------------------------------------------------------------------------------*/ -void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) { - - classinfo *class; - methodinfo *meth; - - class = class_get(c1); - if (class == NULL) { - return; /*Note: Since NativeCalls is for mult programs some may not be loaded - that's ok */ - } - - if (class->classUsed == NOTUSED) { - class->classUsed = USED; /* MARK CLASS USED */ - /* add marked methods to callgraph */ - addMarkedMethods(class); - } +/* Helper fn for initialize **********************************************/ - meth = class_findmethod (class, m1, d1); - if (meth == NULL) { - utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1); - printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n"); - } - else - rtaMarkSubs(class,meth); +int getline(char *line, int max, FILE *inFP) { +if (fgets(line, max, inFP) == NULL) + return 0; +else + return strlen((const char *) line); } -/*-------------------------------------------------------------------------------*/ - -void findMarkNativeUsedClass (utf * c) { - classinfo *class; - - class = class_get(c); - if (class == NULL) panic("parseRT: Class used by Native method called not loaded!!!"); - class->classUsed = USED; +/* Initialize RTA Work list ***********************************************/ + +/*-- Get meth ptr for class.meth desc and add to RTA worklist --*/ +#define SYSADD(cls,meth,desc,txt) \ + c = class_new(utf_new_char(cls)); \ + LAZYLOADING(c) \ + callmeth = class_resolveclassmethod(c, \ + utf_new_char(meth), \ + utf_new_char(desc), \ + c, \ + false); \ + if (callmeth->class->classUsed != USED) { \ + c->classUsed = PARTUSED; \ + addClassInit(callmeth->class, \ + CLINITS_T,FINALIZE_T,ADDMARKED_T);\ + } \ + callmeth->monoPoly = POLY; \ + addToRtaWorkList(callmeth,txt); + + +/*-- + Initialize RTA work list with methods/classes from: + System calls + and + rtMissedIn list (missed becaused called from NATIVE &/or dynamic calls +--*/ +methodinfo *initializeRTAworklist(methodinfo *m) { + classinfo *c; + methodinfo* callmeth; + char systxt[] = "System Call :"; + char missedtxt[] = "rtMissedIn Call :"; + + FILE *rtMissedIn; /* Methods missed during previous RTA parse */ + char line[256]; + char* class, *meth, *desc; + methodinfo *rm =NULL; /* return methodinfo ptr to main method */ + + + /* Create RTA call work list */ + rtaWorkList = NEW(list); + list_init(rtaWorkList, OFFSET(rtaNode,linkage) ); + + /* Add first method to call list */ + m->class->classUsed = USED; + addToRtaWorkList(m,systxt); + + /* Add system called methods */ + SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt) + rm = callmeth; + SYSADD("java/lang/System","exit","(I)V",systxt) + /*----- rtMissedIn 0 */ + if ( (rtMissedIn = fopen("rtMissedIn0", "r")) == NULL) { + /*if (opt_verbose) */ + {printf("No rtMissedIn0 file\n");fflush(stdout);} + return rm; + } + while (getline(line,256,rtMissedIn)) { + class = strtok(line, " \n"); + meth = strtok(NULL, " \n"); + desc = strtok(NULL, " \n"); + SYSADD(class,meth,desc,missedtxt) + } + fclose(rtMissedIn); + + + + + return rm; - /* add marked methods to callgraph */ - addMarkedMethods(class); } +/*- end initializeRTAworklist-------- */ -/*-------------------------------------------------------------------------------*/ - -void markNativeMethodsRT(utf *rt_class, utf* rt_method, utf* rt_descriptor) { - int i,j,k; - bool found = false; - - nativecallcompdone = natcall2utf(nativecallcompdone); - - for (i=0; isub != NULL) { - RTAPRINT16stats1; - } - - if (firstCall) { - firstCall=false; - - utf_MAIN = utf_new_char("main"); - INIT = utf_new_char(""); - CLINIT = utf_new_char(""); - FINALIZE = utf_new_char("finalize"); - EMPTY_DESC= utf_new_char("()V"); - - if ( (rtMissed = fopen("rtMissed", "w")) == NULL) { - printf("CACAO - rtMissed file: can't open file to write\n"); - } - else { - fprintf(rtMissed,"To Help User create a dymLoad file \n"); - fprintf(rtMissed, - "Not parsed in the static analysis parse of Main: #rt parse / #missed class.method (descriptor) \n"); - fprintf(rtMissed,"\n\tBEFORE MAIN RT PARSE\n"); - fflush(rtMissed); - fclose(rtMissed); - } - callgraph = MNEW (methodinfo*, MAXCALLGRAPH); /****/ - if ((XTAOPTbypass) || (opt_xta)) { - printf("XTAXTA CALLGRAPHS allocated\n"); - XTAcallgraph = MNEW (methodinfo*, MAXCALLGRAPH); - } - } - - if (m->name == utf_MAIN) { - rtMissed = fopen("rtMissed","a"); - fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n"); - fclose(rtMissed); - AfterMain = true; - } - else { - if ( (rtMissed = fopen("rtMissed", "a")) == NULL) { - printf("CACAO - rtMissed file: can't open file to write\n"); - } - else { - fprintf(rtMissed,"#%i/#%i ",methRTlast+1,missedCnt++ ); - utf_fprint(rtMissed,m->class->name); - fprintf(rtMissed," "); - fprintflags(rtMissed,m->flags); - fprintf(rtMissed," "); - utf_fprint(rtMissed,m->name); - fprintf(rtMissed," "); - utf_fprint(rtMissed,m->descriptor); - fprintf(rtMissed,"\n"); - fflush(rtMissed); - fclose(rtMissed); - } - if (AfterMain) { - printf("#%i : ",methRT); - printf("Method missed by static analysis Main parse. See rtMissed file"); - /*** panic ("Method missed by static analysis Main parse. See rtMissed file");**/ - } - } - - /* At moment start RTA before main when parsed */ - /* Will definitely use flag with to know if ok to apply in-lining. */ + FILE *rtMissedIn; /* Methods missed during previous RTA parse */ + char filenameIn[256] = "rtIn/"; + char line[256]; + char* class, *meth, *desc; + char missedtxt[] = "rtIn/ missed Call :"; + classinfo *c; + methodinfo* callmeth; + + methodinfo *rm =NULL; /* return methodinfo ptr to main method */ + + /*----- rtMissedIn pgm specific */ + strcat(filenameIn, (const char *)mainstring); + if ( (rtMissedIn = fopen(filenameIn, "r")) == NULL) { + /*if (opt_verbose)*/ + {printf("No rtIn/=%s file\n",filenameIn);fflush(stdout);} + return rm; + } + while (getline(line,256,rtMissedIn)) { + class = strtok(line, " \n"); + meth = strtok(NULL, " \n"); + desc = strtok(NULL, " \n"); + if ((class == NULL) || (meth == NULL) || (desc == NULL)) { + fprintf(stderr,"Error in rtMissedIn file for: %s.%s %s\n",class, meth, desc); + fflush(stderr); + panic ("Error in rtMissedIn file for: class.meth, desc\n"); + } + SYSADD(class,meth,desc,missedtxt) + } + fclose(rtMissedIn); + return rm; } -/*-------------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------------*/ -/* still need to look at field sets in 2nd pass and clinit ..... */ -void XTA_jit_parse2(methodinfo *m) -{ - if (XTAdebug >= 1) - printf("\n\nStarting Round 2 XTA !!!!!!!!!!!!!!\n"); - - /* for each method in XTA worklist = callgraph (use RTA for now) */ - methRT=0; - while (methRT <= methRTlast) { - rt_method = callgraph[methRT]; - rt_class = rt_method->class; - rt_descriptor = rt_method->descriptor; - rt_jcodelength = rt_method->jcodelength; - rt_jcode = rt_method->jcode; - - if (! ( (rt_method->flags & ACC_NATIVE ) - || (rt_method->flags & ACC_ABSTRACT) ) ) { - if (XTAdebug >= 1) { - printf("\n!!!!! XTA Round 2 Parse of #%i:",methRT);fflush(stdout); - utf_display(rt_class->name); printf("."); fflush(stdout); - method_display(rt_method); - } - /* if XTA type set changed since last parse */ - if (rt_method->xta->chgdSinceLastParse) { - - /* get types from methods it is calledBy */ - xtaPassAllCalledByParams (); - - /* Pass parameter types to methods it calls and send the return type those called by */ - xtaMethodCalls_and_sendReturnType(); - } - } - methRT++; - } - if (XTAdebug >= 1) { - - printf("\n\nEND_OF Round 2 XTA !!!!!!!!!!!!!!\n"); - printXTACallgraph (); - } - - RTAPRINT14CallgraphLast /*was >=2 */ - RTAPRINT15HeirarchyiLast /*was >= 2 */ - } +/*--------------------------------------------------------*/ +/* parseRTmethod */ +/* input: method to be RTA static parsed */ +/*--------------------------------------------------------*/ +void parseRTmethod(methodinfo *rt_method) { + if (! ( (rt_method->flags & ACC_NATIVE ) + || (rt_method->flags & ACC_ABSTRACT) ) ) + { + /* RTA parse to approxmate.... + what classes/methods will really be used during execution */ + parseRT(rt_method); + } + else { + if (rt_method->flags & ACC_NATIVE ) + { + METHINFOt(rt_method,"TO BE NATIVE RTA PARSED :",DEBUGopcodes); + /* parseRTpseudo(rt_method); */ + } + else { + printf("Abstract method in RTA Work List: "); + METHINFOx(rt_method); + panic("Abstract method in RTA Work List."); + } + } +} -/*-------------------------------------------------------------------------------*/ -void RT_jit_parse(methodinfo *m) +/*-- RTA -- *******************************************************/ +int RT_jit_parse(methodinfo *m) { - /*-- RTA --*/ - if (m->methodUsed == USED) return; - mainRTAparseInit (m); - - /* initialise parameter type descriptor */ - callgraph[++methRTlast] = m; /*-- RTA --*/ - m->methodUsed = USED; - RTAPRINT11addedtoCallgraph - /* then like a new class so add marked methods to callgraph */ - if (m->name == INIT) { /* need for s parsed efore Main */ - classinfo *ci; - ci = m->class; - ci->classUsed = USED; - if (pWhenMarked >= 1) { - printf("Class=");utf_display(ci->name); - } - /* add marked methods to callgraph */ - RTAPRINT11addedtoCallgraph2 - addMarkedMethods(ci); - } /* if */ - - /*-- XTA --*/ - if ((XTAOPTbypass) || (opt_xta)) { - XTAcallgraph[++methXTAlast] = m; - if (m->xta == NULL) { - m->xta = xtainfoInit(m); - } - m->xta->XTAmethodUsed = USED; - {methodinfo *mi = m; - XTAPRINTcallgraph2 - } - } + rtaNode *rta; + methodinfo *mainmeth; - /*-- Call graph work list loop -----------------*/ + /* Should only be called once */ + if (firstCall) { - while (methRT <= methRTlast) { - rt_method = callgraph[methRT]; - rt_class = rt_method->class; - rt_descriptor = rt_method->descriptor; - rt_jcodelength = rt_method->jcodelength; - rt_jcode = rt_method->jcode; + /*----- RTA initializations --------*/ + if (opt_verbose) + log_text("RTA static analysis started.\n"); - if (! ( (rt_method->flags & ACC_NATIVE ) - || (rt_method->flags & ACC_ABSTRACT) ) ) { - parseRT(); - } - else { - RTAPRINT12bAbstractNative - if (rt_method->flags & ACC_NATIVE ) { - RTAPRINT12aNative - /* mark used and add to callgraph methods and classes used by NATIVE method */ - markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor); - } - if (rt_method->flags & ACC_ABSTRACT) { - panic("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n"); - } - } - methRT++; - RTAPRINT12Callgraph - RTAPRINT13Heirarchy - } /* while */ - - - if (m->class->classUsed == NOTUSED) - m->class->classUsed = USED; /* say Main's class has a method used ??*/ - printXTACallgraph (); - RTAPRINT14CallgraphLast /* was >=2*/ - //RTAPRINT15HeirarchyiLast /*was >= 2 */ - - if ((XTAOPTbypass) || (opt_xta)) { - /*--- XTA round 2+ "parse" - use info structures only so not a real parse */ - XTA_jit_parse2(m); - } - /**** DO NOT free if RTA or XTA for now -if (m->name == utf_MAIN) { - MFREE(callgraph,methodinfo*,MAXCALLGRAPH); - if ((XTAOPTbypass) || (opt_xta)) { - printf("XTAXTA CALLGRAPHS returned \n"); - MFREE(XTAcallgraph,methodinfo*,MAXCALLGRAPH); - } - } -****/ + mainmeth = initializeRTAworklist(m); + firstCall = false; /* turn flag off */ - return; + if ( (rtMissed = fopen("rtMissed", "w")) == NULL) { + printf("CACAO - rtMissed file: cant open file to write\n"); + } + /* Note: rtMissed must be renamed to rtMissedIn to be used as input */ + + /*------ process RTA call work list --------*/ + for (rta =list_first(rtaWorkList); + rta != NULL; + rta =list_next(rtaWorkList,rta)) + { + parseRTmethod(rta->method); + } + missedRTAworklist(); + for (rta =list_first(rtaWorkList); + rta != NULL; + rta =list_next(rtaWorkList,rta)) + { + parseRTmethod(rta->method); + } + + fclose(rtMissed); + if (opt_verbose) { + if (opt_stat) { + printRThierarchyInfo(m); + } + printCallgraph(rtaWorkList); + } + + if (opt_verbose) { + log_text("RTA static analysis done.\n"); + } + } +return 0; } - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where @@ -1684,3 +968,4 @@ if (m->name == utf_MAIN) { * tab-width: 4 * End: */ +