Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at
Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: global.h 466 2003-09-25 07:55:50Z carolyn $
+ Last Change: $Id: global.h 468 2003-10-04 17:15:31Z carolyn $
*******************************************************************************/
typedef struct classinfo classinfo;
typedef struct vftbl vftbl;
typedef u1* methodptr;
+typedef struct fieldinfo fieldinfo;
+typedef struct methodinfo methodinfo;
/* constant pool entries *******************************************************
struct constant_arraydescriptor *elementdescriptor;
} constant_arraydescriptor;
+#include "jit/sets.h"
/* data structures of the runtime system **************************************/
/* fieldinfo ******************************************************************/
-typedef struct fieldinfo {/* field of a class */
+struct fieldinfo { /* field of a class */
s4 flags; /* ACC flags */
s4 type; /* basic data type */
utf *name; /* name of field */
double d;
void *a;
} value;
-
-} fieldinfo;
+
+ /*--- XTA ---*/
+ s4 fieldUsed; /* initialized to NOTUSED; set to USED when type checked */
+ bool fieldChecked;
+ classinfo *fldClassType;
+ classSet *XTAclassSet; /* field class type set */
+ s4 lastRoundChgd;
+ /*--- VTA ---*/
+ s4 VTAfieldUsed; /* -1=marked (might be used) 0=not used 1=used */
+ classSetNode *VTAclassSet; /* field class type set */
+
+} ;
struct basicblock;
} exceptiontable;
+/* methodinfo static info ****************************************************/
+/*typedef struct rtainfo {
+
+} rtainfo; */
/* methodinfo *****************************************************************/
-typedef struct methodinfo { /* method structure */
- s4 flags; /* ACC flags */
+struct methodinfo { /* method structure */
+ s4 flags; /* ACC flags */
utf *name; /* name of method */
utf *descriptor; /* JavaVM descriptor string of method */
s4 returntype; /* only temporary valid, return type */
+ classinfo *returnclass; /* pointer to classinfo for the rtn type */ /*XTA*/
s4 paramcount; /* only temporary valid, parameter count */
u1 *paramtypes; /* only temporary valid, parameter types */
+ classinfo **paramclass; /* pointer to classinfo for a parameter */ /*XTA*/
+
classinfo *class; /* class, the method belongs to */
s4 vftblindex; /* index of method in virtual function table
(if it is a virtual method) */
u1 *mcode; /* pointer to machine code */
u1 *entrypoint; /* entry point in machine code */
- s4 methodUsed; /* -1=marked (might be used) 0=not used 1=used CO-RT*/
- s4 numSubDefs; /* # sub definitions marked USED */
+ /*rtainfo rta;*/
+ /*xtainfo xta;*/
- s4 natCalls; /* number of methods calls */
+ s4 methodUsed; /* marked (might be used later) /not used /used */
+ s4 monoPoly; /* call is mono or poly or unknown */ /*RT stats */
+ /* should # method def'd and used be kept after static parse (will it be used?) */
+ s4 subRedefs;
+ s4 subRedefsUsed;
- s4 XTAclasscount; /* number of classes in XTA class set */
- classinfo *XTAclassSet; /* XTA class set*/
-
+ /* --- XTA --- */
+ s4 XTAmethodUsed; /* XTA if used in callgraph - not used /used */
+ classSet *XTAclassSet; /* method class type set */
+ classSet *PartClassSet; /* method class type set */
+
+ classSetNode *paramClassSet; /* cone set of methods parameters */
+
+ methSet *calls; /* methods this method calls */
+ methSet *calledBy; /* methods that call this method */
+ methSet *marked; /* methods that marked by this method */
+ methSet *markedBy;
+ fldSet *fldsUsed; /* fields used by this method */
+ bool chgdSinceLastParse; /* Changed since last parse ? */
+
+ s4 lastRoundParsed; /* Last round parsed */
+ methSetNode *interfaceCalls; /* methods this method calls as interface */
+
+ /* --- VTA --- */
+ classSetNode *VTAclassSet; /* method class type set */
+ methSetNode *VTAcalls; /* methods this method calls */
+ classSetNode **VTAlocalSets; /*VTA*/
+ classSetNode **VTAstackType; /*VTA*/
+};
-} methodinfo;
/* innerclassinfo *************************************************************/
s4 instancesize; /* size of an instance of this class */
#ifdef SIZE_FROM_CLASSINFO
s4 alignedsize; /* size of an instance, aligned to the
- allocation size on the heap */
+ allocation size on the heap */
#endif
vftbl *vftbl; /* pointer to virtual function table */
s4 classUsed; /* 0= not used 1 = used CO-RT */
- classinfo *impldBy; /* implemented by class pointer */
- classinfo *nextimpldBy; /* ptr to next class in impldBy class list */
-
+ classSetNode *impldBy; /* implemented by class set */
};
extern bool verbose;
extern bool opt_rt; /* Rapid Type Analysis for better inlining CO-RT*/
extern bool opt_xta; /* X Type Analysis for better inlining CO-XTA*/
+extern bool opt_vta; /* Variable Type Analysis for better inlining CO-VTA*/
extern int pClassHeir;
extern int pCallgraph;
void removecompilerstub (u1 *stub);
void removenativestub (u1 *stub);
+/*------------ Method /Class Used Markers -------------------------------*/
+
+/* Class flags =
+ USED all methods and fields are available;
+ PARTUSED = specific methods (static, <init>, <clinit>, inherited def used, special) used,
+ but not instanciated
+ NOTUSED = nothing used in class - not needed
+*/
+
+/* Method Flags =
+ USED = method definition is used
+ PARTUSED = method definition will be used if class instanciated
+ NOTUSED = method defintion never used
+*/
+
+#define USED 2
+#define PARTUSED 1
+#define MARKED 1
+#define NOTUSED 0
+
+#define MONO 0
+#define MONO1 1 /* potential poly that is really mono */
+#define POLY 2
#endif
-EXTRA_DIST = mcode.c parse.c reg.c stack.c jitdef.h inline.c parseRT.h parseXTA.h
+EXTRA_DIST = mcode.c parse.c reg.c stack.c jitdef.h inline.c sets.h sets.c parseRT.h parseXTA.h parseRTstats.h sets.h sets.c
Author: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: parse.c 467 2003-09-26 01:55:25Z didi $
+ Last Change: $Id: parse.c 468 2003-10-04 17:15:31Z carolyn $
include Rapid Type Analysis parse - 5/2003 - carolyn
*******************************************************************************/
#include "math.h"
+#include "sets.h"
/* data about the currently parsed method */
static classinfo *rt_class; /* class the compiled method belongs to */
-//INLINING
+/*INLINING*/
#include "inline.c"
-//#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);
+/*#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);*/
#define debug_writebranch
/* functionc compiler_addinitclass *********************************************
}
+/* function descriptor2typesL ***************************************************
+
+ decodes a already checked method descriptor. The parameter count, the
+ return type and the argument types are stored in the passed methodinfo.
+ gets and saves classptr for object ref.s
+
+*******************************************************************************/
+
+classSetNode * descriptor2typesL (methodinfo *m)
+{
+int debugInfo = 0;
+ int i;
+ u1 *types, *tptr;
+ int pcount, c;
+ char *utf_ptr;
+ classinfo** classtypes;
+ char *class;
+ char *desc;
+ classSetNode *p=NULL;
+if (debugInfo >= 1) {
+ printf("In descriptor2typesL >>>\t"); fflush(stdout);
+ utf_display(m->class->name); printf(".");
+ method_display(m);fflush(stdout);
+ }
+
+ pcount = 0;
+ desc = MNEW (char, 256);
+ types = DMNEW (u1, m->descriptor->blength);
+ classtypes = MNEW (classinfo*, m->descriptor->blength+1);
+ m->returnclass = NULL;
+ tptr = types;
+ if (!(m->flags & ACC_STATIC)) {
+ *tptr++ = TYPE_ADR;
+ if (debugInfo >= 1) {
+ printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
+ }
+ classtypes[pcount] = m->class;
+ p = addClassCone(p, m->class);
+ pcount++;
+ }
+
+ utf_ptr = m->descriptor->text + 1;
+ strcpy (desc,utf_ptr);
+
+ while ((c = *desc++) != ')') {
+ pcount++;
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': *tptr++ = TYPE_INT;
+ break;
+ case 'J': *tptr++ = TYPE_LNG;
+ break;
+ case 'F': *tptr++ = TYPE_FLT;
+ break;
+ case 'D': *tptr++ = TYPE_DBL;
+ break;
+ case 'L': *tptr++ = TYPE_ADR;
+ /* get class string */
+ class = strtok(desc,";");
+ desc = strtok(NULL,"\0");
+ /* get/save classinfo ptr */
+ classtypes[pcount-1] = class_get(utf_new_char(class));
+ p = addClassCone(p, class_get(utf_new_char(class)));
+ if (debugInfo >= 1) {
+ printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
+ printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
+ utf_display(classtypes[pcount-1]->name);
+ }
+ break;
+ case '[': *tptr++ = TYPE_ADR;
+ while (c == '[')
+ c = *desc++;
+ /* get class string */
+ if (c == 'L') {
+ class = strtok(desc,";");
+ desc = strtok(NULL,"\0");
+ /* get/save classinfo ptr */
+ classtypes[pcount-1] = class_get(utf_new_char(class));
+ p= addClassCone(p, class_get(utf_new_char(class)));
+ if (debugInfo >= 1) {
+ printf("[Param#%i 's class type is: %s\n",pcount-1,class);
+ printf("[classtypes[%i]=",pcount-1);fflush(stdout);
+ utf_display(classtypes[pcount-1]->name);
+ printf("\n");
+ }
+ }
+ else
+ classtypes[pcount-1] = NULL;
+ break;
+ default:
+ panic("Ill formed methodtype-descriptor");
+ }
+ }
+
+ /* compute return type */
+ switch (*desc++) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': m->returntype = TYPE_INT;
+ break;
+ case 'J': m->returntype = TYPE_LNG;
+ break;
+ case 'F': m->returntype = TYPE_FLT;
+ break;
+ case 'D': m->returntype = TYPE_DBL;
+ break;
+ case '[':
+ m->returntype = TYPE_ADR;
+ c = *desc;
+ while (c == '[')
+ c = *desc++;
+ if (c != 'L') break;
+ *desc++;
+
+ case 'L':
+ m->returntype = TYPE_ADR;
+
+ /* get class string */
+ class = strtok(desc,";");
+ m->returnclass = class_get(utf_new_char(class));
+ if (m->returnclass == NULL) {
+ printf("class=%s :\t",class);
+ panic ("return class not found");
+ }
+ break;
+ case 'V': m->returntype = TYPE_VOID;
+ break;
+
+ default: panic("Ill formed methodtype-descriptor-ReturnType");
+ }
+
+ m->paramcount = pcount;
+ m->paramtypes = types;
+ m->paramclass = classtypes;
+
+if (debugInfo >=1) {
+ if (pcount > 0) {
+ for (i=0; i< m->paramcount; i++) {
+ if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
+ printf("Param #%i is:\t",i);
+ utf_display(m->paramclass[i]->name);
+ printf("\n");
+ }
+ }
+ }
+ if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
+ printf("\tReturn Type is:\t"); fflush(stdout);
+ utf_display(m->returnclass->name);
+ printf("\n");
+ }
+
+ printf("params2types: START results in a set \n");
+ printf("param2types: A Set size=%i=\n",sizeOfSet(p));
+ printSet(p);
+ }
+
+return p;
+}
+
/* function descriptor2types ***************************************************
decodes a already checked method descriptor. The parameter count, the
panic("branch target out of code-boundary");}
#define bound_check1(i) {if((i< 0) || (i>cumjcodelength)) \
panic("branch target out of code-boundary");}
-// FIXME really use cumjcodelength for the bound_checkers ?
+/* FIXME really use cumjcodelength for the bound_checkers ? */
static xtable* fillextable (xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
{
bool useinltmp;
static int xta1 = 0;
-//INLINING
+/*INLINING*/
if (useinlining)
{
label_index = inlinfo->label_index;
exceptiontablelength=cumextablelength;
}
- useinltmp = useinlining; //FIXME remove this after debugging
- //useinlining = false; // and merge the if-statements
+ useinltmp = useinlining; /*FIXME remove this after debugging */
+ /*useinlining = false; /* and merge the if-statements */
if (!useinlining) {
cumjcodelength = jcodelength;
if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
}
- /*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
+ /*RTAprint*/ if ( ((opt_rt) ||(opt_xta) || (opt_vta)) && ((pOpcodes == 2) || (pOpcodes == 3)) )
/*RTAprint*/ {printf("PARSE method name =");
/*RTAprint*/ utf_display(method->class->name);printf(".");
/*RTAprint*/ method_display(method); printf(">\n\n");fflush(stdout);}
- if (opt_rt) {
+ if ((opt_rt) || (opt_xta)) {
RT_jit_parse(method);
}
- else {
- if ((opt_xta) && (xta1 == 0)) {
- /*printf("XTA - not available yet\n"); */
- /*xta1++; */
- XTA_jit_parse(method);
- /*XTAprint*/ if (((pOpcodes == 1) || (pOpcodes == 3)) && opt_rt)
- /*XTAprint*/ {printf("XTA PARSE method name =");
- /*XTAprint*/ utf_display(rt_method->class->name);printf(".");
- /*XTAprint*/ method_display(rt_method); printf(">\n\n");fflush(stdout);}
-
- }
-
- }
+ else {
+ if (opt_vta)
+ printf("VTA requested, but not yet implemented\n");
+ }
+
#ifdef OLD_COMPILER
/* generate the same addresses as the old JIT compiler */
for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
- // DEBUG printf("p:%d gp:%d ",p,gp);
+ /* DEBUG printf("p:%d gp:%d ",p,gp); */
-//INLINING
+/*INLINING*/
if ((useinlining) && (gp == nextgp)) {
u1 *tptr;
bool *readonly = NULL;
op += *tptr;
OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
- // block_index[gp] |= (ipc << 1); //FIXME: necessary ?
+ /* block_index[gp] |= (ipc << 1); /*FIXME: necessary ? */
}
inlining_save_compiler_variables();
inlining_set_compiler_variables(tmpinlinf);
}
opcode = code_get_u1 (p); /* fetch op code */
-
+
/*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
/*RTAprint*/ {printf("Parse<%i> p=%i<%i< opcode=<%i> %s\n",
/*RTAprint*/ pOpcodes, p,rt_jcodelength,opcode,icmd_names[opcode]);}
-
block_index[gp] |= (ipc << 1); /* store intermediate count */
if (isinlinedmethod) {
- /* if (p==jcodelength-1) { //return is at end of inlined method
+ /* if (p==jcodelength-1) { /*return is at end of inlined method **
OP(ICMD_NOP);
break;
- }*/
+ } */
blockend = true;
OP1(ICMD_GOTO, inlinfo->stopgp);
break;
/* INLINING */
- if ((isinlinedmethod) && (p==jcodelength-1)) { //end of an inlined method
- // printf("setting gp from %d to %d\n",gp, inlinfo->stopgp);
+ if ((isinlinedmethod) && (p==jcodelength-1)) { /*end of an inlined method */
+ /* printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
gp = inlinfo->stopgp;
inlining_restore_compiler_variables();
list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
tmpinlinf = list_first(inlinfo->inlinedmethods);
nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
}
- // printf("nextpgp: %d\n", nextgp);
+ /* printf("nextpgp: %d\n", nextgp); */
label_index=inlinfo->label_index;
firstlocal = inlinfo->firstlocal;
}
if (useinlining) inlining_cleanup();
useinlining = useinltmp;
}
-
+#include "sets.c"
#include "parseRT.h"
-#include "parseXTA.h"
/*
* These are local overrides for various environment variables in Emacs.
+++ /dev/null
-/*
-/* Defines of debug / trace /info prints
-/* to make the actual code more readable
-/*
-/* opcodes that are not RTA - to gather info
-/*
-/* Empty no print version
-*/
-
-#define INFOP01newarray
-
-#define INFOP02anewarray
-
-#define INFOP03multianewarray
-
-#define INFOP03multianewarrayX
-
#include "natcalls.h"
#include "parseRTprint.h" /* RTAPRINT trace/info/debug prints */
-
-/*------------ Method /Class Used Markers -------------------------------*/
-#define USED 1
-#define NOTUSED 0
-#define JUSTMARKED -1
-
-/* class only */
-#define METH_USED_BY_SUB -1
-#define MARKEDSUPER -2
+#include "sets.h"
/*------------ global variables -----------------------------------------*/
+#define MAXCALLGRAPH 5000
+
+bool XTAOPTbypass = false;
+bool XTAOPTbypass2 = false; /* for now invokeinterface */
+bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
+int XTAdebug = 0;
+int XTAfld = 0;
+
+int I; /* ASTORE /ALOAD index */
+
int methRT = 0;
int methRTlast = -1;;
-int methRTmax=5000;
-methodinfo *callgraph[5000];
+int methRTmax=MAXCALLGRAPH;
+methodinfo *callgraph [MAXCALLGRAPH];
+
+
+int methXTA = 0;
+int methXTAlast = -1;;
+int methXTAmax=MAXCALLGRAPH;
+methodinfo *XTAcallgraph[MAXCALLGRAPH];
static bool nativecallcompdone=0 ;
-static bool mainStarted = false;
static bool firstCall= true;
static FILE *rtMissed; /* Methods missed during RTA parse of Main */
- /* so easier to build dynmanic calls file */
-static FILE *dynClasss; /* Classes /methods used, but seen by static analysis */
+ /* so easier to build dynmanic calls file */
-static utf *INIT ;
-static utf *CLINIT ;
-static utf *FINALIZE;
+static utf *utf_MAIN; /* utf_new_char("main"); */
+static utf *INIT ; /* utf_new_char("<init>"); */
+static utf *CLINIT ; /* utf_new_char("<clinit>"); */
+static utf *FINALIZE; /* utf_new_char("finalize"); */
+static utf *EMPTY_DESC; /* utf_new_char("V()"); */
static int missedCnt = 0;
-/*--- Statistics ----------------------------------------------------------*/
-
-int unRTclassHeirCnt=0;
-int unRTmethodCnt = 0;
-
-/*-----*/
-int RTclassHeirNotUsedCnt=0;
-int RTclassHeirUsedCnt=0;
-int RTclassHeirBySubCnt=0;
-int RTclassHeirSuperCnt=0;
-
-int RTmethodNotUsedCnt = 0;
-int RTmethodNotUsedCnt1= 0;
-int RTmethodNotUsedCnt2= 0;
-int RTmethodUsedCnt = 0;
-int RTmethodMarkedCnt= 0;
-
-/* What might be inlined of the Used Methods */
-int RTmethodFinal = 0;
-int RTmethodStatic = 0;
-int RTmethodFinalStatic = 0;
-int RTmethodNoSubs = 0;
-
-int RTmethodFinal100 = 0;
-int RTmethodStatic100 = 0;
-int RTmethodFinalStatic100 = 0;
-int RTmethodNoSubs100 = 0;
-
-#define MAXCODLEN 10
-
-int RTmethodNoSubsAbstract = 0;
-int RTmethod1Used = 0;
-
-/*------------- RTAprint flags ------------------------------------------------------------------*/
-int pCallgraph = 0; /* 0 - dont print 1 - print at end from main */
- /* 2 - print at end of RT parse call */
- /* 3- print after each method RT parse */
-int pClassHeir = 1; /* 0 - dont print 1 - print at end from main */
- /* 2 - print at end of RT parse call 3-print after each method RT parse */
-int pClassHeirStatsOnly = 1; /* Print only the statistical summary info for class heirarchy */
-
-int pOpcodes = 0; /* 0 - don't print 1- print in parse RT 2- print in parse */
- /* 3 - print in both */
-int pWhenMarked = 0; /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
- /* 2 - print when marked+methods called */
- /* 3 - print when class/method looked at */
-int pStats = 0; /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
-
-/*-----------------------------------------------------------------------------------------------*/
-
-void printCallgraph ()
- { int i;
-
- for (i=0;i<=methRTlast;i++) {
- printf(" (%i): ",i);
- utf_display(callgraph[i]->class->name);
- printf(":");
- method_display(callgraph[i]);
- }
+static bool useArrayOpcodes = false;
+static bool useFieldOpcodes = false;
+static bool useObjectrefOpcodes = false;
+static bool useOtherOpcodes = false;
- printf("\n");
- }
-/*--------------------------------------------------------------*/
-void printObjectClassHeirarchy1() {
-if (pStats >= 1) {
- unRTclassHeirCnt=0;
- unRTmethodCnt = 0;
- printObjectClassHeirarchy(class_java_lang_Object);
- printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
- unRTclassHeirCnt,unRTmethodCnt);
- }
-
-}
-/*--------------------------------------------------------------*/
-void printObjectClassHeirarchy(classinfo *class) {
-
-classinfo *subs;
-methodinfo *meth;
-int t,m,cnt;
-
-if (class == NULL) {return;}
- unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
- if (pStats == 2) {
- printf("\n");
- /* Class Name */
- for (t=0;t<class->index;t++) printf("\t");
- if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
-
- printf("Class: ");
- utf_display(class->name);
- printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
- /* Print methods used */
- cnt=0;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
- if (cnt == 0) {
- for (t=0;t<class->index;t++) printf("\t");
- printf("Methods used:\n");
- }
- for (t=0;t<class->index;t++) printf("\t");
- printf("\t");
- utf_display(meth->class->name);
- printf(".");
- method_display(meth);
- cnt++;
- }
- if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
- }
+static s4 currentXTAround = 0;
+static s4 prevXTAround = -1;
- for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- printObjectClassHeirarchy(subs);
- }
+#include "jit/parseRTstats.h"
-}
/*--------------------------------------------------------------*/
-/*--------------------------------------------------------------*/
-void printRTClassHeirarchy(classinfo *class) {
-
-
-
-classinfo *subs;
-methodinfo *meth;
-int m,cnt;
-
-if (class == NULL) {return;}
- /* Class Name */
- if (class->classUsed == NOTUSED) {
- RTclassHeirNotUsedCnt++;
- RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
- RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
- if (meth->methodUsed == USED) {
- if (pClassHeirStatsOnly >= 2) {
- printf("METHOD marked used in CLASS marked NOTUSED: ");
- utf_display(class->name);
- printf(".");
- method_display(meth);
- printf("<%i>\n\t",meth->methodUsed);
- fflush(stdout);
- panic("METHOD marked used in CLASS marked NOTUSED\n");
- }
- }
- }
+/* 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 <used flags c/m> <%i/%i> %i\t", \
+ meth->class->classUsed, \
+ meth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
+ utf_display(meth->class->name);printf("."); \
+ method_display(meth);fflush(stdout);} \
}
- if (class->classUsed != NOTUSED) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\nClass: ");
- utf_display(class->name);
- printf(" <%i> (depth=%i) ",class->classUsed,class->index);
- }
- if (class->classUsed == METH_USED_BY_SUB) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\tClass not instanciated - but methods resolved to this class' code\n");
- }
- RTclassHeirBySubCnt++;
- }
- else {
- if (class->classUsed == MARKEDSUPER) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\tClass not instanciated - but used by super init\n");
- }
- RTclassHeirSuperCnt++;
- }
- else {
- if (pClassHeirStatsOnly >= 2) {
- printf("\n");
- }
- RTclassHeirUsedCnt++;
- }
- }
-
- /* Print methods used */
- cnt=0;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
-
- if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
- if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt++;
- if (meth->methodUsed == JUSTMARKED) RTmethodMarkedCnt++;
- if (meth->methodUsed == USED) {
- RTmethodUsedCnt++;
- if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
- RTmethodFinal++;
- if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
- }
-
- if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
- RTmethodStatic++;
- if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
- }
-
- if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
- RTmethodFinalStatic++;
- if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
- }
-
- if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
- && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
- RTmethodNoSubs++;
- if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
- }
-
- if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
- && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
-
- if (pClassHeirStatsOnly >= 2) {
- if (cnt == 0) {
- printf("Methods used:\n");
- }
- cnt++;
- printf("\t");
- utf_display(meth->class->name);
- printf(".");
- method_display(meth);
- }
- }
- }
- if (pClassHeirStatsOnly >= 2) {
- if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
- }
- }
-
- for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- printRTClassHeirarchy(subs);
- }
-}
/*--------------------------------------------------------------*/
-
-void printRThierarchyInfo(methodinfo *m) {
-
- /*-- init for statistics --*/
- RTclassHeirNotUsedCnt=0;
- RTclassHeirUsedCnt=0;
- RTclassHeirBySubCnt=0;
- RTclassHeirSuperCnt=0;
- RTmethodNotUsedCnt = 0;
- RTmethodNotUsedCnt1 = 0;
- RTmethodNotUsedCnt2 = 0;
- RTmethodUsedCnt = 0;
- RTmethodMarkedCnt= 0;
-
-
- /*-- --*/
- if (pClassHeirStatsOnly >= 2) {
- printf("\nRT Class Heirarchy for ");
- printf("--- start of RT info --------------- after :\n");
- if (m != NULL) {
- utf_display(m->class->name);
- printf(".");
- method_display(m);
- printf("\n");
- }
- }
- printRTClassHeirarchy(class_java_lang_Object);
- if (pClassHeirStatsOnly >= 2) {
- printf("--- end of RT info ---------------\n");
- }
- if (pClassHeirStatsOnly >= 1) {
-
- /*-- statistic results --*/
- printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Heirarchy Statistics:\n");
- printf(" Used \t#%i \tclasses\t/ Used \t#%i methods \t of USED: %i%% \t of ALL: %i%% \n",
- RTclassHeirUsedCnt,RTmethodUsedCnt,
- ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
- ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
- printf(" Used by Subtype \t#%i \tclasses\t/\n",RTclassHeirBySubCnt);
- printf(" Used as Super \t#%i \tclasses\t/\n\n",RTclassHeirSuperCnt);
- printf(" Not Used \t#%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
- printf(" \t \t \t/ Just Marked \t#%i methods\n\n",RTmethodMarkedCnt);
- printf(" In Not Used \t \tclasses\t/ Not Used \t#%i methods\n",RTmethodNotUsedCnt1);
- printf(" In Used \t \tclasses\t/ Not Used \t#%i methods\n",RTmethodNotUsedCnt2);
- printf(" Total \t#%i \tclasses\t/ Total \t#%i methods\n\n",
- RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirBySubCnt + RTclassHeirSuperCnt,
- RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt );
-
- printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
- RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
- printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
- RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
- }
+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;
}
-/*--------------------------------------------------------------*/
-/* addToCallgraph - adds to RTA callgraph and */
-/* sets meth->methodUsed to USED */
-/* */
-/* To avoid unnecessary calls and dup entries in callgraph */
-/* meth should not be null */
-/* meth->methodUsed should be NOTUSED when called */
-/* meth's class should be USED */
-/* */
-/*--------------------------------------------------------------*/
-
-void addToCallgraph (methodinfo * meth) {
- int mfound =0;
- int im;
- int i;
-/* -- Pre-condition tests for adding method to call graph --*/
-if (meth==NULL) {panic("Trying to add a NULL method to callgraph"); return; }
-if (meth->methodUsed == USED) return; /*This should be test before fn call to avoid needless fn call */
- /* invokevirtual can be abstract */
- /* need to try to resolve /mark method */
- /* but... need document what should be */
- /* done / how to tell if doesn't resolved*/
-if (meth->flags & ACC_ABSTRACT) { /*printf("addToCallGraph returning because Abstract method\n"); */
- return;}
-
-if (meth->class->classUsed == NOTUSED) {
- if (pWhenMarked >= 1) {
- printf("AddToCallGraph method's class not used nor marked<%i> SUPER?\n",
- meth->class->classUsed);
- utf_display(meth->class->name);printf(".");
- utf_display(meth->name);printf("\n");
- panic("addToCallgraph called when class was NOTUSED\n");
- }
- return;
- }
-
- /*-- Add it to callgraph (mark used) --*/
- callgraph[++methRTlast] = meth ;
- RTAPRINTcallgraph1
- meth->methodUsed = USED;
-}
/*--------------------------------------------------------------*/
/* 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 JUSTMARKED
+/* -> 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 METH_USED_BY_SUB
+/* -> mark class with defined method as PARTUSED
/*--------------------------------------------------------------*/
-void markMethod(classinfo *class, methodinfo *topmethod) {
+void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
utf *name = topmethod -> name;
utf *descriptor = topmethod -> descriptor;
- s4 flags = topmethod -> flags;
-
methodinfo *submeth;
- methodinfo *initmeth;
- classinfo *ci;
- int m;
- submeth = class_findmethod(class, name, descriptor);
+ 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) {
- if (submeth != NULL) {
+ /*--- 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 JUSTMARKED
-*/
- if (submeth->class->classUsed != USED) {
- if (submeth->methodUsed == NOTUSED) {
- submeth->methodUsed = JUSTMARKED;
- RTAPRINTmarkMethod1
- } }
-
- else {
-
- /* Class marked used in some way and method defined in this class ->
- /* -> mark method as USED
- */
- if ((submeth ->methodUsed != USED) && (submeth->class->classUsed == USED)) {
- addToCallgraph(submeth);
- } }
- }
+ /* 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 {
- /* 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 METH_USED_BY_SUB
- */
-
- if (class->classUsed == USED) {
- classinfo *s = class->super;
- int found = 0;
- methodinfo *supermeth;
-
- while ((s!=NULL) && (found == 0)) {
- supermeth = class_findmethod(s, name, descriptor);
- if (supermeth != NULL) {
- found = 1;
- if ((s->classUsed == NOTUSED)
- || (s->classUsed == MARKEDSUPER)) {
-
- s->classUsed = METH_USED_BY_SUB;
- RTAPRINTmarkMethod2
- }
-
- if (supermeth->methodUsed !=USED) {
- addToCallgraph(supermeth);
- }
- } /* end if !NULL */
- else {
- s = s->super;
- } /* end else NULL */
- } /* end while */
-
- if ((s == NULL) && (found == 0))
- panic("parse RT: Method not found in class hierarchy");
- } /* if current class used */
-
- } /* end else Null */
+ /*--- 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 */
}
/*-------------------------------------------------------------------------------*/
/* and any subclass where the method is defined and/or class is used
/*
/*-------------------------------------------------------------------------------*/
-
-void markSubs(classinfo *class, methodinfo *topmethod) {
+void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
RTAPRINTmarkSubs1
- markMethod(class, topmethod); /* Mark method in class where it was found */
+ rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
if (class->sub != NULL) {
classinfo *subs;
- int subMcnt= 0;
if (!(topmethod->flags & ACC_FINAL )) {
for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
RTAPRINTmarkSubs1
- markSubs(subs, topmethod);
+ 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; ii<ci->methodscount; 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 */
+/*-------------------------------------------------------------------------------*/
+bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) {
+
+classSetNode *p;
+classSetNode *c;
+classSetNode *c1;
+classSetNode *cprev;
+bool rc = false;
+
+ if (XTAdebug >= 1) {
+ printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
+
+ printf("\tIN SmCalled set : ");
+ utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
+ printClassSet(SmCalled->XTAclassSet); printf("\n");
+
+ printf("\tIN SmCalls set: ");
+ utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
+ printClassSet(SmCalls->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->paramClassSet == NULL) {
+ SmCalled->paramClassSet = descriptor2typesL(SmCalled);
+ }
+ if (XTAdebug >= 1) {
+ printf("\tParamPassed\n"); fflush(stdout);
+ printSet(SmCalled->paramClassSet);fflush(stdout);
+ printf("\n"); fflush(stdout);
+ }
+
+if (lastptrInto->lastptrIntoClassSet2 == NULL) {
+ if (SmCalls->XTAclassSet != NULL)
+ c1 = SmCalls->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->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->XTAclassSet = SmCalled->XTAclassSet = add2ClassSet(SmCalled->XTAclassSet, c->classType);
+ rc = true;
+ }
+ cprev = c;
+ }
+ }
+lastptrInto->lastptrIntoClassSet2 = cprev;
+ if (XTAdebug >= 1) {
+ printf("\tOUT SmCalled set: ");fflush(stdout);
+ printClassSet(SmCalled->XTAclassSet);fflush(stdout);
+
+ printf("\tOUT SmCalls set: ");fflush(stdout);
+ printClassSet(SmCalls->XTAclassSet);fflush(stdout);
+
+ printf("\tOUT lastptrInto="); fflush(stdout);
+ if (lastptrInto->lastptrIntoClassSet2 != NULL)
+ utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
+
+ printf("<rc=%i>\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->paramClassSet == NULL)) {
+ SmCalled->paramClassSet = descriptor2typesL(SmCalled);
+ }
+
+if (SmCalled->returnclass == NULL) {
+ if (XTAdebug >= 1)
+ printf("\tReturn type is NULL\n");
+ return;
+ }
+
+ 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->XTAclassSet);
+
+ printf("\tIN SmCalled set: ");
+ utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
+ printClassSet(SmCalled->XTAclassSet);
+ }
+
+
+if (SmCalled->XTAclassSet == NULL)
+ cs1 = NULL;
+else
+ cs1 = SmCalled->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->XTAclassSet = add2ClassSet(SmCalls->XTAclassSet, c);
+ rc = true;
+ }
+ }
+
+ if (XTAdebug >= 1) {
+ printf("\tOUT SmCalls set: ");
+ printClassSet(SmCalls->XTAclassSet);
+ }
+return rc;
+}
+
+/*-------------------------------------------------------------------------------*/
+void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
+
+ if (mi->XTAmethodUsed != USED) { /* if static method not in callgraph */
+ XTAcallgraph[++methXTAlast] = mi;
+ mi->XTAmethodUsed = USED;
+ XTAPRINTcallgraph2
+ }
+ /* add call edges */
+ rt_method->calls = add2MethSet(rt_method->calls, mi);
+ rt_method->calls->tail->monoPoly = monoPoly;
+ mi->calledBy = add2MethSet(mi->calledBy, rt_method);
+if (mi->calledBy == NULL) panic("mi->calledBy is NULL!!!");
+if (rt_method->calls == NULL) panic("rt_method->calls is NULL!!!");
+}
+
+
+/*--------------------------------------------------------------*/
+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 xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
+{
+ utf *name = topmethod -> name;
+ utf *descriptor = topmethod -> descriptor;
+ methodinfo *submeth;
+
+/****
+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 (rt_method->calls != NULL) {
+ if (inMethSet(rt_method->calls->head,submeth)) return;
+ }
+ /*----*/
+ if (submeth->class == class) {
+
+ /*--- 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->marked = add2MethSet(rt_method->marked, submeth);
+ }
+ }
+ }
+ 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->marked = add2MethSet(rt_method->marked, submeth);
+ /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->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;
+}
+
+/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
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");
if (m1 >= 0) { /* No <clinit> available - ignore */
- /* Get clinit methodinfo ptr */
- mi = class_findmethod (ci,ci->methods[m1].name , NULL);
+ /* 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);
+ }
- if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
}
- }
if (mf >= 0) {
- /* Get finalize methodinfo ptr */
- mi = class_findmethod (ci,ci->methods[mf].name , NULL);
+ /* Get finalize methodinfo ptr */
+ mi = class_findmethod (ci,ci->methods[mf].name , NULL);
- if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
+ /*--- 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 */
/* Get clinit methodinfo ptr */
mi = class_findmethod (ci,ci->methods[m2].name , NULL);
+ /*--- RTA ---*/
if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
- }
- }
-
-/* add marked methods to callgraph */
-for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
+ mi->class->classUsed = PARTUSED;
+ ADDTOCALLGRAPH(mi)
}
- }
+ /*--- XTA ---*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ xtaAddCallEdges(mi,MONO);
+ }
+ }
+
+/* add marked methods to callgraph */
+addMarkedMethods(ci);
+
return m;
}
+(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
+
+/*-------------------------------------------------------------------------------*/
+/*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
+int ii,jj,mm;
+
+/* add used interfaces methods to callgraph */
+for (jj=0; jj < ci -> interfacescount; jj++) {
+ classinfo *ici = ci -> interfaces [jj];
+
+if (pWhenMarked >= 1) {
+ printf("BInterface used: ");fflush(stdout);
+ utf_display(ici->name);
+ printf("<%i>\t",ici -> classUsed ); fflush(stdout);
+ if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
+ if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
+ if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
+ fflush(stdout);
+ }
+ /* add class to interfaces list of classes that implement it */
+ ici -> impldBy = addElement(ici -> impldBy, ci);
+
+ /* if interface class is used */
+ if (ici -> classUsed != NOTUSED) {
+
+ /* 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 (imi->methodUsed != USED) {
+ if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
+ if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
+ utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+ }
+ }
+ if (imi->methodUsed == USED) {
+if (pWhenMarked >= 1) {
+ 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");
+ }
+ rtaMarkSubs(ci,imi);
+ }
+ }
+ }
+ }
+
+}
+/*-------------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------------*/
+void xtaMarkInterfaceSubs(methodinfo *mCalled) {
+ classSetNode * Si;
+ classinfo * Smi;
+
+ /* 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;
+
+ 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->XTAclassSet != NULL)
+ subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->XTAclassSet->head);
+
+ printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
+ printSet(subtypesUsedSet);
+ xtaMarkSubs(submeth->class, submeth, subtypesUsedSet);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------------*/
+bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
+
+bool rc = false;
+
+if (fi->fieldChecked) {
+ if (fi->fldClassType != NULL)
+ return true; /* field has a class type */
+ else
+ return false;
+ }
+fi->fieldChecked = true;
+
+if (fi->type == TYPE_ADDRESS) {
+ char *utf_ptr = fi->descriptor->text; /* current position in utf text */
+
+ if (*utf_ptr != 'L') {
+ while (*utf_ptr++ =='[') ;
+ }
+
+ if (*utf_ptr =='L') {
+ rc = true;
+ if (fi->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->fldClassType= class; /* save field's type class ptr */
+ }
+ /* save used edges */
+ rt_method->fldsUsed = add2FldSet(rt_method->fldsUsed, fi);
+ }
+ }
+return rc;
+}
+
+/*-------------------------------------------------------------------------------*/
+void xtaPassAllCalledByParams () {
+methSetNode *SmCalled;
+methSetNode *s1;
+if (rt_method->calledBy == NULL) return;
+ if (XTAdebug >= 1) {
+ printf("calledBy method set: "); fflush(stdout);
+ printMethodSet(rt_method->calledBy); fflush(stdout);
+ }
+if (rt_method->calledBy == NULL)
+ s1 = NULL;
+else
+ s1 = rt_method->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);
+ }
+
+ rt_method->chgdSinceLastParse = false;
+ xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
+ }
+}
+
/*-------------------------------------------------------------------------------*/
+void xtaMethodCalls_and_sendReturnType()
+{
+ methSetNode *SmCalled; /* for return type */
+ methSetNode *SmCalls; /* for calls param types */
+ methSetNode *s1;
+ bool chgd = false;
+if (rt_method->calls == NULL) return;
+ if (XTAdebug >= 1) {
+ printf("calls method set Return type: ");
+ printMethodSet(rt_method->calls);
+ printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->calls)\n");fflush(stdout);
+ }
+ /* for each method that this method calls */
+ if (rt_method->calls == NULL)
+ s1 = NULL;
+ else
+ s1 = SmCalls=rt_method->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->chgdSinceLastParse)) {
+ SmCalls->methRef->chgdSinceLastParse = true;
+ }
+ }
+
+ /* for each calledBy method */
+ /* send return type */
+ if (rt_method->calledBy == NULL)
+ s1 = NULL;
+ else
+ s1 = rt_method->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->chgdSinceLastParse)) {
+ SmCalled->methRef->chgdSinceLastParse = chgd;
+ }
+ }
+
+}
+/*-------------------------------------------------------------------------------*/
static void parseRT()
{
int p; /* java instruction counter */
RTAPRINT01method
- /* scan all java instructions */
+ if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
+
+ xtaPassAllCalledByParams ();
+ }
+ /* scan all java instructions */
for (p = 0; p < rt_jcodelength; p = nextp) {
opcode = rt_code_get_u1 (p); /* fetch op code */
- RTAPRINT02opcode
+ RTAPRINT02opcode
+ fflush(stdout);
nextp = p + jcommandsize[opcode]; /* compute next instruction start */
switch (opcode) {
}
break;
+ case JAVA_ALOAD_0:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD0 %s i=%i\n", opcode_names[opcode],0);
+ class_showconstanti(rt_class, 0);
+ break;
+
+ case JAVA_ALOAD_1:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD1 %s i=%i\n", opcode_names[opcode],1);
+ class_showconstanti(rt_class, 1);
+ break;
+
+ case JAVA_ALOAD_2:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD2 %s i=%i\n", opcode_names[opcode],2);
+ class_showconstanti(rt_class, 2);
+ break;
+
+ case JAVA_ALOAD_3:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD3 %s i=%i\n", opcode_names[opcode],3);
+ class_showconstanti(rt_class, 3);
+ break;
+
case JAVA_ALOAD:
{
constant_FMIref *mr;
nextp = p+3;
iswide = false;
}
-if (pWhenMarked >= 4) {
- printf("I-ALOAD %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
- /*class_showconstanti(rt_class, i); */
- }
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOADs %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
+ class_showconstanti(rt_class, i);
}
-
break;
/* 54 -58 */
}
break;
+
+ case JAVA_ASTORE_0:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],0);
+ class_showconstanti(rt_class,0);
+I=0;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_1:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],1);
+ class_showconstanti(rt_class, 1);
+I=1;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_2:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],2);
+ class_showconstanti(rt_class, 2);
+I=2;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_3:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],3);
+ class_showconstanti(rt_class, 3);
+I=3;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
case JAVA_ASTORE:
if (!iswide)
i = rt_code_get_u1(p+1);
nextp = p+3;
}
- if (pWhenMarked >= 4) {
- printf("I-ASTORE %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
- /*class_showconstanti(rt_class, rt_jcode[p+1]);*/
- }
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
+ class_showconstanti(rt_class, rt_jcode[p+1]);
+
+ /* old if (CONSTANT_Class == rt_class->cptags [rt_jcode[p+1]] ) { */
+I=rt_jcode[p+1];
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
break;
+
/* 132 */
case JAVA_IINC:
{
}
/*-------------------------------*/
-#include "parseEXTRAopcodes.h" /* opcodes just for info */
/* managing arrays ************************************************/
- INFOP01newarray
+ case JAVA_ANEWARRAY:
+ /* ---->>>> */ if (useArrayOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ constant_FMIref *ar;
+ voidptr e;
+ classinfo *c;
+ /* array or class type ? */
+ if (class_constanttype (rt_class, i) != CONSTANT_Arraydescriptor) {
+ e = class_getconstant(rt_class, i, CONSTANT_Class);
+ c = (classinfo *)e;
+ if (c->classUsed == NOTUSED)
+ c->classUsed = PARTUSED;
+/*COtest*/ printf("ANEWARRAY Mark class=");utf_display ( c-> name );printf("=>PARTUSED\n");
+ }
+ }
+ break;
- INFOP02anewarray
+ case JAVA_MULTIANEWARRAY:
+ /* ---->>>> */ if (useArrayOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ constant_arraydescriptor *ar;
+ int t;
+ arraydesc: ar = class_getconstant(rt_class, i, CONSTANT_Arraydescriptor);
+ /*ar = rt_class-> cpinfos [i]; */
+ t = ar->arraytype;
+ while (ARRAYTYPE_ARRAY== t) {
+ ar = ar->elementdescriptor;
+ t = ar->arraytype;
+ }
+ if (ARRAYTYPE_OBJECT == t) {
+ printf("MULTINEWARRAY 1Marking class=");utf_display(ar->objectclass->name);printf("\n");
+ if (ar->objectclass->classUsed == NOTUSED) {
+ ar->objectclass->classUsed == PARTUSED;
+ }
+ }
+ }
+ break;
- INFOP03multianewarray
/*-------------------------------*/
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 (xtaAddFldClassTypeInfo(fi)) {
+ /* Field type is a class */
+ classSetNode *c;
+ classSetNode *c1 = NULL;
+ fldSetNode *fn;
+
+ /******
+ Can a ptr be kept so don't check whole XTA class set each time?
+ cp = fi->methodsUsedBy->lastxxxxClass;
+ if (cp != NULL) {
+ if (cp->nextClass != NULL)
+ c1 = cp -> nextClass;
+ }
+ ****/
+
+ if (rt_method->XTAclassSet != NULL)
+ c1 = rt_method->XTAclassSet->head;
+ if (XTAfld >=1 ) {
+ printf("rt XTA class set =");fflush(stdout);
+ printClassSet(rt_method->XTAclassSet);
+ printf("\t\tField class type = ");fflush(stdout);
+ utf_display(fi->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->fldClassType->vftbl;
+ vftbl *c_cl_vt = c-> classType->vftbl;
+ if (XTAfld >=2 ) {
+ printf("\tXTA class = ");fflush(stdout);
+ utf_display(c->classType->name);
+ printf("<b=%i> ",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);
+ }
+
+ printf("\t\tField class type = ");fflush(stdout);
+ utf_display(fi->fldClassType->name);
+ printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
+ }
+
+ if ((f_cl_vt->baseval <= c_cl_vt->baseval)
+ && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
+ fi->XTAclassSet = add2ClassSet(fi->XTAclassSet,c->classType);
+ }
+ /****cprev = c->classType; ***/
+ }
+ if (rt_method->fldsUsed != NULL) {
+ fn = inFldSet(rt_method->fldsUsed->head, fi);
+ if (fn != NULL)
+ fn->readPUT = true;
+ }
+ /***fi->methodsUsedBy->lastxxxClass ***/
+ /*** = addElement(fi->methodsUsedBy->lastxxxClass, c->classType); ***/
+ }
+ }
+
+ }
+ break;
+
case JAVA_GETSTATIC:
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 (xtaAddFldClassTypeInfo(fi)) {
+ /* Field type is a class */
+ classSetNode *c;
+ classSetNode *c1 = NULL;
+ fldSetNode *fn;
+
+ /*******************/
+
+ /*******
+ Can a ptr be kept so don't check whole XTA class set each time?
+ cp = fi->methodsUsedBy->lastxxxxClass;
+ if (cp != NULL) {
+ if (cp->nextClass != NULL)
+ c1 = cp -> nextClass;
+ }
+ *******/
+
+ if (fi->XTAclassSet != NULL)
+ c1 = fi->XTAclassSet->head;
+
+ /*--- GETSTATIC specific ---*/
+ /* Sm = union of Sm and Sx */
+ for (c=c1; c != NULL; c=c->nextClass) {
+ bool addFlg = false;
+ if (rt_method->XTAclassSet ==NULL)
+ addFlg = true;
+ else {
+ if (!(inSet (rt_method->XTAclassSet->head, c->classType) ))
+ addFlg = true;
+ }
+ if (addFlg) {
+ rt_method->XTAclassSet
+ = add2ClassSet(rt_method->XTAclassSet,c->classType);
+ }
+ /*** cprev = c->classType; ***/
+ }
+
+ if (rt_method->fldsUsed != NULL) {
+ fn = inFldSet(rt_method->fldsUsed->head, fi);
+ if (fn != NULL)
+ fn->writeGET = true;
+ }
+
+ /**** fi->methodsUsedBy->lastxxxClass ***/
+ /*** = addElement(fi->methodsUsedBy->lastxxxClass, c->classType); ***/
+ }
+ }
+
+ }
+ break;
+
+ case JAVA_PUTFIELD:
+ case JAVA_GETFIELD:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
classinfo *ci;
methodinfo *mi;
int m;
+class_showconstanti(rt_class,i); fflush(stdout);
fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
- /* type of field */
- fi = class_findfield (fr->class,fr->name, fr->descriptor);
- ci = fr->class;
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ ci = fr->class; /* class with the local field */
+ /* either current class or inherited (a super) */
+ /* descriptor has type of field ref'd */
RTAPRINT03putstatic1
- addClassInit(ci);
-
+ /*** OP2A(opcode, fi->type, fi); ***/
}
break;
+
- /* method invocation *****/
+ /*-------------------- method invocation ---------------------*/
case JAVA_INVOKESTATIC:
i = rt_code_get_u2(p + 1);
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);
-
- if (mi->methodUsed != USED) { /* if static method not in callgraph */
- addToCallgraph(mi);
- }
+ addClassInit(mi->class);
+
+ ADDTOCALLGRAPH(mi)
+fflush(stdout);
+ /*-- XTA --*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ xtaAddCallEdges(mi,MONO);
+ } /* end XTA */
}
break;
constant_FMIref *mr;
methodinfo *mi;
classinfo *ci;
- int ii;
mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
mi = class_findmethod (mr->class, mr->name, mr->descriptor);
- RTAPRINT06invoke_spec_virt1
-
- if (mi->name != INIT) { /* if method called is PRIVATE */
- RTAPRINT07invoke_spec_virt2
- markSubs(mi->class,mi);
- break;
+ 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 */
}
- /* new class so add marked methods */
- if ( mi->methodUsed != USED) {
-
- /* if parsing <init> method and it calls its super <init>
- /* -> mark the class of super as MARKEDSUPER
- */
- if ((INIT == mi->name)
- && (INIT == rt_method->name)
- && (rt_class->super == mi->class) /* <init> calling super ? */
- && (mi->class->classUsed == NOTUSED)) /* only if not used at all */
- mi->class->classUsed = MARKEDSUPER;
- else {
- /* Normal <init> - mark class as USED and <init> to callgraph */
- ci = mi->class;
- ci->classUsed = USED;
-
- /* add marked methods to callgraph */
- for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
- }
- }
+
+ else {
+ /*--- Test for super <init> which is: <init> calling its super class <init> -*/
+
+ /* new class so add marked methods */
+ if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
+ /*--- process NORMAL <init> method ---------------------------------------------*/
+ if ( mi->methodUsed != USED) {
+ /* Normal <init>
+ - mark class as USED and <init> 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->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci );
+ xtaAddCallEdges(mi,MONO);
+ RTAPRINT06CXTAinvoke_spec_init1
+ } /* end XTA */
+ }
}
+ }
- addToCallgraph(mi); /* add to call graph after setting classUsed flag */
- } }
+ }
break;
{
constant_FMIref *mr;
methodinfo *mi;
- classinfo *ci;
- int ii;
mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
- mi = class_findmethod (mr->class, mr->name, mr->descriptor);
- RTAPRINT06invoke_spec_virt1
-
- if (mi->name == INIT) {
- panic("An <init> method called from invokevirtual, but invokespecial expected\n");
- return;
- }
- /*--------------------------------------------------------------*/
- RTAPRINT07invoke_spec_virt2
- markSubs(mi->class,mi);
+ 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->XTAclassSet != NULL)
+ subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->XTAclassSet->head);
+ /*****
+ printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
+ printSet(subtypesUsedSet);
+ *****/
+ xtaMarkSubs(mi->class, mi, subtypesUsedSet);
+ } /* end XTA */
}
break;
{
constant_FMIref *mr;
methodinfo *mi;
- classinfo *ci;
- classinfo *subs;
-
+ 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");
- RTAPRINT08AinvokeInterface0
- ci = mi->class;
- subs = ci->impldBy;
- RTAPRINT08invokeInterface1
- while (subs != NULL) {
- RTAPRINT09invokeInterface2
+ /*--- 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 (subs->classUsed != NOTUSED)
- markSubs(subs, mi); /* method may not be found so...??? */
- subs = subs->nextimpldBy;
+ 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;
classinfo *ci;
int ii;
classinfo *subs;
- ci = class_getconstant (rt_class, i, CONSTANT_Class);
-
- /* Add this class to the implemented by list of the abstract interface */
- for (ii=0; ii < ci -> interfacescount; ii++) {
- subs = ci -> interfaces [ii]->impldBy;
- ci -> interfaces [ii]->impldBy = ci;
- ci -> interfaces [ii]->nextimpldBy = ci;
- }
- if (ci->classUsed == NOTUSED) {
+ 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) {
int ii;
RTAPRINT10new
ci->classUsed = USED; /* add to heirarchy */
+ /* Add this class to the implemented by list of the abstract interface */
+ addUsedInterfaceMethods(ci);
addClassInit(ci);
- /* add marked methods to callgraph ?? here or in init??? */
}
+ /*--- XTA ---*/
+ if ((XTAOPTbypass) || (opt_xta))
+ {
+ rt_method->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci ); /*XTA*/
+ RTAPRINT10newXTA
+ }
}
break;
+ /* ---- Reference Opcodes --------------------------------------------*/
+
+ case JAVA_CHECKCAST:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+
+ i = rt_code_get_u2(p+1);
+ {
+ classinfo *ci;
+
+ /* array type cast-check */
+ if (class_constanttype (rt_class, i) == CONSTANT_Arraydescriptor) {
+class_showconstanti(rt_class,i);
+goto arraydesc; /* better to make a fn later ?? */
+panic("arraydescriptor in checkcast - panic so find it");
+ /***
+ LOADCONST_A(class_getconstant(rt_class, i, CONSTANT_Arraydescriptor));
+ s_count++;
+ BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ ****/
+ }
+ else { /* object type cast-check */
+ ci = class_getconstant(rt_class, i, CONSTANT_Class);
+ ci->classUsed =PARTUSED;
+/*RTtest p1*/ if (pWhenMarked >= 2) {
+/*RTtest*/ printf("checkcast class=");utf_display(ci->name);printf(" marked PARTUSED\n");
+/*RTtest*/ }
+ /*****
+ LOADCONST_A(class_getconstant(irt_class, i, CONSTANT_Class));
+ s_count++;
+ BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
+ OP2A(opcode, 1, (class_getconstant(rt_class, i, CONSTANT_Class)));
+ ****/
+ }
+ }
+ break;
+
+ case JAVA_INSTANCEOF:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ classinfo *ci;
+
+ /* array type cast-check */
+ if (class_constanttype (rt_class, i) == CONSTANT_Arraydescriptor) {
+class_showconstanti(rt_class,i);
+goto arraydesc; /* better to make a fn later */
+panic("arraydescriptor in instanceof- panic so find it");
+ /***
+ LOADCONST_A(class_getconstant(rt_class, i, CONSTANT_Arraydescriptor));
+ ***/
+ }
+ else { /* object type cast-check */
+ ci = class_getconstant(rt_class, i, CONSTANT_Class);
+ ci->classUsed =PARTUSED;
+/*RTtest p1*/ if (pWhenMarked >= 2) {
+/*RTtest*/ printf("checkcast class=");utf_display(ci->name);printf(" marked PARTUSED\n");
+/*RTtest*/ }
+ }
+ }
+ break;
+
+ case JAVA_MONITORENTER:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+/* comes from stack - how put on stack???? */
+#ifdef USE_THREADS
+ if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+ if (checknull) {
+ /****
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ ***/
+ }
+ else {
+ /****
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ ***/
+ }
+#else
+ /***
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+ ***/
+#endif
+ }
+ else
+#endif
+ {
+ /***
+ OP(ICMD_NULLCHECKPOP);
+ ***/
+ }
+ break;
+
+ case JAVA_MONITOREXIT:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+/* comes from stack - how put on stack???? */
+#ifdef USE_THREADS
+ if (checksync) {
+ /***
+ BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+ ***/
+ }
+ else
+#endif
+ {
+ /***
+ OP(ICMD_POP);
+ ***/
+ }
+ break;
+
+ case JAVA_ARETURN:
+ /* ---->>>> */ if (useOtherOpcodes == false) break; /* <<<<<<******* */
+/* set a variable with type from input and track it to here */
+ /***
+ blockend = true;
+ OP(opcode);
+ ***/
+ break;
+
+ case JAVA_ATHROW:
+ /* ---->>>> */ if (useOtherOpcodes == false) break; /* <<<<<<******* */
+ /***
+ blockend = true;
+ OP(opcode);
+ ***/
+ break;
+
default:
break;
if (p != rt_jcodelength)
panic("Command-sequence crosses code-boundary");
+if ((XTAOPTbypass) || (opt_xta))
+ xtaMethodCalls_and_sendReturnType();
+
+
}
+/*-------------------------------------------------------------------------------*/
+/* RTA add Native Methods/ Class functions */
/*-------------------------------------------------------------------------------*/
void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
}
if (class->classUsed == NOTUSED) {
- class->classUsed = USED;
+ class->classUsed = USED; /* MARK CLASS USED */
/* add marked methods to callgraph */
- for (ii=0; ii<class->methodscount; ii++) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&class->methods[ii]);
- }
- }
+ addMarkedMethods(class);
}
meth = class_findmethod (class, m1, d1);
if (meth == NULL) {
utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
- panic("parseRT: Method given is used by Native method call, but NOT FOUND");
+ printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
}
-markSubs(class,meth);
+else
+ rtaMarkSubs(class,meth);
}
/*-------------------------------------------------------------------------------*/
class->classUsed = USED;
/* add marked methods to callgraph */
-for (ii=0; ii<class->methodscount; ii++) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&class->methods[ii]);
- }
- }
- }
-
+addMarkedMethods(class);
}
for (i=0; i<NATIVECALLSSIZE; i++) {
if (rt_class == nativeCompCalls[i].classname) {
+
/* find native class.method invoked */
for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
+
if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
&& (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
nativeCompCalls[i].methods[j].methodCalls[k].methodname,
nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
- /*RTprint
+ /*RTprint
printf("\nmark method used: "); fflush(stdout);
utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
/*-------------------------------------------------------------------------------*/
-void mainRTAparseInit ( )
+/*-------------------------------------------------------------------------------*/
+void mainRTAparseInit (methodinfo *m )
{
+/*printf("MAIN_NOT_STARTED \n");*/
if (class_java_lang_Object->sub != NULL) {
RTAPRINT16stats1
}
if (firstCall) {
firstCall=false;
+ utf_MAIN = utf_new_char("main");
+ INIT = utf_new_char("<init>");
+ CLINIT = utf_new_char("<clinit>");
+ 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");
}
}
- /* At moment start RTA before main when parsed
- /* Will definitely use flag with to know if ok to apply in-lining.
- */
-}
+if (m->name == utf_MAIN) {
+ rtMissed = fopen("rtMissed","a");
+ fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
+ fclose(rtMissed);
+ }
+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);
+ }
+ }
+ /* At moment start RTA before main when parsed */
+ /* Will definitely use flag with to know if ok to apply in-lining. */
+}
/*-------------------------------------------------------------------------------*/
-
-void RT_jit_parse(methodinfo *m)
+/*-------------------------------------------------------------------------------*/
+/* still need to look at field sets in 2nd pass and clinit ..... */
+void XTA_jit_parse2(methodinfo *m)
{
-utf *utf_MAIN = utf_new_char("main");
-
- if (m->methodUsed == USED) return;
+ 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->chgdSinceLastParse) {
- INIT = utf_new_char("<init>");
- CLINIT = utf_new_char("<clinit>");
- FINALIZE = utf_new_char("finalize");
+ /* get types from methods it is calledBy */
+ xtaPassAllCalledByParams ();
- if (!mainStarted) {
- mainRTAparseInit ();
- }
- if (m->name == utf_MAIN) {
- rtMissed = fopen("rtMissed","a");
- fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
- fclose(rtMissed);
- }
- 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);
+ /* 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 */
+}
+/*-------------------------------------------------------------------------------*/
+
+void RT_jit_parse(methodinfo *m)
+{
+ /*-- RTA --*/
+ if (m->methodUsed == USED) return;
+ mainRTAparseInit (m);
+
/* initialise parameter type descriptor */
- callgraph[++methRTlast] = m;
- RTAPRINT11addedtoCallgraph
+ callgraph[++methRTlast] = m; /*-- RTA --*/
m->methodUsed = USED;
+ RTAPRINT11addedtoCallgraph
/* <init> then like a new class so add marked methods to callgraph */
- if (m->name == INIT) {
+ if (m->name == INIT) { /* need for <init>s parsed efore Main */
classinfo *ci;
int ii;
ci = m->class;
ci->classUsed = USED;
+ if (pWhenMarked >= 1) {
+ printf("Class=");utf_display(ci->name);
+ }
/* add marked methods to callgraph */
RTAPRINT11addedtoCallgraph2
- for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
- }
- } /* for */
+ addMarkedMethods(ci);
} /* if */
+ /*-- XTA --*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ XTAcallgraph[++methXTAlast] = m;
+ m->XTAmethodUsed = USED;
+ {methodinfo *mi = m;
+ XTAPRINTcallgraph2
+ }
+ }
+
+ /*-- Call graph work list loop -----------------*/
+
while (methRT <= methRTlast) {
rt_method = callgraph[methRT];
rt_class = rt_method->class;
rt_jcode = rt_method->jcode;
if (! ( (rt_method->flags & ACC_NATIVE )
- || (rt_method->flags & ACC_ABSTRACT) ) )
+ || (rt_method->flags & ACC_ABSTRACT) ) ) {
parseRT();
+ }
else {
- if (pOpcodes == 1) {
- printf("\nPROCESS_abstract or native\n");
- utf_display(rt_method->class->name); printf(".");
- method_display(rt_method); printf("\n"); fflush(stdout);
- }
-
+ RTAPRINT12bAbstractNative
if (rt_method->flags & ACC_NATIVE ) {
+ RTAPRINT12aNative
/* mark used and add to callgraph methods and classes used by NATIVE method */
- RTAPRINT12aNative
markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
}
if (rt_method->flags & ACC_ABSTRACT) {
- printf("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
+ 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 ??*/
- RTAPRINT14CallgraphLast
- RTAPRINT15HeirarchyiLast
+ 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);
+ }
+
+return;
}
+#define XTAPRINTcallgraph1 if(pWhenMarked>=1) \
+ {printf("\n XTA Added to Call Graph #%i:", \
+ methRTlast); \
+ printf("\t <used flags c/m> <%i/%i> %i\t", \
+ submeth->class->classUsed, \
+ submeth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
+ utf_display(submeth->class->name);printf("."); \
+ method_display(submeth);fflush(stdout);}
+
+#define XTAPRINTcallgraph2 if(pWhenMarked>=1) { \
+ printf("\n XTA Added to Call Graph #%i:", \
+ methXTAlast); \
+ printf(" method name ="); \
+ utf_display(mi->class->name);printf("."); \
+ method_display(mi);fflush(stdout); \
+ }
+
#define RTAPRINTcallgraph1 if(pWhenMarked>=1) \
{printf("\n Added to Call Graph #%i:", \
- methRTlast);printf(" method name ="); \
+ methRTlast); \
+ printf("\t <used flags c/m> <%i/%i> %i\t", \
+ meth->class->classUsed, \
+ meth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
utf_display(meth->class->name);printf("."); \
- method_display(meth);fflush(stdout);}
+ method_display(meth);fflush(stdout);}
#define RTAPRINTmarkMethod1 if (pWhenMarked >= 2) { \
- printf("Just Marking Method - class:%s not used <%i>\n",class->name->text,class->index); \
+ printf("<%i/%i> Just Marking Method - class: <index=%i>\n", \
+ submeth->methodUsed, \
+ submeth->class->index); \
+ utf_display(submeth->class->name); \
method_display(submeth); \
}
}
#define RTAPRINTmarkMethod2 if (pWhenMarked >= 2) { \
- printf("Class marked Used by Subtype :");utf_display(s->name);printf("\n");}
+ printf("Class marked Used by Subtype :");utf_display(submeth->name);printf("\n");}
#define RTAPRINTmarkSubs1 if (pWhenMarked>=3) { \
utf *name = topmethod -> name; \
#define RTAPRINT01method if ((pOpcodes == 1) || (pOpcodes == 3)) \
{printf("*********************************\n"); \
- printf("PARSE RT method name ="); \
+ printf("PARSE RT method name = <%i/%i>",rt_method->class->classUsed,rt_method->methodUsed); \
utf_display(rt_method->class->name);printf("."); \
utf_display(rt_method->name);printf("\n\n"); \
method_display(rt_method); printf(">\n\n");fflush(stdout);}
p,rt_jcodelength,opcode,opcode_names[opcode]); \
fflush(stdout); }
-#define RTAPRINT03putstatic1 if (pWhenMarked >= 5) { \
+#define RTAPRINT03putstatic1 if (pWhenMarked >= 1) { \
+ class_showconstanti(rt_class,i); \
+ }
+
+#define RTAPRINT03putstatic1o_OLD if (pWhenMarked >= 1) { \
+ class_showconstanti(rt_class,i); \
printf("FMIref = "); \
utf_display ( fr->class->name ); \
printf ("."); \
printf("INVOKESTATIC\n"); fflush(stdout);}
+#define RTAPRINT06Ainvoke_spec_super1 if (pWhenMarked >= 1) { \
+ printf("class flags:"); fflush(stdout); \
+ utf_display(ci->name); \
+ printflags(ci->flags); \
+ printf("\n"); fflush(stdout); \
+ printf("method flags:"); fflush(stdout); \
+ utf_display(mi->name); \
+ printflags(mi->flags); \
+ printf("\n"); fflush(stdout); \
+ }
+
+#define RTAPRINT06Binvoke_spec_super2 if (pWhenMarked >= 1) { \
+ printf("SUPERRRRRRRRRRRRRRR"); \
+ utf_display(mi->descriptor); \
+ printf(" class super ="); fflush(stdout); \
+ utf_display(rt_class->super->name); fflush(stdout); \
+ printf("\t ==? "); fflush(stdout); \
+ printf(" class =");fflush(stdout); \
+ utf_display(mi->class->name); fflush(stdout); \
+ printf("\n"); fflush(stdout); \
+ printf("Ainterface count = "); fflush(stdout); \
+ printf(" %i\n", ci -> interfacescount); \
+ fflush(stdout); \
+ }
+
+#define RTAPRINT06Binvoke_spec_init if (pWhenMarked >= 1) { \
+ printf("Binterface count = "); fflush(stdout); \
+ printf(" %i\n", ci -> interfacescount); \
+ fflush(stdout); \
+ }
+
+#define RTAPRINT06CXTAinvoke_spec_init1 if (pWhenMarked >= 1) { \
+ printf("\n XTA Added to Call Graph #%i:", \
+ methXTAlast); \
+ printf(" method name ="); \
+ utf_display(mi->class->name);printf("."); \
+ method_display(mi);fflush(stdout); \
+ }
+
+
#define RTAPRINT06invoke_spec_virt1 if ((pOpcodes == 1) ||(pOpcodes == 3) || (pWhenMarked >= 2)) { \
- printf(" method name ="); \
- method_display(mi); \
+ printf("INVOKE method name <%i/%i> =",mi->class->classUsed,mi->methodUsed); \
utf_display(mi->class->name); printf("."); \
- utf_display(mi->name); \
- printf("\taINVOKESPECIAL/VIRTUAL\n"); fflush(stdout); }
+ method_display(mi); \
+ fflush(stdout); }
-#define RTAPRINT07invoke_spec_virt2 if (pWhenMarked >= 3) { \
+#define RTAPRINT07invoke_spec_virt2 if (pWhenMarked >= 1) { \
printf("Calling MarkSubs from SPECIAL/VIRTUAL :"); \
- utf_display(mi->class->name);printf(":"); \
- utf_display(mi->name);printf("\n"); }
+ utf_display(mi->class->name);printf(".V."); \
+ method_display(mi); }
#define RTAPRINT08AinvokeInterface0 if (pWhenMarked >= 2) { \
utf_display(mi->class->name); \
- method_display(mi); printf("\n");}
+ method_display(mi); printf("\n");} \
+ if (pWhenMarked >= 1) { \
+ printf("INTERFACE CLASS <");fflush(stdout); \
+ utf_display(mi->class->name); fflush(stdout); \
+ printf("> used flag=%i\n", mi->class->classUsed); \
+ fflush(stdout); \
+ method_display(mi); \
+ fflush(stdout); \
+ printf("AAAAA\n");fflush(stdout); \
+ }
-#define RTAPRINT08invokeInterface1 if (pWhenMarked >= 3) { \
+#define RTAPRINT08invokeInterface1 if (pWhenMarked >= 1) { \
printf("Implemented By classes :\n"); \
+ fflush(stdout); \
if (subs == NULL) printf(" \tNOT IMPLEMENTED !!!\n"); \
+ printf("ZZZZZ\n");fflush(stdout); \
}
#define RTAPRINT09invokeInterface2 if (pWhenMarked >= 3) { \
- printf("\t");utf_display(subs->name); printf(" <%i>\n",subs->classUsed); \
+ printf("\t");utf_display(isubs->name); printf(" <%i>\n",isubs->classUsed); \
}
#define RTAPRINT10new if (pWhenMarked >= 2) { \
- printf("NEW Class marked Used :"); \
+ printf("NEW Class marked Used :"); fflush(stdout);\
utf_display(ci->name); \
fflush(stdout);}
+#define RTAPRINT10newXTA if (pWhenMarked >= 1) { \
+ utf_display(ci->name);printf(" XTA_NEW\n"); \
+ printSet(rt_method->XTAclassSet->head); \
+ }
+
#define RTAPRINT11addedtoCallgraph if (pWhenMarked >= 1){ \
printf("\n<Added to Call Graph #%i:",methRTlast); \
method_display(m); \
utf_display(rt_descriptor); fflush(stdout); printf("\n"); \
}
+#define RTAPRINT12bAbstractNative if (pOpcodes == 1) { \
+ printf("\nPROCESS_abstract or native\n"); \
+ utf_display(rt_method->class->name); printf("."); \
+ method_display(rt_method); printf("\n"); fflush(stdout); \
+ }
+
#define RTAPRINT12Callgraph if (pCallgraph >= 3) { \
printf("RTA Callgraph after RTA Call\n"); \
printCallgraph (); \
--- /dev/null
+
+/*--- Statistics ----------------------------------------------------------*/
+
+int unRTclassHeirCnt=0;
+int unRTmethodCnt = 0;
+
+/*-----*/
+int RTclassHeirNotUsedCnt=0;
+int RTclassHeirUsedCnt=0;
+int RTclassHeirPartUsedCnt=0;
+int RTclassHeirSuperCnt=0;
+
+int RTmethodNotUsedCnt = 0;
+int RTmethodNotUsedCnt1= 0;
+int RTmethodNotUsedCnt2= 0;
+int RTmethodUsedCnt = 0;
+int RTmethodMarkedCnt= 0;
+
+/* What might be inlined of the Used Methods */
+int RTmethodFinal = 0;
+int RTmethodStatic = 0;
+int RTmethodFinalStatic = 0;
+int RTmethodNoSubs = 0;
+
+int RTmethodMono;
+int RTmethodPossiblePoly;
+int RTmethodPolyReallyMono;
+int RTmethodPoly;
+
+int RTmethodFinal100 = 0;
+int RTmethodStatic100 = 0;
+int RTmethodFinalStatic100 = 0;
+int RTmethodNoSubs100 = 0;
+
+#define MAXCODLEN 10
+
+int RTmethodNoSubsAbstract = 0;
+int RTmethod1Used = 0;
+
+int RTmethodAbstract = 0;
+
+int subRedefsCnt =0;
+int subRedefsCntUsed =0;
+
+/*------------- RTAprint flags ------------------------------------------------------------------*/
+int pCallgraph = 0; /* 0 - dont print 1 - print at end from main */
+ /* 2 - print at end of RT parse call */
+ /* 3- print after each method RT parse */
+int pClassHeir = 1; /* 0 - dont print 1 - print at end from main */
+ /* 2 - print at end of RT parse call 3-print after each method RT parse */
+int pClassHeirStatsOnly = 1; /* usually 2 Print only the statistical summary info for class heirarchy */
+
+int pOpcodes = 0; /* 0 - don't print 1- print in parse RT 2- print in parse */
+ /* 3 - print in both */
+int pWhenMarked = 0; /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
+ /* 2 - print when marked+methods called */
+ /* 3 - print when class/method looked at */
+int pStats = 0; /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
+
+/*-----------------------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------------------*/
+void printXTACallgraph ()
+ { int i;
+if (XTAdebug >= 1) {
+printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
+ for (i=0;i<=methXTAlast;i++) {
+ printf(" (%i): ",i);
+ utf_display(XTAcallgraph[i]->class->name);
+ printf(":");
+ method_display(XTAcallgraph[i]);
+ }
+
+ printf("\n\n");
+ }
+ }
+
+/*-----------------------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------------------*/
+
+void printCallgraph ()
+ { int i;
+
+printf("----- RTA Callgraph Worklist:<%i>\n",methRTlast);
+ for (i=0;i<=methRTlast;i++) {
+ printf(" (%i): ",i);
+ utf_display(callgraph[i]->class->name);
+ printf(":");
+ method_display(callgraph[i]);
+ }
+
+ printf("\n\n");
+ }
+/*--------------------------------------------------------------*/
+void printObjectClassHeirarchy1() {
+if (pStats >= 1) {
+ unRTclassHeirCnt=0;
+ unRTmethodCnt = 0;
+ printObjectClassHeirarchy(class_java_lang_Object);
+ printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
+ unRTclassHeirCnt,unRTmethodCnt);
+ }
+
+}
+/*--------------------------------------------------------------*/
+void printObjectClassHeirarchy(classinfo *class) {
+
+classinfo *subs;
+methodinfo *meth;
+int t,m,cnt;
+
+if (class == NULL) {return;}
+ unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
+ if (pStats == 2) {
+ printf("\n");
+ /* Class Name */
+ for (t=0;t<class->index;t++) printf("\t");
+ if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
+
+ printf("Class: ");
+ utf_display(class->name);
+ printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
+ /* Print methods used */
+ cnt=0;
+ for (m=0; m < class->methodscount; m++) {
+ meth = &class->methods[m];
+ if (cnt == 0) {
+ for (t=0;t<class->index;t++) printf("\t");
+ printf("aMethods used:\n");
+ }
+ for (t=0;t<class->index;t++) printf("\t");
+ printf("\t");
+ utf_display(meth->class->name);
+ printf(".");
+ method_display(meth);
+ cnt++;
+ }
+ if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
+ }
+
+ for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
+ printObjectClassHeirarchy(subs);
+ }
+
+}
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+int subdefd(methodinfo *meth) {
+ classinfo *subs;
+ methodinfo *submeth;
+
+/*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
+
+ if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
+ panic("Possible Poly call for FINAL or STATIC\n");
+
+ if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
+ return 0;
+ }
+ if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
+
+/*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
+
+ for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
+ submeth = class_findmethod(subs, meth->name, meth->descriptor);
+ if (submeth != NULL) {
+ subRedefsCnt++;
+ if (submeth->methodUsed == USED) {
+ subRedefsCntUsed++;
+ /*return 1;*/
+ }
+ else {
+ if (subdefd(submeth) > 0)
+ ; /*return 1;*/
+ }
+ }
+ }
+ if (subRedefsCntUsed > 0) return 1;
+ return 0;
+}
+/*--------------------------------------------------------------*/
+
+void printRTClassHeirarchy(classinfo *class) {
+
+classinfo *subs;
+methodinfo *meth;
+int m,cnt;
+
+if (class == NULL) {return;}
+ /* Class Name */
+ if (class->classUsed == NOTUSED) {
+ RTclassHeirNotUsedCnt++;
+ RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
+ RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
+ for (m=0; m < class->methodscount; m++) {
+ meth = &class->methods[m];
+ if (meth->methodUsed == USED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("METHOD marked used in CLASS marked NOTUSED: ");
+ utf_display(class->name);
+ printf(".");
+ method_display(meth);
+ printf("<%i>\n\t",meth->methodUsed);
+ fflush(stdout);
+ printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
+ }
+ }
+ }
+ }
+
+ if (class->classUsed != NOTUSED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\nClass: ");
+ utf_display(class->name);
+ printf(" <%i> (depth=%i) ",class->classUsed,class->index);
+
+ printf("\tbase/diff =%3d/%3d\n",
+ class->vftbl->baseval,
+ class->vftbl->diffval);
+ }
+
+ if (class->classUsed == PARTUSED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\tClass not instanciated - but methods/fields resolved to this class' code (static,inits,fields,super)\n");
+ }
+ RTclassHeirPartUsedCnt++;
+ }
+ else {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\n");
+ }
+ RTclassHeirUsedCnt++;
+ }
+
+
+ /* Print methods used */
+ cnt=0;
+ for (m=0; m < class->methodscount; m++) {
+
+ meth = &class->methods[m];
+
+ if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
+ if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
+ if (meth->methodUsed == USED) {
+ RTmethodUsedCnt++;
+ if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
+ RTmethodFinal++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
+ }
+
+ if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
+ RTmethodStatic++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
+ }
+
+ if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
+ RTmethodFinalStatic++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
+ }
+
+ if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
+ && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
+ RTmethodNoSubs++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
+ }
+
+ if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
+ && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
+
+ if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
+
+ if (meth->monoPoly == MONO) RTmethodMono++;
+ if (meth->monoPoly == POLY) {
+ RTmethodPossiblePoly++;
+ subRedefsCnt = 0;
+ subRedefsCntUsed = 0;
+ if (meth->flags & ACC_ABSTRACT ) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("STATS: abstract_method=");
+ utf_display(meth->class->name);printf(".");
+ method_display(meth);
+ }
+ }
+ else {
+ if (subdefd(meth) == 0) {
+ meth->monoPoly = MONO1;
+ RTmethodPolyReallyMono++;
+ }
+ else {
+ RTmethodPoly++;
+ meth->subRedefs = subRedefsCnt;
+ meth->subRedefsUsed = subRedefsCntUsed;
+ }
+ }
+ }
+
+ if (pClassHeirStatsOnly >= 2) {
+ if (cnt == 0) {
+ printf("bMethods used:\n");
+ }
+ cnt++;
+ printf("\t");
+ utf_display(meth->class->name);
+ printf(".");
+ method_display(meth);
+ printf("\t\t");
+ if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
+ if ( (XTAOPTbypass3) || (opt_xta)) {
+ if (meth->XTAclassSet == NULL)
+ printf("class set never created\n");
+ else
+ printSet(meth->XTAclassSet->head);
+ }
+ }
+ }
+ }
+ if (pClassHeirStatsOnly >= 2) {
+ if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
+ }
+ }
+
+ for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
+ printRTClassHeirarchy(subs);
+ }
+}
+/*--------------------------------------------------------------*/
+void printRTInterfaceClasses() {
+ int ii,jj,mm;
+ classinfo *ci = class_java_lang_Object;
+ classSetNode *subs;
+
+ int RTmethodInterfaceClassImplementedCnt = 0;
+ int RTmethodInterfaceClassUsedCnt = 0;
+
+ int RTmethodInterfaceMethodTotalCnt = 0;
+ int RTmethodInterfaceMethodNotUsedCnt = 0;
+ int RTmethodInterfaceMethodUsedCnt = 0;
+
+ int RTmethodClassesImpldByTotalCnt = 0;
+
+ int RTmethodInterfaceMonoCnt = 0;
+ int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
+
+ int RTmethodNoSubsAbstractCnt = 0;
+
+for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
+ classinfo * ici = subs->classType;
+ classinfo * isubs = subs->classType;
+ classinfo * iBy;
+ classSetNode * inBy;
+ int impldBycnt;
+
+ if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
+ if (pClassHeir >= 2) {
+ printf("Interface class: ");fflush(stdout);
+ utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
+ }
+ RTmethodInterfaceClassImplementedCnt++;
+ if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
+ if (pClassHeir >= 2) {
+ printf("\n\t\t\tImplemented by classes:\n");
+ }
+ impldBycnt = 0;
+ /* get the total impldBy classes Used */
+ for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
+ impldBycnt++;
+ RTmethodClassesImpldByTotalCnt++;
+ if (pClassHeir >= 2) {
+ printf("\t\t\t");utf_display(inBy->classType->name);
+ printf("\n");
+ }
+ if (inBy->classType->classUsed == NOTUSED)
+ panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
+ }
+ if (pClassHeir >= 2) {
+ printf("\t\t\tImpld by: %i\n",impldBycnt);
+ }
+ if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
+
+ /* if interface class is used */
+ if (ici -> classUsed != NOTUSED) {
+ if (pClassHeir >= 2) {
+ printf(" cMethods used:\n");
+ }
+
+ /* for each interface method implementation that has been used */
+ for (mm=0; mm< ici->methodscount; mm++) {
+ methodinfo *imi = &(ici->methods[mm]);
+ RTmethodInterfaceMethodTotalCnt++;
+ if (imi->methodUsed != USED) {
+ RTmethodInterfaceMethodNotUsedCnt++;
+ }
+ if (imi->methodUsed == USED) {
+ RTmethodInterfaceMethodUsedCnt++;
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\t\t");
+ utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+ }
+ if (impldBycnt == 1) {
+ classinfo *cii;
+ methodinfo *mii;
+ int i;
+
+ /* if only 1 implementing class then possibly really mono call */
+ inBy = ici->impldBy;
+ cii = inBy->classType;
+
+ mii = class_findmethod(cii, imi->name, imi->descriptor);
+ if (mii == NULL) {
+ /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
+ imi->monoPoly = MONO1;
+ RTmethodInterfacePolyReallyMonoCnt++;
+ }
+ else {
+ if (imi->monoPoly != POLY)
+ panic ("interface monopoly not POLY");
+
+ if (mii->monoPoly != POLY) {
+ imi->monoPoly = MONO1;
+ RTmethodInterfacePolyReallyMonoCnt++;
+ }
+ else {
+ imi->monoPoly = POLY;
+ }
+ }
+ }
+ }
+ }
+ if (pClassHeir >= 2) {
+ printf("\n");
+ }
+ }
+ }
+if (pClassHeirStatsOnly >= 1) {
+ printf("\n\n >>>>>>>>>>>>>>>>>>>> Interface Statistics Summary: \n");
+ printf("Classes: Total: %i \tUSED: %i \tIMPLD BY: \t%i \tJUST 1 IMPLD BY: %i \tNOSUB: %i \n",
+ RTmethodInterfaceClassImplementedCnt,
+ RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
+ RTmethodNoSubsAbstractCnt);
+ printf("Methods: Total: %i \tNOTUSED: %i \tUSED: \t%i \tPoly that resolves to Mono %i \n",
+ RTmethodInterfaceMethodTotalCnt,
+ RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
+ }
+}
+/*--------------------------------------------------------------*/
+
+void printRThierarchyInfo(methodinfo *m) {
+
+ /*-- init for statistics --*/
+ RTclassHeirNotUsedCnt=0;
+ RTclassHeirUsedCnt=0;
+ RTclassHeirPartUsedCnt=0;
+ RTclassHeirSuperCnt=0;
+ RTmethodNotUsedCnt = 0;
+ RTmethodNotUsedCnt1 = 0;
+ RTmethodNotUsedCnt2 = 0;
+ RTmethodUsedCnt = 0;
+ RTmethodMarkedCnt= 0;
+
+
+ /*-- --*/
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\nRT Class Heirarchy for ");
+ printf("--- start of RT info --------------- after :\n");
+ if (m != NULL) {
+ utf_display(m->class->name);
+ printf(".");
+ method_display(m);
+ printf("\n");
+ }
+ }
+ printRTClassHeirarchy(class_java_lang_Object);
+ if (pClassHeirStatsOnly >= 2) {
+ printf("--- end of RT info ---------------\n");
+ }
+ if (pClassHeirStatsOnly >= 1) {
+
+ /*-- statistic results --*/
+ printRTInterfaceClasses();
+
+ printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Heirarchy Statistics:\n");
+ printf(" Used \t%i \tclasses\t/ Used \t%i methods \t of USED: %i%% \t of ALL: %i%% \n",
+ RTclassHeirUsedCnt,RTmethodUsedCnt,
+ ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
+ ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
+ printf(" Part Used \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt);
+ printf(" Not Used \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
+ printf(" \t \t \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt);
+ printf(" In Not Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt1);
+ printf(" In Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt2);
+ printf(" Total \t%i \tclasses\t/ Total \t%i methods\n\n",
+ RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,
+ RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2 + RTmethodUsedCnt + RTmethodMarkedCnt );
+
+ printf(" Mono vs. Polymorhpic calls:\n");
+ printf(" Mono calls \t%i \tPoly that resolves to Mono \t%i \tPoly calls \t%i\n\n",
+ RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
+
+ printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
+ RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
+
+ printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+ RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
+ printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+ RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
+ }
+}
+
+++ /dev/null
-/********************** parseRT.h ******************************************
- Parser and print functions for X Type Analyis (XTA)
- used to only compile methods that may actually be used.
-
- 5/12/2003 only prints info that will need to put in the various sets
- Goal: find which opcodes need to get info from...
-***************************************************************************/
-/********** internal function: printflags (only for debugging) ***************/
-
-static void printflags (u2 f)
-{
- if ( f & ACC_PUBLIC ) printf (" PUBLIC");
- if ( f & ACC_PRIVATE ) printf (" PRIVATE");
- if ( f & ACC_PROTECTED ) printf (" PROTECTED");
- if ( f & ACC_STATIC ) printf (" STATIC");
- if ( f & ACC_FINAL ) printf (" FINAL");
- if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
- if ( f & ACC_VOLATILE ) printf (" VOLATILE");
- if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
- if ( f & ACC_NATIVE ) printf (" NATIVE");
- if ( f & ACC_INTERFACE ) printf (" INTERFACE");
- if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
-}
-
-/**************** Function: xfield_display (debugging only) ********************/
-static void xfield_display (fieldinfo *f)
-{
-printf (" ");
-printflags (f -> flags);
-printf (" ");
-utf_display (f -> name);
-printf (" ");
-utf_display (f -> descriptor);
-printf (" offset: %ld\n", (long int) (f -> offset) );
-}
-
-
-/*-------------------------------------------------------------------------------*/
-
-#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]))
-
-
-/*-------------------------------------------------------------------------------*/
-
-static void parseXTA()
-{
- 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 */
-
- /*XTAprint*/ {printf("*********************************\n");
- /*XTAprint*/ printf("PARSE XTA method name =");
- /*XTAprint*/ utf_display(rt_method->class->name);printf(".");
- /*XTAprint*/ utf_display(rt_method->name);printf("\n\n");
- /*XTAprint*/ method_display(rt_method); printf(">\n\n");fflush(stdout);}
-
- /* scan all java instructions */
-
-
- for (p = 0; p < rt_jcodelength; p = nextp) {
- opcode = rt_code_get_u1 (p); /* fetch op code */
-
- /*XTAprint*/ {printf("Parse RT p=%i<%i< opcode=<%i> %s\n",
- /*XTAprint*/ p,rt_jcodelength,opcode,opcode_names[opcode]);
- /*XTAprint*/ fflush(stdout); }
-
- nextp = p + jcommandsize[opcode]; /* compute next instruction start */
- switch (opcode) {
-
-/* Opcodes with no info for XTA */
-/* NOP */
-/* BIPUSH, SIPUSH - and all CONST opcodes just not read/write of field*/
-/* illegal opcodes */
-
-/*--------------------------------*/
-/* LOADCONST opcodes */
- case JAVA_BIPUSH:
- printf("BIPUSH value=%i\n",(rt_code_get_s1(p+1)));
- /*LOADCONST_I(code_get_s1(p+1));*/
- break;
-
- case JAVA_SIPUSH:
- printf("SIPUSH value=%i\n",(rt_code_get_s2(p+1)));
- /*LOADCONST_I(code_get_s2(p+1));*/
- break;
- /*
- case JAVA_LDC1:
- ...
- case JAVA_LDC2:
- case JAVA_LDC2W:
- ...
- */
- case JAVA_ACONST_NULL:
- printf("ACONST_NULL value=NULL\n" );
- /* LOADCONST_A(NULL);*/
- break;
-
- case JAVA_ICONST_M1:
- case JAVA_ICONST_0:
- case JAVA_ICONST_1:
- case JAVA_ICONST_2:
- case JAVA_ICONST_3:
- case JAVA_ICONST_4:
- case JAVA_ICONST_5:
- printf("JAVA_ICONST_x value=%i\n",(opcode - JAVA_ICONST_0 ) );
- /* LOADCONST_I(opcode - JAVA_ICONST_0);*/
- break;
-
- case JAVA_LCONST_0:
- case JAVA_LCONST_1:
- printf("JAVA_LCONST_x value=%d\n",(opcode - JAVA_LCONST_0 ) );
- /* LOADCONST_L(opcode - JAVA_LCONST_0);*/
- break;
-
- case JAVA_FCONST_0:
- case JAVA_FCONST_1:
- case JAVA_FCONST_2:
-printf("JAVA_FCONST_x value=%f\n",(opcode - JAVA_FCONST_0 ) );
- /* LOADCONST_F(opcode - JAVA_FCONST_0);*/
- break;
-
- case JAVA_DCONST_0:
- case JAVA_DCONST_1:
-printf("JAVA_DCONST_x value=%d\n",(opcode - JAVA_DCONST_0 ) );
- /* LOADCONST_D(opcode - JAVA_DCONST_0);*/
- break;
-
-/*--------------------------------*/
-/* 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;
- }
- break;
- /* 132 */
- case JAVA_IINC:
- {
- int v;
-
- if (iswide) {
- iswide = false;
- 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;
- 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;
- }
-
-
- 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;
- }
-
-/*-------------------------------*/
-
- case JAVA_PUTSTATIC:
- case JAVA_GETSTATIC:
- i = rt_code_get_u2(p + 1);
- {
- constant_FMIref *fr;
- fieldinfo *fi;
-
- fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
- fi = class_findfield (fr->class,fr->name, fr->descriptor);
- /*COtest*/ xfield_display (fi);
- /*COtest */ printf(" in class.field =");utf_display(fr->class->name); printf(".");
- /*COtest */ utf_display(fr->name);printf("\tPUT/GET STATIC\n");
-
- }
- break;
-
- case JAVA_PUTFIELD:
- case JAVA_GETFIELD:
- i = rt_code_get_u2(p + 1);
- {
- constant_FMIref *fr;
- fieldinfo *fi;
-
- fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
- fi = class_findfield (fr->class,fr->name, fr->descriptor);
- /*COtest*/ xfield_display (fi);
- /*COtest */ printf(" in class.field =");utf_display(fr->class->name); printf(".");
- /*COtest */ utf_display(fr->name);printf("\tPUT/GET FIELD\n");
-
-
- }
- break;
-
-
-/*-------------------------------*/
- /* managing arrays ************************************************/
-
- case JAVA_NEWARRAY:
- switch (rt_code_get_s1(p+1)) {
- case 4: /* boolean */
- /*COtest*/ printf("***** NEW boolean array\n");
- break;
- case 5:
- /*COtest*/ printf("***** NEW char array\n");
- break;
- case 6:
- /*COtest*/ printf("***** NEW float array\n");
- break;
- case 7:
- /*COtest*/ printf("***** NEW double array\n");
- break;
- case 8:
- /*COtest*/ printf("***** NEW byte array\n");
- break;
- case 9:
- /*COtest*/ printf("***** NEW short array\n");
- break;
- case 10:
- /*COtest*/ printf("***** NEW int array\n");
- break;
- case 11:
- /*COtest*/ printf("***** NEW long array\n");
- break;
- default: panic("XTA: Invalid array-type to create");
- }
- break;
-
-
- case JAVA_ANEWARRAY:
- i = rt_code_get_u2(p+1);
- {
- constant_FMIref *ar;
- voidptr e;
-/*COtest*/ printf("ARRAY<%i> type=%i=",i,(int) rt_class->cptags[i] ); utf_display(rt_class->name);printf("\n");
- /* array or class type ? */
- if (class_constanttype (rt_class, i) != CONSTANT_Arraydescriptor) {
- e = class_getconstant(rt_class, i, CONSTANT_Class);
-/*COtest*/ utf_display ( ((classinfo*)e) -> name );printf(">b\n");
- /******
- /*COtest if (ar == NULL) printf(" ARRAY2xNULL\n");
- /*COtest else {
- /*COtest printf(" ARRAY2 Name=");utf_display(ar->name);printf("\n");
- /*COtest }
- ****/
- }
- }
- break;
- case JAVA_MULTIANEWARRAY:
- i = rt_code_get_u2(p+1);
- {
- constant_FMIref *ar;
- ar = class_getconstant(rt_class, i, CONSTANT_Arraydescriptor);
- /******
- /*COtest if (ar == NULL) printf(" ARRAY2xNULL\n");
- /*COtest else {
- /*COtest printf(" ARRAY2 Name=");utf_display(ar->name);printf("\n");
- /*COtest }
- constant_arraydescriptor *desc =
- class_getconstant (rt_class, i, CONSTANT_Arraydescriptor);
- ****/
- }
- break;
-
-
-/*-------------------------------*/
- /* method invocation *****/
-
- 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);
-
- /*RTAprint*/ printf(" method name =");
- /*RTAprint*/ utf_display(mi->class->name); printf(".");
- /*RTAprint*/ utf_display(mi->name);printf("\tINVOKE STATIC\n");
- /*RTAprint*/ fflush(stdout);
- }
- break;
-
-
- case JAVA_INVOKESPECIAL:
- 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);
-
- /*RTAprint*/ {printf(" method name =");
- /*RTAprint*/ utf_display(mi->class->name); printf(".");
- /*RTAprint*/ utf_display(mi->name);
- /*RTAprint*/ printf("\tbINVOKESPECIAL/VIRTUAL\n"); fflush(stdout); }
-
- }
- break;
-
- case JAVA_INVOKEINTERFACE:
- i = code_get_u2(p + 1);
- {
- constant_FMIref *mr;
- methodinfo *mi;
-
- mr = class_getconstant (rt_class, i, CONSTANT_InterfaceMethodref);
- mi = class_findmethod (mr->class, mr->name, mr->descriptor);
-
- /*RTAprint*/ {printf(" method name =");
- /*RTAprint*/ utf_display(mi->class->name); printf(".");
- /*RTAprint*/ utf_display(mi->name); printf("\n");
- /*RTAprint*/ method_display(mi); printf("INVOKE INTERFACE>\n\n");fflush(stdout);}
-
-
- if (mi->flags & ACC_STATIC)
- panic ("Static/Nonstatic mismatch calling static method");
- /*descriptor2types(mi); */
- }
- break;
-
- /* miscellaneous object operations *******/
-
- case JAVA_NEW:
- i = rt_code_get_u2 (p+1);
- {
- constant_FMIref *cr;
- classinfo *ci;
-
- ci = class_getconstant (rt_class, i, CONSTANT_Class);
- /*RTAprint*/ printf(" NEW fmi info = ");
- /*RTAprint*/ utf_display (ci->name);fflush(stdout); printf("\n");
- }
- break;
-
-
-
- default:
- break;
-
- } /* end switch */
-
-
- } /* end for */
-
- if (p != rt_jcodelength)
- panic("Command-sequence crosses code-boundary");
-
-}
-
-/*-------------------------------------------------------------------------------*/
-
-void XTA_jit_parse(methodinfo *m)
-{
- rt_method = m;
- rt_class = rt_method->class;
- rt_descriptor = rt_method->descriptor;
- rt_jcodelength = rt_method->jcodelength;
- rt_jcode = rt_method->jcode;
-
- parseXTA();
-}
--- /dev/null
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sets.h"
+
+
+/*
+ * set.c - functions to manipulate ptr sets.
+ */
+
+/*------------------------------------------------------------*/
+/*-- fieldinfo call set fns */
+/*------------------------------------------------------------*/
+fldSetNode *inFldSet (fldSetNode *s, fieldinfo *f)
+ {
+ fldSetNode* i;
+ for (i=s; i != NULL; i = i->nextfldRef) {
+ if (i->fldRef == f) {
+ return i; /* true = found */
+ }
+ }
+ return NULL;
+ }
+
+/*------------------------------------------------------------*/
+/* */
+fldSetNode *addFldRef(fldSetNode *s, fieldinfo *f)
+ {
+ fldSetNode *s1 = s;
+ if (!inFldSet(s,f)) {
+ s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
+ s1->nextfldRef = s;
+ s1->fldRef = f;
+ s1->readPUT = false;
+ s1->writeGET = false;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+fldSet *add2FldSet(fldSet *sf, fieldinfo *f)
+ {
+ fldSetNode *s1;
+ fldSetNode *s;
+
+ if (sf == NULL) {
+ sf = createFldSet();
+ }
+ s = sf->head;
+ if (!inFldSet(s,f)) {
+ s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
+ if (sf->head == NULL) {
+ sf->head = s1;
+ sf->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sf->tail->nextfldRef = s1;
+ sf->length++;
+ s1->index = sf->length;
+ }
+ s1->nextfldRef = NULL;
+ s1->fldRef = f;
+ s1->readPUT = false;
+ s1->writeGET = false;
+ sf->tail = s1;
+ }
+ return sf;
+ }
+
+/*------------------------------------------------------------*/
+fldSet *createFldSet( )
+ {
+ fldSet *s;
+ s = (fldSet *)malloc(sizeof(fldSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/*-- methodinfo call set fns */
+/*------------------------------------------------------------*/
+int inMethSet (methSetNode *s, methodinfo *m)
+ {
+ methSetNode* i;
+ for (i=s; i != NULL; i = i->nextmethRef) {
+ if (i->methRef == m) {
+ return (int)1; /* true = found */
+ }
+ }
+ return (int)0;
+ }
+
+/*------------------------------------------------------------*/
+methSetNode *addMethRef(methSetNode *s, methodinfo *m)
+ {
+ methSetNode *s1 = s;
+ if (!inMethSet(s,m)) {
+ s1 = (methSetNode *)malloc(sizeof(methSetNode));
+ s1->nextmethRef= s;
+ s1->methRef = m;
+ s1->lastptrIntoClassSet2 = NULL;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ s1->monoPoly = MONO;
+ }
+
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+methSet *add2MethSet(methSet *sm, methodinfo *m)
+ {
+ methSetNode *s1;
+ methSetNode *s;
+
+ if (sm == NULL) {
+ sm = createMethSet();
+ }
+ s = sm->head;
+ if (!inMethSet(s,m)) {
+ s1 = (methSetNode *)malloc(sizeof(methSetNode));
+ if (sm->head == NULL) {
+ sm->head = s1;
+ sm->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sm->tail->nextmethRef = s1;
+ sm->length++;
+ s1->index = sm->length;
+ }
+ s1->monoPoly = MONO;
+ s1->nextmethRef= NULL;
+ s1->methRef = m;
+ s1->lastptrIntoClassSet2 = NULL;
+ sm->tail = s1;
+ }
+ return sm;
+ }
+
+/*------------------------------------------------------------*/
+methSet *createMethSet( )
+ {
+ methSet *s;
+ s = (methSet *)malloc(sizeof(methSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/*-- classinfo XTA set fns */
+/*------------------------------------------------------------*/
+int inSet (classSetNode *s, classinfo *c)
+ {
+ classSetNode* i;
+ for (i=s; i != NULL; i = i->nextClass) {
+ if (i->classType == c) {
+ return ((i->index)+1); /* true = found */
+ }
+ }
+ return (int)0;
+ }
+
+/*------------------------------------------------------------*/
+classSetNode *addElement(classSetNode *s, classinfo *c)
+ {
+ classSetNode *s1 = s;
+ if (!inSet(s,c)) {
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ s1->nextClass= s;
+ s1->classType = c;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+classSet *add2ClassSet(classSet *sc, classinfo *c)
+ {
+ classSetNode *s1;
+ classSetNode *s;
+
+ if (sc == NULL) {
+ sc = createClassSet();
+ }
+ s = sc->head;
+
+ if (!inSet(s,c)) {
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ if (sc->head == NULL) {
+ sc->head = s1;
+ sc->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sc->tail->nextClass = s1;
+ sc->length++;
+ s1->index = sc->length;
+ }
+ s1->classType = c;
+ s1->nextClass= NULL;
+ sc->tail = s1;
+ }
+ return sc;
+ }
+
+/*------------------------------------------------------------*/
+classSet *createClassSet( )
+ {
+ classSet *s;
+ s = (classSet *)malloc(sizeof(classSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/* Returns:
+/* -1 c is a subclass of an existing set element
+/* 0 c class type cone does not overlap any set element
+/* 1 c is a superclass of an existing set element
+*/
+
+int inRange (classSetNode *s, classinfo *c)
+ {
+ classSetNode* i;
+ int rc=0;
+
+ for (i=s; i != NULL; i = i->nextClass) {
+ classinfo *cs = i->classType;
+ if (cs->vftbl->baseval <= c->vftbl->baseval) {
+ if (c->vftbl->baseval <= (cs->vftbl->baseval+cs->vftbl->diffval)) {
+ rc = -1; /* subtype */
+ }
+ }
+ else {
+ if (cs->vftbl->baseval < (c->vftbl->baseval+c->vftbl->diffval)) {
+ i->classType = c; /* replace element with its new super */
+ rc = 1; /* super */
+ }
+ }
+ }
+ return rc;
+ }
+
+/*------------------------------------------------------------*/
+/* adds class if not subtype of an existing set element */
+/* if "new" class is super class of an existing element */
+/* then replace the existing element with the "new" class */
+
+classSetNode *addClassCone(classSetNode *s, classinfo *c)
+ {
+ classSetNode *s1 = s;
+
+if (inRange(s,c) == 0) {
+ /* not in set nor cone of an existing element so add */
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ s1->nextClass= s;
+ s1->classType = c;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+classSetNode * intersectSubtypesWithSet(classinfo *t, classSetNode *s) {
+ classSetNode *s1 = NULL;
+ classSetNode *c;
+
+ /* for each s class */
+ for (c=s; c != NULL; c = c->nextClass) {
+ vftbl *t_cl_vt = t->vftbl;
+ vftbl *c_cl_vt = c->classType->vftbl;
+
+ /* if s class is in the t Class range */
+ if ( (t_cl_vt->baseval <= c_cl_vt->baseval)
+ && (c_cl_vt->baseval <= (t_cl_vt->baseval+t_cl_vt->diffval)) ) {
+
+ /* add s class to return class set */
+ s1 = addElement(s1,c->classType);
+ }
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+int sizeOfSet(classSetNode *s) {
+/*** need to update */
+ int cnt=0;
+ classSetNode * i;
+ for (i=s; i != NULL; i = i->nextClass) cnt++;
+ return cnt;
+ }
+
+/*------------------------------------------------------------*/
+int printSet(classSetNode *s)
+ {
+ classSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of types: <");
+ printf("\t\tEmpty Set\n");
+ }
+ else {
+ printf("<%i>Set of types: ",s->index);
+ for (i=s; i != NULL; i = i->nextClass) {
+ printf("\t#%i: ",cnt);
+ if (i->classType == NULL) {
+ printf("NULL CLASS");
+ fflush(stdout);
+ }
+ else {
+ utf_display(i->classType->name);
+ fflush(stdout);
+ printf("<b%i/d%i> ",i->classType->vftbl->baseval,i->classType->vftbl->diffval);
+ fflush(stdout);
+ }
+ cnt++;
+ }
+ printf(">\n");
+ }
+ return cnt;
+ }
+/*------------------------------------------------------------*/
+int printClassSet(classSet *sc) {
+if (sc == NULL) {
+ printf("Class Set not yet created\n");
+ return 0;
+ }
+else
+ return (printSet(sc->head));
+}
+
+/*------------------------------------------------------------*/
+int printMethSet(methSetNode *s)
+ {
+ methSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of Methods: "); fflush(stdout);
+ printf("\t\tEmpty Set\n"); fflush(stdout);
+ }
+ else {
+ printf("<%i>Set of Methods: ",s->index);fflush(stdout);
+ for (i=s; i != NULL; i = i->nextmethRef) {
+ printf("\t#%i: ",cnt);
+
+ /* class.method */
+ utf_display(i->methRef->class->name);
+ printf(".");
+ method_display(i->methRef);
+
+ /* lastptr <class> */
+ printf("\t<");
+ if (i->lastptrIntoClassSet2 != NULL)
+ utf_display(i->lastptrIntoClassSet2->classType->name);
+ printf(">\n");
+
+ cnt++;
+ }
+ printf("\n");
+ }
+ return cnt;
+ }
+/*------------------------------------------------------------*/
+int printMethodSet(methSet *sm) {
+if (sm == NULL) {
+ printf("Method Set not yet created\n");
+ return 0;
+ }
+else
+ return (printMethSet(sm->head));
+}
+/*------------------------------------------------------------*/
+int printFldSet(fldSetNode *s)
+ {
+ fldSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of Fields: ");
+ printf("\tEmpty Set\n");
+ }
+ else {
+ printf("<%i>Set of Fields: ",s->index);
+ for (i=s; i != NULL; i = i->nextfldRef) {
+ printf("\t#%i: ",cnt);
+ printf("(%ir/%iw)",i->readPUT,i->writeGET);
+ field_display(i->fldRef);
+ cnt++;
+ }
+ printf("\n");
+ }
+ return cnt;
+ }
+
+/*------------------------------------------------------------*/
+int printFieldSet(fldSet *sf) {
+if (sf == NULL) {
+ printf("Field Set not yet created\n");
+ return 0;
+ }
+else
+ return (printFldSet(sf->head));
+}
+/*------------------------------------------------------------*/
+/*void destroy_set */
+
--- /dev/null
+#ifndef __SET__
+#define __SET__
+
+typedef struct methSet methSet;
+typedef struct methSetNode methSetNode;
+typedef struct fldSet fldSet;
+typedef struct fldSetNode fldSetNode;
+typedef struct classSet classSet;
+typedef struct classSetNode classSetNode;
+
+
+/*------------------------------------------------------------*/
+/*-- flds used by a method set fns */
+/*------------------------------------------------------------*/
+struct fldSet {
+ fldSetNode *head;
+ fldSetNode *tail;
+ fldSetNode *pos;
+ s4 length;
+ };
+
+
+struct fldSetNode {
+ fieldinfo *fldRef;
+ fldSetNode *nextfldRef;
+ bool readPUT;
+ bool writeGET;
+ s2 index;
+ };
+fldSetNode *inFldSet (fldSetNode *, fieldinfo *);
+fldSetNode *addFldRef(fldSetNode *, fieldinfo *);
+fldSet *add2FldSet(fldSet *, fieldinfo *);
+fldSet *createFldSet();
+int printFldSet (fldSetNode *);
+int printFieldSet (fldSet *);
+
+
+/*------------------------------------------------------------*/
+/*-- methodinfo call set fns */
+/*------------------------------------------------------------*/
+struct methSet {
+ methSetNode *head;
+ methSetNode *tail;
+ methSetNode *pos;
+ s4 length;
+ };
+
+struct methSetNode {
+ methodinfo *methRef;
+ methSetNode *nextmethRef;
+ classSetNode *lastptrIntoClassSet2;
+ s2 index;
+ s4 monoPoly;
+ };
+
+int inMethSet (methSetNode *, methodinfo *);
+methSetNode *addMethRef(methSetNode *, methodinfo *);
+methSet *add2MethSet(methSet *, methodinfo *);
+methSet *createMethSet();
+int printMethSet (methSetNode *);
+int printMethodSet (methSet *);
+
+/*------------------------------------------------------------*/
+/*-- classinfo XTA set fns */
+/*------------------------------------------------------------*/
+
+struct classSet {
+ classSetNode *head;
+ classSetNode *tail;
+ classSetNode *pos;
+ s4 length;
+ };
+
+struct classSetNode {
+ classinfo *classType;
+ classSetNode *nextClass;
+ s2 index;
+ };
+
+int inSet (classSetNode *, classinfo *);
+classSetNode * addElement(classSetNode *, classinfo *);
+classSet * add2ClassSet(classSet *, classinfo *);
+classSet * createClassSet();
+int inRange (classSetNode *, classinfo *);
+classSetNode * addClassCone(classSetNode *, classinfo *);
+classSetNode * intersectSubtypesWithSet(classinfo *, classSetNode *);
+int setSize(classSetNode *);
+int printSet(classSetNode *);
+int printClassSet(classSet *);
+
+#endif
+
extern bool newcompiler; /* true if new compiler is used */
bool opt_rt = false; /* true if RTA parse should be used RT-CO */
bool opt_xta = false; /* true if XTA parse should be used XTA-CO */
+bool opt_vta = false; /* true if VTA parse should be used VTA-CO */
int count_class_infos = 0; /* variables for measurements */
int count_const_pool_len = 0;
d -> arraytype = ARRAYTYPE_OBJECT;
d -> objectclass = class_new ( utf_new(utf_ptr+1, namelen-3) );
- d -> objectclass -> classUsed = 0; /* not used initially CO-RT */
+ d -> objectclass -> classUsed = NOTUSED; /* not used initially CO-RT */
d -> objectclass -> impldBy = NULL;
- d -> objectclass -> nextimpldBy = NULL;
break;
}
return d;
f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
f -> type = jtype = desc_to_type (f->descriptor); /* data type */
f -> offset = 0; /* offset from start of object */
+ f -> fieldUsed = NOTUSED; /*XTA*/
+ f -> fldClassType = NULL; /*XTA*/
+ f -> XTAclassSet = NULL; /*XTA*/
+ f -> lastRoundChgd = -1;
switch (f->type) {
case TYPE_INT: f->value.i = 0; break;
m -> entrypoint = NULL;
m -> mcode = NULL;
m -> stubroutine = NULL;
- m -> methodUsed = 0;
- m -> XTAclasscount = 0;
- m -> numSubDefs = 0;
+ m -> methodUsed = NOTUSED;
+ m -> XTAmethodUsed = NOTUSED;
+ m -> monoPoly = MONO;
+ m -> subRedefs = 0;
+ m -> subRedefsUsed = 0;
+
+ /* --- XTA --- */
+ /*if (opt_xta) { */
+ m -> XTAclassSet = NULL; /*XTA*/
+ m -> paramClassSet = NULL; /*XTA*/
+ m -> calls = NULL; /*XTA*/
+ m -> calledBy = NULL; /*XTA*/
+ m -> chgdSinceLastParse = false; /*XTA*/
+
+ m -> marked = NULL; /*XTA*/
+ m -> markedBy = NULL; /*XTA*/
+ m -> fldsUsed = NULL; /*XTA*/
+ m -> interfaceCalls = NULL; /*XTA*/
+ m -> lastRoundParsed = -1;
+ m -> interfaceCalls = NULL; /*XTA*/
+ /*}*/
if (! (m->flags & ACC_NATIVE) ) {
m -> stubroutine = createcompilerstub (m);
class_loadcpool (c);
- c -> classUsed = 0; /* not used initially CO-RT */
+ c -> classUsed = NOTUSED; /* not used initially CO-RT */
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
/* ACC flags */
c -> flags = suck_u2 ();
if (super == NULL) { /* class java.long.Object */
c->index = 0;
- c->classUsed = 1; /* Object class is always used CO-RT*/
+ c->classUsed = USED; /* Object class is always used CO-RT*/
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
c->instancesize = sizeof(java_objectheader);
vftbllength = supervftbllength = 0;
u4 i = ii;
voidptr e;
-printf ("#%d: ", (int) i);
e = c -> cpinfos [i];
+printf ("#%d: ", (int) i);
if (e) {
switch (c -> cptags [i]) {
case CONSTANT_Class:
for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
/* create primitive class */
classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
- c -> classUsed = 0; /* not used initially CO-RT */
+ c -> classUsed = NOTUSED; /* not used initially CO-RT */
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
/* prevent loader from loading primitive class */
list_remove (&unloadedclasses, c);
/* create class for wrapping the primitive type */
primitivetype_table[i].class_wrap =
class_new( utf_new_char(primitivetype_table[i].wrapname) );
- primitivetype_table[i].class_wrap -> classUsed = 0; /* not used initially CO-RT */
+ primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
primitivetype_table[i].class_wrap -> impldBy = NULL;
- primitivetype_table[i].class_wrap -> nextimpldBy = NULL;
}
}
/* create class for arrays */
class_array = class_new ( utf_new_char ("The_Array_Class") );
- class_array -> classUsed = 0; /* not used initially CO-RT */
+ class_array -> classUsed = NOTUSED; /* not used initially CO-RT */
class_array -> impldBy = NULL;
- class_array -> nextimpldBy = NULL;
list_remove (&unloadedclasses, class_array);
/* create class for strings, load it after class Object was loaded */
string_class = utf_new_char ("java/lang/String");
class_java_lang_String = class_new(string_class);
- class_java_lang_String -> classUsed = 0; /* not used initially CO-RT */
+ class_java_lang_String -> classUsed = NOTUSED; /* not used initially CO-RT */
class_java_lang_String -> impldBy = NULL;
- class_java_lang_String -> nextimpldBy = NULL;
list_remove (&unloadedclasses, class_java_lang_String);
classinfo *subs;
c->vftbl->baseval = ++classvalue;
+
subs = c->sub;
while (subs != NULL) {
loader_compute_class_values(subs);
subs = subs->nextsub;
}
c->vftbl->diffval = classvalue - c->vftbl->baseval;
+
/*
{
int i;
Mark Probst EMAIL: cacao@complang.tuwien.ac.at
Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: main.c 467 2003-09-26 01:55:25Z didi $
+ Last Change: $Id: main.c 468 2003-10-04 17:15:31Z carolyn $
*******************************************************************************/
#define OPT_INLINING 25
#define OPT_RT 26
#define OPT_XTA 27
+#define OPT_VTA 28
struct {char *name; bool arg; int value;} opts[] = {
{"i", true, OPT_INLINING},
{"rt", false, OPT_RT},
{"xta", false, OPT_XTA},
+ {"vta", false, OPT_VTA},
{NULL, false, 0}
};
printf (" p ............. optimize argument renaming\n");
printf (" o ............. inline methods of foreign classes\n");
printf (" -rt .................. use rapid type analysis\n");
- printf (" -xta ................. use xta\n");
+ printf (" -xta ................. use x type analysis\n");
+ printf (" -vta ................. use variable type analysis\n");
}
break;
case OPT_XTA:
- opt_xta = true;
+ /***opt_xta = true; not yet **/
+ break;
+
+ case OPT_VTA:
+ /***opt_vta = true; not yet **/
break;
default:
/*RTAprint*/ printCallgraph (); }
/*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
- /*RTprint*/ printf("Last RTA Class Heirarchy -");
+ /*RTprint*/ printf("Last RTA Info -");
/*RTprint*/ printRThierarchyInfo(mainmethod);
/*RTprint*/ }
/*RTprint*/ printObjectClassHeirarchy1( );
/*RTAprint*/ printCallgraph (NULL); }
/*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
- /*RTprint*/ printf("Last RTA Class Heirarchy -");
+ /*RTprint*/ printf("RTA Information -");
/*RTprint*/ printRThierarchyInfo(NULL); }
if (verbose || getcompilingtime || statistics) {
},
},
+{"wait" , "(J)V",
+ {
+ {"Runner" , "run", "()V;"},
+ },
},
-1, {2 }
+
+},
+2, {2,1 }
},
/*------------------------------------*/
Mark Probst EMAIL: cacao@complang.tuwien.ac.at
Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: cacao.c 467 2003-09-26 01:55:25Z didi $
+ Last Change: $Id: cacao.c 468 2003-10-04 17:15:31Z carolyn $
*******************************************************************************/
#define OPT_INLINING 25
#define OPT_RT 26
#define OPT_XTA 27
+#define OPT_VTA 28
struct {char *name; bool arg; int value;} opts[] = {
{"i", true, OPT_INLINING},
{"rt", false, OPT_RT},
{"xta", false, OPT_XTA},
+ {"vta", false, OPT_VTA},
{NULL, false, 0}
};
printf (" p ............. optimize argument renaming\n");
printf (" o ............. inline methods of foreign classes\n");
printf (" -rt .................. use rapid type analysis\n");
- printf (" -xta ................. use xta\n");
+ printf (" -xta ................. use x type analysis\n");
+ printf (" -vta ................. use variable type analysis\n");
}
break;
case OPT_XTA:
- opt_xta = true;
+ /***opt_xta = true; not yet **/
+ break;
+
+ case OPT_VTA:
+ /***opt_vta = true; not yet **/
break;
default:
/*RTAprint*/ printCallgraph (); }
/*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
- /*RTprint*/ printf("Last RTA Class Heirarchy -");
+ /*RTprint*/ printf("Last RTA Info -");
/*RTprint*/ printRThierarchyInfo(mainmethod);
/*RTprint*/ }
/*RTprint*/ printObjectClassHeirarchy1( );
/*RTAprint*/ printCallgraph (NULL); }
/*RTprint*/ if ((pClassHeir >= 1) && (opt_rt)) {
- /*RTprint*/ printf("Last RTA Class Heirarchy -");
+ /*RTprint*/ printf("RTA Information -");
/*RTprint*/ printRThierarchyInfo(NULL); }
if (verbose || getcompilingtime || statistics) {
void *m;
if (!nomallocmem) {
- nomallocmem = malloc(16777216);
+ nomallocmem = malloc(16777216);
nomalloctop = nomallocmem + 16777216;
nomallocptr = nomallocmem;
}
},
},
+{"wait" , "(J)V",
+ {
+ {"Runner" , "run", "()V;"},
+ },
},
-1, {2 }
+
+},
+2, {2,1 }
},
/*------------------------------------*/
Changes: Mark Probst (schani) EMAIL: cacao@complang.tuwien.ac.at
Philipp Tomsich (phil) EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: global.h 466 2003-09-25 07:55:50Z carolyn $
+ Last Change: $Id: global.h 468 2003-10-04 17:15:31Z carolyn $
*******************************************************************************/
typedef struct classinfo classinfo;
typedef struct vftbl vftbl;
typedef u1* methodptr;
+typedef struct fieldinfo fieldinfo;
+typedef struct methodinfo methodinfo;
/* constant pool entries *******************************************************
struct constant_arraydescriptor *elementdescriptor;
} constant_arraydescriptor;
+#include "jit/sets.h"
/* data structures of the runtime system **************************************/
/* fieldinfo ******************************************************************/
-typedef struct fieldinfo {/* field of a class */
+struct fieldinfo { /* field of a class */
s4 flags; /* ACC flags */
s4 type; /* basic data type */
utf *name; /* name of field */
double d;
void *a;
} value;
-
-} fieldinfo;
+
+ /*--- XTA ---*/
+ s4 fieldUsed; /* initialized to NOTUSED; set to USED when type checked */
+ bool fieldChecked;
+ classinfo *fldClassType;
+ classSet *XTAclassSet; /* field class type set */
+ s4 lastRoundChgd;
+ /*--- VTA ---*/
+ s4 VTAfieldUsed; /* -1=marked (might be used) 0=not used 1=used */
+ classSetNode *VTAclassSet; /* field class type set */
+
+} ;
struct basicblock;
} exceptiontable;
+/* methodinfo static info ****************************************************/
+/*typedef struct rtainfo {
+
+} rtainfo; */
/* methodinfo *****************************************************************/
-typedef struct methodinfo { /* method structure */
- s4 flags; /* ACC flags */
+struct methodinfo { /* method structure */
+ s4 flags; /* ACC flags */
utf *name; /* name of method */
utf *descriptor; /* JavaVM descriptor string of method */
s4 returntype; /* only temporary valid, return type */
+ classinfo *returnclass; /* pointer to classinfo for the rtn type */ /*XTA*/
s4 paramcount; /* only temporary valid, parameter count */
u1 *paramtypes; /* only temporary valid, parameter types */
+ classinfo **paramclass; /* pointer to classinfo for a parameter */ /*XTA*/
+
classinfo *class; /* class, the method belongs to */
s4 vftblindex; /* index of method in virtual function table
(if it is a virtual method) */
u1 *mcode; /* pointer to machine code */
u1 *entrypoint; /* entry point in machine code */
- s4 methodUsed; /* -1=marked (might be used) 0=not used 1=used CO-RT*/
- s4 numSubDefs; /* # sub definitions marked USED */
+ /*rtainfo rta;*/
+ /*xtainfo xta;*/
- s4 natCalls; /* number of methods calls */
+ s4 methodUsed; /* marked (might be used later) /not used /used */
+ s4 monoPoly; /* call is mono or poly or unknown */ /*RT stats */
+ /* should # method def'd and used be kept after static parse (will it be used?) */
+ s4 subRedefs;
+ s4 subRedefsUsed;
- s4 XTAclasscount; /* number of classes in XTA class set */
- classinfo *XTAclassSet; /* XTA class set*/
-
+ /* --- XTA --- */
+ s4 XTAmethodUsed; /* XTA if used in callgraph - not used /used */
+ classSet *XTAclassSet; /* method class type set */
+ classSet *PartClassSet; /* method class type set */
+
+ classSetNode *paramClassSet; /* cone set of methods parameters */
+
+ methSet *calls; /* methods this method calls */
+ methSet *calledBy; /* methods that call this method */
+ methSet *marked; /* methods that marked by this method */
+ methSet *markedBy;
+ fldSet *fldsUsed; /* fields used by this method */
+ bool chgdSinceLastParse; /* Changed since last parse ? */
+
+ s4 lastRoundParsed; /* Last round parsed */
+ methSetNode *interfaceCalls; /* methods this method calls as interface */
+
+ /* --- VTA --- */
+ classSetNode *VTAclassSet; /* method class type set */
+ methSetNode *VTAcalls; /* methods this method calls */
+ classSetNode **VTAlocalSets; /*VTA*/
+ classSetNode **VTAstackType; /*VTA*/
+};
-} methodinfo;
/* innerclassinfo *************************************************************/
s4 instancesize; /* size of an instance of this class */
#ifdef SIZE_FROM_CLASSINFO
s4 alignedsize; /* size of an instance, aligned to the
- allocation size on the heap */
+ allocation size on the heap */
#endif
vftbl *vftbl; /* pointer to virtual function table */
s4 classUsed; /* 0= not used 1 = used CO-RT */
- classinfo *impldBy; /* implemented by class pointer */
- classinfo *nextimpldBy; /* ptr to next class in impldBy class list */
-
+ classSetNode *impldBy; /* implemented by class set */
};
extern bool verbose;
extern bool opt_rt; /* Rapid Type Analysis for better inlining CO-RT*/
extern bool opt_xta; /* X Type Analysis for better inlining CO-XTA*/
+extern bool opt_vta; /* Variable Type Analysis for better inlining CO-VTA*/
extern int pClassHeir;
extern int pCallgraph;
-EXTRA_DIST = mcode.c parse.c reg.c stack.c jitdef.h inline.c parseRT.h parseXTA.h
+EXTRA_DIST = mcode.c parse.c reg.c stack.c jitdef.h inline.c sets.h sets.c parseRT.h parseXTA.h parseRTstats.h sets.h sets.c
#include "natcalls.h"
#include "parseRTprint.h" /* RTAPRINT trace/info/debug prints */
-
-/*------------ Method /Class Used Markers -------------------------------*/
-#define USED 1
-#define NOTUSED 0
-#define JUSTMARKED -1
-
-/* class only */
-#define METH_USED_BY_SUB -1
-#define MARKEDSUPER -2
+#include "sets.h"
/*------------ global variables -----------------------------------------*/
+#define MAXCALLGRAPH 5000
+
+bool XTAOPTbypass = false;
+bool XTAOPTbypass2 = false; /* for now invokeinterface */
+bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
+int XTAdebug = 0;
+int XTAfld = 0;
+
+int I; /* ASTORE /ALOAD index */
+
int methRT = 0;
int methRTlast = -1;;
-int methRTmax=5000;
-methodinfo *callgraph[5000];
+int methRTmax=MAXCALLGRAPH;
+methodinfo *callgraph [MAXCALLGRAPH];
+
+
+int methXTA = 0;
+int methXTAlast = -1;;
+int methXTAmax=MAXCALLGRAPH;
+methodinfo *XTAcallgraph[MAXCALLGRAPH];
static bool nativecallcompdone=0 ;
-static bool mainStarted = false;
static bool firstCall= true;
static FILE *rtMissed; /* Methods missed during RTA parse of Main */
- /* so easier to build dynmanic calls file */
-static FILE *dynClasss; /* Classes /methods used, but seen by static analysis */
+ /* so easier to build dynmanic calls file */
-static utf *INIT ;
-static utf *CLINIT ;
-static utf *FINALIZE;
+static utf *utf_MAIN; /* utf_new_char("main"); */
+static utf *INIT ; /* utf_new_char("<init>"); */
+static utf *CLINIT ; /* utf_new_char("<clinit>"); */
+static utf *FINALIZE; /* utf_new_char("finalize"); */
+static utf *EMPTY_DESC; /* utf_new_char("V()"); */
static int missedCnt = 0;
-/*--- Statistics ----------------------------------------------------------*/
-
-int unRTclassHeirCnt=0;
-int unRTmethodCnt = 0;
-
-/*-----*/
-int RTclassHeirNotUsedCnt=0;
-int RTclassHeirUsedCnt=0;
-int RTclassHeirBySubCnt=0;
-int RTclassHeirSuperCnt=0;
-
-int RTmethodNotUsedCnt = 0;
-int RTmethodNotUsedCnt1= 0;
-int RTmethodNotUsedCnt2= 0;
-int RTmethodUsedCnt = 0;
-int RTmethodMarkedCnt= 0;
-
-/* What might be inlined of the Used Methods */
-int RTmethodFinal = 0;
-int RTmethodStatic = 0;
-int RTmethodFinalStatic = 0;
-int RTmethodNoSubs = 0;
-
-int RTmethodFinal100 = 0;
-int RTmethodStatic100 = 0;
-int RTmethodFinalStatic100 = 0;
-int RTmethodNoSubs100 = 0;
-
-#define MAXCODLEN 10
-
-int RTmethodNoSubsAbstract = 0;
-int RTmethod1Used = 0;
-
-/*------------- RTAprint flags ------------------------------------------------------------------*/
-int pCallgraph = 0; /* 0 - dont print 1 - print at end from main */
- /* 2 - print at end of RT parse call */
- /* 3- print after each method RT parse */
-int pClassHeir = 1; /* 0 - dont print 1 - print at end from main */
- /* 2 - print at end of RT parse call 3-print after each method RT parse */
-int pClassHeirStatsOnly = 1; /* Print only the statistical summary info for class heirarchy */
-
-int pOpcodes = 0; /* 0 - don't print 1- print in parse RT 2- print in parse */
- /* 3 - print in both */
-int pWhenMarked = 0; /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
- /* 2 - print when marked+methods called */
- /* 3 - print when class/method looked at */
-int pStats = 0; /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
-
-/*-----------------------------------------------------------------------------------------------*/
-
-void printCallgraph ()
- { int i;
-
- for (i=0;i<=methRTlast;i++) {
- printf(" (%i): ",i);
- utf_display(callgraph[i]->class->name);
- printf(":");
- method_display(callgraph[i]);
- }
+static bool useArrayOpcodes = false;
+static bool useFieldOpcodes = false;
+static bool useObjectrefOpcodes = false;
+static bool useOtherOpcodes = false;
- printf("\n");
- }
-/*--------------------------------------------------------------*/
-void printObjectClassHeirarchy1() {
-if (pStats >= 1) {
- unRTclassHeirCnt=0;
- unRTmethodCnt = 0;
- printObjectClassHeirarchy(class_java_lang_Object);
- printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
- unRTclassHeirCnt,unRTmethodCnt);
- }
-
-}
-/*--------------------------------------------------------------*/
-void printObjectClassHeirarchy(classinfo *class) {
-
-classinfo *subs;
-methodinfo *meth;
-int t,m,cnt;
-
-if (class == NULL) {return;}
- unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
- if (pStats == 2) {
- printf("\n");
- /* Class Name */
- for (t=0;t<class->index;t++) printf("\t");
- if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
-
- printf("Class: ");
- utf_display(class->name);
- printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
- /* Print methods used */
- cnt=0;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
- if (cnt == 0) {
- for (t=0;t<class->index;t++) printf("\t");
- printf("Methods used:\n");
- }
- for (t=0;t<class->index;t++) printf("\t");
- printf("\t");
- utf_display(meth->class->name);
- printf(".");
- method_display(meth);
- cnt++;
- }
- if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
- }
+static s4 currentXTAround = 0;
+static s4 prevXTAround = -1;
- for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- printObjectClassHeirarchy(subs);
- }
+#include "jit/parseRTstats.h"
-}
/*--------------------------------------------------------------*/
-/*--------------------------------------------------------------*/
-void printRTClassHeirarchy(classinfo *class) {
-
-
-
-classinfo *subs;
-methodinfo *meth;
-int m,cnt;
-
-if (class == NULL) {return;}
- /* Class Name */
- if (class->classUsed == NOTUSED) {
- RTclassHeirNotUsedCnt++;
- RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
- RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
- if (meth->methodUsed == USED) {
- if (pClassHeirStatsOnly >= 2) {
- printf("METHOD marked used in CLASS marked NOTUSED: ");
- utf_display(class->name);
- printf(".");
- method_display(meth);
- printf("<%i>\n\t",meth->methodUsed);
- fflush(stdout);
- panic("METHOD marked used in CLASS marked NOTUSED\n");
- }
- }
- }
+/* 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 <used flags c/m> <%i/%i> %i\t", \
+ meth->class->classUsed, \
+ meth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
+ utf_display(meth->class->name);printf("."); \
+ method_display(meth);fflush(stdout);} \
}
- if (class->classUsed != NOTUSED) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\nClass: ");
- utf_display(class->name);
- printf(" <%i> (depth=%i) ",class->classUsed,class->index);
- }
- if (class->classUsed == METH_USED_BY_SUB) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\tClass not instanciated - but methods resolved to this class' code\n");
- }
- RTclassHeirBySubCnt++;
- }
- else {
- if (class->classUsed == MARKEDSUPER) {
- if (pClassHeirStatsOnly >= 2) {
- printf("\tClass not instanciated - but used by super init\n");
- }
- RTclassHeirSuperCnt++;
- }
- else {
- if (pClassHeirStatsOnly >= 2) {
- printf("\n");
- }
- RTclassHeirUsedCnt++;
- }
- }
-
- /* Print methods used */
- cnt=0;
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
-
- if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
- if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt++;
- if (meth->methodUsed == JUSTMARKED) RTmethodMarkedCnt++;
- if (meth->methodUsed == USED) {
- RTmethodUsedCnt++;
- if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
- RTmethodFinal++;
- if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
- }
-
- if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
- RTmethodStatic++;
- if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
- }
-
- if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
- RTmethodFinalStatic++;
- if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
- }
-
- if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
- && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
- RTmethodNoSubs++;
- if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
- }
-
- if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
- && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
-
- if (pClassHeirStatsOnly >= 2) {
- if (cnt == 0) {
- printf("Methods used:\n");
- }
- cnt++;
- printf("\t");
- utf_display(meth->class->name);
- printf(".");
- method_display(meth);
- }
- }
- }
- if (pClassHeirStatsOnly >= 2) {
- if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
- }
- }
-
- for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- printRTClassHeirarchy(subs);
- }
-}
/*--------------------------------------------------------------*/
-
-void printRThierarchyInfo(methodinfo *m) {
-
- /*-- init for statistics --*/
- RTclassHeirNotUsedCnt=0;
- RTclassHeirUsedCnt=0;
- RTclassHeirBySubCnt=0;
- RTclassHeirSuperCnt=0;
- RTmethodNotUsedCnt = 0;
- RTmethodNotUsedCnt1 = 0;
- RTmethodNotUsedCnt2 = 0;
- RTmethodUsedCnt = 0;
- RTmethodMarkedCnt= 0;
-
-
- /*-- --*/
- if (pClassHeirStatsOnly >= 2) {
- printf("\nRT Class Heirarchy for ");
- printf("--- start of RT info --------------- after :\n");
- if (m != NULL) {
- utf_display(m->class->name);
- printf(".");
- method_display(m);
- printf("\n");
- }
- }
- printRTClassHeirarchy(class_java_lang_Object);
- if (pClassHeirStatsOnly >= 2) {
- printf("--- end of RT info ---------------\n");
- }
- if (pClassHeirStatsOnly >= 1) {
-
- /*-- statistic results --*/
- printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Heirarchy Statistics:\n");
- printf(" Used \t#%i \tclasses\t/ Used \t#%i methods \t of USED: %i%% \t of ALL: %i%% \n",
- RTclassHeirUsedCnt,RTmethodUsedCnt,
- ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
- ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
- printf(" Used by Subtype \t#%i \tclasses\t/\n",RTclassHeirBySubCnt);
- printf(" Used as Super \t#%i \tclasses\t/\n\n",RTclassHeirSuperCnt);
- printf(" Not Used \t#%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
- printf(" \t \t \t/ Just Marked \t#%i methods\n\n",RTmethodMarkedCnt);
- printf(" In Not Used \t \tclasses\t/ Not Used \t#%i methods\n",RTmethodNotUsedCnt1);
- printf(" In Used \t \tclasses\t/ Not Used \t#%i methods\n",RTmethodNotUsedCnt2);
- printf(" Total \t#%i \tclasses\t/ Total \t#%i methods\n\n",
- RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirBySubCnt + RTclassHeirSuperCnt,
- RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt );
-
- printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
- RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
- printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
- RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
- }
+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;
}
-/*--------------------------------------------------------------*/
-/* addToCallgraph - adds to RTA callgraph and */
-/* sets meth->methodUsed to USED */
-/* */
-/* To avoid unnecessary calls and dup entries in callgraph */
-/* meth should not be null */
-/* meth->methodUsed should be NOTUSED when called */
-/* meth's class should be USED */
-/* */
-/*--------------------------------------------------------------*/
-
-void addToCallgraph (methodinfo * meth) {
- int mfound =0;
- int im;
- int i;
-/* -- Pre-condition tests for adding method to call graph --*/
-if (meth==NULL) {panic("Trying to add a NULL method to callgraph"); return; }
-if (meth->methodUsed == USED) return; /*This should be test before fn call to avoid needless fn call */
- /* invokevirtual can be abstract */
- /* need to try to resolve /mark method */
- /* but... need document what should be */
- /* done / how to tell if doesn't resolved*/
-if (meth->flags & ACC_ABSTRACT) { /*printf("addToCallGraph returning because Abstract method\n"); */
- return;}
-
-if (meth->class->classUsed == NOTUSED) {
- if (pWhenMarked >= 1) {
- printf("AddToCallGraph method's class not used nor marked<%i> SUPER?\n",
- meth->class->classUsed);
- utf_display(meth->class->name);printf(".");
- utf_display(meth->name);printf("\n");
- panic("addToCallgraph called when class was NOTUSED\n");
- }
- return;
- }
-
- /*-- Add it to callgraph (mark used) --*/
- callgraph[++methRTlast] = meth ;
- RTAPRINTcallgraph1
- meth->methodUsed = USED;
-}
/*--------------------------------------------------------------*/
/* 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 JUSTMARKED
+/* -> 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 METH_USED_BY_SUB
+/* -> mark class with defined method as PARTUSED
/*--------------------------------------------------------------*/
-void markMethod(classinfo *class, methodinfo *topmethod) {
+void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
utf *name = topmethod -> name;
utf *descriptor = topmethod -> descriptor;
- s4 flags = topmethod -> flags;
-
methodinfo *submeth;
- methodinfo *initmeth;
- classinfo *ci;
- int m;
- submeth = class_findmethod(class, name, descriptor);
+ 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) {
- if (submeth != NULL) {
+ /*--- 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 JUSTMARKED
-*/
- if (submeth->class->classUsed != USED) {
- if (submeth->methodUsed == NOTUSED) {
- submeth->methodUsed = JUSTMARKED;
- RTAPRINTmarkMethod1
- } }
-
- else {
-
- /* Class marked used in some way and method defined in this class ->
- /* -> mark method as USED
- */
- if ((submeth ->methodUsed != USED) && (submeth->class->classUsed == USED)) {
- addToCallgraph(submeth);
- } }
- }
+ /* 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 {
- /* 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 METH_USED_BY_SUB
- */
-
- if (class->classUsed == USED) {
- classinfo *s = class->super;
- int found = 0;
- methodinfo *supermeth;
-
- while ((s!=NULL) && (found == 0)) {
- supermeth = class_findmethod(s, name, descriptor);
- if (supermeth != NULL) {
- found = 1;
- if ((s->classUsed == NOTUSED)
- || (s->classUsed == MARKEDSUPER)) {
-
- s->classUsed = METH_USED_BY_SUB;
- RTAPRINTmarkMethod2
- }
-
- if (supermeth->methodUsed !=USED) {
- addToCallgraph(supermeth);
- }
- } /* end if !NULL */
- else {
- s = s->super;
- } /* end else NULL */
- } /* end while */
-
- if ((s == NULL) && (found == 0))
- panic("parse RT: Method not found in class hierarchy");
- } /* if current class used */
-
- } /* end else Null */
+ /*--- 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 */
}
/*-------------------------------------------------------------------------------*/
/* and any subclass where the method is defined and/or class is used
/*
/*-------------------------------------------------------------------------------*/
-
-void markSubs(classinfo *class, methodinfo *topmethod) {
+void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
RTAPRINTmarkSubs1
- markMethod(class, topmethod); /* Mark method in class where it was found */
+ rtaMarkMethod(class, topmethod); /* Mark method in class where it was found */
if (class->sub != NULL) {
classinfo *subs;
- int subMcnt= 0;
if (!(topmethod->flags & ACC_FINAL )) {
for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
RTAPRINTmarkSubs1
- markSubs(subs, topmethod);
+ 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; ii<ci->methodscount; 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 */
+/*-------------------------------------------------------------------------------*/
+bool xtaPassParams (methodinfo *SmCalled, methodinfo *SmCalls, methSetNode *lastptrInto) {
+
+classSetNode *p;
+classSetNode *c;
+classSetNode *c1;
+classSetNode *cprev;
+bool rc = false;
+
+ if (XTAdebug >= 1) {
+ printf("\n>>>>>>>>>>>>>>>>><<<xtaPassParams \n");fflush(stdout);
+
+ printf("\tIN SmCalled set : ");
+ utf_display(SmCalled->class->name);printf("."); method_display(SmCalled);
+ printClassSet(SmCalled->XTAclassSet); printf("\n");
+
+ printf("\tIN SmCalls set: ");
+ utf_display(SmCalls->class->name);printf("."); method_display(SmCalls);
+ printClassSet(SmCalls->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->paramClassSet == NULL) {
+ SmCalled->paramClassSet = descriptor2typesL(SmCalled);
+ }
+ if (XTAdebug >= 1) {
+ printf("\tParamPassed\n"); fflush(stdout);
+ printSet(SmCalled->paramClassSet);fflush(stdout);
+ printf("\n"); fflush(stdout);
+ }
+
+if (lastptrInto->lastptrIntoClassSet2 == NULL) {
+ if (SmCalls->XTAclassSet != NULL)
+ c1 = SmCalls->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->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->XTAclassSet = SmCalled->XTAclassSet = add2ClassSet(SmCalled->XTAclassSet, c->classType);
+ rc = true;
+ }
+ cprev = c;
+ }
+ }
+lastptrInto->lastptrIntoClassSet2 = cprev;
+ if (XTAdebug >= 1) {
+ printf("\tOUT SmCalled set: ");fflush(stdout);
+ printClassSet(SmCalled->XTAclassSet);fflush(stdout);
+
+ printf("\tOUT SmCalls set: ");fflush(stdout);
+ printClassSet(SmCalls->XTAclassSet);fflush(stdout);
+
+ printf("\tOUT lastptrInto="); fflush(stdout);
+ if (lastptrInto->lastptrIntoClassSet2 != NULL)
+ utf_display(lastptrInto->lastptrIntoClassSet2->classType->name);
+
+ printf("<rc=%i>\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->paramClassSet == NULL)) {
+ SmCalled->paramClassSet = descriptor2typesL(SmCalled);
+ }
+
+if (SmCalled->returnclass == NULL) {
+ if (XTAdebug >= 1)
+ printf("\tReturn type is NULL\n");
+ return;
+ }
+
+ 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->XTAclassSet);
+
+ printf("\tIN SmCalled set: ");
+ utf_display(SmCalled->class->name); printf("."); method_display(SmCalled);
+ printClassSet(SmCalled->XTAclassSet);
+ }
+
+
+if (SmCalled->XTAclassSet == NULL)
+ cs1 = NULL;
+else
+ cs1 = SmCalled->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->XTAclassSet = add2ClassSet(SmCalls->XTAclassSet, c);
+ rc = true;
+ }
+ }
+
+ if (XTAdebug >= 1) {
+ printf("\tOUT SmCalls set: ");
+ printClassSet(SmCalls->XTAclassSet);
+ }
+return rc;
+}
+
+/*-------------------------------------------------------------------------------*/
+void xtaAddCallEdges(methodinfo *mi, s4 monoPoly) {
+
+ if (mi->XTAmethodUsed != USED) { /* if static method not in callgraph */
+ XTAcallgraph[++methXTAlast] = mi;
+ mi->XTAmethodUsed = USED;
+ XTAPRINTcallgraph2
+ }
+ /* add call edges */
+ rt_method->calls = add2MethSet(rt_method->calls, mi);
+ rt_method->calls->tail->monoPoly = monoPoly;
+ mi->calledBy = add2MethSet(mi->calledBy, rt_method);
+if (mi->calledBy == NULL) panic("mi->calledBy is NULL!!!");
+if (rt_method->calls == NULL) panic("rt_method->calls is NULL!!!");
+}
+
+
+/*--------------------------------------------------------------*/
+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 xtaMarkMethod(classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet)
+{
+ utf *name = topmethod -> name;
+ utf *descriptor = topmethod -> descriptor;
+ methodinfo *submeth;
+
+/****
+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 (rt_method->calls != NULL) {
+ if (inMethSet(rt_method->calls->head,submeth)) return;
+ }
+ /*----*/
+ if (submeth->class == class) {
+
+ /*--- 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->marked = add2MethSet(rt_method->marked, submeth);
+ }
+ }
+ }
+ 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->marked = add2MethSet(rt_method->marked, submeth);
+ /*printf("Added to marked Set: "); fflush(stdout);printMethodSet(rt_method->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;
+}
+
+/*-------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------*/
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");
if (m1 >= 0) { /* No <clinit> available - ignore */
- /* Get clinit methodinfo ptr */
- mi = class_findmethod (ci,ci->methods[m1].name , NULL);
+ /* 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);
+ }
- if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
}
- }
if (mf >= 0) {
- /* Get finalize methodinfo ptr */
- mi = class_findmethod (ci,ci->methods[mf].name , NULL);
+ /* Get finalize methodinfo ptr */
+ mi = class_findmethod (ci,ci->methods[mf].name , NULL);
- if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
+ /*--- 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 */
/* Get clinit methodinfo ptr */
mi = class_findmethod (ci,ci->methods[m2].name , NULL);
+ /*--- RTA ---*/
if ( mi->methodUsed != USED) {
- mi->class->classUsed = USED;
- addToCallgraph(mi);
- }
- }
-
-/* add marked methods to callgraph */
-for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
+ mi->class->classUsed = PARTUSED;
+ ADDTOCALLGRAPH(mi)
}
- }
+ /*--- XTA ---*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ xtaAddCallEdges(mi,MONO);
+ }
+ }
+
+/* add marked methods to callgraph */
+addMarkedMethods(ci);
+
return m;
}
+(((u4)rt_jcode[p+2])<<8)+rt_jcode[p+3]))
+
+/*-------------------------------------------------------------------------------*/
+/*xx*/ void addUsedInterfaceMethods(classinfo *ci) {
+int ii,jj,mm;
+
+/* add used interfaces methods to callgraph */
+for (jj=0; jj < ci -> interfacescount; jj++) {
+ classinfo *ici = ci -> interfaces [jj];
+
+if (pWhenMarked >= 1) {
+ printf("BInterface used: ");fflush(stdout);
+ utf_display(ici->name);
+ printf("<%i>\t",ici -> classUsed ); fflush(stdout);
+ if (ici -> classUsed == NOTUSED) printf("\t classUsed=NOTUSED\n" );
+ if (ici -> classUsed == USED) printf("\t classUsed=USED\n");
+ if (ici -> classUsed == PARTUSED) printf("\t classUsed=PARTUSED\n");
+ fflush(stdout);
+ }
+ /* add class to interfaces list of classes that implement it */
+ ici -> impldBy = addElement(ici -> impldBy, ci);
+
+ /* if interface class is used */
+ if (ici -> classUsed != NOTUSED) {
+
+ /* 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 (imi->methodUsed != USED) {
+ if (imi->methodUsed == NOTUSED) printf("Interface Method notused: ");
+ if (imi->methodUsed == MARKED) printf("Interface Method marked: ");
+ utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+ }
+ }
+ if (imi->methodUsed == USED) {
+if (pWhenMarked >= 1) {
+ 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");
+ }
+ rtaMarkSubs(ci,imi);
+ }
+ }
+ }
+ }
+
+}
+/*-------------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------------*/
+void xtaMarkInterfaceSubs(methodinfo *mCalled) {
+ classSetNode * Si;
+ classinfo * Smi;
+
+ /* 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;
+
+ 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->XTAclassSet != NULL)
+ subtypesUsedSet = intersectSubtypesWithSet(submeth->class, rt_method->XTAclassSet->head);
+
+ printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
+ printSet(subtypesUsedSet);
+ xtaMarkSubs(submeth->class, submeth, subtypesUsedSet);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------------*/
+bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
+
+bool rc = false;
+
+if (fi->fieldChecked) {
+ if (fi->fldClassType != NULL)
+ return true; /* field has a class type */
+ else
+ return false;
+ }
+fi->fieldChecked = true;
+
+if (fi->type == TYPE_ADDRESS) {
+ char *utf_ptr = fi->descriptor->text; /* current position in utf text */
+
+ if (*utf_ptr != 'L') {
+ while (*utf_ptr++ =='[') ;
+ }
+
+ if (*utf_ptr =='L') {
+ rc = true;
+ if (fi->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->fldClassType= class; /* save field's type class ptr */
+ }
+ /* save used edges */
+ rt_method->fldsUsed = add2FldSet(rt_method->fldsUsed, fi);
+ }
+ }
+return rc;
+}
+
+/*-------------------------------------------------------------------------------*/
+void xtaPassAllCalledByParams () {
+methSetNode *SmCalled;
+methSetNode *s1;
+if (rt_method->calledBy == NULL) return;
+ if (XTAdebug >= 1) {
+ printf("calledBy method set: "); fflush(stdout);
+ printMethodSet(rt_method->calledBy); fflush(stdout);
+ }
+if (rt_method->calledBy == NULL)
+ s1 = NULL;
+else
+ s1 = rt_method->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);
+ }
+
+ rt_method->chgdSinceLastParse = false;
+ xtaPassParams(rt_method, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
+ }
+}
+
/*-------------------------------------------------------------------------------*/
+void xtaMethodCalls_and_sendReturnType()
+{
+ methSetNode *SmCalled; /* for return type */
+ methSetNode *SmCalls; /* for calls param types */
+ methSetNode *s1;
+ bool chgd = false;
+if (rt_method->calls == NULL) return;
+ if (XTAdebug >= 1) {
+ printf("calls method set Return type: ");
+ printMethodSet(rt_method->calls);
+ printf("AAAAAAAAAAAAAAFTER printMethSett(rt_method->calls)\n");fflush(stdout);
+ }
+ /* for each method that this method calls */
+ if (rt_method->calls == NULL)
+ s1 = NULL;
+ else
+ s1 = SmCalls=rt_method->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->chgdSinceLastParse)) {
+ SmCalls->methRef->chgdSinceLastParse = true;
+ }
+ }
+
+ /* for each calledBy method */
+ /* send return type */
+ if (rt_method->calledBy == NULL)
+ s1 = NULL;
+ else
+ s1 = rt_method->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->chgdSinceLastParse)) {
+ SmCalled->methRef->chgdSinceLastParse = chgd;
+ }
+ }
+
+}
+/*-------------------------------------------------------------------------------*/
static void parseRT()
{
int p; /* java instruction counter */
RTAPRINT01method
- /* scan all java instructions */
+ if ( ((XTAOPTbypass) || (opt_xta)) && (rt_method->name != utf_MAIN)) {
+
+ xtaPassAllCalledByParams ();
+ }
+ /* scan all java instructions */
for (p = 0; p < rt_jcodelength; p = nextp) {
opcode = rt_code_get_u1 (p); /* fetch op code */
- RTAPRINT02opcode
+ RTAPRINT02opcode
+ fflush(stdout);
nextp = p + jcommandsize[opcode]; /* compute next instruction start */
switch (opcode) {
}
break;
+ case JAVA_ALOAD_0:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD0 %s i=%i\n", opcode_names[opcode],0);
+ class_showconstanti(rt_class, 0);
+ break;
+
+ case JAVA_ALOAD_1:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD1 %s i=%i\n", opcode_names[opcode],1);
+ class_showconstanti(rt_class, 1);
+ break;
+
+ case JAVA_ALOAD_2:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD2 %s i=%i\n", opcode_names[opcode],2);
+ class_showconstanti(rt_class, 2);
+ break;
+
+ case JAVA_ALOAD_3:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOAD3 %s i=%i\n", opcode_names[opcode],3);
+ class_showconstanti(rt_class, 3);
+ break;
+
case JAVA_ALOAD:
{
constant_FMIref *mr;
nextp = p+3;
iswide = false;
}
-if (pWhenMarked >= 4) {
- printf("I-ALOAD %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
- /*class_showconstanti(rt_class, i); */
- }
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ALOADs %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
+ class_showconstanti(rt_class, i);
}
-
break;
/* 54 -58 */
}
break;
+
+ case JAVA_ASTORE_0:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],0);
+ class_showconstanti(rt_class,0);
+I=0;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_1:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],1);
+ class_showconstanti(rt_class, 1);
+I=1;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_2:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],2);
+ class_showconstanti(rt_class, 2);
+I=2;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
+ case JAVA_ASTORE_3:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i\n", opcode_names[opcode],3);
+ class_showconstanti(rt_class, 3);
+I=3;
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
+ break;
+
case JAVA_ASTORE:
if (!iswide)
i = rt_code_get_u1(p+1);
nextp = p+3;
}
- if (pWhenMarked >= 4) {
- printf("I-ASTORE %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
- /*class_showconstanti(rt_class, rt_jcode[p+1]);*/
- }
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ printf("ASTOREs %s i=%i <%x>\n", opcode_names[opcode],i,rt_jcode[p+1]);
+ class_showconstanti(rt_class, rt_jcode[p+1]);
+
+ /* old if (CONSTANT_Class == rt_class->cptags [rt_jcode[p+1]] ) { */
+I=rt_jcode[p+1];
+if (CONSTANT_Class == rt_class->cptags [I] ) {
+ printf("ASTORE CONSTANT #%i_Class found =",I);
+ utf_display(((classinfo*)rt_class->cpinfos [I])->name);
+ printf("\n");
+ ((classinfo*)rt_class->cpinfos [I])->classUsed = PARTUSED;
+ }
+
break;
+
/* 132 */
case JAVA_IINC:
{
}
/*-------------------------------*/
-#include "parseEXTRAopcodes.h" /* opcodes just for info */
/* managing arrays ************************************************/
- INFOP01newarray
+ case JAVA_ANEWARRAY:
+ /* ---->>>> */ if (useArrayOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ constant_FMIref *ar;
+ voidptr e;
+ classinfo *c;
+ /* array or class type ? */
+ if (class_constanttype (rt_class, i) != CONSTANT_Arraydescriptor) {
+ e = class_getconstant(rt_class, i, CONSTANT_Class);
+ c = (classinfo *)e;
+ if (c->classUsed == NOTUSED)
+ c->classUsed = PARTUSED;
+/*COtest*/ printf("ANEWARRAY Mark class=");utf_display ( c-> name );printf("=>PARTUSED\n");
+ }
+ }
+ break;
- INFOP02anewarray
+ case JAVA_MULTIANEWARRAY:
+ /* ---->>>> */ if (useArrayOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ constant_arraydescriptor *ar;
+ int t;
+ arraydesc: ar = class_getconstant(rt_class, i, CONSTANT_Arraydescriptor);
+ /*ar = rt_class-> cpinfos [i]; */
+ t = ar->arraytype;
+ while (ARRAYTYPE_ARRAY== t) {
+ ar = ar->elementdescriptor;
+ t = ar->arraytype;
+ }
+ if (ARRAYTYPE_OBJECT == t) {
+ printf("MULTINEWARRAY 1Marking class=");utf_display(ar->objectclass->name);printf("\n");
+ if (ar->objectclass->classUsed == NOTUSED) {
+ ar->objectclass->classUsed == PARTUSED;
+ }
+ }
+ }
+ break;
- INFOP03multianewarray
/*-------------------------------*/
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 (xtaAddFldClassTypeInfo(fi)) {
+ /* Field type is a class */
+ classSetNode *c;
+ classSetNode *c1 = NULL;
+ fldSetNode *fn;
+
+ /******
+ Can a ptr be kept so don't check whole XTA class set each time?
+ cp = fi->methodsUsedBy->lastxxxxClass;
+ if (cp != NULL) {
+ if (cp->nextClass != NULL)
+ c1 = cp -> nextClass;
+ }
+ ****/
+
+ if (rt_method->XTAclassSet != NULL)
+ c1 = rt_method->XTAclassSet->head;
+ if (XTAfld >=1 ) {
+ printf("rt XTA class set =");fflush(stdout);
+ printClassSet(rt_method->XTAclassSet);
+ printf("\t\tField class type = ");fflush(stdout);
+ utf_display(fi->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->fldClassType->vftbl;
+ vftbl *c_cl_vt = c-> classType->vftbl;
+ if (XTAfld >=2 ) {
+ printf("\tXTA class = ");fflush(stdout);
+ utf_display(c->classType->name);
+ printf("<b=%i> ",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);
+ }
+
+ printf("\t\tField class type = ");fflush(stdout);
+ utf_display(fi->fldClassType->name);
+ printf("<b=%i/+d=%i> \n",f_cl_vt->baseval,(f_cl_vt->baseval+f_cl_vt->diffval)); fflush(stdout);
+ }
+
+ if ((f_cl_vt->baseval <= c_cl_vt->baseval)
+ && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
+ fi->XTAclassSet = add2ClassSet(fi->XTAclassSet,c->classType);
+ }
+ /****cprev = c->classType; ***/
+ }
+ if (rt_method->fldsUsed != NULL) {
+ fn = inFldSet(rt_method->fldsUsed->head, fi);
+ if (fn != NULL)
+ fn->readPUT = true;
+ }
+ /***fi->methodsUsedBy->lastxxxClass ***/
+ /*** = addElement(fi->methodsUsedBy->lastxxxClass, c->classType); ***/
+ }
+ }
+
+ }
+ break;
+
case JAVA_GETSTATIC:
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 (xtaAddFldClassTypeInfo(fi)) {
+ /* Field type is a class */
+ classSetNode *c;
+ classSetNode *c1 = NULL;
+ fldSetNode *fn;
+
+ /*******************/
+
+ /*******
+ Can a ptr be kept so don't check whole XTA class set each time?
+ cp = fi->methodsUsedBy->lastxxxxClass;
+ if (cp != NULL) {
+ if (cp->nextClass != NULL)
+ c1 = cp -> nextClass;
+ }
+ *******/
+
+ if (fi->XTAclassSet != NULL)
+ c1 = fi->XTAclassSet->head;
+
+ /*--- GETSTATIC specific ---*/
+ /* Sm = union of Sm and Sx */
+ for (c=c1; c != NULL; c=c->nextClass) {
+ bool addFlg = false;
+ if (rt_method->XTAclassSet ==NULL)
+ addFlg = true;
+ else {
+ if (!(inSet (rt_method->XTAclassSet->head, c->classType) ))
+ addFlg = true;
+ }
+ if (addFlg) {
+ rt_method->XTAclassSet
+ = add2ClassSet(rt_method->XTAclassSet,c->classType);
+ }
+ /*** cprev = c->classType; ***/
+ }
+
+ if (rt_method->fldsUsed != NULL) {
+ fn = inFldSet(rt_method->fldsUsed->head, fi);
+ if (fn != NULL)
+ fn->writeGET = true;
+ }
+
+ /**** fi->methodsUsedBy->lastxxxClass ***/
+ /*** = addElement(fi->methodsUsedBy->lastxxxClass, c->classType); ***/
+ }
+ }
+
+ }
+ break;
+
+ case JAVA_PUTFIELD:
+ case JAVA_GETFIELD:
+ /* ---->>>> */ if (useFieldOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p + 1);
+ {
+ constant_FMIref *fr;
+ fieldinfo *fi;
classinfo *ci;
methodinfo *mi;
int m;
+class_showconstanti(rt_class,i); fflush(stdout);
fr = class_getconstant (rt_class, i, CONSTANT_Fieldref);
- /* type of field */
- fi = class_findfield (fr->class,fr->name, fr->descriptor);
- ci = fr->class;
+ fi = class_findfield (fr->class, fr->name, fr->descriptor);
+ ci = fr->class; /* class with the local field */
+ /* either current class or inherited (a super) */
+ /* descriptor has type of field ref'd */
RTAPRINT03putstatic1
- addClassInit(ci);
-
+ /*** OP2A(opcode, fi->type, fi); ***/
}
break;
+
- /* method invocation *****/
+ /*-------------------- method invocation ---------------------*/
case JAVA_INVOKESTATIC:
i = rt_code_get_u2(p + 1);
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);
-
- if (mi->methodUsed != USED) { /* if static method not in callgraph */
- addToCallgraph(mi);
- }
+ addClassInit(mi->class);
+
+ ADDTOCALLGRAPH(mi)
+fflush(stdout);
+ /*-- XTA --*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ xtaAddCallEdges(mi,MONO);
+ } /* end XTA */
}
break;
constant_FMIref *mr;
methodinfo *mi;
classinfo *ci;
- int ii;
mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
mi = class_findmethod (mr->class, mr->name, mr->descriptor);
- RTAPRINT06invoke_spec_virt1
-
- if (mi->name != INIT) { /* if method called is PRIVATE */
- RTAPRINT07invoke_spec_virt2
- markSubs(mi->class,mi);
- break;
+ 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 */
}
- /* new class so add marked methods */
- if ( mi->methodUsed != USED) {
-
- /* if parsing <init> method and it calls its super <init>
- /* -> mark the class of super as MARKEDSUPER
- */
- if ((INIT == mi->name)
- && (INIT == rt_method->name)
- && (rt_class->super == mi->class) /* <init> calling super ? */
- && (mi->class->classUsed == NOTUSED)) /* only if not used at all */
- mi->class->classUsed = MARKEDSUPER;
- else {
- /* Normal <init> - mark class as USED and <init> to callgraph */
- ci = mi->class;
- ci->classUsed = USED;
-
- /* add marked methods to callgraph */
- for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
- }
- }
+
+ else {
+ /*--- Test for super <init> which is: <init> calling its super class <init> -*/
+
+ /* new class so add marked methods */
+ if (( mi->methodUsed != USED) || (mi->class->classUsed == PARTUSED)) {
+ /*--- process NORMAL <init> method ---------------------------------------------*/
+ if ( mi->methodUsed != USED) {
+ /* Normal <init>
+ - mark class as USED and <init> 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->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci );
+ xtaAddCallEdges(mi,MONO);
+ RTAPRINT06CXTAinvoke_spec_init1
+ } /* end XTA */
+ }
}
+ }
- addToCallgraph(mi); /* add to call graph after setting classUsed flag */
- } }
+ }
break;
{
constant_FMIref *mr;
methodinfo *mi;
- classinfo *ci;
- int ii;
mr = class_getconstant (rt_class, i, CONSTANT_Methodref);
- mi = class_findmethod (mr->class, mr->name, mr->descriptor);
- RTAPRINT06invoke_spec_virt1
-
- if (mi->name == INIT) {
- panic("An <init> method called from invokevirtual, but invokespecial expected\n");
- return;
- }
- /*--------------------------------------------------------------*/
- RTAPRINT07invoke_spec_virt2
- markSubs(mi->class,mi);
+ 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->XTAclassSet != NULL)
+ subtypesUsedSet = intersectSubtypesWithSet(mi->class, rt_method->XTAclassSet->head);
+ /*****
+ printf(" \nXTA subtypesUsedSet: "); fflush(stdout);
+ printSet(subtypesUsedSet);
+ *****/
+ xtaMarkSubs(mi->class, mi, subtypesUsedSet);
+ } /* end XTA */
}
break;
{
constant_FMIref *mr;
methodinfo *mi;
- classinfo *ci;
- classinfo *subs;
-
+ 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");
- RTAPRINT08AinvokeInterface0
- ci = mi->class;
- subs = ci->impldBy;
- RTAPRINT08invokeInterface1
- while (subs != NULL) {
- RTAPRINT09invokeInterface2
+ /*--- 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 (subs->classUsed != NOTUSED)
- markSubs(subs, mi); /* method may not be found so...??? */
- subs = subs->nextimpldBy;
+ 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;
classinfo *ci;
int ii;
classinfo *subs;
- ci = class_getconstant (rt_class, i, CONSTANT_Class);
-
- /* Add this class to the implemented by list of the abstract interface */
- for (ii=0; ii < ci -> interfacescount; ii++) {
- subs = ci -> interfaces [ii]->impldBy;
- ci -> interfaces [ii]->impldBy = ci;
- ci -> interfaces [ii]->nextimpldBy = ci;
- }
- if (ci->classUsed == NOTUSED) {
+ 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) {
int ii;
RTAPRINT10new
ci->classUsed = USED; /* add to heirarchy */
+ /* Add this class to the implemented by list of the abstract interface */
+ addUsedInterfaceMethods(ci);
addClassInit(ci);
- /* add marked methods to callgraph ?? here or in init??? */
}
+ /*--- XTA ---*/
+ if ((XTAOPTbypass) || (opt_xta))
+ {
+ rt_method->XTAclassSet = add2ClassSet(rt_method->XTAclassSet,ci ); /*XTA*/
+ RTAPRINT10newXTA
+ }
}
break;
+ /* ---- Reference Opcodes --------------------------------------------*/
+
+ case JAVA_CHECKCAST:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+
+ i = rt_code_get_u2(p+1);
+ {
+ classinfo *ci;
+
+ /* array type cast-check */
+ if (class_constanttype (rt_class, i) == CONSTANT_Arraydescriptor) {
+class_showconstanti(rt_class,i);
+goto arraydesc; /* better to make a fn later ?? */
+panic("arraydescriptor in checkcast - panic so find it");
+ /***
+ LOADCONST_A(class_getconstant(rt_class, i, CONSTANT_Arraydescriptor));
+ s_count++;
+ BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
+ ****/
+ }
+ else { /* object type cast-check */
+ ci = class_getconstant(rt_class, i, CONSTANT_Class);
+ ci->classUsed =PARTUSED;
+/*RTtest p1*/ if (pWhenMarked >= 2) {
+/*RTtest*/ printf("checkcast class=");utf_display(ci->name);printf(" marked PARTUSED\n");
+/*RTtest*/ }
+ /*****
+ LOADCONST_A(class_getconstant(irt_class, i, CONSTANT_Class));
+ s_count++;
+ BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
+ OP2A(opcode, 1, (class_getconstant(rt_class, i, CONSTANT_Class)));
+ ****/
+ }
+ }
+ break;
+
+ case JAVA_INSTANCEOF:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+ i = rt_code_get_u2(p+1);
+ {
+ classinfo *ci;
+
+ /* array type cast-check */
+ if (class_constanttype (rt_class, i) == CONSTANT_Arraydescriptor) {
+class_showconstanti(rt_class,i);
+goto arraydesc; /* better to make a fn later */
+panic("arraydescriptor in instanceof- panic so find it");
+ /***
+ LOADCONST_A(class_getconstant(rt_class, i, CONSTANT_Arraydescriptor));
+ ***/
+ }
+ else { /* object type cast-check */
+ ci = class_getconstant(rt_class, i, CONSTANT_Class);
+ ci->classUsed =PARTUSED;
+/*RTtest p1*/ if (pWhenMarked >= 2) {
+/*RTtest*/ printf("checkcast class=");utf_display(ci->name);printf(" marked PARTUSED\n");
+/*RTtest*/ }
+ }
+ }
+ break;
+
+ case JAVA_MONITORENTER:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+/* comes from stack - how put on stack???? */
+#ifdef USE_THREADS
+ if (checksync) {
+#ifdef SOFTNULLPTRCHECK
+ if (checknull) {
+ /****
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ ***/
+ }
+ else {
+ /****
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+ BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
+ ***/
+ }
+#else
+ /***
+ BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
+ ***/
+#endif
+ }
+ else
+#endif
+ {
+ /***
+ OP(ICMD_NULLCHECKPOP);
+ ***/
+ }
+ break;
+
+ case JAVA_MONITOREXIT:
+ /* ---->>>> */ if (useObjectrefOpcodes == false) break; /* <<<<<<******* */
+/* comes from stack - how put on stack???? */
+#ifdef USE_THREADS
+ if (checksync) {
+ /***
+ BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
+ ***/
+ }
+ else
+#endif
+ {
+ /***
+ OP(ICMD_POP);
+ ***/
+ }
+ break;
+
+ case JAVA_ARETURN:
+ /* ---->>>> */ if (useOtherOpcodes == false) break; /* <<<<<<******* */
+/* set a variable with type from input and track it to here */
+ /***
+ blockend = true;
+ OP(opcode);
+ ***/
+ break;
+
+ case JAVA_ATHROW:
+ /* ---->>>> */ if (useOtherOpcodes == false) break; /* <<<<<<******* */
+ /***
+ blockend = true;
+ OP(opcode);
+ ***/
+ break;
+
default:
break;
if (p != rt_jcodelength)
panic("Command-sequence crosses code-boundary");
+if ((XTAOPTbypass) || (opt_xta))
+ xtaMethodCalls_and_sendReturnType();
+
+
}
+/*-------------------------------------------------------------------------------*/
+/* RTA add Native Methods/ Class functions */
/*-------------------------------------------------------------------------------*/
void findMarkNativeUsedMeth (utf * c1, utf* m1, utf* d1) {
}
if (class->classUsed == NOTUSED) {
- class->classUsed = USED;
+ class->classUsed = USED; /* MARK CLASS USED */
/* add marked methods to callgraph */
- for (ii=0; ii<class->methodscount; ii++) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&class->methods[ii]);
- }
- }
+ addMarkedMethods(class);
}
meth = class_findmethod (class, m1, d1);
if (meth == NULL) {
utf_display(class->name);printf(".");utf_display(m1);printf(" ");utf_display(d1);
- panic("parseRT: Method given is used by Native method call, but NOT FOUND");
+ printf("WARNING from parseRT: Method given is used by Native method call, but NOT FOUND\n");
}
-markSubs(class,meth);
+else
+ rtaMarkSubs(class,meth);
}
/*-------------------------------------------------------------------------------*/
class->classUsed = USED;
/* add marked methods to callgraph */
-for (ii=0; ii<class->methodscount; ii++) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- if (class->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&class->methods[ii]);
- }
- }
- }
-
+addMarkedMethods(class);
}
for (i=0; i<NATIVECALLSSIZE; i++) {
if (rt_class == nativeCompCalls[i].classname) {
+
/* find native class.method invoked */
for (j=0; (!(found) && (j<nativeCompCalls[i].methCnt)); j++) {
+
if ( (rt_method == nativeCompCalls[i].methods[j].methodname)
&& (rt_descriptor == nativeCompCalls[i].methods[j].descriptor)) {
nativeCompCalls[i].methods[j].methodCalls[k].methodname,
nativeCompCalls[i].methods[j].methodCalls[k].descriptor);
- /*RTprint
+ /*RTprint
printf("\nmark method used: "); fflush(stdout);
utf_display(nativeCompCalls[i].methods[j].methodCalls[k].classname); printf(".");fflush(stdout);
utf_display(nativeCompCalls[i].methods[j].methodCalls[k].methodname); printf("=="); fflush(stdout);
/*-------------------------------------------------------------------------------*/
-void mainRTAparseInit ( )
+/*-------------------------------------------------------------------------------*/
+void mainRTAparseInit (methodinfo *m )
{
+/*printf("MAIN_NOT_STARTED \n");*/
if (class_java_lang_Object->sub != NULL) {
RTAPRINT16stats1
}
if (firstCall) {
firstCall=false;
+ utf_MAIN = utf_new_char("main");
+ INIT = utf_new_char("<init>");
+ CLINIT = utf_new_char("<clinit>");
+ 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");
}
}
- /* At moment start RTA before main when parsed
- /* Will definitely use flag with to know if ok to apply in-lining.
- */
-}
+if (m->name == utf_MAIN) {
+ rtMissed = fopen("rtMissed","a");
+ fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
+ fclose(rtMissed);
+ }
+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);
+ }
+ }
+ /* At moment start RTA before main when parsed */
+ /* Will definitely use flag with to know if ok to apply in-lining. */
+}
/*-------------------------------------------------------------------------------*/
-
-void RT_jit_parse(methodinfo *m)
+/*-------------------------------------------------------------------------------*/
+/* still need to look at field sets in 2nd pass and clinit ..... */
+void XTA_jit_parse2(methodinfo *m)
{
-utf *utf_MAIN = utf_new_char("main");
-
- if (m->methodUsed == USED) return;
+ 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->chgdSinceLastParse) {
- INIT = utf_new_char("<init>");
- CLINIT = utf_new_char("<clinit>");
- FINALIZE = utf_new_char("finalize");
+ /* get types from methods it is calledBy */
+ xtaPassAllCalledByParams ();
- if (!mainStarted) {
- mainRTAparseInit ();
- }
- if (m->name == utf_MAIN) {
- rtMissed = fopen("rtMissed","a");
- fprintf(rtMissed,"\n\n\tAFTER MAIN RT PARSE\n");
- fclose(rtMissed);
- }
- 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);
+ /* 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 */
+}
+/*-------------------------------------------------------------------------------*/
+
+void RT_jit_parse(methodinfo *m)
+{
+ /*-- RTA --*/
+ if (m->methodUsed == USED) return;
+ mainRTAparseInit (m);
+
/* initialise parameter type descriptor */
- callgraph[++methRTlast] = m;
- RTAPRINT11addedtoCallgraph
+ callgraph[++methRTlast] = m; /*-- RTA --*/
m->methodUsed = USED;
+ RTAPRINT11addedtoCallgraph
/* <init> then like a new class so add marked methods to callgraph */
- if (m->name == INIT) {
+ if (m->name == INIT) { /* need for <init>s parsed efore Main */
classinfo *ci;
int ii;
ci = m->class;
ci->classUsed = USED;
+ if (pWhenMarked >= 1) {
+ printf("Class=");utf_display(ci->name);
+ }
/* add marked methods to callgraph */
RTAPRINT11addedtoCallgraph2
- for (ii=0; ii<ci->methodscount; ii++) {
- if (ci->methods[ii].methodUsed == JUSTMARKED) {
- addToCallgraph(&ci->methods[ii]);
- }
- } /* for */
+ addMarkedMethods(ci);
} /* if */
+ /*-- XTA --*/
+ if ((XTAOPTbypass) || (opt_xta)) {
+ XTAcallgraph[++methXTAlast] = m;
+ m->XTAmethodUsed = USED;
+ {methodinfo *mi = m;
+ XTAPRINTcallgraph2
+ }
+ }
+
+ /*-- Call graph work list loop -----------------*/
+
while (methRT <= methRTlast) {
rt_method = callgraph[methRT];
rt_class = rt_method->class;
rt_jcode = rt_method->jcode;
if (! ( (rt_method->flags & ACC_NATIVE )
- || (rt_method->flags & ACC_ABSTRACT) ) )
+ || (rt_method->flags & ACC_ABSTRACT) ) ) {
parseRT();
+ }
else {
- if (pOpcodes == 1) {
- printf("\nPROCESS_abstract or native\n");
- utf_display(rt_method->class->name); printf(".");
- method_display(rt_method); printf("\n"); fflush(stdout);
- }
-
+ RTAPRINT12bAbstractNative
if (rt_method->flags & ACC_NATIVE ) {
+ RTAPRINT12aNative
/* mark used and add to callgraph methods and classes used by NATIVE method */
- RTAPRINT12aNative
markNativeMethodsRT(rt_class->name,rt_method->name,rt_descriptor);
}
if (rt_method->flags & ACC_ABSTRACT) {
- printf("ABSTRACT_SHOULD not ever get into the callgraph!!!!!****!!!****!!!!****!!!!\n");
+ 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 ??*/
- RTAPRINT14CallgraphLast
- RTAPRINT15HeirarchyiLast
+ 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);
+ }
+
+return;
}
+#define XTAPRINTcallgraph1 if(pWhenMarked>=1) \
+ {printf("\n XTA Added to Call Graph #%i:", \
+ methRTlast); \
+ printf("\t <used flags c/m> <%i/%i> %i\t", \
+ submeth->class->classUsed, \
+ submeth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
+ utf_display(submeth->class->name);printf("."); \
+ method_display(submeth);fflush(stdout);}
+
+#define XTAPRINTcallgraph2 if(pWhenMarked>=1) { \
+ printf("\n XTA Added to Call Graph #%i:", \
+ methXTAlast); \
+ printf(" method name ="); \
+ utf_display(mi->class->name);printf("."); \
+ method_display(mi);fflush(stdout); \
+ }
+
#define RTAPRINTcallgraph1 if(pWhenMarked>=1) \
{printf("\n Added to Call Graph #%i:", \
- methRTlast);printf(" method name ="); \
+ methRTlast); \
+ printf("\t <used flags c/m> <%i/%i> %i\t", \
+ meth->class->classUsed, \
+ meth->methodUsed, \
+ USED); \
+ printf(" method name ="); \
utf_display(meth->class->name);printf("."); \
- method_display(meth);fflush(stdout);}
+ method_display(meth);fflush(stdout);}
#define RTAPRINTmarkMethod1 if (pWhenMarked >= 2) { \
- printf("Just Marking Method - class:%s not used <%i>\n",class->name->text,class->index); \
+ printf("<%i/%i> Just Marking Method - class: <index=%i>\n", \
+ submeth->methodUsed, \
+ submeth->class->index); \
+ utf_display(submeth->class->name); \
method_display(submeth); \
}
}
#define RTAPRINTmarkMethod2 if (pWhenMarked >= 2) { \
- printf("Class marked Used by Subtype :");utf_display(s->name);printf("\n");}
+ printf("Class marked Used by Subtype :");utf_display(submeth->name);printf("\n");}
#define RTAPRINTmarkSubs1 if (pWhenMarked>=3) { \
utf *name = topmethod -> name; \
#define RTAPRINT01method if ((pOpcodes == 1) || (pOpcodes == 3)) \
{printf("*********************************\n"); \
- printf("PARSE RT method name ="); \
+ printf("PARSE RT method name = <%i/%i>",rt_method->class->classUsed,rt_method->methodUsed); \
utf_display(rt_method->class->name);printf("."); \
utf_display(rt_method->name);printf("\n\n"); \
method_display(rt_method); printf(">\n\n");fflush(stdout);}
p,rt_jcodelength,opcode,opcode_names[opcode]); \
fflush(stdout); }
-#define RTAPRINT03putstatic1 if (pWhenMarked >= 5) { \
+#define RTAPRINT03putstatic1 if (pWhenMarked >= 1) { \
+ class_showconstanti(rt_class,i); \
+ }
+
+#define RTAPRINT03putstatic1o_OLD if (pWhenMarked >= 1) { \
+ class_showconstanti(rt_class,i); \
printf("FMIref = "); \
utf_display ( fr->class->name ); \
printf ("."); \
printf("INVOKESTATIC\n"); fflush(stdout);}
+#define RTAPRINT06Ainvoke_spec_super1 if (pWhenMarked >= 1) { \
+ printf("class flags:"); fflush(stdout); \
+ utf_display(ci->name); \
+ printflags(ci->flags); \
+ printf("\n"); fflush(stdout); \
+ printf("method flags:"); fflush(stdout); \
+ utf_display(mi->name); \
+ printflags(mi->flags); \
+ printf("\n"); fflush(stdout); \
+ }
+
+#define RTAPRINT06Binvoke_spec_super2 if (pWhenMarked >= 1) { \
+ printf("SUPERRRRRRRRRRRRRRR"); \
+ utf_display(mi->descriptor); \
+ printf(" class super ="); fflush(stdout); \
+ utf_display(rt_class->super->name); fflush(stdout); \
+ printf("\t ==? "); fflush(stdout); \
+ printf(" class =");fflush(stdout); \
+ utf_display(mi->class->name); fflush(stdout); \
+ printf("\n"); fflush(stdout); \
+ printf("Ainterface count = "); fflush(stdout); \
+ printf(" %i\n", ci -> interfacescount); \
+ fflush(stdout); \
+ }
+
+#define RTAPRINT06Binvoke_spec_init if (pWhenMarked >= 1) { \
+ printf("Binterface count = "); fflush(stdout); \
+ printf(" %i\n", ci -> interfacescount); \
+ fflush(stdout); \
+ }
+
+#define RTAPRINT06CXTAinvoke_spec_init1 if (pWhenMarked >= 1) { \
+ printf("\n XTA Added to Call Graph #%i:", \
+ methXTAlast); \
+ printf(" method name ="); \
+ utf_display(mi->class->name);printf("."); \
+ method_display(mi);fflush(stdout); \
+ }
+
+
#define RTAPRINT06invoke_spec_virt1 if ((pOpcodes == 1) ||(pOpcodes == 3) || (pWhenMarked >= 2)) { \
- printf(" method name ="); \
- method_display(mi); \
+ printf("INVOKE method name <%i/%i> =",mi->class->classUsed,mi->methodUsed); \
utf_display(mi->class->name); printf("."); \
- utf_display(mi->name); \
- printf("\taINVOKESPECIAL/VIRTUAL\n"); fflush(stdout); }
+ method_display(mi); \
+ fflush(stdout); }
-#define RTAPRINT07invoke_spec_virt2 if (pWhenMarked >= 3) { \
+#define RTAPRINT07invoke_spec_virt2 if (pWhenMarked >= 1) { \
printf("Calling MarkSubs from SPECIAL/VIRTUAL :"); \
- utf_display(mi->class->name);printf(":"); \
- utf_display(mi->name);printf("\n"); }
+ utf_display(mi->class->name);printf(".V."); \
+ method_display(mi); }
#define RTAPRINT08AinvokeInterface0 if (pWhenMarked >= 2) { \
utf_display(mi->class->name); \
- method_display(mi); printf("\n");}
+ method_display(mi); printf("\n");} \
+ if (pWhenMarked >= 1) { \
+ printf("INTERFACE CLASS <");fflush(stdout); \
+ utf_display(mi->class->name); fflush(stdout); \
+ printf("> used flag=%i\n", mi->class->classUsed); \
+ fflush(stdout); \
+ method_display(mi); \
+ fflush(stdout); \
+ printf("AAAAA\n");fflush(stdout); \
+ }
-#define RTAPRINT08invokeInterface1 if (pWhenMarked >= 3) { \
+#define RTAPRINT08invokeInterface1 if (pWhenMarked >= 1) { \
printf("Implemented By classes :\n"); \
+ fflush(stdout); \
if (subs == NULL) printf(" \tNOT IMPLEMENTED !!!\n"); \
+ printf("ZZZZZ\n");fflush(stdout); \
}
#define RTAPRINT09invokeInterface2 if (pWhenMarked >= 3) { \
- printf("\t");utf_display(subs->name); printf(" <%i>\n",subs->classUsed); \
+ printf("\t");utf_display(isubs->name); printf(" <%i>\n",isubs->classUsed); \
}
#define RTAPRINT10new if (pWhenMarked >= 2) { \
- printf("NEW Class marked Used :"); \
+ printf("NEW Class marked Used :"); fflush(stdout);\
utf_display(ci->name); \
fflush(stdout);}
+#define RTAPRINT10newXTA if (pWhenMarked >= 1) { \
+ utf_display(ci->name);printf(" XTA_NEW\n"); \
+ printSet(rt_method->XTAclassSet->head); \
+ }
+
#define RTAPRINT11addedtoCallgraph if (pWhenMarked >= 1){ \
printf("\n<Added to Call Graph #%i:",methRTlast); \
method_display(m); \
utf_display(rt_descriptor); fflush(stdout); printf("\n"); \
}
+#define RTAPRINT12bAbstractNative if (pOpcodes == 1) { \
+ printf("\nPROCESS_abstract or native\n"); \
+ utf_display(rt_method->class->name); printf("."); \
+ method_display(rt_method); printf("\n"); fflush(stdout); \
+ }
+
#define RTAPRINT12Callgraph if (pCallgraph >= 3) { \
printf("RTA Callgraph after RTA Call\n"); \
printCallgraph (); \
--- /dev/null
+
+/*--- Statistics ----------------------------------------------------------*/
+
+int unRTclassHeirCnt=0;
+int unRTmethodCnt = 0;
+
+/*-----*/
+int RTclassHeirNotUsedCnt=0;
+int RTclassHeirUsedCnt=0;
+int RTclassHeirPartUsedCnt=0;
+int RTclassHeirSuperCnt=0;
+
+int RTmethodNotUsedCnt = 0;
+int RTmethodNotUsedCnt1= 0;
+int RTmethodNotUsedCnt2= 0;
+int RTmethodUsedCnt = 0;
+int RTmethodMarkedCnt= 0;
+
+/* What might be inlined of the Used Methods */
+int RTmethodFinal = 0;
+int RTmethodStatic = 0;
+int RTmethodFinalStatic = 0;
+int RTmethodNoSubs = 0;
+
+int RTmethodMono;
+int RTmethodPossiblePoly;
+int RTmethodPolyReallyMono;
+int RTmethodPoly;
+
+int RTmethodFinal100 = 0;
+int RTmethodStatic100 = 0;
+int RTmethodFinalStatic100 = 0;
+int RTmethodNoSubs100 = 0;
+
+#define MAXCODLEN 10
+
+int RTmethodNoSubsAbstract = 0;
+int RTmethod1Used = 0;
+
+int RTmethodAbstract = 0;
+
+int subRedefsCnt =0;
+int subRedefsCntUsed =0;
+
+/*------------- RTAprint flags ------------------------------------------------------------------*/
+int pCallgraph = 0; /* 0 - dont print 1 - print at end from main */
+ /* 2 - print at end of RT parse call */
+ /* 3- print after each method RT parse */
+int pClassHeir = 1; /* 0 - dont print 1 - print at end from main */
+ /* 2 - print at end of RT parse call 3-print after each method RT parse */
+int pClassHeirStatsOnly = 1; /* usually 2 Print only the statistical summary info for class heirarchy */
+
+int pOpcodes = 0; /* 0 - don't print 1- print in parse RT 2- print in parse */
+ /* 3 - print in both */
+int pWhenMarked = 0; /* 0 - don't print 1 - print when added to callgraph + when native parsed*/
+ /* 2 - print when marked+methods called */
+ /* 3 - print when class/method looked at */
+int pStats = 0; /* 0 - don't print; 1= analysis only; 2= whole unanalysed class heirarchy*/
+
+/*-----------------------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------------------*/
+void printXTACallgraph ()
+ { int i;
+if (XTAdebug >= 1) {
+printf("----- XTA Callgraph Worklist:<%i>\n",methXTAlast);
+ for (i=0;i<=methXTAlast;i++) {
+ printf(" (%i): ",i);
+ utf_display(XTAcallgraph[i]->class->name);
+ printf(":");
+ method_display(XTAcallgraph[i]);
+ }
+
+ printf("\n\n");
+ }
+ }
+
+/*-----------------------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------------------*/
+
+void printCallgraph ()
+ { int i;
+
+printf("----- RTA Callgraph Worklist:<%i>\n",methRTlast);
+ for (i=0;i<=methRTlast;i++) {
+ printf(" (%i): ",i);
+ utf_display(callgraph[i]->class->name);
+ printf(":");
+ method_display(callgraph[i]);
+ }
+
+ printf("\n\n");
+ }
+/*--------------------------------------------------------------*/
+void printObjectClassHeirarchy1() {
+if (pStats >= 1) {
+ unRTclassHeirCnt=0;
+ unRTmethodCnt = 0;
+ printObjectClassHeirarchy(class_java_lang_Object);
+ printf("\n >>>>>>>>>>>>>>>>>>>> END of unanalysed Class Heirarchy: #%i classes / #%i methods\n\n",
+ unRTclassHeirCnt,unRTmethodCnt);
+ }
+
+}
+/*--------------------------------------------------------------*/
+void printObjectClassHeirarchy(classinfo *class) {
+
+classinfo *subs;
+methodinfo *meth;
+int t,m,cnt;
+
+if (class == NULL) {return;}
+ unRTclassHeirCnt++; unRTmethodCnt += class->methodscount;
+ if (pStats == 2) {
+ printf("\n");
+ /* Class Name */
+ for (t=0;t<class->index;t++) printf("\t");
+ if (class->flags & ACC_INTERFACE) printf("ABSTRACT ");
+
+ printf("Class: ");
+ utf_display(class->name);
+ printf(" <%i> (depth=%i) \n",class->classUsed,class->index);
+ /* Print methods used */
+ cnt=0;
+ for (m=0; m < class->methodscount; m++) {
+ meth = &class->methods[m];
+ if (cnt == 0) {
+ for (t=0;t<class->index;t++) printf("\t");
+ printf("aMethods used:\n");
+ }
+ for (t=0;t<class->index;t++) printf("\t");
+ printf("\t");
+ utf_display(meth->class->name);
+ printf(".");
+ method_display(meth);
+ cnt++;
+ }
+ if (cnt > 0) printf("> %i of %i methods\n",cnt, class->methodscount);
+ }
+
+ for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
+ printObjectClassHeirarchy(subs);
+ }
+
+}
+/*--------------------------------------------------------------*/
+/*--------------------------------------------------------------*/
+int subdefd(methodinfo *meth) {
+ classinfo *subs;
+ methodinfo *submeth;
+
+/*printf("subdefd for:");utf_display(meth->class->name);printf(".");method_display(meth); fflush(stdout);*/
+
+ if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
+ panic("Possible Poly call for FINAL or STATIC\n");
+
+ if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
+ return 0;
+ }
+ if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
+
+/*printf("s exist for:");utf_display(meth->class->name);printf(".");method_display(meth);*/
+
+ for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
+ submeth = class_findmethod(subs, meth->name, meth->descriptor);
+ if (submeth != NULL) {
+ subRedefsCnt++;
+ if (submeth->methodUsed == USED) {
+ subRedefsCntUsed++;
+ /*return 1;*/
+ }
+ else {
+ if (subdefd(submeth) > 0)
+ ; /*return 1;*/
+ }
+ }
+ }
+ if (subRedefsCntUsed > 0) return 1;
+ return 0;
+}
+/*--------------------------------------------------------------*/
+
+void printRTClassHeirarchy(classinfo *class) {
+
+classinfo *subs;
+methodinfo *meth;
+int m,cnt;
+
+if (class == NULL) {return;}
+ /* Class Name */
+ if (class->classUsed == NOTUSED) {
+ RTclassHeirNotUsedCnt++;
+ RTmethodNotUsedCnt = RTmethodNotUsedCnt + class->methodscount;
+ RTmethodNotUsedCnt1 = RTmethodNotUsedCnt1 + class->methodscount;
+ for (m=0; m < class->methodscount; m++) {
+ meth = &class->methods[m];
+ if (meth->methodUsed == USED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("METHOD marked used in CLASS marked NOTUSED: ");
+ utf_display(class->name);
+ printf(".");
+ method_display(meth);
+ printf("<%i>\n\t",meth->methodUsed);
+ fflush(stdout);
+ printf("\n\n\n\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
+ }
+ }
+ }
+ }
+
+ if (class->classUsed != NOTUSED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\nClass: ");
+ utf_display(class->name);
+ printf(" <%i> (depth=%i) ",class->classUsed,class->index);
+
+ printf("\tbase/diff =%3d/%3d\n",
+ class->vftbl->baseval,
+ class->vftbl->diffval);
+ }
+
+ if (class->classUsed == PARTUSED) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\tClass not instanciated - but methods/fields resolved to this class' code (static,inits,fields,super)\n");
+ }
+ RTclassHeirPartUsedCnt++;
+ }
+ else {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\n");
+ }
+ RTclassHeirUsedCnt++;
+ }
+
+
+ /* Print methods used */
+ cnt=0;
+ for (m=0; m < class->methodscount; m++) {
+
+ meth = &class->methods[m];
+
+ if (meth->methodUsed == NOTUSED) RTmethodNotUsedCnt2++;
+ if (meth->methodUsed == MARKED) RTmethodMarkedCnt++;
+ if (meth->methodUsed == USED) {
+ RTmethodUsedCnt++;
+ if ( (meth->flags & ACC_FINAL ) && (!(meth->flags & ACC_STATIC)) ) {
+ RTmethodFinal++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodFinal100++;
+ }
+
+ if ( (meth->flags & ACC_STATIC) && (!(meth->flags & ACC_FINAL )) ) {
+ RTmethodStatic++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodStatic100++;
+ }
+
+ if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) ) {
+ RTmethodFinalStatic++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodFinalStatic100++;
+ }
+
+ if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
+ && ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT)) )) {
+ RTmethodNoSubs++;
+ if (meth->jcodelength < MAXCODLEN) RTmethodNoSubs100++;
+ }
+
+ if ((! ((meth->flags & ACC_FINAL ) && (meth->flags & ACC_STATIC)) )
+ && ((meth->class->sub == NULL) && (meth->flags & ACC_ABSTRACT) )) RTmethodNoSubsAbstract++;
+
+ if (meth->flags & ACC_ABSTRACT) RTmethodAbstract++;
+
+ if (meth->monoPoly == MONO) RTmethodMono++;
+ if (meth->monoPoly == POLY) {
+ RTmethodPossiblePoly++;
+ subRedefsCnt = 0;
+ subRedefsCntUsed = 0;
+ if (meth->flags & ACC_ABSTRACT ) {
+ if (pClassHeirStatsOnly >= 2) {
+ printf("STATS: abstract_method=");
+ utf_display(meth->class->name);printf(".");
+ method_display(meth);
+ }
+ }
+ else {
+ if (subdefd(meth) == 0) {
+ meth->monoPoly = MONO1;
+ RTmethodPolyReallyMono++;
+ }
+ else {
+ RTmethodPoly++;
+ meth->subRedefs = subRedefsCnt;
+ meth->subRedefsUsed = subRedefsCntUsed;
+ }
+ }
+ }
+
+ if (pClassHeirStatsOnly >= 2) {
+ if (cnt == 0) {
+ printf("bMethods used:\n");
+ }
+ cnt++;
+ printf("\t");
+ utf_display(meth->class->name);
+ printf(".");
+ method_display(meth);
+ printf("\t\t");
+ if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\t", meth->subRedefsUsed, meth->subRedefs);
+ if ( (XTAOPTbypass3) || (opt_xta)) {
+ if (meth->XTAclassSet == NULL)
+ printf("class set never created\n");
+ else
+ printSet(meth->XTAclassSet->head);
+ }
+ }
+ }
+ }
+ if (pClassHeirStatsOnly >= 2) {
+ if (cnt > 0) printf("> %i of %i methods used\n",cnt, class->methodscount);
+ }
+ }
+
+ for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
+ printRTClassHeirarchy(subs);
+ }
+}
+/*--------------------------------------------------------------*/
+void printRTInterfaceClasses() {
+ int ii,jj,mm;
+ classinfo *ci = class_java_lang_Object;
+ classSetNode *subs;
+
+ int RTmethodInterfaceClassImplementedCnt = 0;
+ int RTmethodInterfaceClassUsedCnt = 0;
+
+ int RTmethodInterfaceMethodTotalCnt = 0;
+ int RTmethodInterfaceMethodNotUsedCnt = 0;
+ int RTmethodInterfaceMethodUsedCnt = 0;
+
+ int RTmethodClassesImpldByTotalCnt = 0;
+
+ int RTmethodInterfaceMonoCnt = 0;
+ int RTmethodInterfacePolyReallyMonoCnt=0; /* look at every method that implments and see if its poly or mono1*/
+
+ int RTmethodNoSubsAbstractCnt = 0;
+
+for (subs = ci->impldBy; subs != NULL; subs = subs->nextClass) {
+ classinfo * ici = subs->classType;
+ classinfo * isubs = subs->classType;
+ classinfo * iBy;
+ classSetNode * inBy;
+ int impldBycnt;
+
+ if (isubs->sub == NULL) RTmethodNoSubsAbstractCnt++;
+ if (pClassHeir >= 2) {
+ printf("Interface class: ");fflush(stdout);
+ utf_display(ici->name); printf("\t#Methods=%i",ici->methodscount);
+ }
+ RTmethodInterfaceClassImplementedCnt++;
+ if (ici -> classUsed == USED) {RTmethodInterfaceClassUsedCnt++;}
+ if (pClassHeir >= 2) {
+ printf("\n\t\t\tImplemented by classes:\n");
+ }
+ impldBycnt = 0;
+ /* get the total impldBy classes Used */
+ for (inBy = ici->impldBy; inBy != NULL; inBy = inBy->nextClass) {
+ impldBycnt++;
+ RTmethodClassesImpldByTotalCnt++;
+ if (pClassHeir >= 2) {
+ printf("\t\t\t");utf_display(inBy->classType->name);
+ printf("\n");
+ }
+ if (inBy->classType->classUsed == NOTUSED)
+ panic("printRTInterfaceClasses: class in the implemented list without being used!!!??");
+ }
+ if (pClassHeir >= 2) {
+ printf("\t\t\tImpld by: %i\n",impldBycnt);
+ }
+ if (impldBycnt== 1) RTmethodInterfaceMonoCnt++;
+
+ /* if interface class is used */
+ if (ici -> classUsed != NOTUSED) {
+ if (pClassHeir >= 2) {
+ printf(" cMethods used:\n");
+ }
+
+ /* for each interface method implementation that has been used */
+ for (mm=0; mm< ici->methodscount; mm++) {
+ methodinfo *imi = &(ici->methods[mm]);
+ RTmethodInterfaceMethodTotalCnt++;
+ if (imi->methodUsed != USED) {
+ RTmethodInterfaceMethodNotUsedCnt++;
+ }
+ if (imi->methodUsed == USED) {
+ RTmethodInterfaceMethodUsedCnt++;
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\t\t");
+ utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+ }
+ if (impldBycnt == 1) {
+ classinfo *cii;
+ methodinfo *mii;
+ int i;
+
+ /* if only 1 implementing class then possibly really mono call */
+ inBy = ici->impldBy;
+ cii = inBy->classType;
+
+ mii = class_findmethod(cii, imi->name, imi->descriptor);
+ if (mii == NULL) {
+ /* assume its resolved up the heirarchy and just 1 possiblity so MONO1 */
+ imi->monoPoly = MONO1;
+ RTmethodInterfacePolyReallyMonoCnt++;
+ }
+ else {
+ if (imi->monoPoly != POLY)
+ panic ("interface monopoly not POLY");
+
+ if (mii->monoPoly != POLY) {
+ imi->monoPoly = MONO1;
+ RTmethodInterfacePolyReallyMonoCnt++;
+ }
+ else {
+ imi->monoPoly = POLY;
+ }
+ }
+ }
+ }
+ }
+ if (pClassHeir >= 2) {
+ printf("\n");
+ }
+ }
+ }
+if (pClassHeirStatsOnly >= 1) {
+ printf("\n\n >>>>>>>>>>>>>>>>>>>> Interface Statistics Summary: \n");
+ printf("Classes: Total: %i \tUSED: %i \tIMPLD BY: \t%i \tJUST 1 IMPLD BY: %i \tNOSUB: %i \n",
+ RTmethodInterfaceClassImplementedCnt,
+ RTmethodInterfaceClassUsedCnt,RTmethodClassesImpldByTotalCnt, RTmethodInterfaceMonoCnt,
+ RTmethodNoSubsAbstractCnt);
+ printf("Methods: Total: %i \tNOTUSED: %i \tUSED: \t%i \tPoly that resolves to Mono %i \n",
+ RTmethodInterfaceMethodTotalCnt,
+ RTmethodInterfaceMethodNotUsedCnt,RTmethodInterfaceMethodUsedCnt, RTmethodInterfacePolyReallyMonoCnt);
+ }
+}
+/*--------------------------------------------------------------*/
+
+void printRThierarchyInfo(methodinfo *m) {
+
+ /*-- init for statistics --*/
+ RTclassHeirNotUsedCnt=0;
+ RTclassHeirUsedCnt=0;
+ RTclassHeirPartUsedCnt=0;
+ RTclassHeirSuperCnt=0;
+ RTmethodNotUsedCnt = 0;
+ RTmethodNotUsedCnt1 = 0;
+ RTmethodNotUsedCnt2 = 0;
+ RTmethodUsedCnt = 0;
+ RTmethodMarkedCnt= 0;
+
+
+ /*-- --*/
+ if (pClassHeirStatsOnly >= 2) {
+ printf("\nRT Class Heirarchy for ");
+ printf("--- start of RT info --------------- after :\n");
+ if (m != NULL) {
+ utf_display(m->class->name);
+ printf(".");
+ method_display(m);
+ printf("\n");
+ }
+ }
+ printRTClassHeirarchy(class_java_lang_Object);
+ if (pClassHeirStatsOnly >= 2) {
+ printf("--- end of RT info ---------------\n");
+ }
+ if (pClassHeirStatsOnly >= 1) {
+
+ /*-- statistic results --*/
+ printRTInterfaceClasses();
+
+ printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Heirarchy Statistics:\n");
+ printf(" Used \t%i \tclasses\t/ Used \t%i methods \t of USED: %i%% \t of ALL: %i%% \n",
+ RTclassHeirUsedCnt,RTmethodUsedCnt,
+ ((100*RTmethodUsedCnt)/(RTmethodUsedCnt + RTmethodNotUsedCnt2)) ,
+ ((100*RTmethodUsedCnt)/ (RTmethodNotUsedCnt + RTmethodUsedCnt + RTmethodMarkedCnt)) );
+ printf(" Part Used \t%i \tclasses\t/\n",RTclassHeirPartUsedCnt);
+ printf(" Not Used \t%i \tclasses\t/\n\n",RTclassHeirNotUsedCnt);
+ printf(" \t \t \t/ Just Marked \t%i methods\n\n",RTmethodMarkedCnt);
+ printf(" In Not Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt1);
+ printf(" In Used \t \tclasses\t/ Not Used \t%i methods\n",RTmethodNotUsedCnt2);
+ printf(" Total \t%i \tclasses\t/ Total \t%i methods\n\n",
+ RTclassHeirNotUsedCnt + RTclassHeirUsedCnt + RTclassHeirPartUsedCnt,
+ RTmethodNotUsedCnt1 + RTmethodNotUsedCnt2 + RTmethodUsedCnt + RTmethodMarkedCnt );
+
+ printf(" Mono vs. Polymorhpic calls:\n");
+ printf(" Mono calls \t%i \tPoly that resolves to Mono \t%i \tPoly calls \t%i\n\n",
+ RTmethodMono, RTmethodPolyReallyMono, RTmethodPoly);
+
+ printf(" No Subs: Total=\t%i \tAbstract No Subs= \t%i \tAbstract methods used =\t%i\n",
+ RTmethodNoSubs, RTmethodNoSubsAbstract, RTmethodAbstract);
+
+ printf(" Inlining possible: \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+ RTmethodFinal, RTmethodStatic,RTmethodFinalStatic, RTmethodNoSubs);
+ printf(" Code size < 100 \tFINALs %i \tSTATICs %i \t FINAL & STATIC %i \t Class has No Subs %i \n",
+ RTmethodFinal100, RTmethodStatic100,RTmethodFinalStatic100, RTmethodNoSubs100);
+ }
+}
+
--- /dev/null
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sets.h"
+
+
+/*
+ * set.c - functions to manipulate ptr sets.
+ */
+
+/*------------------------------------------------------------*/
+/*-- fieldinfo call set fns */
+/*------------------------------------------------------------*/
+fldSetNode *inFldSet (fldSetNode *s, fieldinfo *f)
+ {
+ fldSetNode* i;
+ for (i=s; i != NULL; i = i->nextfldRef) {
+ if (i->fldRef == f) {
+ return i; /* true = found */
+ }
+ }
+ return NULL;
+ }
+
+/*------------------------------------------------------------*/
+/* */
+fldSetNode *addFldRef(fldSetNode *s, fieldinfo *f)
+ {
+ fldSetNode *s1 = s;
+ if (!inFldSet(s,f)) {
+ s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
+ s1->nextfldRef = s;
+ s1->fldRef = f;
+ s1->readPUT = false;
+ s1->writeGET = false;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+fldSet *add2FldSet(fldSet *sf, fieldinfo *f)
+ {
+ fldSetNode *s1;
+ fldSetNode *s;
+
+ if (sf == NULL) {
+ sf = createFldSet();
+ }
+ s = sf->head;
+ if (!inFldSet(s,f)) {
+ s1 = (fldSetNode *)malloc(sizeof(fldSetNode));
+ if (sf->head == NULL) {
+ sf->head = s1;
+ sf->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sf->tail->nextfldRef = s1;
+ sf->length++;
+ s1->index = sf->length;
+ }
+ s1->nextfldRef = NULL;
+ s1->fldRef = f;
+ s1->readPUT = false;
+ s1->writeGET = false;
+ sf->tail = s1;
+ }
+ return sf;
+ }
+
+/*------------------------------------------------------------*/
+fldSet *createFldSet( )
+ {
+ fldSet *s;
+ s = (fldSet *)malloc(sizeof(fldSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/*-- methodinfo call set fns */
+/*------------------------------------------------------------*/
+int inMethSet (methSetNode *s, methodinfo *m)
+ {
+ methSetNode* i;
+ for (i=s; i != NULL; i = i->nextmethRef) {
+ if (i->methRef == m) {
+ return (int)1; /* true = found */
+ }
+ }
+ return (int)0;
+ }
+
+/*------------------------------------------------------------*/
+methSetNode *addMethRef(methSetNode *s, methodinfo *m)
+ {
+ methSetNode *s1 = s;
+ if (!inMethSet(s,m)) {
+ s1 = (methSetNode *)malloc(sizeof(methSetNode));
+ s1->nextmethRef= s;
+ s1->methRef = m;
+ s1->lastptrIntoClassSet2 = NULL;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ s1->monoPoly = MONO;
+ }
+
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+methSet *add2MethSet(methSet *sm, methodinfo *m)
+ {
+ methSetNode *s1;
+ methSetNode *s;
+
+ if (sm == NULL) {
+ sm = createMethSet();
+ }
+ s = sm->head;
+ if (!inMethSet(s,m)) {
+ s1 = (methSetNode *)malloc(sizeof(methSetNode));
+ if (sm->head == NULL) {
+ sm->head = s1;
+ sm->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sm->tail->nextmethRef = s1;
+ sm->length++;
+ s1->index = sm->length;
+ }
+ s1->monoPoly = MONO;
+ s1->nextmethRef= NULL;
+ s1->methRef = m;
+ s1->lastptrIntoClassSet2 = NULL;
+ sm->tail = s1;
+ }
+ return sm;
+ }
+
+/*------------------------------------------------------------*/
+methSet *createMethSet( )
+ {
+ methSet *s;
+ s = (methSet *)malloc(sizeof(methSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/*-- classinfo XTA set fns */
+/*------------------------------------------------------------*/
+int inSet (classSetNode *s, classinfo *c)
+ {
+ classSetNode* i;
+ for (i=s; i != NULL; i = i->nextClass) {
+ if (i->classType == c) {
+ return ((i->index)+1); /* true = found */
+ }
+ }
+ return (int)0;
+ }
+
+/*------------------------------------------------------------*/
+classSetNode *addElement(classSetNode *s, classinfo *c)
+ {
+ classSetNode *s1 = s;
+ if (!inSet(s,c)) {
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ s1->nextClass= s;
+ s1->classType = c;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+classSet *add2ClassSet(classSet *sc, classinfo *c)
+ {
+ classSetNode *s1;
+ classSetNode *s;
+
+ if (sc == NULL) {
+ sc = createClassSet();
+ }
+ s = sc->head;
+
+ if (!inSet(s,c)) {
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ if (sc->head == NULL) {
+ sc->head = s1;
+ sc->pos = s1;
+ s1->index = 1;
+ }
+ else {
+ sc->tail->nextClass = s1;
+ sc->length++;
+ s1->index = sc->length;
+ }
+ s1->classType = c;
+ s1->nextClass= NULL;
+ sc->tail = s1;
+ }
+ return sc;
+ }
+
+/*------------------------------------------------------------*/
+classSet *createClassSet( )
+ {
+ classSet *s;
+ s = (classSet *)malloc(sizeof(classSet));
+ s->head = NULL;
+ s->tail = NULL;
+ s->pos = NULL;
+ s->length = 0;
+ return s;
+ }
+
+/*------------------------------------------------------------*/
+/* Returns:
+/* -1 c is a subclass of an existing set element
+/* 0 c class type cone does not overlap any set element
+/* 1 c is a superclass of an existing set element
+*/
+
+int inRange (classSetNode *s, classinfo *c)
+ {
+ classSetNode* i;
+ int rc=0;
+
+ for (i=s; i != NULL; i = i->nextClass) {
+ classinfo *cs = i->classType;
+ if (cs->vftbl->baseval <= c->vftbl->baseval) {
+ if (c->vftbl->baseval <= (cs->vftbl->baseval+cs->vftbl->diffval)) {
+ rc = -1; /* subtype */
+ }
+ }
+ else {
+ if (cs->vftbl->baseval < (c->vftbl->baseval+c->vftbl->diffval)) {
+ i->classType = c; /* replace element with its new super */
+ rc = 1; /* super */
+ }
+ }
+ }
+ return rc;
+ }
+
+/*------------------------------------------------------------*/
+/* adds class if not subtype of an existing set element */
+/* if "new" class is super class of an existing element */
+/* then replace the existing element with the "new" class */
+
+classSetNode *addClassCone(classSetNode *s, classinfo *c)
+ {
+ classSetNode *s1 = s;
+
+if (inRange(s,c) == 0) {
+ /* not in set nor cone of an existing element so add */
+ s1 = (classSetNode *)malloc(sizeof(classSetNode));
+ s1->nextClass= s;
+ s1->classType = c;
+ if (s == NULL)
+ s1->index = 1;
+ else
+ s1->index = s->index+1;
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+classSetNode * intersectSubtypesWithSet(classinfo *t, classSetNode *s) {
+ classSetNode *s1 = NULL;
+ classSetNode *c;
+
+ /* for each s class */
+ for (c=s; c != NULL; c = c->nextClass) {
+ vftbl *t_cl_vt = t->vftbl;
+ vftbl *c_cl_vt = c->classType->vftbl;
+
+ /* if s class is in the t Class range */
+ if ( (t_cl_vt->baseval <= c_cl_vt->baseval)
+ && (c_cl_vt->baseval <= (t_cl_vt->baseval+t_cl_vt->diffval)) ) {
+
+ /* add s class to return class set */
+ s1 = addElement(s1,c->classType);
+ }
+ }
+ return s1;
+ }
+
+/*------------------------------------------------------------*/
+int sizeOfSet(classSetNode *s) {
+/*** need to update */
+ int cnt=0;
+ classSetNode * i;
+ for (i=s; i != NULL; i = i->nextClass) cnt++;
+ return cnt;
+ }
+
+/*------------------------------------------------------------*/
+int printSet(classSetNode *s)
+ {
+ classSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of types: <");
+ printf("\t\tEmpty Set\n");
+ }
+ else {
+ printf("<%i>Set of types: ",s->index);
+ for (i=s; i != NULL; i = i->nextClass) {
+ printf("\t#%i: ",cnt);
+ if (i->classType == NULL) {
+ printf("NULL CLASS");
+ fflush(stdout);
+ }
+ else {
+ utf_display(i->classType->name);
+ fflush(stdout);
+ printf("<b%i/d%i> ",i->classType->vftbl->baseval,i->classType->vftbl->diffval);
+ fflush(stdout);
+ }
+ cnt++;
+ }
+ printf(">\n");
+ }
+ return cnt;
+ }
+/*------------------------------------------------------------*/
+int printClassSet(classSet *sc) {
+if (sc == NULL) {
+ printf("Class Set not yet created\n");
+ return 0;
+ }
+else
+ return (printSet(sc->head));
+}
+
+/*------------------------------------------------------------*/
+int printMethSet(methSetNode *s)
+ {
+ methSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of Methods: "); fflush(stdout);
+ printf("\t\tEmpty Set\n"); fflush(stdout);
+ }
+ else {
+ printf("<%i>Set of Methods: ",s->index);fflush(stdout);
+ for (i=s; i != NULL; i = i->nextmethRef) {
+ printf("\t#%i: ",cnt);
+
+ /* class.method */
+ utf_display(i->methRef->class->name);
+ printf(".");
+ method_display(i->methRef);
+
+ /* lastptr <class> */
+ printf("\t<");
+ if (i->lastptrIntoClassSet2 != NULL)
+ utf_display(i->lastptrIntoClassSet2->classType->name);
+ printf(">\n");
+
+ cnt++;
+ }
+ printf("\n");
+ }
+ return cnt;
+ }
+/*------------------------------------------------------------*/
+int printMethodSet(methSet *sm) {
+if (sm == NULL) {
+ printf("Method Set not yet created\n");
+ return 0;
+ }
+else
+ return (printMethSet(sm->head));
+}
+/*------------------------------------------------------------*/
+int printFldSet(fldSetNode *s)
+ {
+ fldSetNode* i;
+ int cnt=0;
+
+ if (s == NULL) {
+ printf("Set of Fields: ");
+ printf("\tEmpty Set\n");
+ }
+ else {
+ printf("<%i>Set of Fields: ",s->index);
+ for (i=s; i != NULL; i = i->nextfldRef) {
+ printf("\t#%i: ",cnt);
+ printf("(%ir/%iw)",i->readPUT,i->writeGET);
+ field_display(i->fldRef);
+ cnt++;
+ }
+ printf("\n");
+ }
+ return cnt;
+ }
+
+/*------------------------------------------------------------*/
+int printFieldSet(fldSet *sf) {
+if (sf == NULL) {
+ printf("Field Set not yet created\n");
+ return 0;
+ }
+else
+ return (printFldSet(sf->head));
+}
+/*------------------------------------------------------------*/
+/*void destroy_set */
+
--- /dev/null
+#ifndef __SET__
+#define __SET__
+
+typedef struct methSet methSet;
+typedef struct methSetNode methSetNode;
+typedef struct fldSet fldSet;
+typedef struct fldSetNode fldSetNode;
+typedef struct classSet classSet;
+typedef struct classSetNode classSetNode;
+
+
+/*------------------------------------------------------------*/
+/*-- flds used by a method set fns */
+/*------------------------------------------------------------*/
+struct fldSet {
+ fldSetNode *head;
+ fldSetNode *tail;
+ fldSetNode *pos;
+ s4 length;
+ };
+
+
+struct fldSetNode {
+ fieldinfo *fldRef;
+ fldSetNode *nextfldRef;
+ bool readPUT;
+ bool writeGET;
+ s2 index;
+ };
+fldSetNode *inFldSet (fldSetNode *, fieldinfo *);
+fldSetNode *addFldRef(fldSetNode *, fieldinfo *);
+fldSet *add2FldSet(fldSet *, fieldinfo *);
+fldSet *createFldSet();
+int printFldSet (fldSetNode *);
+int printFieldSet (fldSet *);
+
+
+/*------------------------------------------------------------*/
+/*-- methodinfo call set fns */
+/*------------------------------------------------------------*/
+struct methSet {
+ methSetNode *head;
+ methSetNode *tail;
+ methSetNode *pos;
+ s4 length;
+ };
+
+struct methSetNode {
+ methodinfo *methRef;
+ methSetNode *nextmethRef;
+ classSetNode *lastptrIntoClassSet2;
+ s2 index;
+ s4 monoPoly;
+ };
+
+int inMethSet (methSetNode *, methodinfo *);
+methSetNode *addMethRef(methSetNode *, methodinfo *);
+methSet *add2MethSet(methSet *, methodinfo *);
+methSet *createMethSet();
+int printMethSet (methSetNode *);
+int printMethodSet (methSet *);
+
+/*------------------------------------------------------------*/
+/*-- classinfo XTA set fns */
+/*------------------------------------------------------------*/
+
+struct classSet {
+ classSetNode *head;
+ classSetNode *tail;
+ classSetNode *pos;
+ s4 length;
+ };
+
+struct classSetNode {
+ classinfo *classType;
+ classSetNode *nextClass;
+ s2 index;
+ };
+
+int inSet (classSetNode *, classinfo *);
+classSetNode * addElement(classSetNode *, classinfo *);
+classSet * add2ClassSet(classSet *, classinfo *);
+classSet * createClassSet();
+int inRange (classSetNode *, classinfo *);
+classSetNode * addClassCone(classSetNode *, classinfo *);
+classSetNode * intersectSubtypesWithSet(classinfo *, classSetNode *);
+int setSize(classSetNode *);
+int printSet(classSetNode *);
+int printClassSet(classSet *);
+
+#endif
+
Author: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
- Last Change: $Id: parse.c 467 2003-09-26 01:55:25Z didi $
+ Last Change: $Id: parse.c 468 2003-10-04 17:15:31Z carolyn $
include Rapid Type Analysis parse - 5/2003 - carolyn
*******************************************************************************/
#include "math.h"
+#include "sets.h"
/* data about the currently parsed method */
static classinfo *rt_class; /* class the compiled method belongs to */
-//INLINING
+/*INLINING*/
#include "inline.c"
-//#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);
+/*#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);*/
#define debug_writebranch
/* functionc compiler_addinitclass *********************************************
}
+/* function descriptor2typesL ***************************************************
+
+ decodes a already checked method descriptor. The parameter count, the
+ return type and the argument types are stored in the passed methodinfo.
+ gets and saves classptr for object ref.s
+
+*******************************************************************************/
+
+classSetNode * descriptor2typesL (methodinfo *m)
+{
+int debugInfo = 0;
+ int i;
+ u1 *types, *tptr;
+ int pcount, c;
+ char *utf_ptr;
+ classinfo** classtypes;
+ char *class;
+ char *desc;
+ classSetNode *p=NULL;
+if (debugInfo >= 1) {
+ printf("In descriptor2typesL >>>\t"); fflush(stdout);
+ utf_display(m->class->name); printf(".");
+ method_display(m);fflush(stdout);
+ }
+
+ pcount = 0;
+ desc = MNEW (char, 256);
+ types = DMNEW (u1, m->descriptor->blength);
+ classtypes = MNEW (classinfo*, m->descriptor->blength+1);
+ m->returnclass = NULL;
+ tptr = types;
+ if (!(m->flags & ACC_STATIC)) {
+ *tptr++ = TYPE_ADR;
+ if (debugInfo >= 1) {
+ printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
+ }
+ classtypes[pcount] = m->class;
+ p = addClassCone(p, m->class);
+ pcount++;
+ }
+
+ utf_ptr = m->descriptor->text + 1;
+ strcpy (desc,utf_ptr);
+
+ while ((c = *desc++) != ')') {
+ pcount++;
+ switch (c) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': *tptr++ = TYPE_INT;
+ break;
+ case 'J': *tptr++ = TYPE_LNG;
+ break;
+ case 'F': *tptr++ = TYPE_FLT;
+ break;
+ case 'D': *tptr++ = TYPE_DBL;
+ break;
+ case 'L': *tptr++ = TYPE_ADR;
+ /* get class string */
+ class = strtok(desc,";");
+ desc = strtok(NULL,"\0");
+ /* get/save classinfo ptr */
+ classtypes[pcount-1] = class_get(utf_new_char(class));
+ p = addClassCone(p, class_get(utf_new_char(class)));
+ if (debugInfo >= 1) {
+ printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
+ printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
+ utf_display(classtypes[pcount-1]->name);
+ }
+ break;
+ case '[': *tptr++ = TYPE_ADR;
+ while (c == '[')
+ c = *desc++;
+ /* get class string */
+ if (c == 'L') {
+ class = strtok(desc,";");
+ desc = strtok(NULL,"\0");
+ /* get/save classinfo ptr */
+ classtypes[pcount-1] = class_get(utf_new_char(class));
+ p= addClassCone(p, class_get(utf_new_char(class)));
+ if (debugInfo >= 1) {
+ printf("[Param#%i 's class type is: %s\n",pcount-1,class);
+ printf("[classtypes[%i]=",pcount-1);fflush(stdout);
+ utf_display(classtypes[pcount-1]->name);
+ printf("\n");
+ }
+ }
+ else
+ classtypes[pcount-1] = NULL;
+ break;
+ default:
+ panic("Ill formed methodtype-descriptor");
+ }
+ }
+
+ /* compute return type */
+ switch (*desc++) {
+ case 'B':
+ case 'C':
+ case 'I':
+ case 'S':
+ case 'Z': m->returntype = TYPE_INT;
+ break;
+ case 'J': m->returntype = TYPE_LNG;
+ break;
+ case 'F': m->returntype = TYPE_FLT;
+ break;
+ case 'D': m->returntype = TYPE_DBL;
+ break;
+ case '[':
+ m->returntype = TYPE_ADR;
+ c = *desc;
+ while (c == '[')
+ c = *desc++;
+ if (c != 'L') break;
+ *desc++;
+
+ case 'L':
+ m->returntype = TYPE_ADR;
+
+ /* get class string */
+ class = strtok(desc,";");
+ m->returnclass = class_get(utf_new_char(class));
+ if (m->returnclass == NULL) {
+ printf("class=%s :\t",class);
+ panic ("return class not found");
+ }
+ break;
+ case 'V': m->returntype = TYPE_VOID;
+ break;
+
+ default: panic("Ill formed methodtype-descriptor-ReturnType");
+ }
+
+ m->paramcount = pcount;
+ m->paramtypes = types;
+ m->paramclass = classtypes;
+
+if (debugInfo >=1) {
+ if (pcount > 0) {
+ for (i=0; i< m->paramcount; i++) {
+ if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
+ printf("Param #%i is:\t",i);
+ utf_display(m->paramclass[i]->name);
+ printf("\n");
+ }
+ }
+ }
+ if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) {
+ printf("\tReturn Type is:\t"); fflush(stdout);
+ utf_display(m->returnclass->name);
+ printf("\n");
+ }
+
+ printf("params2types: START results in a set \n");
+ printf("param2types: A Set size=%i=\n",sizeOfSet(p));
+ printSet(p);
+ }
+
+return p;
+}
+
/* function descriptor2types ***************************************************
decodes a already checked method descriptor. The parameter count, the
panic("branch target out of code-boundary");}
#define bound_check1(i) {if((i< 0) || (i>cumjcodelength)) \
panic("branch target out of code-boundary");}
-// FIXME really use cumjcodelength for the bound_checkers ?
+/* FIXME really use cumjcodelength for the bound_checkers ? */
static xtable* fillextable (xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
{
bool useinltmp;
static int xta1 = 0;
-//INLINING
+/*INLINING*/
if (useinlining)
{
label_index = inlinfo->label_index;
exceptiontablelength=cumextablelength;
}
- useinltmp = useinlining; //FIXME remove this after debugging
- //useinlining = false; // and merge the if-statements
+ useinltmp = useinlining; /*FIXME remove this after debugging */
+ /*useinlining = false; /* and merge the if-statements */
if (!useinlining) {
cumjcodelength = jcodelength;
if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
}
- /*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
+ /*RTAprint*/ if ( ((opt_rt) ||(opt_xta) || (opt_vta)) && ((pOpcodes == 2) || (pOpcodes == 3)) )
/*RTAprint*/ {printf("PARSE method name =");
/*RTAprint*/ utf_display(method->class->name);printf(".");
/*RTAprint*/ method_display(method); printf(">\n\n");fflush(stdout);}
- if (opt_rt) {
+ if ((opt_rt) || (opt_xta)) {
RT_jit_parse(method);
}
- else {
- if ((opt_xta) && (xta1 == 0)) {
- /*printf("XTA - not available yet\n"); */
- /*xta1++; */
- XTA_jit_parse(method);
- /*XTAprint*/ if (((pOpcodes == 1) || (pOpcodes == 3)) && opt_rt)
- /*XTAprint*/ {printf("XTA PARSE method name =");
- /*XTAprint*/ utf_display(rt_method->class->name);printf(".");
- /*XTAprint*/ method_display(rt_method); printf(">\n\n");fflush(stdout);}
-
- }
-
- }
+ else {
+ if (opt_vta)
+ printf("VTA requested, but not yet implemented\n");
+ }
+
#ifdef OLD_COMPILER
/* generate the same addresses as the old JIT compiler */
for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
- // DEBUG printf("p:%d gp:%d ",p,gp);
+ /* DEBUG printf("p:%d gp:%d ",p,gp); */
-//INLINING
+/*INLINING*/
if ((useinlining) && (gp == nextgp)) {
u1 *tptr;
bool *readonly = NULL;
op += *tptr;
OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
- // block_index[gp] |= (ipc << 1); //FIXME: necessary ?
+ /* block_index[gp] |= (ipc << 1); /*FIXME: necessary ? */
}
inlining_save_compiler_variables();
inlining_set_compiler_variables(tmpinlinf);
}
opcode = code_get_u1 (p); /* fetch op code */
-
+
/*RTAprint*/ if ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
/*RTAprint*/ {printf("Parse<%i> p=%i<%i< opcode=<%i> %s\n",
/*RTAprint*/ pOpcodes, p,rt_jcodelength,opcode,icmd_names[opcode]);}
-
block_index[gp] |= (ipc << 1); /* store intermediate count */
if (isinlinedmethod) {
- /* if (p==jcodelength-1) { //return is at end of inlined method
+ /* if (p==jcodelength-1) { /*return is at end of inlined method **
OP(ICMD_NOP);
break;
- }*/
+ } */
blockend = true;
OP1(ICMD_GOTO, inlinfo->stopgp);
break;
/* INLINING */
- if ((isinlinedmethod) && (p==jcodelength-1)) { //end of an inlined method
- // printf("setting gp from %d to %d\n",gp, inlinfo->stopgp);
+ if ((isinlinedmethod) && (p==jcodelength-1)) { /*end of an inlined method */
+ /* printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
gp = inlinfo->stopgp;
inlining_restore_compiler_variables();
list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
tmpinlinf = list_first(inlinfo->inlinedmethods);
nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
}
- // printf("nextpgp: %d\n", nextgp);
+ /* printf("nextpgp: %d\n", nextgp); */
label_index=inlinfo->label_index;
firstlocal = inlinfo->firstlocal;
}
if (useinlining) inlining_cleanup();
useinlining = useinltmp;
}
-
+#include "sets.c"
#include "parseRT.h"
-#include "parseXTA.h"
/*
* These are local overrides for various environment variables in Emacs.
extern bool newcompiler; /* true if new compiler is used */
bool opt_rt = false; /* true if RTA parse should be used RT-CO */
bool opt_xta = false; /* true if XTA parse should be used XTA-CO */
+bool opt_vta = false; /* true if VTA parse should be used VTA-CO */
int count_class_infos = 0; /* variables for measurements */
int count_const_pool_len = 0;
d -> arraytype = ARRAYTYPE_OBJECT;
d -> objectclass = class_new ( utf_new(utf_ptr+1, namelen-3) );
- d -> objectclass -> classUsed = 0; /* not used initially CO-RT */
+ d -> objectclass -> classUsed = NOTUSED; /* not used initially CO-RT */
d -> objectclass -> impldBy = NULL;
- d -> objectclass -> nextimpldBy = NULL;
break;
}
return d;
f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
f -> type = jtype = desc_to_type (f->descriptor); /* data type */
f -> offset = 0; /* offset from start of object */
+ f -> fieldUsed = NOTUSED; /*XTA*/
+ f -> fldClassType = NULL; /*XTA*/
+ f -> XTAclassSet = NULL; /*XTA*/
+ f -> lastRoundChgd = -1;
switch (f->type) {
case TYPE_INT: f->value.i = 0; break;
m -> entrypoint = NULL;
m -> mcode = NULL;
m -> stubroutine = NULL;
- m -> methodUsed = 0;
- m -> XTAclasscount = 0;
- m -> numSubDefs = 0;
+ m -> methodUsed = NOTUSED;
+ m -> XTAmethodUsed = NOTUSED;
+ m -> monoPoly = MONO;
+ m -> subRedefs = 0;
+ m -> subRedefsUsed = 0;
+
+ /* --- XTA --- */
+ /*if (opt_xta) { */
+ m -> XTAclassSet = NULL; /*XTA*/
+ m -> paramClassSet = NULL; /*XTA*/
+ m -> calls = NULL; /*XTA*/
+ m -> calledBy = NULL; /*XTA*/
+ m -> chgdSinceLastParse = false; /*XTA*/
+
+ m -> marked = NULL; /*XTA*/
+ m -> markedBy = NULL; /*XTA*/
+ m -> fldsUsed = NULL; /*XTA*/
+ m -> interfaceCalls = NULL; /*XTA*/
+ m -> lastRoundParsed = -1;
+ m -> interfaceCalls = NULL; /*XTA*/
+ /*}*/
if (! (m->flags & ACC_NATIVE) ) {
m -> stubroutine = createcompilerstub (m);
class_loadcpool (c);
- c -> classUsed = 0; /* not used initially CO-RT */
+ c -> classUsed = NOTUSED; /* not used initially CO-RT */
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
/* ACC flags */
c -> flags = suck_u2 ();
if (super == NULL) { /* class java.long.Object */
c->index = 0;
- c->classUsed = 1; /* Object class is always used CO-RT*/
+ c->classUsed = USED; /* Object class is always used CO-RT*/
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
c->instancesize = sizeof(java_objectheader);
vftbllength = supervftbllength = 0;
u4 i = ii;
voidptr e;
-printf ("#%d: ", (int) i);
e = c -> cpinfos [i];
+printf ("#%d: ", (int) i);
if (e) {
switch (c -> cptags [i]) {
case CONSTANT_Class:
for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
/* create primitive class */
classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
- c -> classUsed = 0; /* not used initially CO-RT */
+ c -> classUsed = NOTUSED; /* not used initially CO-RT */
c -> impldBy = NULL;
- c -> nextimpldBy = NULL;
/* prevent loader from loading primitive class */
list_remove (&unloadedclasses, c);
/* create class for wrapping the primitive type */
primitivetype_table[i].class_wrap =
class_new( utf_new_char(primitivetype_table[i].wrapname) );
- primitivetype_table[i].class_wrap -> classUsed = 0; /* not used initially CO-RT */
+ primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
primitivetype_table[i].class_wrap -> impldBy = NULL;
- primitivetype_table[i].class_wrap -> nextimpldBy = NULL;
}
}
/* create class for arrays */
class_array = class_new ( utf_new_char ("The_Array_Class") );
- class_array -> classUsed = 0; /* not used initially CO-RT */
+ class_array -> classUsed = NOTUSED; /* not used initially CO-RT */
class_array -> impldBy = NULL;
- class_array -> nextimpldBy = NULL;
list_remove (&unloadedclasses, class_array);
/* create class for strings, load it after class Object was loaded */
string_class = utf_new_char ("java/lang/String");
class_java_lang_String = class_new(string_class);
- class_java_lang_String -> classUsed = 0; /* not used initially CO-RT */
+ class_java_lang_String -> classUsed = NOTUSED; /* not used initially CO-RT */
class_java_lang_String -> impldBy = NULL;
- class_java_lang_String -> nextimpldBy = NULL;
list_remove (&unloadedclasses, class_java_lang_String);
classinfo *subs;
c->vftbl->baseval = ++classvalue;
+
subs = c->sub;
while (subs != NULL) {
loader_compute_class_values(subs);
subs = subs->nextsub;
}
c->vftbl->diffval = classvalue - c->vftbl->baseval;
+
/*
{
int i;
void m2( ) {ax = 2;
// System.out.println("In A.m2: "+ax);
}
+
}
class C extends A {
static int cx = 1;
+
void m1( ) {ax = 100; cx=1;
}
+
public static void main(String[] s) {
A a;
B b = new B();
chmod 644 *; \
chmod 755 input; \
sh setup.sh || true; \
- ../../cacao -ieee sun.tools.javac.Main -d . *.java && \
- ../../cacao -ieee Main > $@.output; \
+ ../../cacao -rt -ieee sun.tools.javac.Main -d . *.java && \
+ ../../cacao -rt -ieee Main > $@.output; \
sh postoutput.sh || true; \
)
diff --brief $@/$@.output $@.output
void *m;
if (!nomallocmem) {
- nomallocmem = malloc(16777216);
+ nomallocmem = malloc(16777216);
nomalloctop = nomallocmem + 16777216;
nomallocptr = nomallocmem;
}