+++ /dev/null
-/* src/vm/jit/inline/parseRT.c - parser and print functions for Rapid Type
- Analyis
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- Changes: Christian Thalinger
-
- $Id: parseRT.c 4357 2006-01-22 23:33:38Z 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
- cannot be found by parsing. The following files supply missing methods:
-
- rtMissedIn0 - (provided) has the methods missed by every java program
- rtMissed||mainClassName - is program specific.
-
- A file rtMissed will be written by RT analysis of any methods missed.
-
- This file can be renamed to rtMissed concatenated with the main class name.
-
- Example:
- ./cacao -rt hello
-
- inlining with virtuals should fail if the returned rtMissed is not empty.
- so...
- mv rtMissed rtMissedhello
- ./cacao hello
-
-Results: (currently) with -stat see # methods marked used
-
-****************/
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-#include "cacao/cacao.h"
-#include "mm/memory.h"
-#include "toolbox/list.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;
-
-
-
-/*********************************************************************/
-
-void addToRtaWorkList(methodinfo *meth, char *info) {
- rtaNode *rta;
-
-if (meth->methodUsed == USED) return;
-
-if (!(meth->flags & ACC_ABSTRACT)) {
-#if defined(ENABLE_STATISTICS)
- count_methods_marked_used++;
-#endif
- METHINFOt(meth,info,RTA_DEBUGopcodes)
- if (meth->class->super.cls != NULL) {
- CLASSNAME(meth->class->super.cls,"\tsuper=",RTA_DEBUGr)
- }
- else {
- 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) {
- 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,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_println(imi);fflush(stdout);
- }
- }
- if (imi->methodUsed == USED) {
- if (RTA_DEBUGinf) {
- printf("Interface Method used: "); utf_display(ici->name);printf(".");method_println(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*/
-/* with the same method name */
-/* */
-/*------------------------------------------------------------------------*/
-void rtaAddMarkedMethods(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) {
- addToRtaWorkList(mi,
- "addTo was MARKED:");
- }
- else { /*** ??? Should this be an else or ??? */
- for (jj=0; jj < ci -> interfacescount; 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)
- && (imi->descriptor == mi->descriptor))) {
- addToRtaWorkList(mi,
- "addTo was interfaced used/MARKED:");
- }
- } /*end for */
- }
- }
- }
- }
-}
-
-#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 RTAaddClassInit(classinfo *ci, bool clinits, bool finalizes, bool addmark)
-{
- methodinfo *mi;
-
- if (addmark)
- ci->classUsed = USED;
-
- if (clinits) { /* No <clinit> available - ignore */
- mi = class_findmethod(ci,
- utf_clinit,
- utf_void__void);
- if (mi) {
- if (ci->classUsed != USED)
- ci->classUsed = PARTUSED;
- mi->monoPoly = MONO;
- addToRtaWorkList(mi,"addTo CLINIT added:");
- }
- }
-
- /*Special Case for System class init:
- add java/lang/initializeSystemClass to callgraph */
- if (ci->name == utf_new_char("initializeSystemClass")) {
- /* ?? what is name of method ?? */
- }
-
- if (finalizes) {
- mi = class_findmethod(ci,
- utf_new_char("finalize"),
- utf_void__void);
- if (mi) {
- if (ci->classUsed != USED)
- ci->classUsed = PARTUSED;
- mi->monoPoly = MONO;
- addToRtaWorkList(mi,"addTo FINALIZE added:");
- }
- }
-
- if (addmark) {
- rtaAddMarkedMethods(ci);
- }
- rtaAddUsedInterfaceMethods(ci);
-
-}
-
-
-/*--------------------------------------------------------------*/
-/* Mark the method with same name /descriptor in topmethod */
-/* in class */
-/* */
-/* Class marked USED and method defined in this class -> */
-/* -> mark method as USED */
-/* Class not marked USED and method defined in this class -> */
-/* -> if Method NOTUSED mark method as MARKED */
-/* */
-/* Class USED, but method not defined in this class -> */
-/* -> 1) search up the heirarchy and mark method where defined */
-/* 2) if class where method is defined is not USED -> */
-/* -> mark class with defined method as PARTUSED */
-/*--------------------------------------------------------------*/
-
-void rtaMarkMethod(classinfo *class, methodinfo *topmethod) {
-
-utf *name = topmethod->name;
-utf *descriptor = topmethod->descriptor;
-methodinfo *submeth;
-
-/* See if method defined in class heirarchy */
-submeth = class_resolvemethod(class, name, descriptor);
-METHINFOt(submeth,"rtaMarkMethod submeth:",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 */
- RTAaddClassInit( submeth->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- submeth->monoPoly = POLY;
- addToRtaWorkList(submeth,
- "addTo RTA VIRT CONE:");
- return;
-#endif
-
- if (submeth->class == class) {
-
- /*--- Method defined in class -----------------------------*/
- if ( submeth->class->classUsed == USED) {
- /* method defined in this class -> */
- /* Class IS marked USED */
- /* -> mark method as USED */
- submeth->monoPoly = POLY;
- addToRtaWorkList(submeth,
- "addTo VIRT CONE 1:");
- }
- else {
- /* method defined in this class -> */
- /* Class IS NOT marked USED (PART or NOTUSED) */
- /* -> if Method NOTUSED mark method as MARKED */
- METHINFOt(submeth,
- "\tmarked VIRT CONE 2:",RTA_DEBUGr);
- submeth->monoPoly = POLY;
- submeth->methodUsed = MARKED;
- /* Note: if class NOTUSED and subclass is used handled */
- /* by subsequent calls to rtaMarkMethods for cone */
- }
- } /* end defined in class */
-
- 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 :",RTA_DEBUGr);
- }
- }
- /* add method to rta work list if conditions met */
- /*??if ( (submeth->class->classUsed == USED) || */
- if (class->classUsed == USED) {
- submeth->monoPoly = POLY;
- addToRtaWorkList(submeth,
- "addTo VIRT CONE 3:");
- }
- } /* end NOT defined in class */
-
-}
-
-/*----------------------------------------------------------------------*/
-/* Mark the method with the same name and descriptor as topmethod */
-/* and any subclass where the method is defined and/or class is used */
-/* */
-/*----------------------------------------------------------------------*/
-void rtaMarkSubs(classinfo *class, methodinfo *topmethod) {
-
- /* Mark method in class */
- CLASSNAME1(class," MARKSUBS ",RTA_DEBUGr);
- METHINFOt(topmethod," TOP ",RTA_DEBUGr);
- rtaMarkMethod(class, topmethod);
-
- /* Mark method in subclasses */
- if (class->sub != NULL) {
- classinfo *subs;
-
- if (!(topmethod->flags & ACC_FINAL )) {
- for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- CLASSNAME1(subs," SUBS ",RTA_DEBUGr);
- rtaMarkSubs(subs, topmethod);
- }
- }
- }
- return;
-}
-
-
-/*********************************************************************/
-
-void rtaMarkInterfaceSubs(methodinfo *mi) {
- classSetNode *subs;
- if (mi->class->classUsed == NOTUSED) {
- mi->class->classUsed = USED;
- class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
- }
-
- /* add interface class to list kept in Object */
- mi->methodUsed = USED;
- mi->monoPoly = POLY;
-
- subs = mi->class->impldBy;
- /*RTAPRINT08invokeInterface1*/
- if (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;
- 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)
-{
- int p; /* java instruction counter */
- int nextp; /* start of next java instruction */
- int opcode; /* java opcode */
- int i; /* temp for different uses (counters)*/
- bool iswide = false; /* true if last instruction was a wide*/
- int rc = 1;
-
-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(RTA_DEBUGopcodes)
-
- nextp = p + jcommandsize[opcode]; /* compute next instrtart */
- if (nextp > m->jcodelength) {
- log_text("Unexpected end of bytecode");
- assert(0);
- }
-
- switch (opcode) {
-
- case JAVA_ILOAD:
- case JAVA_LLOAD:
- case JAVA_FLOAD:
- case JAVA_DLOAD:
- case JAVA_ALOAD:
-
- case JAVA_ISTORE:
- case JAVA_LSTORE:
- case JAVA_FSTORE:
- case JAVA_DSTORE:
- case JAVA_ASTORE:
-
- if (iswide) {
- nextp = p + 3;
- iswide = false;
- }
- break;
-
- case JAVA_IINC:
- {
-
- if (iswide) {
- iswide = false;
- nextp = p + 5;
- }
- }
- break;
-
- /* wider index for loading, storing and incrementing */
-
- case JAVA_WIDE:
- iswide = true;
- nextp = p + 1;
- break;
-
- case JAVA_RET:
- if (iswide) {
- nextp = p + 3;
- iswide = false;
- }
- break;
-
- case JAVA_LOOKUPSWITCH:
- {
- s4 num;
- nextp = ALIGN((p + 1), 4) + 4;
- num = code_get_u4(nextp,m);
- nextp += (code_get_u4(nextp,m)) * 8 + 4;
- break;
- }
-
-
- case JAVA_TABLESWITCH:
- {
- s4 num;
- nextp = ALIGN ((p + 1),4);
- num = code_get_s4(nextp + 4, m);
- num = code_get_s4(nextp + 8, m) - num;
- nextp = nextp + 16 + 4 * num;
- break;
- }
- /*********************/
- case JAVA_PUTSTATIC:
- case JAVA_GETSTATIC:
-
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *fr;
- fieldinfo *fi;
- classinfo *frclass;
-
- fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
- if (!fr)
- return 0;
- if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
- log_text("Could not resolve class reference");
- assert(0);
- }
-
- LAZYLOADING(frclass);
-
- fi = class_resolvefield(frclass,
- fr->name,
- fr->descriptor,
- m->class,
- true);
-
- if (!fi)
- 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;
- 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 != 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 ---------------------------------------------*/
-
- 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 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:",,RTA_DEBUGr);printf(".");fflush(stdout);
-utf_display(mr->name); printf(" "); fflush(stdout);
-utf_display(mr->descriptor); printf("\n");fflush(stdout);
-***/
- }
- break;
-
- case JAVA_INVOKEVIRTUAL:
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *mr;
- methodinfo *mi;
- classinfo *mrclass;
-
- /* XXX why this direct access, this should not be! */
- mr = m->class->cpinfos[i];
- /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
- 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,"INVOKEVIRTUAL ::",RTA_DEBUGopcodes);
- if ((mi->flags & ACC_STATIC)
- || (mi->flags & ACC_PRIVATE)
- || (mi->flags & ACC_FINAL) )
- {
- if (mi->class->classUsed == NOTUSED){
- RTAaddClassInit(mi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- }
- mi->monoPoly = MONO;
- addToRtaWorkList(mi,
- "addTo INVOKEVIRTUAL ");
- }
- else {
- mi->monoPoly = POLY;
- rtaMarkSubs(mi->class,mi);
- }
- }
- else {
-CLASSNAME1(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);
- }
- }
- break;
-
- case JAVA_INVOKEINTERFACE:
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *mr;
- methodinfo *mi;
- classinfo *mrclass;
-
- mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
- 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(mrclass,
- mr->name,
- mr->descriptor,
- m->class,
- false);
- if (mi)
- {
- METHINFOt(mi,"\tINVOKEINTERFACE: ",RTA_DEBUGopcodes)
- rtaMarkInterfaceSubs(mi);
- }
- /* see INVOKESTATIC for explanation about */
- /* case when Interface is not resolved */
- /*method_descriptor2types(mi);
- ?? do need paramcnt? for RTA (or just XTA)*/
- }
- break;
-
- case JAVA_NEW:
- /* means class is at least passed as a parameter */
- /* class is really instantiated when class.<init> called*/
- i = code_get_u2(p + 1,m);
- {
- 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",RTA_DEBUGr);
- RTAaddClassInit(ci, CLINITS_T, FINALIZE_T,ADDMARKED_T);
- }
- break;
-
- case JAVA_CHECKCAST:
- case JAVA_INSTANCEOF:
- /* class used */
- i = code_get_u2(p + 1,m);
- {
- 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,RTA_DEBUGr);
- if (cls->classUsed == NOTUSED){
- RTAaddClassInit(cls,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- }
- }
- break;
-
- default:
- break;
-
- } /* end switch */
-
- } /* end for */
-
- return rc;
-}
-
-/* Helper fn for initialize **********************************************/
-
-int RTAgetline(char *line, int max, FILE *inFP) {
-if (fgets(line, max, inFP) == NULL)
- return 0;
-else
- return strlen((const char *) line);
-}
-
-/* Initialize RTA Work list ***********************************************/
-
-/*-- Get meth ptr for class.meth desc and add to RTA worklist --*/
-#define SYSADD(cls,meth,desc,txt) \
- c = load_class_bootstrap(utf_new_char(cls)); \
- LAZYLOADING(c) \
- callmeth = class_resolveclassmethod(c, \
- utf_new_char(meth), \
- utf_new_char(desc), \
- c, \
- false); \
- if (callmeth->class->classUsed != USED) { \
- c->classUsed = PARTUSED; \
- RTAaddClassInit(callmeth->class, \
- CLINITS_T,FINALIZE_T,ADDMARKED_T);\
- } \
- callmeth->monoPoly = POLY; \
- addToRtaWorkList(callmeth,txt);
-
-
-/*-- -----------------------------------------------------------------------------
- System calls
- and
- rtMissedIn list (missed becaused called from NATIVE &/or dynamic calls
- *-- -----------------------------------------------------------------------------*/
-methodinfo *initializeRTAworklist(methodinfo *m) {
- classinfo *c;
- methodinfo* callmeth;
- char systxt[] = "System Call :";
- char missedtxt[] = "rtMissedIn Call :";
-
- FILE *rtMissedIn; /* Methods missed during previous RTA parse */
- char line[256];
- char* class, *meth, *desc;
- methodinfo *rm =NULL; /* return methodinfo ptr to main method */
-
-
- /* Create RTA call work list */
- rtaWorkList = NEW(list);
- list_init(rtaWorkList, OFFSET(rtaNode,linkage) );
-
- /* Add first method to call list */
- m->class->classUsed = USED;
- addToRtaWorkList(m,systxt);
- /* Add system called methods */
-/*** SYSADD(mainstring, "main","([Ljava/lang/String;)V",systxt) ***/
- SYSADD(MAINCLASS, MAINMETH, MAINDESC,systxt)
- rm = callmeth;
-/*** SYSADD("java/lang/System","exit","(I)V",systxt) ***/
- SYSADD(EXITCLASS, EXITMETH, EXITDESC, systxt)
- /*----- rtMissedIn 0 */
- if ( (rtMissedIn = fopen("rtMissedIn0", "r")) == NULL) {
- /*if (opt_verbose) */
- {printf("No rtMissedIn0 file\n");fflush(stdout);}
- return rm;
- }
- while (RTAgetline(line,256,rtMissedIn)) {
- class = strtok(line, " \n");
- meth = strtok(NULL, " \n");
- desc = strtok(NULL, " \n");
- SYSADD(class,meth,desc,missedtxt)
- }
- 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(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 (RTAgetline(line,256,rtMissedIn)) {
- class = strtok(line, " \n");
- meth = strtok(NULL, " \n");
- desc = strtok(NULL, " \n");
- 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;
-}
-
-
-
-/*--------------------------------------------------------*/
-/* 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)
-{
- rtaNode *rta;
- methodinfo *mainmeth;
-
- /* Should only be called once */
- if (firstCall) {
-
- /*----- RTA initializations --------*/
- 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");
- }
- /* Note: rtMissed must be renamed to rtMissedIn to be used as input */
-
- /*------ process RTA call work list --------*/
- for (rta =list_first(rtaWorkList);
- rta != NULL;
- rta =list_next(rtaWorkList,rta))
- {
- parseRTmethod(rta->method);
- }
- missedRTAworklist();
- for (rta =list_first(rtaWorkList);
- rta != NULL;
- rta =list_next(rtaWorkList,rta))
- {
- parseRTmethod(rta->method);
- }
-
- fclose(rtMissed);
- if (opt_verbose) {
- if (opt_stat) {
- printRThierarchyInfo(m);
- }
- printCallgraph(rtaWorkList);
- }
-
- if (opt_verbose) {
- log_text("RTA static analysis done.\n");
- }
- }
-return 0;
-}
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
-
+++ /dev/null
-/* jit/parseRT.h - RTA parser header
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- $Id: parseRT.h 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-#ifndef _PARSERT_H
-#define _PARSERT_H
-
-#include "vm/global.h"
-
-
-extern FILE *rtMissed; /* Methods missed during RTA parse of Main */
-
-typedef struct {
- listnode linkage;
- methodinfo *method;
- } rtaNode ;
-
-
-extern int RT_jit_parse(methodinfo *m);
-
-#endif /* _PARSERT_H */
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
-
+++ /dev/null
-/*------------- 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 = 2; /* 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*/
-
-/*-----------------------------------------------------------------------------------------------*/
-
-bool useXTAcallgraph = false;
-bool XTAOPTbypass = false;
-bool XTAOPTbypass2 = false; /* for now invokeinterface */
-bool XTAOPTbypass3 = false; /* print XTA classsets in stats */
-int XTAdebug = 0;
-int XTAfld = 0;
-
-
+++ /dev/null
-/*
- * Defines of debug / trace /info prints
- * to make the actual code more readable
- *
- * COtest prints are just debug
- * RTAprint prints are trace /info prints
- */
-
-#define METHINFOx(mm) \
- { \
- printf("<c%i/m%i/p%i>\t", \
- mm->class->classUsed,mm->methodUsed, mm->monoPoly); \
- method_println(mm); }
-
-#define METHINFO(mm,flg) \
-if (flg) { \
- printf("<c%i/m%i/p%i>\t", \
- mm->class->classUsed,mm->methodUsed, mm->monoPoly); \
- method_println(mm); }
-
-#define METHINFOtx(mm,TXT) \
- { \
- printf(TXT); \
- METHINFOx(mm) \
- }
-
-#define METHINFOt(mm,TXT,flg) \
-if (flg) { \
- printf(TXT); \
- METHINFO(mm,flg) \
- }
-
-#define CLASSNAME1(cls,TXT,flg) \
-if (flg) {printf(TXT); \
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); fflush(stdout);}
-
-#define CLASSNAMEop(cls,flg) \
-if (flg) {printf("\t%s: ",opcode_names[opcode]);\
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); printf("\n");fflush(stdout);}
-
-#define CLASSNAME(cls,TXT,flg) \
-if (flg) { printf(TXT); \
- printf("<c%i>\t",cls->classUsed); \
- utf_display(cls->name); printf("\n");fflush(stdout);}
-
-#define SHOWOPCODE(flg) \
-if (flg) {printf("Parse p=%i<%i< opcode=<%i> %s\n", \
- p, m->jcodelength,opcode,opcode_names[opcode]);}
-#define SHOWOPCODE1 \
- printf("<%i< opcode=<%i> %s\n", \
- m->jcodelength,opcode,opcode_names[opcode]);
-
-/*** old prints ******************************************/
-#ifdef OLDRT
-
-#include "parseRTstats.h"
-
-
-#define XTAPRINTcallgraph1 if(pWhenMarked>=1) \
- {printf("\n XTA Added to Call Graph #%i:", \
- methXTAlast); \
- 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_println(submeth);fflush(stdout);}
-
-#define XTAPRINTcallgraph2 if(pWhenMarked>=1) { \
- printf("\n XTA Added to Call Graph #%i:", \
- methXTAlast); \
- printf(" method name ="); fflush(stdout);\
- utf_display(mi->class->name);printf(".");fflush(stdout); \
- method_println(mi);fflush(stdout); \
- }
-
-#define RTAPRINTcallgraph1 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_println(meth);fflush(stdout);}
-
-
-#define RTAPRINTmarkMethod1 if (pWhenMarked >= 2) { \
- printf("<%i> Just Marking Method - class: <index=%i>\n", \
- submeth->methodUsed, \
- submeth->class->index); \
- utf_display(submeth->class->name); \
- method_println(submeth); \
- }
-
-#define RTAPRINTmarkMethod1aa if (pWhenMarked >= 2) { \
- printf("Top Method/Class Abstract -- init found\n"); \
- method_println(submeth); \
- }
-
-#define RTAPRINTmarkMethod1A if (pWhenMarked >= 2) { \
- printf("Top Method/Class Abstract -- Marking Method & init - & marking class used <%i>\n",class->index); \
- method_println(submeth); \
- }
-
-#define RTAPRINTmarkMethod2 if (pWhenMarked >= 2) { \
- printf("Class marked Used by Subtype :");utf_display(submeth->name);printf("\n");}
-
-#define RTAPRINTmarkSubs1 if (pWhenMarked>=3) { \
- utf *name = topmethod -> name; \
- printf("markMethod: "); utf_display(class->name); \
- printf(".");utf_display(name); printf("\n");}
-
-#define RTAPRINTmarkSubs2 if (pWhenMarked>=3) { \
- printf("markSubs: "); utf_display(subs->name);printf("."); \
- utf_display(name); printf("\n");}
-
-#define RTAPRINT01method if ((pOpcodes == 1) || (pOpcodes == 3)) \
- {printf("*********************************\n"); fflush(stdout); \
- printf("<%i/%i>PARSE RT method name = <%i/%i>", \
- methRT,methRTlast,rt_method->class->classUsed,rt_method->methodUsed); fflush(stdout);\
- utf_display(rt_method->class->name);printf(".");fflush(stdout); \
- utf_display(rt_method->name);printf("\n\n"); fflush(stdout);\
- method_println(rt_method); printf(">\n\n");fflush(stdout);}
-
-#define RTAPRINT02opcode if ((pOpcodes == 1) || (pOpcodes == 3)) \
- {printf("Parse RT p=%i<%i< opcode=<%i> %s\n", \
- p,rt_jcodelength,opcode,opcode_names[opcode]); \
- fflush(stdout); }
-
-#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 ("."); \
- utf_display ( fr->name); \
- printf (" type="); \
- utf_display ( fr->descriptor ); \
- printf("\n Field ="); \
- field_display (fi); \
- printf(" in class.field =");utf_display(ci->name); printf("."); \
- utf_display(fr->name);printf("\tPUT/GET STATIC\n"); fflush(stdout); \
- printf("For %s:",ci->name->text);fflush(stdout); \
- printf("#methods=%i\n",ci->methodscount); fflush(stdout); \
- }
-
-#define RTAPRINT04invokestatic1 if (((pOpcodes == 1) ||(pOpcodes == 3)) || (pWhenMarked >= 2)) { \
- printf(" method name ="); \
- utf_display(mi->class->name); printf("."); \
- utf_display(mi->name);printf("\t<%i>INVOKE STATIC\n",mi->methodUsed); \
- fflush(stdout);}
-
-#define RTAPRINT05invokestatic2 if (pWhenMarked >= 2) { \
- printf("Class marked Used :"); \
- utf_display(rt_class->name); \
- 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_println(mi);fflush(stdout); \
- }
-
-
-#define RTAPRINT06invoke_spec_virt1 if ((pOpcodes == 1) ||(pOpcodes == 3) || (pWhenMarked >= 2)) { \
- printf("INVOKE method name <%i/%i> =",mi->class->classUsed,mi->methodUsed); \
- utf_display(mi->class->name); printf("."); \
- method_println(mi); \
- fflush(stdout); }
-
-#define RTAPRINT07invoke_spec_virt2 if ((pOpcodes == 1) ||(pOpcodes == 3) || (pWhenMarked >= 1)) { \
- utf_display(mi->class->name);printf("."); \
- method_println(mi); }
-
-#define RTAPRINT08AinvokeInterface0 if (pWhenMarked >= 2) { \
- utf_display(mi->class->name); \
- method_println(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_println(mi); \
- fflush(stdout); \
- }
-
-#define RTAPRINT08invokeInterface1 if (pWhenMarked >= 1) { \
- printf("Implemented By classes :\n"); \
- fflush(stdout); \
- if (subs == NULL) printf(" \tNOT IMPLEMENTED !!!\n"); \
- fflush(stdout); \
- }
-
-#define RTAPRINT09invokeInterface2 if (pWhenMarked >= 3) { \
- printf("\t");utf_display(isubs->name); printf(" <%i>\n",isubs->classUsed); \
- }
-
-#define RTAPRINT10new if (pWhenMarked >= 2) { \
- 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->xta->XTAclassSet->head); \
- }
-
-#define RTAPRINT11addedtoCallgraph if (pWhenMarked >= 1){ \
- printf("\n<Added to Call Graph #%i:",methRTlast); \
- method_println(m); \
- printf("<%i> method name =",methRTlast);utf_display(m->class->name); printf("."); \
- utf_display(m->name);printf("\n"); \
- }
-
-#define RTAPRINT11addedtoCallgraph2 if (pWhenMarked >= 1){ \
- utf_display(ci->name); printf("."); \
- method_println(m); printf("\t\t"); \
- printf("<init> W/O new -- Add marked methods...\n<"); \
- }
-
-#define RTAPRINT12aNative if (pWhenMarked >= 1) { \
- printf("Native = "); fflush(stdout); \
- utf_display(rt_class->name); printf("."); fflush(stdout); \
- utf_display(rt_method->name); printf(" "); fflush(stdout); \
- 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_println(rt_method); printf("\n"); fflush(stdout); \
- }
-
-#define RTAPRINT12Callgraph if (pCallgraph >= 3) { \
- printf("RTA Callgraph after RTA Call\n"); \
- printCallgraph (); \
- }
-
-#define RTAPRINT13Heirarchy if (pClassHeir >= 3) { \
- printf("RTA Classheirarchy after RTA Call\n"); \
- printRThierarchyInfo(m); \
- }
-
-#define RTAPRINT14CallgraphLast if (pCallgraph >= 2) { \
- printf("RTA Callgraph after last method in callgraph - so far >888888888888888888\n"); \
- printCallgraph (); \
- }
-
-#define RTAPRINT15HeirarchyiLast if (pClassHeir >= 2) { \
- printf("RTA Classheirarchy after last method in callgraph - so far >888888888888888888\n"); \
- printRThierarchyInfo(m); \
- }
-
-#define RTAPRINT16stats1 if (pStats == 2) { \
- printf("OBJECT SUBS ARE_THERE 1\n"); \
- printObjectClassHeirarchy(class_java_lang_Object); \
- }
-#endif /* OLDRT */
+++ /dev/null
-/* sr/cvm/jit/inline/parseRTstats.c -
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- Changes: Christian Thalinger
-
- $Id: parseRTstats.c 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-#include <stdio.h>
-
-#include "config.h"
-#include "toolbox/list.h"
-#include "vm/class.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
-#include "vm/jit/inline/parseRT.h"
-#include "vm/jit/inline/parseRTstats.h"
-#include "vm/jit/inline/parseRTprint.h"
-
-
-int pClassHeirStatsOnly = 2;
-int pClassHeir = 2;
-
-/*--- 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;
-
-
-
-/*--------------------------------------------------------------*/
-void printCallgraph (list *rtaWorkList)
-{
- int i = 1;
- rtaNode *rta;
- methodinfo *rt_meth;
-
-#if defined(ENABLE_STATISTICS)
- printf("-*-*-*-*- RTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
-#endif
-
- for (rta =list_first(rtaWorkList);
- rta != NULL;
- rta =list_next(rtaWorkList,rta))
- {
- rt_meth = rta->method;
-
- printf(" (%i): ",i++);
- method_println(rt_meth);
- }
-
- printf("\n\n");
-
-}
-/*--------------------------------------------------------------*/
-/*--------------------------------------------------------------*/
-/*--------------------------------------------------------------*/
-int subdefd(methodinfo *meth) {
- classinfo *subs;
- methodinfo *submeth;
-
- printf("subdefd for:");
- method_println(meth);
-
- if ( (meth->flags & ACC_STATIC) && (meth->flags & ACC_FINAL ) )
- printf("\n\n\nPossible Poly call for FINAL or STATIC\n\n\n");
-
- if ((meth->class->sub == NULL) && (!(meth->flags & ACC_ABSTRACT )) ) {
- return 0;
- }
- if (meth->flags & ACC_ABSTRACT ) ; /*printf("AB\n"); fflush(stdout); */
-
- printf("sub exist for:");method_println(meth);
-
- for (subs = meth->class->sub;subs != NULL;subs = subs->nextsub) {
- submeth = class_findmethod_approx(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;
-}
-
-/*--------------------------------------------------------------*/
-#define CLASSINFO(cls,txt) { \
- printf(txt); fflush(stdout); \
- printf(" <c%i>(depth=%i) ",cls->classUsed,cls->index); \
- printf("\tbase/diff =%3d/%3d\t", \
- cls->vftbl->baseval, \
- cls->vftbl->diffval); \
- utf_display(cls->name); printf("\n"); fflush(stdout); }
-
-/*--------------------------------------------------------------*/
-
-void printRTClassHeirarchy2(classinfo *class) {
-classinfo *s;
- methodinfo *meth;
- int m;
-
- if (class == NULL) {return;}
- CLASSINFO(class,"CLASS: ");
- for (s = class->super.cls; s != NULL; s = s->super.cls) {
- CLASSINFO(s,"SUPER:: ");
- }
-
- printf("METHODs: "); fflush(stdout);
-
- for (m=0; m < class->methodscount; m++) {
- meth = &class->methods[m];
- printf("(%i) ",m);
- METHINFOx(meth);
- }
- printf("---------------------------\n");fflush(stdout);
-
- if (class->sub != NULL) printf("SUBS:\n:");
- else printf("NO SUBS\n");
- fflush(stdout);
-
- for (s = class->sub; s != NULL; s = s->nextsub) {
- printRTClassHeirarchy2(s);
- printf("---------------------------\n");fflush(stdout);
- }
-}
-
-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("\nMETHOD marked used in CLASS marked NOTUSED: \n\t");
- method_println(meth);
- printf("<%i>\n\t",meth->methodUsed);
- fflush(stdout);
- printf("\nMETHOD marked used in CLASS marked NOTUSED\n\n\n\n");
- }
- }
- else {
- printf(" UNUSED METHOD "); fflush(stdout);
- method_println(meth);
- }
- }
- }
-
- 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=");
- method_println(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");
- method_println(meth);
- printf("\t\t");
- if (meth->monoPoly != MONO) printf("\t\tRedefs used/total<%i/%i>\n", meth->subRedefsUsed, meth->subRedefs);
- }
- }
- }
- if (pClassHeirStatsOnly >= 2) {
- if (cnt > 0) {
- if (class->classUsed == PARTUSED)
- printf("> %i of %i methods (part)used\n",cnt, class->methodscount);
- if (class->classUsed == USED)
- printf("> %i of %i methods used\n",cnt, class->methodscount);
- }
- }
- }
-
- for (subs = class->sub; subs != NULL; subs = subs->nextsub) {
- printRTClassHeirarchy(subs);
- }
-}
-/*--------------------------------------------------------------*/
-void printRTInterfaceClasses() {
- int 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;
- 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)
- printf("\n\n\nprintRTInterfaceClasses: class in the implemented list without being used!!!??\n\n\n");
- fflush(stdout);
- }
- 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");
- method_println(imi);
- }
- if (impldBycnt == 1) {
- classinfo *cii;
- methodinfo *mii;
-
- /* 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)
- printf("\n\n\ninterface monopoly not POLY\n\n\n");
- **/
- 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;
-
-
-printf("RT Heirarchy:------------\n"); fflush(stdout);
- /*-- --*/
- printf("\nRT Class Hierarchy for ");
- if (m != NULL) {
- method_println(m);
- printf("\n");
- }
- else {
- printf(" called with NULL method\n");
- return;
- }
- /**printRTClassHeirarchy(class_java_lang_Object); **/
- printRTClassHeirarchy(m->class);
- printf("--- end of RT info ---------------\n");
-
- if (pClassHeirStatsOnly >= 10) {
- /*-- statistic results --*/
- if (opt_rt)
- printRTInterfaceClasses();
-
- printf("\n >>>>>>>>>>>>>>>>>>>> Analysed Class Hierarchy 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. Polymorphic 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);
- }
-}
-
-
-/*--------------------------------------------------------------*/
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
-
+++ /dev/null
-/* jit/parseRTstats.h -
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- $Id: parseRTstats.h 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-
-#ifndef _PARSERTSTATS_H
-#define _PARSERTSTATS_H
-
-/* function prototypes */
-void printCallgraph (list *rtaWorkList); /* print RTA worklist of methods */
-void printRThierarchyInfo(methodinfo *m);
-void printRTClassHeirarchy2(classinfo *class);
-
-
-#endif /* _PARSERTSTATS_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
+++ /dev/null
-/*****
-If V() then why add call edges since no type info passed?
- does nothing happen when the method with V() is XTA parsed? class info is standalone then
- what about clinits?
-Check initialization... need at least a dummy called by ...
-
-... why no error now????
-
-What about recursion??? x.a calls x.a
-
-Now wondering if there is a memory corruption because XTA seems to finish ok
-****/
-
-/* src/vm/jit/inline/parseXTA.c - parser and print functions for
- Rapid Type Analyis
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- Changes: Christian Thalinger
-
- $Id: parseXTA.c 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-/*--------------------------------------
-XTA so far
-static
-fields
-virtual
-interfaces - started
-clinit / final
-general initialization
-----
-interfaces
-+ hand coded calls for system
-2nd interation (want to try it in inlining)
-
-Testing
-
-?? PARTUSED???
-----------------------------------*/
-
-/***************
- XTA Type Static Analysis of Java program
- used -xta option is turned on either explicitly
- or automatically with inlining of virtuals.
-
- XTA is called for reachable methods and keeps sets for each Method and Field used as follows:
-1. Work list of reachable methods is initialized to main + JVM called methods
- + missed methods
-2. For virtual method call from M of e.m then
- a. Add all static lookup of m in the cone of e = ce.mi to reachable worklist
- JAVA_INVOKESTATIC/ JAVA_INVOKESPECIAL - xtaAddCallEdges
- JAVA_INVOKEVIRTUAL - xtaMarkSubs
- JAVA_INVOKEINTERFACES
- b. Add mi's parameters class + subtypes that are used by M to mi used classes
- When XTA parsed follow the calls list (beg. parseXTA)
- c. Add mi's return type + subtypes used by mi to M's used classes
- When XTA parsed follow the calledBy list (end parseXTA)
- d. Add ce of mi to mi's used classes
- static/special - addXTAcalledges
- virtual - xtaMarkSubs if subclass used -> xtaAddCallEdges
- if subclass not used -> add ce.mi to markedby temp set
-
-3. new C (new, <init>, & similiar) then add C to M's used classes
- JAVA_NEW, INVOKE_SPECIAL <init>, JAVA_CHECKCAST / JAVA_INSTANCEOF - classinit
-4. read Field X.f: add X to M's used classes
- JAVA_GETSTATIC
-5. write Field X.f: add X+subtypes that are used by M to X's classes
- JAVA_PUTSTATIC
-
-
- If M calls
- USAGE:
- Methods called by NATIVE methods and classes loaded dynamically
- cannot be found by parsing. The following files supply missing methods:
-
- xtaMissedIn0 - (provided) has the methods missed by every java program
- xtaMissed||mainClassName - is program specific.
-
- A file xtaMissed will be written by XTA analysis of any methods missed.
-
- This file can be renamed to xtaMissed concatenated with the main class name.
-
- Example:
- ./cacao -xta hello
-
- inlining with virtuals should fail if the returned xtaMissed is not empty.
- so...
- mv xtaMissed xtaMissedhello
- ./cacao hello
-
-Results: (currently) with -stat see # methods marked used
-
-****************/
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "config.h"
-#include "cacao/cacao.h"
-#include "mm/memory.h"
-#include "toolbox/list.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/parseXTA.h"
-#include "vm/jit/inline/parseRTstats.h"
-#include "vm/jit/inline/parseRTprint.h"
-
-
-
-static bool firstCall= true;
-static list *xtaWorkList;
-FILE *xtaMissed; /* Methods missed during XTA parse of Main */
-
-bool XTA_DEBUGinf = false;
-bool XTA_DEBUGr = false;
-bool XTA_DEBUGopcodes = false;
-
-char * clsFlgs [] = {"NOTUSED", "PARTUSED", "USED"};
-char * methFlgs [] = {"NOTUSED", "MARKED", "USED"};
-
-/*********************************************************************/
-/*********************************************************************/
-
-/* 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
-
-*******************************************************************************/
-
-static 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;
- classinfo *clsinfo;
-
- if (debugInfo >= 1) {
- printf("In descriptor2typesL >>>\t"); fflush(stdout);
- utf_display(m->class->name); printf(".");
- method_println(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 */
- if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
- log_text("could not load class in descriptor2typesL");
- assert(0);
- }
- classtypes[pcount-1] = clsinfo;
- p = addClassCone(p, clsinfo);
- 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 */
- if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
- log_text("could not load class in descriptor2typesL");
- assert(0);
- }
- classtypes[pcount-1] = clsinfo;
- p= addClassCone(p, clsinfo);
- 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:
- log_text("Ill formed methodtype-descriptor");
- assert(0);
- }
- }
-
- /* 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;
- c = *desc;
- if (c == 'L')
- *(desc++);
- case 'L':
- m->returntype = TYPE_ADR;
-
- /* get class string */
- class = strtok(desc,";");
- if (!(clsinfo = load_class_bootstrap(utf_new_char(class)))) {
- log_text("could not load class in descriptor2typesL");
- assert(0);
- }
- m->returnclass = clsinfo;
- if (m->returnclass == NULL) {
- printf("class=<%s>\t",class); fflush(stdout);
- log_text("return class not found");
- assert(0);
- }
- break;
- case 'V': m->returntype = TYPE_VOID;
- break;
-
- default:
- log_text("Ill formed methodtype-descriptor-ReturnType");
- assert(0);
- }
-
- 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;
-}
-
-
-
-/*-------------------------------------------------------------------------------*/
-
-xtafldinfo * xtafldinfoInit (fieldinfo *f)
-{
- if (f->xta != NULL)
- return f->xta;
-
- f->xta = NEW(xtafldinfo);
-
- f->xta->fieldChecked = false;
- f->xta->fldClassType = NULL;
- f->xta->XTAclassSet = NULL;
-
- return f->xta;
-}
-
-/*-------------------------------------------------------------------------------*/
-
-xtainfo *xtainfoInit(methodinfo *m)
-{
- if (m->xta != NULL)
- return m->xta; /* already initialized */
-
-#if defined(ENABLE_STATISTICS)
- count_methods_marked_used++;
-#endif
-
- m ->xta = (xtainfo *) NEW(xtainfo);
- m ->xta-> XTAmethodUsed = NOTUSED;
-
- /* xta sets for a method */
- m->xta->fldsUsed = NULL;
- m ->xta-> XTAclassSet = NULL;
- /* Methods's have access to the class they are a part of */
- m ->xta-> XTAclassSet = add2ClassSet ( m ->xta-> XTAclassSet, m->class);
- /* cone set of methods parameters */
- /* what if no param?? is it NULL then, too? */
- /****** class not loaded so take param info from superclass ??? */
- m->xta->paramClassSet = descriptor2typesL(m);
-
- /* Edges */
- m->xta->calls = NULL;
- m->xta->calledBy = NULL;
- m ->xta->markedBy = NULL;
-
- m->xta->chgdSinceLastParse = false;
- return m->xta;
-
- /* thought needed at some earlier point */
- /*m ->xta->interfaceCalls = NULL*/
-}
-
-/*-------------------------------------------------------------------------------*/
-void xtaAddCallEdges(methodinfo *mCalls, methodinfo *mCalled, s4 monoPoly, char *info) {
- xtaNode *xta = NULL;
-
-
-if (mCalled->flags & ACC_ABSTRACT) return;
-/* First call to this method initializations */
- /******
-printf("mCalled->methodUsed =%i != %i = USED is ",mCalled->methodUsed, USED); fflush(stdout);
-printf(" <%i> T%i/%iF\n",(mCalled->methodUsed!= USED), true,false); fflush(stdout);
- ******/
-
-if (mCalled->methodUsed != USED) {
- /******
- printf("\n>>>>>>%s:\n",info); fflush(stdout);
- printf("Add to Worklist mCalls_=");fflush(stdout);
- if (mCalls!=NULL) {
- printf("<"); fflush(stdout);
- METHINFOx(mCalls)
- printf("> "); fflush(stdout);
- }
- else
- {
- printf("NULL\n");fflush(stdout);
- }
-
- printf("mCalled=");fflush(stdout);
- if (mCalled!=NULL) {
- printf("<"); fflush(stdout);
- METHINFOx(mCalled)
- printf("> "); fflush(stdout);
- }
- else
- {printf("NULL\n");fflush(stdout);}
- ****/
- mCalled->xta = xtainfoInit(mCalled);
- mCalled ->methodUsed = USED; /* used to see if method in the work list of methods */
- xta = NEW(xtaNode);
- xta->method = mCalled ;
- list_addlast(xtaWorkList,xta);
- }
-
-if ((mCalls == NULL) && (!(monoPoly == SYSCALL)) ) {} /* panic when init file correct is */
-
-if ((mCalls == mCalled) /* recursion doesn't change class set nor field set so ignore */
- || (mCalls == NULL)) {return; }
-
-
-/*** printf(" AddCallEdges\n"); fflush(stdout); ***/
-/* Add call edges */
-mCalls->xta = xtainfoInit(mCalls);
-mCalls->xta->calls = add2MethSet(mCalls->xta->calls, mCalled);
- /* mono if static, private, final else virtual so poly */
-mCalls->xta->calls->tail->monoPoly = monoPoly;
-
-mCalled->xta->calledBy = add2MethSet(mCalled->xta->calledBy, mCalls);
-
-/* IS THIS REALLY NEEDED???? */
-if (mCalled->xta->calledBy == NULL) {
- log_text("mCalled->xta->calledBy is NULL!!!");
- assert(0);
-}
-if (mCalls->xta->calls == NULL) {
- log_text("mCalls->xta->calls is NULL!!!");
- assert(0);
-}
-
-}
-
-
-/*-------------------------------------------------------------------------------*/
-bool xtaPassParams (methodinfo *Called, methodinfo *Calls, methSetNode *lastptrInto)
-{
- classSetNode *p;
- classSetNode *c;
- classSetNode *c1;
- classSetNode *cprev;
- bool chgd = false;
-
- /* prevent compiler warnings */
-
- c1 = NULL;
-
- if (lastptrInto->lastptrIntoClassSet2 == NULL) {
- if (Calls->xta->XTAclassSet != NULL)
- c1 = Calls->xta->XTAclassSet->head;
- /*else already c1 = NULL; */
- }
- else {
- /* start with type where left off */
- c1 = lastptrInto->lastptrIntoClassSet2;
- c1 = c1 -> nextClass; /* even if NULL */
- }
- if (c1 == NULL) return false;
-
- cprev = NULL;
- /* for each Param Class */
- for ( p=Called->xta->paramClassSet; p != NULL; p = p->nextClass) {
-
- /* for each SmCalls class */
- for (c=c1; c != NULL; c = c->nextClass) {
- vftbl_t *p_cl_vt;
- vftbl_t *c_cl_vt;
-
- LAZYLOADING(c->classType) /* if not loaded is it really needed ??? */
-
- p_cl_vt = p->classType->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 Calls class to CalledBy Class set */
- Called->xta->XTAclassSet = Called->xta->XTAclassSet = add2ClassSet(Called->xta->XTAclassSet, c->classType);
- chgd = true;
- }
- cprev = c;
- }
- }
- lastptrInto->lastptrIntoClassSet2 = cprev;
- return chgd;
-}
-
-
-/*-------------------------------------------------------------------------------*/
-void xtaPassAllCalledByParams (methodinfo *m) {
- methSetNode *SmCalled;
- if (m->xta->calledBy == NULL)
- return;
- for (SmCalled = m->xta->calledBy->head;
- SmCalled != NULL;
- SmCalled = SmCalled->nextmethRef) {
- m->xta->chgdSinceLastParse = false; /* re'init flag */
- xtaPassParams(m, SmCalled->methRef,SmCalled); /* chg flag output ignored for 1st regular parse */
- }
-}
-
-
-/*-------------------------------------------------------------------------------*/
-void xtaPassFldPUT(methodinfo *m, fldSetNode *fN)
-{
- /* Field type is a class */
- classSetNode *c;
- classSetNode *c1 = NULL;
- classSetNode *cp = NULL;
- classSetNode *cprev= NULL;
-
- fieldinfo *fi;
-
- if (fN != NULL)
- fi = fN->fldRef;
- else
- return;
-
-/* Use lastptr so don't check whole XTA class set each time */
- cp = fN->lastptrPUT;
- if (cp != NULL) {
- if (cp->nextClass != NULL)
- c1 = cp -> nextClass;
- }
- else {
- if (m->xta->XTAclassSet != NULL)
- c1 = m->xta->XTAclassSet->head;
- }
-
- /*--- PUTSTATIC specific ---*/
- /* Sx = intersection of type+subtypes(field x) */
- /* and Sm (where putstatic code is) */
- for (c=c1; c != NULL; c=c->nextClass) {
- vftbl_t *f_cl_vt;
- vftbl_t *c_cl_vt;
-
- LAZYLOADING1(fi->xta->fldClassType)
-
- f_cl_vt = fi->xta->fldClassType->vftbl;
- c_cl_vt = c-> classType->vftbl;
- if ((f_cl_vt->baseval <= c_cl_vt->baseval)
- && (c_cl_vt->baseval <= (f_cl_vt->baseval+f_cl_vt->diffval)) ) {
- fi->xta->XTAclassSet = add2ClassSet(fi->xta->XTAclassSet,c->classType);
- }
- cprev = c;
- }
- fN->lastptrPUT = cprev;
-}
-/*-------------------------------------------------------------------------------*/
-void xtaPassFldGET(methodinfo *m, fldSetNode *fN)
-{
- /* Field type is a class */
- classSetNode *c;
- classSetNode *c1 = NULL;
- classSetNode *cp = NULL;
- classSetNode *cprev= NULL;
-
- fieldinfo *fi;
- if (fN != NULL)
- fi = fN->fldRef;
- else
- return;
-
-/* Use lastptr so don't check whole XTA class set each time */
- cp = fN->lastptrGET;
- if (cp != NULL) {
- if (cp->nextClass != NULL)
- c1 = cp -> nextClass;
- }
- else {
- if (fi->xta->XTAclassSet != NULL)
- c1 = fi->xta->XTAclassSet->head;
- }
-
- /*--- GETSTATIC specific ---*/
- /* Sm = union of Sm and Sx */
- for (c=c1; c != NULL; c=c->nextClass) {
- bool addFlg = false;
- if (m->xta->XTAclassSet ==NULL)
- addFlg = true;
- else {
- if (!(inSet (m->xta->XTAclassSet->head, c->classType) ))
- addFlg = true;
- }
- if (addFlg) {
- m->xta->XTAclassSet
- = add2ClassSet(m->xta->XTAclassSet,c->classType);
- }
- cprev = c;
- }
-
- fN->lastptrGET = cprev;
-}
-
-
-/*-------------------------------------------------------------------------------*/
-void xtaAllFldsUsed (methodinfo *m) {
- fldSetNode *f;
- fldSetNode *f1=NULL;
- /* bool chgd = false */
-
- if (m->xta->fldsUsed == NULL) return;
-
- /* for each field that this method uses */
- f1 = m->xta->fldsUsed->head;
-
- for (f=f1; f != NULL; f = f->nextfldRef) {
-
- if (f->writePUT)
- xtaPassFldPUT(m,f);
- if (f->readGET)
- xtaPassFldGET(m,f);
- }
-}
-
-/*-------------------------------------------------------------------------------*/
-bool xtaPassReturnType(methodinfo *Called, methodinfo *Calls) {
-
- classSetNode* cs;
- classSetNode* cs1;
- bool fchgd = false;
-
- /* Get Called return class is null */
- if ((Called->returnclass == NULL) && (Called->xta->paramClassSet == NULL)) {
- Called->xta->paramClassSet = descriptor2typesL(Called); /* old comment - in new xta struc init */
- }
-
- if (Called->returnclass == NULL) {
- return fchgd;
- }
-
- if (Called->xta->XTAclassSet == NULL)
- cs1 = NULL;
- else
- cs1 = Called->xta->XTAclassSet->head;
-
- for (cs =cs1; cs != NULL; cs = cs->nextClass) {
- classinfo *c = cs->classType;
- vftbl_t *r_cl_vt;
- vftbl_t *c_cl_vt;
- LAZYLOADING(c)
- LAZYLOADING(Called->returnclass)
- r_cl_vt = Called->returnclass->vftbl;
- c_cl_vt = c->vftbl;
-
- /* if class is a subtype of the return type, then add to Calls 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)) ) {
- Calls->xta->XTAclassSet = add2ClassSet(Calls->xta->XTAclassSet, c);
- fchgd = true;
- }
- }
-
- return fchgd;
-}
-
-
-/*-------------------------------------------------------------------------------*/
-void xtaMethodCalls_and_sendReturnType(methodinfo *m)
-{
- methSetNode *SmCalled; /* for return type */
- methSetNode *SmCalls; /* for calls param types */
- methSetNode *s1=NULL;
- bool chgd = false;
-
- xtaAllFldsUsed (m);
-
- if (m->xta == NULL) {
- log_text("m->xta null for return type");
- assert(0);
- }
-
- /* for each method that this method calls */
- if (m->xta->calls == NULL)
- s1 = NULL;
- else
- s1 = SmCalls=m->xta->calls->head;
-
- for (SmCalls=s1; SmCalls != NULL; SmCalls = SmCalls->nextmethRef) {
- /* pass param types */
- bool chgd = false;
- chgd = xtaPassParams (SmCalls->methRef, m, SmCalls);
- /* if true chgd after its own parse */
- if (!(SmCalls->methRef->xta->chgdSinceLastParse)) {
- SmCalls->methRef->xta->chgdSinceLastParse = true;
- }
- }
-
- /* for each calledBy method */
- /* send return type */
- if (m->xta->calledBy == NULL)
- s1 = NULL;
- else
- s1 = m->xta->calledBy->head;
- for (SmCalled=s1; SmCalled != NULL; SmCalled = SmCalled->nextmethRef) {
-
- chgd = xtaPassReturnType(m, SmCalled->methRef);
- if (!(SmCalled->methRef->xta->chgdSinceLastParse)) {
- SmCalled->methRef->xta->chgdSinceLastParse = chgd;
- }
- }
-
-}
-
-/*-------------------------------------------------------------------------------*/
-bool xtaAddFldClassTypeInfo(fieldinfo *fi) {
-
- bool is_classtype = false; /* return value */
-
- if (fi->xta->fieldChecked) {
- if (fi->xta->fldClassType != NULL)
- return true; /* field has a class type */
- else
- return false;
- }
- fi->xta->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') {
- is_classtype = true;
- if (fi->xta->fldClassType== NULL) {
- char *desc;
- char *cname;
- classinfo * class;
-
- desc = MNEW(char, 256);
- strcpy(desc,++utf_ptr);
- cname = strtok(desc,";");
- if (!(class = load_class_bootstrap(utf_new_char(cname)))) {
- log_text("could not load class in xtaAddFldClassTypeInfo");
- assert(0);
- }
- fi->xta->fldClassType= class; /* save field's type class ptr */
- }
- }
- }
- return is_classtype;
-}
-
-/*--------------------------------------------------------------*/
-/* Mark the method with same name /descriptor in topmethod */
-/* in class */
-/* */
-/* Class marked USED and method defined in this class -> */
-/* -> add call edges = USED */
-/* Class not marked USED and method defined in this class -> */
-/* -> if Method NOTUSED mark method as MARKED */
-/* */
-/* Class USED, but method not defined in this class -> */
-/* -> 1) search up the heirarchy and mark method where defined */
-/* 2) if class where method is defined is not USED -> */
-/* -> ????mark class with defined method as PARTUSED */
-/*--------------------------------------------------------------*/
-
-
-void xtaMarkMethod(classinfo *class, methodinfo *mCalls, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
-
-utf *name = topmethod->name;
-utf *descriptor = topmethod->descriptor;
-methodinfo *submeth;
-
-/* See if method defined in class heirarchy */
-submeth = class_resolvemethod(class, name, descriptor);
-METHINFOt(submeth,"xtaMarkMethod submeth:",XTA_DEBUGr);
-if (submeth == NULL) {
- utf_display(class->name); printf(".");
- METHINFOx(topmethod);
- printf("parse XTA: Method not found in class hierarchy");fflush(stdout);
- assert(0);
-}
-
-/* if submeth called previously from this method then return */
-if (mCalls->xta->calls != NULL) {
- if (inMethSet(mCalls->xta->calls->head,submeth)) return;
- }
-
-#undef CTA
-#ifdef CTA
- XTAaddClassInit(submeth, submeth->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- if (inSet(subtypesUsedSet,submeth->class)) {
- submeth->monoPoly = POLY;
- xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
- "00addTo XTA VIRT CONE:");
- }
- return;
-#endif
-
- if (submeth->class == class) {
-
- /*--- Method defined in class -----------------------------*/
- if (inSet(subtypesUsedSet,submeth->class)) {
- /* method defined in this class -> */
- /* Class IS marked USED */
- /* -> mark method as USED */
- submeth->monoPoly = POLY;
- xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
- "01addTo VIRT CONE 1:");
- }
- else {
- /* method defined in this class -> */
- /* Class IS NOT marked USED (PART or NOTUSED) */
- /* -> if Method NOTUSED mark method as MARKED */
- METHINFOt(submeth,
- "\tmarked VIRT CONE 2:",XTA_DEBUGr);
- submeth->monoPoly = POLY;
- if (submeth->xta == NULL) {
- submeth->xta = xtainfoInit(submeth);
- }
- submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
- submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
- /* Note: if class NOTUSED and subclass is used handled */
- /* by subsequent calls to xtaMarkMethods for cone */
- }
- } /* end defined in class */
-
- else {
- /*--- Method NOT defined in class - defined up the heirarchy ---------------*/
- /* then check class the method could be called with */
-
- /* first mark classes if needed */
- if (!(inSet(subtypesUsedSet,submeth->class))) {
- submeth->class->classUsed = PARTUSED;
- if (!(inSet(subtypesUsedSet,class))) {
- submeth->monoPoly = POLY;
- if (submeth->xta == NULL)
- submeth->xta = xtainfoInit(submeth);
- submeth->methodUsed = MARKED; /* used to see if method in the work list of methods */
- submeth->xta->markedBy = add2MethSet(submeth->xta->markedBy,mCalls);
- METHINFOt(submeth,"JUST MARKED :",XTA_DEBUGr);
- }
- }
- /* add method to xta work list if conditions met */
- if (inSet(subtypesUsedSet,class)) {
- submeth->monoPoly = POLY;
- xtaAddCallEdges(mCalls, submeth, submeth->monoPoly,
- "02addTo VIRT CONE 3:");
- }
- } /* end NOT defined in class */
-
-}
-
-/*----------------------------------------------------------------------*/
-/* Mark the method with the same name and descriptor as topmethod */
-/* and any subclass where the method is defined and/or class is used */
-/* */
-/*----------------------------------------------------------------------*/
-
-void xtaMarkSubs(methodinfo *mCalls, classinfo *class, methodinfo *topmethod, classSetNode *subtypesUsedSet) {
- /* xtaPRINTmarkSubs1*/
- xtaMarkMethod(class, mCalls, 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) {
- xtaMarkSubs(mCalls, subs, topmethod, subtypesUsedSet);
- }
- }
- }
-}
-
-
-/**************************************************************************/
-/* Add Marked methods for input class ci */
-/* Add methods with the same name and descriptor as implemented interfaces*/
-/* with the same method name */
-/* ??? interface part not XTA checked */
-/*------------------------------------------------------------------------*/
-void xtaAddMarkedMethods(methodinfo *mCalls, 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->xta != NULL) {
- if (mi->xta->markedBy != NULL) {
- methSetNode *mcnode;
- for (mcnode = mi->xta->markedBy->head; mcnode != NULL; mcnode = mcnode ->nextmethRef) {
- methodinfo *mCalls = mcnode->methRef;
- xtaAddCallEdges(mCalls, mi, mi->monoPoly,
- "03addToInit was Marked added:");
- }
- }
-
- else { /* NOT XTA checked yet */
- for (jj=0; jj < ci -> interfacescount; 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:",XTA_DEBUGinf)
- /*if interface method=method is used*/
- if ( (imi->methodUsed == USED)
- && ( (imi->name == mi->name)
- && (imi->descriptor == mi->descriptor))) {
- xtaAddCallEdges(mCalls, mi, mi->monoPoly,
- "04addTo was interfaced used/MARKED:");
- }
- } /*end for */
- }
- }
- }
- }
- }
-}
-
-
-/*------------------------------------------------------------------------*/
-void xtaAddUsedInterfaceMethods(methodinfo *m, 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 (XTA_DEBUGinf) {
- printf("BInterface used: ");fflush(stdout);
- utf_display(ici->name);
- printf("<%i>\tclassUsed=%s\n",ici -> classUsed,clsFlgs[ici->classUsed] ); 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 ( (XTA_DEBUGinf) && (imi->methodUsed != USED)) {
- printf("Interface Method %s: ", methFlgs[imi->methodUsed]);
- utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
- }
- if (imi->methodUsed == USED) {
- if (XTA_DEBUGinf) {
- printf("Interface Method used: "); utf_display(ici->name);printf(".");method_println(imi);fflush(stdout);
- /* Mark this method used in the (used) implementing class &its subclasses */
- printf("rMAY ADD methods that was used by an interface\n");
- }
- if ((utf_clinit != imi->name) &&
- (utf_init != imi->name))
- {
- classSetNode *subtypesUsedSet = NULL;
- if (m->xta->XTAclassSet != NULL) {
- subtypesUsedSet =
- intersectSubtypesWithSet
- (imi->class, m->xta->XTAclassSet->head);
- }
- else /* can any methods be added if 1 set is NULL ??? */
- subtypesUsedSet = addElement(subtypesUsedSet, m->class);
- xtaMarkSubs(m, ci, imi, subtypesUsedSet);
- imi->monoPoly = POLY;
-
- }
- }
- } /* end for method */
- } /* end != NOTUSED */
- } /* end for interface */
-
-}
-
-
-/*----------------------------------------------------------------------*/
-
-#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 XTAaddClassInit(methodinfo *mCalls, classinfo *ci, bool clinits, bool finalizes, bool addmark)
-{
- methodinfo *mi;
-
- if (addmark)
- ci->classUsed = USED;
-
- if (clinits) { /* No <clinit> available - ignore */
- mi = class_findmethod(ci, utf_clinit, utf_void__void);
- if (mi) {
- if (ci->classUsed != USED)
- ci->classUsed = PARTUSED;
- mi->monoPoly = MONO;
- xtaAddCallEdges(mCalls, mi, mi->monoPoly,
- "05addTo CLINIT added:");
- }
- }
-
- /*Special Case for System class init:
- add java/lang/initializeSystemClass to callgraph */
- if (ci->name == utf_new_char("initializeSystemClass")) {
- /* ?? what is name of method ?? */
- }
-
- if (finalizes) {
- mi = class_findmethod(ci, utf_finalize, utf_void__void);
- if (mi) {
- if (ci->classUsed != USED)
- ci->classUsed = PARTUSED;
- mi->monoPoly = MONO;
- xtaAddCallEdges(mCalls, mi, mi->monoPoly,
- "06addTo FINALIZE added:");
- }
- }
-
- if (addmark) {
- xtaAddMarkedMethods(mCalls, ci);
- }
-
- /* always so know have access to the interface methods */
- xtaAddUsedInterfaceMethods(mCalls,ci);
-
-}
-
-/*-------------------------------------------------------------------------------*/
-
-/*********************************************************************/
-/*********************************************************************/
-
-/*-------------------------------------------------------------------*/
-
-void xtaMarkInterfaceSubs(methodinfo *m, methodinfo *mi) {
- classSetNode *subs;
- if (mi->class->classUsed == NOTUSED) {
- mi->class->classUsed = USED;
- /* add interface class to list kept in Object */
- class_java_lang_Object->impldBy = addElement(class_java_lang_Object -> impldBy, mi->class);
- }
-
- mi->methodUsed = USED;
- mi->monoPoly = POLY;
-
- /*XTAPRINT08invokeInterface1*/
- if (XTA_DEBUGinf) {
- subs = mi->class->impldBy;
- METHINFO(mi,XTA_DEBUGinf)
- printf("Implemented By classes :\n");fflush(stdout);
- if (subs == NULL) printf("\tNOT IMPLEMENTED !!!\n"); fflush(stdout);
- }
- for (subs = mi->class->impldBy; subs != NULL; subs = subs->nextClass) {
- methodinfo *submeth;
- if (XTA_DEBUGinf) {
- printf("\t");utf_display(subs->classType->name);fflush(stdout);
- printf(" <%i>\n",subs->classType->classUsed);fflush(stdout);
- }
-
- /*Mark method (mark/used) in classes that implement method*/
- submeth = class_findmethod(subs->classType, mi->name, mi->descriptor);
- if (submeth != NULL) {
- classSetNode *subtypesUsedSet = NULL;
- submeth->monoPoly = POLY; /* poly even if nosubs */
- submeth->xta = xtainfoInit(submeth);
-
- submeth->xta->XTAmethodUsed = USED;
- if (m->xta->XTAclassSet != NULL) {
- subtypesUsedSet = /* interface classes cone */
- intersectSubtypesWithSet(subs->classType, m->xta->XTAclassSet->head);
- }
- else { /* can any methods be added if 1 set is NULL ??? */
- subtypesUsedSet = addElement(subtypesUsedSet, m->class);
- }
- xtaMarkSubs(m, subs->classType, submeth, subtypesUsedSet);
- }
-
- } /* end for */
-}
-
-
-
-/*********************************************************************/
-
-int parseXTA(methodinfo *m)
-{
- int p; /* java instruction counter */
- int nextp; /* start of next java instruction */
- int opcode; /* java opcode */
- int i; /* temp for different uses (counters)*/
- bool iswide = false; /* true if last instruction was a wide*/
- int rc = 1;
-
-if (m->methodXTAparsed) return 0;
-else m->methodXTAparsed = true;
-
-/***XTA_DEBUGopcodes=false;***/
-/***printf("\n-----------------------------------\n"); **/
-METHINFOt(m,"\n----XTA PARSING:",XTA_DEBUGopcodes);
-if ((XTA_DEBUGr)||(XTA_DEBUGopcodes)) printf("\n");
-/***XTA_DEBUGopcodes=false;***/
- if (m->xta == NULL) {
- xtainfoInit (m);
- }
- else {
- xtaPassAllCalledByParams (m);
- }
-
-/* scan all java instructions */
- for (p = 0; p < m->jcodelength; p = nextp) {
-
- opcode = code_get_u1(p,m); /* fetch op code */
- SHOWOPCODE(XTA_DEBUGopcodes)
-
- nextp = p + jcommandsize[opcode]; /* compute next instr start */
- if (nextp > m->jcodelength) {
- log_text("Unexpected end of bytecode");
- assert(0);
- }
-
- switch (opcode) {
-
- case JAVA_ILOAD:
- case JAVA_LLOAD:
- case JAVA_FLOAD:
- case JAVA_DLOAD:
- case JAVA_ALOAD:
-
- case JAVA_ISTORE:
- case JAVA_LSTORE:
- case JAVA_FSTORE:
- case JAVA_DSTORE:
- case JAVA_ASTORE:
-
- if (iswide) {
- nextp = p + 3;
- iswide = false;
- }
- break;
-
- case JAVA_IINC:
- {
-
- if (iswide) {
- iswide = false;
- nextp = p + 5;
- }
- }
- break;
-
- /* wider index for loading, storing and incrementing */
-
- case JAVA_WIDE:
- iswide = true;
- nextp = p + 1;
- break;
-
- case JAVA_RET:
- if (iswide) {
- nextp = p + 3;
- iswide = false;
- }
- break;
-
- case JAVA_LOOKUPSWITCH:
- {
- s4 num;
- nextp = ALIGN((p + 1), 4) + 4;
- num = code_get_u4(nextp,m);
- nextp += (code_get_u4(nextp,m)) * 8 + 4;
- break;
- }
-
-
- case JAVA_TABLESWITCH:
- {
- s4 num;
- nextp = ALIGN ((p + 1),4);
- num = code_get_s4(nextp + 4, m);
- num = code_get_s4(nextp + 8, m) - num;
- nextp = nextp + 16 + 4 * num;
- break;
- }
- /*********************/
-
- case JAVA_PUTSTATIC: /* write */
-
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *fr;
- fieldinfo *fi;
- classinfo *frclass;
-
- fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
- if (!fr)
- return 0;
- if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
- log_text("Could not resolve class reference");
- assert(0);
- }
- LAZYLOADING(frclass)
-
- fi = class_resolvefield(frclass,
- fr->name,
- fr->descriptor,
- m->class,
- true);
-
- if (!fi)
- return 0; /* was NULL */
-/***
-printf(" PUTSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
- utf_display(fi->name);printf("\n");fflush(stdout);
-***/
- fi->xta = xtafldinfoInit(fi);
- XTAaddClassInit(m, fi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_F);
- if (xtaAddFldClassTypeInfo(fi)) {
- m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, true,false);
- }
- }
- break;
-
-
- case JAVA_GETSTATIC: /* read */
-
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *fr;
- fieldinfo *fi;
- classinfo *frclass;
-
- fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
- if (!fr)
- return 0;
- if (!resolve_classref(m,fr->classref,resolveEager,true, true,&frclass)) {
- log_text("Could not resolve class reference");
- assert(0);
- }
-
- LAZYLOADING(frclass)
-
- fi = class_resolvefield(frclass,
- fr->name,
- fr->descriptor,
- m->class,
- true);
-
- if (!fi)
- return 0; /* was NULL */
-
-/***
-printf(" GETSTATIC:");fflush(stdout); utf_display(fi->class->name);printf(".");fflush(stdout);
- utf_display(fi->name);printf("\n");fflush(stdout);
-***/
- fi->xta = xtafldinfoInit(fi);
- XTAaddClassInit(m, fi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_F);
- if (xtaAddFldClassTypeInfo(fi)) {
- m->xta->fldsUsed = add2FldSet(m->xta->fldsUsed, fi, false, true);
- }
-
- }
- break;
-
-
-
- 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:: ",XTA_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 != USED) { /* = NOTUSED or PARTUSED */
- XTAaddClassInit(m, 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 XTA working list/set of reachable methods */
- if (opcode == JAVA_INVOKESTATIC) /* if stmt just for debug tracing */
- /* calls , called */
- xtaAddCallEdges(m, mi, MONO,
- "07addTo INVOKESTATIC ");
- else
- xtaAddCallEdges(m, mi, MONO,
- "08addTo INVOKESPECIAL ");
- } /* end STATIC, PRIVATE, FINAL */
-
- else {
- /*---- Handle special <init> calls ---------------------------------------------*/
-
- if (mi->class->classUsed != USED) {
- /* XTA 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:",XTA_DEBUGopcodes);
- /* super init so class may be only used because of its sub-class */
- XTAaddClassInit(m,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:",XTA_DEBUGopcodes);
- XTAaddClassInit(m, mi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- }
- xtaAddCallEdges(m, mi, MONO,
- "09addTo INIT ");
- } /* end just for <init> ()V */
-
- /* <clinit> for class inits do not add marked methods;
- class not yet instaniated */
- if (utf_clinit==mi->name)
- XTAaddClassInit(m, mi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_F);
-
- if (!((utf_init==mi->name))
- || (utf_clinit==mi->name)) {
- METHINFOt(mi,"SPECIAL not init:",XTA_DEBUGopcodes)
- if (mi->class->classUsed !=USED)
- mi->class->classUsed = PARTUSED;
- xtaAddCallEdges(m, mi, MONO,
- "10addTo SPEC notINIT ");
- }
-
- } /* end init'd class not used = class init process was needed */
-
- /* add method to XTA list = set of reachable methods */
- xtaAddCallEdges(m, mi, MONO,
- "11addTo 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(mrclass,"CouldNOT Resolve method:",,XTA_DEBUGr);printf(".");fflush(stdout);
-utf_display(mr->name); printf(" "); fflush(stdout);
-utf_display(mr->descriptor); printf("\n");fflush(stdout);
-***/
- }
- break;
-
- case JAVA_INVOKEVIRTUAL:
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *mr;
- methodinfo *mi;
- classinfo *mrclass;
-
- /* XXX remove direct access */
- mr = m->class->cpinfos[i];
- /*mr = class_getconstant(m->class, i, CONSTANT_Methodref)*/
- 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,"INVOKEVIRTUAL ::",XTA_DEBUGopcodes);
- if ((mi->flags & ACC_STATIC)
- || (mi->flags & ACC_PRIVATE)
- || (mi->flags & ACC_FINAL) )
- { /*** DOES THIS EVER OCCUR ??? */
- if (mi->class->classUsed == NOTUSED){
- XTAaddClassInit(m, mi->class,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- }
- mi->monoPoly = MONO;
- xtaAddCallEdges(m, mi, MONO,
- "12addTo INVOKEVIRTUAL ");
- }
- else { /* normal virtual */
- /* get the set of used subtypes if none at least the current methods class */
- classSetNode *subtypesUsedSet = NULL;
- if (m->xta->XTAclassSet != NULL) {
- subtypesUsedSet =
- intersectSubtypesWithSet(mi->class, m->xta->XTAclassSet->head);
- }
- else { /* can any methods be added if 1 set is NULL ??? */
- subtypesUsedSet = addElement(subtypesUsedSet, m->class);
- }
- mi->monoPoly = POLY;
- xtaMarkSubs(m, mi->class, mi, subtypesUsedSet);
- }
- }
- else {
-CLASSNAME1(mrclass,"CouldNOT Resolve virt meth:",XTA_DEBUGr);printf(".");fflush(stdout);
-utf_display(mr->name); printf(" "); fflush(stdout);
-utf_display(mr->descriptor); printf("\n");fflush(stdout);
- }
- }
- break;
-
- case JAVA_INVOKEINTERFACE:
- i = code_get_u2(p + 1,m);
- {
- constant_FMIref *mr;
- methodinfo *mi;
- classinfo *mrclass;
-
- mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
- 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(mrclass,
- mr->name,
- mr->descriptor,
- m->class,
- false);
- if (mi)
- {
- METHINFOt(mi,"\tINVOKEINTERFACE: ",XTA_DEBUGopcodes)
- xtaMarkInterfaceSubs(m,mi);
- }
- /* see INVOKESTATIC for explanation about */
- /* case when Interface is not resolved */
- /*method_descriptor2types(mi);
- ?? do need paramcnt? for XTA (or just XTA)*/
- }
- break;
-
- case JAVA_NEW:
- /* means class is at least passed as a parameter */
- /* class is really instantiated when class.<init> called*/
- i = code_get_u2(p + 1,m);
- {
- classinfo *cls;
- constant_classref *cr;
- cr = (constant_classref *)class_getconstant(m->class, i, CONSTANT_Class);
- if (!cr)
- return 0;
- resolve_classref(NULL,cr,resolveEager,true, false,&cls);
- /*** s_count++; look for s_counts for VTA */
- /* add marked methods */
- CLASSNAME(cls,"NEW : do nothing",XTA_DEBUGr);
- XTAaddClassInit(m, cls, CLINITS_T, FINALIZE_T,ADDMARKED_T);
- m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
- }
- break;
-
- case JAVA_CHECKCAST:
- case JAVA_INSTANCEOF:
- /* class used */
- i = code_get_u2(p + 1,m);
- {
- 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,XTA_DEBUGr);
- if (cls->classUsed == NOTUSED){
- XTAaddClassInit(m, cls,
- CLINITS_T,FINALIZE_T,ADDMARKED_T);
- m->xta->XTAclassSet = add2ClassSet(m->xta->XTAclassSet,cls );
- }
- }
- break;
-
- default:
- break;
-
- } /* end switch */
-
- } /* end for */
- xtaMethodCalls_and_sendReturnType(m);
-
- return rc;
-}
-
-/* Helper fn for initialize **********************************************/
-
-int XTAgetline(char *line, int max, FILE *inFP) {
-if (fgets(line, max, inFP) == NULL)
- return 0;
-else
- return strlen((const char *) line);
-}
-
-/* Initialize XTA Work list ***********************************************/
-
-/*-- Get meth ptr for class.meth desc and add to XTA worklist --*/
-#define SYSADD(cls,meth,desc, is_mono_poly, txt) \
- c = load_class_bootstrap(utf_new_char(cls)); \
- LAZYLOADING(c) \
- callmeth = class_resolveclassmethod(c, \
- utf_new_char(meth), \
- utf_new_char(desc), \
- c, \
- false); \
- if (callmeth->class->classUsed != USED) { \
- c->classUsed = PARTUSED; \
- XTAaddClassInit(callmeth, callmeth->class, \
- CLINITS_T,FINALIZE_T,ADDMARKED_T);\
- } \
- callmeth->monoPoly = is_mono_poly; \
- xtaAddCallEdges(NULL, callmeth, is_mono_poly, txt);
-
-/*-- ----------------------------------------------------------------------------
- Initialize XTA work list with methods/classes from:
- System calls
- and
- xtaMissedIn list (missed becaused called from NATIVE &/or dynamic calls
--------------------------------------------------------------------------------*/
-methodinfo *initializeXTAworklist(methodinfo *m) {
- classinfo *c;
- methodinfo* callmeth;
- char systxt[] = "2S addTo System Call :";
- char missedtxt[] = "2M addTo xtaMissedIn Call :";
-
- FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
- char line[256];
- char* class, *meth, *desc;
- methodinfo *rm =NULL; /* return methodinfo ptr to main method */
-
-
- /* Create XTA call work list */
- xtaWorkList = NEW(list);
- list_init(xtaWorkList, OFFSET(xtaNode,linkage) );
-
- /* Add first method to call list */
- m->class->classUsed = USED;
- xtaAddCallEdges(NULL, m, SYSCALL, systxt);
-
- /* Add system called methods */
-/*** SYSADD(mainstring, "main","([Ljava/lang/String;)V", SYSCALL, systxt) ***/
- SYSADD(MAINCLASS, MAINMETH, MAINDESC, SYSCALL, systxt)
- rm = callmeth;
-/*** SYSADD("java/lang/System","exit","(I)V",SYSCALL, systxt) ***/
- SYSADD(EXITCLASS, EXITMETH, EXITDESC, SYSCALL, systxt)
- /*----- xtaMissedIn 0 */
- if ( (xtaMissedIn = fopen("xtaMissedIn0", "r")) == NULL) {
- /*if (opt_verbose) */
- {printf("No xtaMissedIn0 file\n");fflush(stdout);}
- return rm;
- }
- while (XTAgetline(line,256,xtaMissedIn)) {
- class = strtok(line, " \n");
- meth = strtok(NULL, " \n");
- desc = strtok(NULL, " \n");
- SYSADD(class,meth,desc, POLY, missedtxt)
- /* ??? Need to hand / hard code who calls it ??? */
- }
- fclose(xtaMissedIn);
-
-
-
-
- return rm;
-
-}
-
-/*- end initializeXTAworklist-------- */
-
-
-/*-------------------------------------------------------------------------------*/
-methodinfo *missedXTAworklist()
-{
- FILE *xtaMissedIn; /* Methods missed during previous XTA parse */
- char filenameIn[256] = "xtaIn/";
- char line[256];
- char* class, *meth, *desc;
- /****
- char* calls_class, *calls_meth, *calls_desc;
- ****/
- char missedtxt[] = "xtaIn/ missed Call :";
- classinfo *c;
- methodinfo* callmeth;
-
- methodinfo *rm =NULL; /* return methodinfo ptr to main method */
-
-
-#if defined(USE_THREADS)
- SYSADD(THREADCLASS, THREADMETH, THREADDESC, SYSCALL, "systxt2")
- SYSADD(THREADGROUPCLASS, THREADGROUPMETH, THREADGROUPDESC, SYSCALL, "systxt2")
-#endif
- /*----- xtaMissedIn pgm specific */
- strcat(filenameIn, (const char *)mainstring);
- if ( (xtaMissedIn = fopen(filenameIn, "r")) == NULL) {
- /*if (opt_verbose)*/
- {printf("No xtaIn/=%s file\n",filenameIn);fflush(stdout);}
- return rm;
- }
- while (XTAgetline(line,256,xtaMissedIn)) {
- /****
- calls_class = strtok(line, " \n");
- calls_meth = strtok(NULL, " \n");
- calls_desc = strtok(NULL, " \n");
-
- class = strtok(NULL, " \n");
- ****/
- class = strtok(line, " \n");
- meth = strtok(NULL, " \n");
- desc = strtok(NULL, " \n");
-
- /****
- if ((calls_class == NULL) || (calls_meth == NULL) || (calls_desc == NULL)
- || (class == NULL) || (meth == NULL) || (desc == NULL))
- ****/
- if ( (class == NULL) || (meth == NULL) || (desc == NULL)) {
- log_text("Error in xtaMissedIn file: Missing a part of calls_class.calls_meth calls calls_desc class.meth desc");
- assert(0);
- }
- SYSADD(class,meth,desc, POLY, missedtxt)
- }
- fclose(xtaMissedIn);
-
- return rm;
-}
-
-
-
-/*--------------------------------------------------------*/
-/* parseXTAmethod */
-/* input: method to be XTA static parsed */
-/*--------------------------------------------------------*/
-void parseXTAmethod(methodinfo *xta_method) {
- if (! ( (xta_method->flags & ACC_NATIVE )
- || (xta_method->flags & ACC_ABSTRACT) ) )
- {
- /* XTA parse to approxmate....
- what classes/methods will really be used during execution */
- parseXTA(xta_method);
- }
- else {
- if (xta_method->flags & ACC_NATIVE )
- {
- METHINFOt(xta_method,"TO BE NATIVE XTA PARSED :",XTA_DEBUGopcodes);
- /* parseXTApseudo(xta_method); */
- }
- else {
- printf("Abstract method in XTA Work List: ");
- METHINFOx(xta_method);
- log_text("Abstract method in XTA Work List.");
- assert(0);
- }
- }
-}
-
-void XTAprintCallgraph (list *xtaWorkList, char * txt);
-
-/*-- XTA -- *******************************************************/
-int XTA_jit_parse(methodinfo *m)
-{
- xtaNode *xta;
- methodinfo *mainmeth;
-
- /* Should only be called once */
- if (firstCall) {
-
- /*----- XTA initializations --------*/
- if (opt_verbose)
- log_text("XTA static analysis started.\n");
-
- mainmeth = initializeXTAworklist(m);
-/** XTAprintCallgraph (xtaWorkList, "after init1"); **/
- firstCall = false; /* turn flag off */
-
- if ( (xtaMissed = fopen("xtaMissed", "w")) == NULL) {
- printf("CACAO - xtaMissed file: cant open file to write\n");
- }
- /* Note: xtaMissed must be renamed to xtaMissedIn to be used as input */
-
- /*------ process XTA call work list --------*/
- for (xta =list_first(xtaWorkList);
- xta != NULL;
- xta =list_next(xtaWorkList,xta))
- {
- parseXTAmethod(xta->method);
-/** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 1"); **/
- }
- missedXTAworklist();
-/** XTAprintCallgraph (xtaWorkList, "after missed"); **/
- for (xta =list_first(xtaWorkList);
- xta != NULL;
- xta =list_next(xtaWorkList,xta))
- {
- parseXTAmethod(xta->method);
-/** XTAprintCallgraph (xtaWorkList, "after an XTA method parse 2"); **/
- }
-
- fclose(xtaMissed);
- if (opt_verbose) {
- if (opt_stat) {
- printf("printXTAhierarchyInfo(m); not yet there\n");
- }
- XTAprintCallgraph (xtaWorkList, "After all XTA parses");
- }
-
- if (opt_verbose) {
- log_text("XTA static analysis done.\n");
- }
- }
-return 0;
-}
-
-/*--------------------------------------------------------------*/
-void XTAprintCallgraph (list *xtaWorkList, char * txt)
-{
- int i = 1;
- xtaNode *xta;
- methodinfo *xta_meth;
-
- printf("\n%s\n",txt);
-#if defined(ENABLE_STATISTICS)
- printf("-*-*-*-*- XTA Callgraph Worklist:<%i>\n",count_methods_marked_used);
-#endif
-
- for (xta =list_first(xtaWorkList);
- xta != NULL;
- xta =list_next(xtaWorkList,xta))
- {
- xta_meth = xta->method;
-
- printf(" (%i): ",i++);
- method_println(xta_meth);
- }
-
- printf("\n\n");
-
-}
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
-
+++ /dev/null
-/* jit/parseXTA.h - XTA parser header
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- $Id: parseXTA.h 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-#ifndef _PARSEXTA_H
-#define _PARSEXTA_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct xtainfo xtainfo;
-typedef struct xtafldinfo xtafldinfo;
-
-
-#include "toolbox/list.h"
-#include "vm/global.h"
-#include "vm/jit/inline/sets.h"
-
-
-#define LAZYLOADING(class) { \
- if (!(class->state & CLASS_LINKED)) \
- if (!link_class(class)) \
- return 0; }
-
-
-
-#define LAZYLOADING1(class) { \
- if (!(class->state & CLASS_LINKED)) \
- if (!link_class(class)) \
- return; }
-
-
-/* methodinfo static info *****************************************************/
-
-struct xtainfo {
- 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 */
-
- /* Needed for interative checking */
- methSet *calls; /* Edges - methods this method calls */
- methSet *calledBy; /* Edges - methods that call this method */
- methSet *markedBy;
- fldSet *fldsUsed; /* fields used by this method */
- /*methSetNode *interfaceCalls*/ /* methods this method calls as interface */
- bool chgdSinceLastParse; /* Changed since last parse ? */
-};
-
-
-/* field, method and class structures *****************************************/
-
-struct xtafldinfo {
- bool fieldChecked;
- classinfo *fldClassType;
- classSet *XTAclassSet; /* field class type set */
-};
-
-
-extern FILE *xtaMissed; /* Methods missed during XTA parse of Main */
-
-typedef struct {
- listnode linkage;
- methodinfo *method;
- } xtaNode ;
-
-
-extern int XTA_jit_parse(methodinfo *m);
-
-#endif /* _PARSEXTA_H */
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
-
+++ /dev/null
-/* vm/jit/inline/sets.c -
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- $Id: sets.c 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-
-#include <stdio.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-#include "vm/global.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/class.h"
-#include "vm/jit/inline/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 = NEW(fldSetNode);
- s1->nextfldRef = s;
- s1->fldRef = f;
- s1->writePUT = false;
- s1->readGET = false;
- s1->lastptrPUT = NULL;
- s1->lastptrGET = NULL;
-
- if (s == NULL)
- s1->index = 1;
- else
- s1->index = s->index+1;
- }
- return s1;
-}
-
-
-/*------------------------------------------------------------*/
-fldSet *add2FldSet(fldSet *sf, fieldinfo *f, bool wput, bool rget)
-{
- fldSetNode *s1;
- fldSetNode *s;
-
- if (sf == NULL) {
- sf = createFldSet();
- }
- s = sf->head;
- s1 = inFldSet(s,f);
- if (s1 == NULL) {
- s1 = NEW(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->writePUT = wput;
- s1->readGET = rget;
- s1->lastptrPUT = NULL;
- s1->lastptrGET = NULL;
- sf->tail = s1;
- }
- else {
- if ((s1->writePUT == false) && (wput))
- s1->writePUT = wput;
- if ((s1->readGET == false) && (rget))
- s1->readGET = rget;
- }
- return sf;
-}
-
-
-/*------------------------------------------------------------*/
-fldSet *createFldSet( )
-{
- fldSet *s;
- s = NEW(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 = NEW(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;
-}
-
-
-/*x------------------------------------------------------------*/
-methSet *add2MethSet(methSet *sm, methodinfo *m)
-{
- methSetNode *snew;
- methSetNode *s;
-
- if (sm == NULL) {
- sm = createMethSet();
- }
- s = sm->head;
- if (!inMethSet(s,m)) {
- snew = NEW(methSetNode);
- if (sm->head == NULL) {
- sm->head = snew;
- sm->pos = snew;
- snew->index = 1;
- }
- else {
- sm->tail->nextmethRef = snew;
- sm->length++;
- snew->index = sm->length;
- }
- snew->monoPoly = MONO;
- snew->nextmethRef= NULL;
- snew->methRef = m;
- snew->lastptrIntoClassSet2 = NULL; /* ????? */
- sm->tail = snew;
- }
- return sm;
-}
-
-
-/*------------------------------------------------------------*/
-methSet *createMethSet( )
-{
- methSet *s;
- s = NEW(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 = NEW(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 = NEW(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 = NEW(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;
- LAZYLOADING(c) /* ??? is c reallz needed ???*/
- 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 = NEW(classSetNode);
- s1->nextClass= s;
- s1->classType = c;
- if (s == NULL)
- s1->index = 1;
- else
- s1->index = s->index+1;
- }
- return s1;
-}
-
-
-/*------------------------------------------------------------*/
-/* intersect the subtypes of class t with class set s */
-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 *t_cl_vt;
- vftbl_t *c_cl_vt;
- LAZYLOADING(c->classType)
- LAZYLOADING(t)
- t_cl_vt = t->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;
-}
-
-
-#if !defined(NDEBUG)
-/*------------------------------------------------------------*/
-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_println(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");fflush(stdout);
- return 0;
- }
- else {
- if (sm->head == NULL) {
- printf("Set of Methods: "); fflush(stdout);
- printf("\t\tEmpty Set\n"); fflush(stdout);
- 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->writePUT,i->readGET);
- field_println(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 */
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */
+++ /dev/null
-/* vm/jit/sets.h -
-
- Copyright (C) 1996-2005, 2006 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.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Contact: cacao@cacaojvm.org
-
- Authors: Carolyn Oates
-
- $Id: sets.h 4357 2006-01-22 23:33:38Z twisti $
-
-*/
-
-
-#ifndef _SET_H
-#define _SET_H
-
-typedef struct methSet methSet;
-typedef struct methSetNode methSetNode;
-typedef struct fldSet fldSet;
-typedef struct fldSetNode fldSetNode;
-typedef struct classSet classSet;
-typedef struct classSetNode classSetNode;
-
-
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/field.h"
-
-
-/*------------ 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 SYSCALL -1 /* XTA initialization ??? should it be used for RTA for main ??? */
-#define MONO 0
-#define MONO1 1 /* potential poly that is really mono */
-#define POLY 2
-
-/*------------------------------------------------------------*/
-/*-- flds used by a method set fns */
-/*------------------------------------------------------------*/
-struct fldSet {
- fldSetNode *head;
- fldSetNode *tail;
- fldSetNode *pos;
- s4 length;
-};
-
-
-struct fldSetNode {
- fieldinfo *fldRef;
- fldSetNode *nextfldRef;
- bool writePUT;
- bool readGET;
- classSetNode *lastptrPUT;
- classSetNode *lastptrGET;
- s2 index;
-};
-
-
-fldSetNode *inFldSet (fldSetNode *, fieldinfo *);
-fldSetNode *addFldRef (fldSetNode *, fieldinfo *);
-fldSet *add2FldSet (fldSet *, fieldinfo *, bool, bool);
-fldSet *createFldSet (void);
-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 (void);
-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 (void);
-int inRange (classSetNode *, classinfo *);
-classSetNode *addClassCone (classSetNode *, classinfo *);
-classSetNode *intersectSubtypesWithSet(classinfo *, classSetNode *);
-int sizeOfSet (classSetNode *s);
-int setSize (classSetNode *);
-int printSet (classSetNode *);
-int printClassSet (classSet *);
-/**classSetNode *copyClassSet (classSetNode *); **/
-
-#endif /* _SETS_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- */