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