-/* jit/parseRT.c - parser and print functions for Rapid Type Analyis
+/* src/vm/jit/inline/parseRT.c - parser and print functions for Rapid Type
+ Analyis
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
- M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+ R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+ C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+ Institut f. Computersprachen - TU Wien
This file is part of CACAO.
Authors: Carolyn Oates
- $Id: parseRT.c 1469 2004-11-08 21:08:13Z carolyn $
+ Changes: Christian Thalinger
-Changes:
-opcode put into functions
-changed class_findmethod class_fetchmethod
+ $Id: parseRT.c 4000 2005-12-22 14:05:01Z twisti $
*/
/***************
+ Rapid Type Static Analysis of Java program
+ used -rt option is turned on either explicitly
+ or automatically with inlining of virtuals.
USAGE:
Methods called by NATIVE methods and classes loaded dynamically
Results: (currently) with -stat see # methods marked used
-TODO: end analysis if mono- or polymorphic call (in parseRTstats)
****************/
+
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include "tables.h"
-
-#include "statistics.h"
-#include "loader.h"
-#include "main.h"
-#include "options.h"
-#include "jit/jit.h"
-#include "jit/parse.h"
+
+#include "config.h"
+#include "cacao/cacao.h"
+#include "mm/memory.h"
#include "toolbox/list.h"
-#include "toolbox/memory.h"
-#include "parseRT.h"
-#include "parseRTstats.h"
+#include "toolbox/logging.h"
+#include "vm/class.h"
+#include "vm/linker.h"
+#include "vm/loader.h"
+#include "vm/resolve.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/parse.h"
+#include "vm/jit/inline/parseRT.h"
+#include "vm/jit/inline/parseRTstats.h"
+#include "vm/jit/inline/parseRTprint.h"
+
+
static bool firstCall= true;
static list *rtaWorkList;
FILE *rtMissed; /* Methods missed during RTA parse of Main */
+
+bool RTA_DEBUGinf = false;
+bool RTA_DEBUGr = false;
+bool RTA_DEBUGopcodes = false;
-#define LAZYLOADING(class) { \
- if (!class_load(class)) \
- return 0; \
- if (!class_link(class)) \
- return 0; }
-
-bool DEBUGr = false;
-bool DEBUGopcodes = false;
-
-#define METHINFO(mm) \
-if (DEBUGr == true) { \
- printf("<c%i/m%i/p%i>\t", \
- mm->class->classUsed,mm->methodUsed, mm->monoPoly); \
- utf_display(mm->class->name); printf("."); fflush(stdout); \
- method_display(mm); fflush(stdout); }
-
-#define METHINFOt(mm,TXT) \
-if (DEBUGr == true) { \
- printf(TXT); \
- printf("<c%i/m%i/p%i>\t", \
- mm->class->classUsed,mm->methodUsed, mm->monoPoly); \
- utf_display(mm->class->name); printf("."); fflush(stdout); \
- method_display(mm); fflush(stdout); }
-
-#define CLASSNAME1(cls,TXT) \
-if (DEBUGr == true) {printf(TXT); \
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); fflush(stdout);}
-
-#define CLASSNAMEop(cls) \
-if (DEBUGr == true) {printf("\t%s: ",opcode_names[opcode]);\
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); printf("\n");fflush(stdout);}
-
-#define CLASSNAME(cls,TXT) \
-if (DEBUGr == true) { printf(TXT); \
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); printf("\n");fflush(stdout);}
-
-#define SHOWOPCODE \
-if (DEBUGopcodes == true) {printf("Parse p=%i<%i< opcode=<%i> %s\n", \
- p, m->jcodelength,opcode,opcode_names[opcode]);}
+
/*********************************************************************/
if (meth->methodUsed == USED) return;
if (!(meth->flags & ACC_ABSTRACT)) {
+#if defined(ENABLE_STATISTICS)
count_methods_marked_used++;
- METHINFOt(meth,info)
- if (meth->class->super != NULL) {
- CLASSNAME(meth->class->super,"\tsuper=")
+#endif
+ METHINFOt(meth,info,RTA_DEBUGopcodes)
+ if (meth->class->super.cls != NULL) {
+ CLASSNAME(meth->class->super.cls,"\tsuper=",RTA_DEBUGr)
}
else {
- if (DEBUGr) printf("\tsuper=NULL\n");}
+ if (RTA_DEBUGr) printf("\tsuper=NULL\n");}
fflush(stdout);
meth ->methodUsed = USED;
rta = NEW(rtaNode);
rta->method = meth ;
list_addlast(rtaWorkList,rta);
-if (meth->class->classUsed == NOTUSED)
- panic("\nADDED method in class not used at all!\n");
+if (meth->class->classUsed == NOTUSED) {
+ METHINFOx(meth)
+ printf("\nADDED method in class not used at all!\n");
+ fflush(stdout);
+ }
}
/***
else {
printf("Method not added to work list!!!<%i> : ",
meth->methodUsed); fflush(stdout);
- METHINFO(meth)
+ METHINFO(meth,true)
}
***/
}
+/**************************************************************************/
+void rtaMarkSubs(classinfo *class, methodinfo *topmethod);
+
+/*------------------------------------------------------------------------*/
+void rtaAddUsedInterfaceMethods(classinfo *ci) {
+ int jj,mm;
+
+ /* add used interfaces methods to callgraph */
+ for (jj=0; jj < ci -> interfacescount; jj++) {
+ classinfo *ici = ci -> interfaces [jj].cls;
+
+ if (RTA_DEBUGinf) {
+ 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 (RTA_DEBUGinf) {
+ 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 (RTA_DEBUGinf) {
+ printf("Interface Method used: "); utf_display(ici->name);printf(".");method_display(imi);fflush(stdout);
+
+ /* Mark this method used in the (used) implementing class and its subclasses */
+ printf("rMAY ADD methods that was used by an interface\n");
+ }
+ if ((utf_clinit != imi->name) &&
+ (utf_init != imi->name))
+ rtaMarkSubs(ci,imi);
+ }
+ }
+ }
+ }
+
+}
+
+
/**************************************************************************/
/* Add Marked methods for input class ci */
/* Add methods with the same name and descriptor as implemented interfaces*/
addToRtaWorkList(mi,
"addTo was MARKED:");
}
- else {
+ else { /*** ??? Should this be an else or ??? */
for (jj=0; jj < ci -> interfacescount; jj++) {
- classinfo *ici = ci -> interfaces [jj];
+ classinfo *ici = ci -> interfaces [jj].cls;
/* use resolve method....!!!! */
if (ici -> classUsed != NOTUSED) {
for (mm=0; mm< ici->methodscount; mm++) {
methodinfo *imi = &(ici->methods[mm]);
+ METHINFOt(imi,"NEW IMPD INTERFACE:",RTA_DEBUGinf)
/*if interface method=method is used*/
if ( (imi->methodUsed == USED)
&& ( (imi->name == mi->name)
}
}
+#define CLINITS_T true
+#define FINALIZE_T true
+#define ADDMARKED_T true
+#define CLINITS_F false
+#define FINALIZE_F false
+#define ADDMARKED_F false
/*********************************************************************/
-void addClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark)
+void RTAaddClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark)
{
methodinfo *mi;
if (clinits) { /* No <clinit> available - ignore */
mi = class_findmethod(ci,
- utf_new_char("<clinit>"),
- utf_new_char("()V"));
+ utf_clinit,
+ utf_void__void);
if (mi) {
if (ci->classUsed != USED)
ci->classUsed = PARTUSED;
if (finalizes) {
mi = class_findmethod(ci,
utf_new_char("finalize"),
- utf_new_char("()V"));
+ utf_void__void);
if (mi) {
if (ci->classUsed != USED)
ci->classUsed = PARTUSED;
if (addmark) {
rtaAddMarkedMethods(ci);
}
+ rtaAddUsedInterfaceMethods(ci);
}
/* See if method defined in class heirarchy */
submeth = class_resolvemethod(class, name, descriptor);
-if (submeth == NULL)
- panic("parse RT: Method not found in class hierarchy");
+METHINFOt(submeth,"rtaMarkMethod submeth:",RTA_DEBUGr);
+if (submeth == NULL) {
+ utf_display(class->name); printf(".");
+ METHINFOx(topmethod);
+ printf("parse RT: Method not found in class hierarchy");fflush(stdout);
+ assert(0);
+ }
if (submeth->methodUsed == USED) return;
#undef CTA
#ifdef CTA
/* Class Type Analysis if class.method in virt cone marks it used */
/* very inexact, too many extra methods */
- addClassInit( submeth->class,
- true,true,true);
+ RTAaddClassInit( submeth->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);
submeth->monoPoly = POLY;
addToRtaWorkList(submeth,
"addTo RTA VIRT CONE:");
/* Class IS NOT marked USED (PART or NOTUSED) */
/* -> if Method NOTUSED mark method as MARKED */
METHINFOt(submeth,
- "\tmarked VIRT CONE 2:");
+ "\tmarked VIRT CONE 2:",RTA_DEBUGr);
submeth->monoPoly = POLY;
submeth->methodUsed = MARKED;
/* Note: if class NOTUSED and subclass is used handled */
else {
/*--- Method NOT defined in class ---------------*/
+ /* then check class the method could be called with */
+
/* first mark classes if needed */
if (submeth->class->classUsed == NOTUSED) {
submeth->class->classUsed = PARTUSED;
if (class->classUsed != USED) {
submeth->monoPoly = POLY;
submeth->methodUsed = MARKED;
- METHINFOt(submeth,"JUST MARKED :");
+ METHINFOt(submeth,"JUST MARKED :",RTA_DEBUGr);
}
}
/* add method to rta work list if conditions met */
- //if ( (submeth->class->classUsed == USED) ||
+ /*??if ( (submeth->class->classUsed == USED) || */
if (class->classUsed == USED) {
submeth->monoPoly = POLY;
addToRtaWorkList(submeth,
void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
/* Mark method in class */
- CLASSNAME1(class," MARKSUBS ");
- METHINFOt(topmethod," TOP ");
+ CLASSNAME1(class," MARKSUBS ",RTA_DEBUGr);
+ METHINFOt(topmethod," TOP ",RTA_DEBUGr);
rtaMarkMethod(class, topmethod);
/* Mark method in subclasses */
if (!(topmethod->flags & ACC_FINAL )) {
for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- CLASSNAME1(subs," SUBS ");
+ CLASSNAME1(subs," SUBS ",RTA_DEBUGr);
rtaMarkSubs(subs, topmethod);
}
}
subs = mi->class->impldBy;
/*RTAPRINT08invokeInterface1*/
+ if (RTA_DEBUGinf) {
+ METHINFO(mi,RTA_DEBUGinf)
+ printf("Implemented By classes :\n");fflush(stdout);
+ if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n");
+ fflush(stdout);
+ }
while (subs != NULL) {
classinfo * isubs = subs->classType;
- /*RTAPRINT09invokeInterface2*/
- /* Mark method (mark/used) in classes that implement the method */
- if (isubs->classUsed != NOTUSED) {
- methodinfo *submeth;
-
- submeth = class_findmethod(isubs,mi->name, mi->descriptor);
- if (submeth != NULL)
- submeth->monoPoly = POLY; /* poly even if nosubs */
- rtaMarkSubs(isubs, mi);
+ methodinfo *submeth;
+ if (RTA_DEBUGinf) {
+ printf("\t");utf_display(isubs->name);fflush(stdout);
+ printf(" <%i>\n",isubs->classUsed);fflush(stdout);
}
+ /*Mark method (mark/used) in classes that implement method*/
+
+ submeth = class_findmethod(isubs,mi->name, mi->descriptor);
+ if (submeth != NULL)
+ submeth->monoPoly = POLY; /* poly even if nosubs */
+ rtaMarkSubs(isubs, mi);
subs = subs->nextClass;
} /* end while */
}
-
/*********************************************************************/
int parseRT(methodinfo *m)
bool iswide = false; /* true if last instruction was a wide*/
int rc = 1;
-METHINFOt(m,"\n----RT PARSING:");
-if (DEBUGr) printf("\n");
+METHINFOt(m,"\n----RT PARSING:",RTA_DEBUGopcodes);
+if ((RTA_DEBUGr)||(RTA_DEBUGopcodes)) printf("\n");
/* scan all java instructions */
for (p = 0; p < m->jcodelength; p = nextp) {
opcode = code_get_u1(p,m); /* fetch op code */
- SHOWOPCODE
+ SHOWOPCODE(RTA_DEBUGopcodes)
nextp = p + jcommandsize[opcode]; /* compute next instrtart */
- if (nextp > m->jcodelength)
- panic("Unexpected end of bytecode");
+ if (nextp > m->jcodelength) {
+ log_text("Unexpected end of bytecode");
+ assert(0);
+ }
switch (opcode) {
{
constant_FMIref *fr;
fieldinfo *fi;
+ classinfo *frclass;
fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
- LAZYLOADING(fr->class)
+ if (!fr)
+ return 0;
+ if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
+ log_text("Could not resolve class reference");
+ assert(0);
+ }
- fi = class_resolvefield(fr->class,
+ LAZYLOADING(frclass);
+
+ fi = class_resolvefield(frclass,
fr->name,
fr->descriptor,
m->class,
true);
if (!fi)
- return 0; // was NULL
-
- CLASSNAME(fi->class,"\tPUTSTATIC: ");
- if (!fi->class->initialized) {
- m->isleafmethod = false;
- }
- addClassInit( fi->class,
- true,true,false);
+ return 0; /* was NULL */
+
+ CLASSNAME(fi->class,"\tPUT/GETSTATIC: ",RTA_DEBUGr);
+ RTAaddClassInit( fi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_F);
}
break;
- case JAVA_INVOKESTATIC:
- case JAVA_INVOKESPECIAL:
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *mr;
- methodinfo *mi;
- m->isleafmethod = false;
- mr = class_getconstant(m->class, i, CONSTANT_Methodref);
- LAZYLOADING(mr->class)
- mi = class_resolveclassmethod(mr->class,
- mr->name,
- mr->descriptor,
- m->class,
- false);
+
+ case JAVA_INVOKESTATIC:
+ case JAVA_INVOKESPECIAL:
+ i = code_get_u2(p + 1,m);
+ {
+ constant_FMIref *mr;
+ methodinfo *mi;
+ classinfo *mrclass;
+
+ mr = class_getconstant(m->class, i, CONSTANT_Methodref);
+ if (!mr)
+ return 0;
+ if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
+ log_text("Could not resolve class reference");
+ assert(0);
+ }
+ LAZYLOADING(mrclass)
+ mi = class_resolveclassmethod( mrclass,
+ mr->name,
+ mr->descriptor,
+ m->class,
+ false);
if (mi)
{
+ METHINFOt(mi,"INVOKESTAT/SPEC:: ",RTA_DEBUGopcodes)
mi->monoPoly = MONO;
+
+ /*---- Handle "leaf" = static, private, final calls----------------------------*/
if ((opcode == JAVA_INVOKESTATIC)
|| (mi->flags & ACC_STATIC)
|| (mi->flags & ACC_PRIVATE)
|| (mi->flags & ACC_FINAL) )
- {
- if (mi->class->classUsed == NOTUSED){
- addClassInit( mi->class,
- true,true,false);
- if (mi->class->classUsed == NOTUSED){
- mi->class->classUsed = PARTUSED; }
- }
- if (mi->class->classUsed == NOTUSED) {
- METHINFOt(mi,"WAS / WARUM 1")
- panic("WAS /WARUM 1 ????");
- }
- if (opcode == JAVA_INVOKESTATIC)
- addToRtaWorkList(mi,
- "addTo INVOKESTATIC ");
- else
- addToRtaWorkList(mi,
- "addTo INVOKESPECIAL ");
- }
+ {
+ if (mi->class->classUsed != USED){ /* = NOTUSED or PARTUSED */
+ RTAaddClassInit(mi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);
+ /* Leaf methods are used whether class is or not */
+ /* so mark class as PARTlyUSED */
+ mi->class->classUsed = PARTUSED;
+ }
+ /* Add to RTA working list/set of reachable methods */
+ if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
+ addToRtaWorkList(mi,
+ "addTo INVOKESTATIC ");
+ else
+ addToRtaWorkList(mi,
+ "addTo INVOKESPECIAL ");
+ }
+
else {
- /* Handle special <init> calls */
-
- /* for now same as rest */
- if (mi->class->classUsed == NOTUSED){
- /* RTA special case:
- call of super's <init> then
- methods of super class not all used */
- if (utf_new_char("<init>")==mi->name) {
- if (m->class->super == mi->class) {
- /* super init */
- addClassInit(mi->class,
- true,true,false);
- if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
- }
- else {
- addClassInit(mi->class,
- true,true,true);
- }
- }
- if (utf_new_char("<clinit>")==mi->name)
- addClassInit( mi->class,
- true,true,false);
-
- if (!((utf_new_char("<init>")==mi->name))
- || (utf_new_char("<clinit>")==mi->name)) {
- METHINFOt(mi,"SPECIAL not init:")
- addClassInit( mi->class,
- true,true,true);
- }
- }
-
- if (utf_new_char("<init>")==mi->name) {
- if (mi->class->classUsed == NOTUSED) {
- METHINFOt(mi,"WAS / WARUM 2")
- panic("WAS /WARUM 2 ????");
- }
+ /*---- Handle special <init> calls ---------------------------------------------*/
+
+ if (mi->class->classUsed != USED) {
+ /* RTA special case:
+ call of super's <init> then
+ methods of super class not all used */
+
+ /*--- <init> ()V is equivalent to "new"
+ indicating a class is used = instaniated ---- */
+ if (utf_init==mi->name) {
+ if ((m->class->super.cls == mi->class)
+ && (m->descriptor == utf_void__void) )
+ {
+ METHINFOt(mi,"SUPER INIT:",RTA_DEBUGopcodes);
+ /* super init so class may be only used because of its sub-class */
+ RTAaddClassInit(mi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_F);
+ if (mi->class->classUsed == NOTUSED) mi->class->classUsed = PARTUSED;
+ }
+ else {
+ /* since <init> indicates classes is used, then add marked methods, too */
+ METHINFOt(mi,"NORMAL INIT:",RTA_DEBUGopcodes);
+ RTAaddClassInit(mi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);
+ }
+ addToRtaWorkList(mi,
+ "addTo INIT ");
+ } /* end just for <init> ()V */
+
+ /* <clinit> for class inits do not add marked methods; class not yet instaniated */
+ if (utf_clinit==mi->name)
+ RTAaddClassInit( mi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_F);
+
+ if (!((utf_init==mi->name))
+ || (utf_clinit==mi->name)) {
+ METHINFOt(mi,"SPECIAL not init:",RTA_DEBUGopcodes)
+ if (mi->class->classUsed !=USED)
+ mi->class->classUsed = PARTUSED;
+ addToRtaWorkList(mi,
+ "addTo SPEC notINIT ");
+ }
+
+ } /* end init'd class not used = class init process was needed */
+
+ /* add method to RTA list = set of reachable methods */
addToRtaWorkList(mi,
- "addTo INVOKESPECIAL ");
- }
- }
+ "addTo SPEC whymissed ");
+ } /* end inits */
}
/*** assume if method can't be resolved won't actually be called or
there is a real error in classpath and in normal parse an exception
will be thrown. Following debug print can verify this
else from if (mi) {
-CLASSNAME1(mr->class,"CouldNOT Resolve method:");printf(".");fflush(stdout);
+CLASSNAME1(mr->class,"CouldNOT Resolve method:",,RTA_DEBUGr);printf(".");fflush(stdout);
utf_display(mr->name); printf(" "); fflush(stdout);
utf_display(mr->descriptor); printf("\n");fflush(stdout);
***/
{
constant_FMIref *mr;
methodinfo *mi;
+ classinfo *mrclass;
- m->isleafmethod = false;
+ /* XXX why this direct access, this should not be! */
mr = m->class->cpinfos[i];
/*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
- LAZYLOADING(mr->class)
- mi = class_resolveclassmethod(mr->class,
+ if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
+ log_text("Could not resolve class reference");
+ assert(0);
+ }
+
+ LAZYLOADING(mrclass)
+ mi = class_resolveclassmethod(mrclass,
mr->name,
mr->descriptor,
m->class,
if (mi)
{
- METHINFOt(mi,"INVOKEVIRTUAL ::");
+ METHINFOt(mi,"INVOKEVIRTUAL ::",RTA_DEBUGopcodes);
if ((mi->flags & ACC_STATIC)
|| (mi->flags & ACC_PRIVATE)
|| (mi->flags & ACC_FINAL) )
{
if (mi->class->classUsed == NOTUSED){
- addClassInit(mi->class,
- true,true,true);
+ RTAaddClassInit(mi->class,
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);
}
mi->monoPoly = MONO;
addToRtaWorkList(mi,
}
}
else {
-CLASSNAME1(mr->class,"CouldNOT Resolve virt meth:");printf(".");fflush(stdout);
+CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",RTA_DEBUGr);printf(".");fflush(stdout);
utf_display(mr->name); printf(" "); fflush(stdout);
utf_display(mr->descriptor); printf("\n");fflush(stdout);
}
{
constant_FMIref *mr;
methodinfo *mi;
-
- m->isleafmethod = false;
+ classinfo *mrclass;
mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
- LAZYLOADING(mr->class)
+ if (!mr)
+ return 0;
+ if (!resolve_classref(m,mr->classref,resolveEager,true, true,&mrclass)) {
+ log_text("Could not resolve class reference");
+ assert(0);
+ }
+
+ LAZYLOADING(mrclass)
- mi = class_resolveinterfacemethod(mr->class,
+ mi = class_resolveinterfacemethod(mrclass,
mr->name,
mr->descriptor,
m->class,
false);
if (mi)
{
- METHINFOt(mi,"\tINVOKEINTERFACE: ")
+ METHINFOt(mi,"\tINVOKEINTERFACE: ",RTA_DEBUGopcodes)
rtaMarkInterfaceSubs(mi);
}
/* see INVOKESTATIC for explanation about */
/* case when Interface is not resolved */
- //descriptor2types(mi); ?? do need paramcnt?
+ /*method_descriptor2types(mi);
+ ?? do need paramcnt? for RTA (or just XTA)*/
}
break;
/* class is really instantiated when class.<init> called*/
i = code_get_u2(p + 1,m);
{
- classinfo *ci;
- ci = class_getconstant(m->class, i, CONSTANT_Class);
- m->isleafmethod = false; /* why for new ? */
- // s_count++; look for s_counts for VTA
- //ci->classUsed=USED;
+ constant_classref *cr;
+ classinfo *ci;
+ cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
+ if (!cr)
+ return 0;
+ resolve_classref(NULL,cr,resolveEager,true, false,&ci);
+ /*** s_count++; look for s_counts for VTA */
/* add marked methods */
- CLASSNAME(ci,"NEW : do nothing");
+ CLASSNAME(ci,"NEW : do nothing",RTA_DEBUGr);
+ RTAaddClassInit(ci, CLINITS_T, FINALIZE_T,ADDMARKED_T);
}
break;
/* class used */
i = code_get_u2(p + 1,m);
{
- classinfo *cls =
- (classinfo *)
- class_getconstant(m->class, i, CONSTANT_Class);
+ constant_classref *cr;
+ classinfo *cls;
+
+ cr = (constant_classref*) class_getconstant(m->class, i, CONSTANT_Class);
+ if (!cr)
+ return 0;
+ resolve_classref(NULL,cr,resolveEager,true, false,&cls);
+
LAZYLOADING(cls)
- CLASSNAMEop(cls);
+ CLASSNAMEop(cls,RTA_DEBUGr);
if (cls->classUsed == NOTUSED){
- addClassInit(cls,
- true,true,true);
+ RTAaddClassInit(cls,
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);
}
}
break;
/* Helper fn for initialize **********************************************/
-int getline(char *line, int max, FILE *inFP) {
+int RTAgetline(char *line, int max, FILE *inFP) {
if (fgets(line, max, inFP) == NULL)
return 0;
else
/*-- Get meth ptr for class.meth desc and add to RTA worklist --*/
#define SYSADD(cls,meth,desc,txt) \
- c = class_new(utf_new_char(cls)); \
+ c = load_class_bootstrap(utf_new_char(cls)); \
LAZYLOADING(c) \
callmeth = class_resolveclassmethod(c, \
utf_new_char(meth), \
false); \
if (callmeth->class->classUsed != USED) { \
c->classUsed = PARTUSED; \
- addClassInit(callmeth->class, \
- true,true,true);\
+ RTAaddClassInit(callmeth->class, \
+ CLINITS_T,FINALIZE_T,ADDMARKED_T);\
} \
callmeth->monoPoly = POLY; \
addToRtaWorkList(callmeth,txt);
-/*--
- Initialize RTA work list with methods/classes from:
+/*-- -----------------------------------------------------------------------------
System calls
and
rtMissedIn list (missed becaused called from NATIVE &/or dynamic calls
---*/
+ *-- -----------------------------------------------------------------------------*/
methodinfo *initializeRTAworklist(methodinfo *m) {
classinfo *c;
methodinfo* callmeth;
- char systxt[] = "System Call :";
+ char systxt[] = "System Call :";
char missedtxt[] = "rtMissedIn Call :";
FILE *rtMissedIn; /* Methods missed during previous RTA parse */
char line[256];
char* class, *meth, *desc;
- char filename[256] = "rtMissed";
methodinfo *rm =NULL; /* return methodinfo ptr to main method */
/* Add first method to call list */
m->class->classUsed = USED;
addToRtaWorkList(m,systxt);
-
/* Add system called methods */
- SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt)
+/*** SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt) ***/
+ SYSADD(MAINCLASS, MAINMETH, MAINDESC,systxt)
rm = callmeth;
- SYSADD("java/lang/Runtime","getRuntime","()Ljava/lang/Runtime;",systxt)
- SYSADD("java/lang/Runtime","exit","(I)V",systxt)
-
+/*** SYSADD("java/lang/System","exit","(I)V",systxt) ***/
+ SYSADD(EXITCLASS, EXITMETH, EXITDESC, systxt)
/*----- rtMissedIn 0 */
if ( (rtMissedIn = fopen("rtMissedIn0", "r")) == NULL) {
- //if (verbose)
+ /*if (opt_verbose) */
{printf("No rtMissedIn0 file\n");fflush(stdout);}
return rm;
}
- while (getline(line,256,rtMissedIn)) {
+ while (RTAgetline(line,256,rtMissedIn)) {
class = strtok(line, " \n");
meth = strtok(NULL, " \n");
desc = strtok(NULL, " \n");
}
fclose(rtMissedIn);
+
+
+
+ return rm;
+
+}
+
+/*- end initializeRTAworklist-------- */
+
+
+
+/*-------------------------------------------------------------------------------*/
+methodinfo *missedRTAworklist()
+{
+ FILE *rtMissedIn; /* Methods missed during previous RTA parse */
+ char filenameIn[256] = "rtIn/";
+ char line[256];
+ char* class, *meth, *desc;
+ char missedtxt[] = "rtIn/ missed Call :";
+ classinfo *c;
+ methodinfo* callmeth;
+
+ methodinfo *rm =NULL; /* return methodinfo ptr to main method */
+
+
+#if defined(USE_THREADS)
+ SYSADD(THREADCLASS, THREADMETH, THREADDESC, "systxt2")
+ SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, "systxt2")
+#endif
/*----- rtMissedIn pgm specific */
- strcat(filename, (const char *)mainstring);
- if ( (rtMissedIn = fopen(filename, "r")) == NULL) {
- //if (verbose)
- {printf("No rtMissedIn=%s file\n",filename);fflush(stdout);}
+ strcat(filenameIn, (const char *)mainstring);
+ if ( (rtMissedIn = fopen(filenameIn, "r")) == NULL) {
+ /*if (opt_verbose)*/
+ {printf("No rtIn/=%s file\n",filenameIn);fflush(stdout);}
return rm;
}
- while (getline(line,256,rtMissedIn)) {
+ while (RTAgetline(line,256,rtMissedIn)) {
class = strtok(line, " \n");
meth = strtok(NULL, " \n");
desc = strtok(NULL, " \n");
- SYSADD(class,meth,desc,missedtxt)
+ if ((class == NULL) || (meth == NULL) || (desc == NULL)) {
+ log_text("Error in rtMissedIn file for: class.meth, desc");
+ assert(0);
}
+ SYSADD(class,meth,desc,missedtxt)
+ }
fclose(rtMissedIn);
+
return rm;
}
-/*- end initializeRTAworklist-------- */
+/*--------------------------------------------------------*/
+/* parseRTmethod */
+/* input: method to be RTA static parsed */
+/*--------------------------------------------------------*/
+void parseRTmethod(methodinfo *rt_method) {
+ if (! ( (rt_method->flags & ACC_NATIVE )
+ || (rt_method->flags & ACC_ABSTRACT) ) )
+ {
+ /* RTA parse to approxmate....
+ what classes/methods will really be used during execution */
+ parseRT(rt_method);
+ }
+ else {
+ if (rt_method->flags & ACC_NATIVE )
+ {
+ METHINFOt(rt_method,"TO BE NATIVE RTA PARSED :",RTA_DEBUGopcodes);
+ /* parseRTpseudo(rt_method); */
+ }
+ else {
+ printf("Abstract method in RTA Work List: ");
+ METHINFOx(rt_method);
+ log_text("Abstract method in RTA Work List.");
+ assert(0);
+ }
+ }
+}
+
/*-- RTA -- *******************************************************/
int RT_jit_parse(methodinfo *m)
{
- methodinfo *rt_method;
rtaNode *rta;
methodinfo *mainmeth;
/* Should only be called once */
if (firstCall) {
- firstCall = false; /* turn flag off */
/*----- RTA initializations --------*/
- if (verbose)
+ if (opt_verbose)
log_text("RTA static analysis started.\n");
mainmeth = initializeRTAworklist(m);
+ firstCall = false; /* turn flag off */
if ( (rtMissed = fopen("rtMissed", "w")) == NULL) {
printf("CACAO - rtMissed file: cant open file to write\n");
rta != NULL;
rta =list_next(rtaWorkList,rta))
{
- rt_method = rta->method;
- if (! ( (rt_method->flags & ACC_NATIVE )
- || (rt_method->flags & ACC_ABSTRACT) ) )
- {
- /* RTA parse to approxmate....
- what classes/methods will really be used during execution */
- parseRT(rt_method);
- }
- else {
- if (rt_method->flags & ACC_NATIVE )
- {
- METHINFOt(rt_method,"TO BE NATIVE RTA PARSED :")
- /* parseRTpseudo(rt_method); */
- }
- else {
- printf("Abstract method in RTA Work List: ");
- METHINFO(rt_method);
- panic("Abstract method in RTA Work List.");
- }
- }
+ parseRTmethod(rta->method);
}
+ missedRTAworklist();
+ for (rta =list_first(rtaWorkList);
+ rta != NULL;
+ rta =list_next(rtaWorkList,rta))
+ {
+ parseRTmethod(rta->method);
+ }
+
fclose(rtMissed);
- if (verbose) {
+ if (opt_verbose) {
if (opt_stat) {
printRThierarchyInfo(m);
}
printCallgraph(rtaWorkList);
}
- if (verbose) {
+ if (opt_verbose) {
log_text("RTA static analysis done.\n");
}
}
* tab-width: 4
* End:
*/
+