* Updated header: Added 2006. Changed address of FSF. Changed email
[cacao.git] / src / vm / jit / inline / inline.c
index 5b3d9b94901bea2c2f12e8b5b87e8616fe071642..6ca958d0a972fc5a4e9d9622a79508e36107db68 100644 (file)
@@ -1,9 +1,9 @@
 /* src/vm/jit/inline/inline.c - code inliner
 
-   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
+   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.
 
 
    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., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Dieter Thuernbeck
 
-   $Id: inline.c 2017 2005-03-09 11:37:33Z twisti $
+   Changes: Christian Thalinger
+
+   $Id: inline.c 4357 2006-01-22 23:33:38Z twisti $
 
 */
 
@@ -56,15 +58,18 @@ Method to be inlined must:
 -ine  JOWENN <- please add
 ---*/
 
+
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 
 #include "mm/memory.h"
 #include "toolbox/logging.h"
 #include "vm/global.h"
+#include "vm/linker.h"
 #include "vm/loader.h"
-#include "vm/tables.h"
 #include "vm/options.h"
+#include "vm/resolve.h"
 #include "vm/statistics.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
@@ -79,20 +84,20 @@ Method to be inlined must:
         printf("<j%i/l%i/s%i/(p)%i>\t", \
                 (mm)->jcodelength,(mm)->maxlocals, \
                (mm)->maxstack, (mm)->paramcount);  \
-        method_display_w_class(mm); }
+        method_println(mm); }
 
 #define METHINFOx(mm) \
     { \
         printf("<c%i/m%i/p%i>\t", \
                 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
-        method_display_w_class(mm); }
+        method_println(mm); }
 
 #define METHINFO(m) \
-  method_display_w_class(m); 
+  method_println(m); 
 
 #define IMETHINFO(m) \
   utf_display(m->class->name); printf("."); fflush(stdout); \
-  method_display(m); fflush(stdout); \
+  method_println(m); fflush(stdout); \
   printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
   printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
   printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
@@ -125,7 +130,7 @@ void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
        inline_env->inlining_stack = NULL;
        inline_env->inlining_rootinfo = NULL;
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        if (in_stats1) {
                int ii;
                for (ii=0; ii<512; ii++) count_in_not[ii]=0;
@@ -143,13 +148,6 @@ void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
 /*     t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
         inlining_init0(m,inline_env);
 
-/* define in options.h; Used in main.c, jit.c & inline.c */
-#ifdef INAFTERMAIN
-if ((utf_new_char("main") == m->name) && (useinliningm)) {
-       useinlining = true;
-       }
-#endif
-
 if (useinlining)
         {
                #ifdef DEBUGi
@@ -242,7 +240,10 @@ void inlining_pop_compiler_variables(
        t_inlining_stacknode *tmp 
          = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
 
-       if (!inline_env->isinlinedmethod) panic("Attempting to pop from inlining stack in toplevel method!\n");
+       if (!inline_env->isinlinedmethod) {
+               log_text("Attempting to pop from inlining stack in toplevel method!");
+               assert(0);
+       }
 
        *i = tmp->i;
        *p = tmp->p;
@@ -384,9 +385,9 @@ bool can_inline (
 bool can = false;
 u2 whycannot = 0;
 if ((inline_env->cummethods < INLINING_MAXMETHODS) && 
-   /*** (!(imi->flags & ACC_ABSTRACT)) && /** Problem from INVOKE STATIC **/
+   /*** (!(imi->flags & ACC_ABSTRACT)) && ** Problem from INVOKE STATIC **/
     (!(imi->flags & ACC_NATIVE)) &&
-    (inlineoutsiders || (m->class == imr->class)) &&
+    (inlineoutsiders || (m->class->name == imr->classref->name)) &&
     (imi->jcodelength < INLINING_MAXCODESIZE) &&
     (imi->jcodelength > 0) &&       /* FIXME: eliminate empty methods? also abstract??*/
     (((!inlinevirtuals)  ||
@@ -394,7 +395,7 @@ if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
      ((opcode != JAVA_INVOKEVIRTUAL) ||
       (opcode != JAVA_INVOKEINTERFACE)) ) &&
     (inlineexceptions || (imi->exceptiontablelength == 0)))  {
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        count_in++;
        if (inlinevirtuals) { 
                if   (opcode == JAVA_INVOKEVIRTUAL) {
@@ -418,7 +419,7 @@ if (!can) {
 
 if  (imi->flags & ACC_NATIVE) return can; 
 if  (imi->flags & ACC_ABSTRACT) return can; 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
   count_in_rejected++;
 #endif
                                                if (opt_verbose) 
@@ -432,16 +433,16 @@ if  (imi->flags & ACC_ABSTRACT) return can;
                                                        METHINFOj(imi)
                                                        }
 
-  if  (!(inlineoutsiders) && (m->class != imr->class)) {
+  if  (!(inlineoutsiders) && (m->class->name != imr->classref->name)) {
        /*** if ((!mult) && (whycannot > 0)) mult = true;  *** First time not needed ***/
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        count_in_outsiders++;
 #endif
        whycannot = whycannot | IN_OUTSIDERS; /* outsider */ 
        }
   if (inline_env->cummethods >= INLINING_MAXMETHODS) { 
        if ((!mult) && (whycannot > 0)) mult = true; 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        count_in_maxDepth++;
 #endif
        whycannot = whycannot | IN_MAXDEPTH;  
@@ -464,13 +465,13 @@ if  (imi->flags & ACC_ABSTRACT) return can;
        if (uniqueVirt )   { 
                /* so know why (and that) a unique virtual was rejected for another reason */ 
                if (opcode == JAVA_INVOKEVIRTUAL) { 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        count_in_uniqueVirt_not_inlined++;
 #endif
                        whycannot = whycannot | IN_UNIQUEVIRT;  
                        }
                else    {
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                        count_in_uniqueInterface_not_inlined++;
 #endif
                        whycannot = whycannot | IN_UNIQUE_INTERFACE;  
@@ -487,19 +488,22 @@ if  (imi->flags & ACC_ABSTRACT) return can;
                }       
        }       
 
-  if  (inlineoutsiders && (m->class != imr->class)) {
+  if  (inlineoutsiders && (m->class->name != imr->classref->name)) {
        whycannot = whycannot | IN_OUTSIDERS; /* outsider */ 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
        count_in_outsiders++;
 #endif
        }
 
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
   if (mult)  
        count_in_rejected_mult++;
 #endif
-  if (whycannot > ((1<<IN_MAX)-1)) panic ("Inline Whynot is too large???\n");
-#if defined(STATISTICS)
+  if (whycannot > ((1<<IN_MAX)-1)) {
+         log_text("Inline Whynot is too large???");
+         assert(0);
+  }
+#if defined(ENABLE_STATISTICS)
   count_in_not[whycannot]++; 
 #endif
   }
@@ -694,7 +698,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m,
                if (opt_stat) { 
                        if ((!isnotrootlevel) && !maxdepthHit) {
                                maxdepthHit = true;
-#if defined(STATISTICS)
+#if defined(ENABLE_STATISTICS)
                                count_in_maxDepth++;
 #endif
                        }
@@ -714,6 +718,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m,
                                {
                                        constant_FMIref *imr;
                                        methodinfo *imi;
+                                       classinfo *imrclass;
 
                                         methodinfo *mout;
                                         bool uniqueVirt= false;
@@ -721,31 +726,49 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m,
 
                                        if (opcode ==JAVA_INVOKEINTERFACE) {
                                            imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
-                                           LAZYLOADING(imr->class)
+                                               if (!imr)
+                                                       return NULL;
+                                               if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
+                                                       log_text("Could not resolve class reference");
+                                                       assert(0);
+                                               }
+                                           LAZYLOADING(imrclass)
                                             imi = class_resolveinterfacemethod(
-                                               imr->class,
+                                               imrclass,
                                                 imr->name,
                                                 imr->descriptor,
                                                 m->class,
                                                        true);
-                                           if (!imi)  /* extra for debug */
-                                               panic("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
-                                          }
-                                       else {
-                                          imr = class_getconstant(m->class, i, CONSTANT_Methodref);
-                                          LAZYLOADING(imr->class)
+                                           if (!imi) { /* extra for debug */
+                                                       log_text("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
+                                                       assert(0);
+                                               }
+
+                                       } else {
+                                               imr = class_getconstant(m->class, i, CONSTANT_Methodref);
+                                               if (!imr)
+                                                       return NULL;
+                                               if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
+                                                       log_text("Could not resolve class reference");
+                                                       assert(0);
+                                               }
+                                          LAZYLOADING(imrclass)
                                           imi = class_resolveclassmethod(
-                                               imr->class,
+                                               imrclass,
                                                imr->name,
                                                imr->descriptor,
                                                m->class,
                                                true);
-                                           if (!imi) /* extra for debug */
-                                               panic("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
+                                           if (!imi) { /* extra for debug */
+                                                       log_text("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
+                                                       assert(0);
+                                               }
                                            }
 
-                                       if (!imi) /* normal-but never get here now */ 
-                                               panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
+                                       if (!imi) { /* normal-but never get here now */ 
+                                               log_text("Exception thrown while parsing bytecode"); /* XXX should be passed on */
+                                               assert(0);
+                                       }
 
 /** Inlining has problem currently with typecheck & inlining **/
 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
@@ -788,7 +811,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m,
 
                                        if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
                                                inlining_methodinfo *tmp;
-                                               descriptor2types(imi);
+                                               method_descriptor2types(imi);
 
                                                inline_env->cummethods++;
 
@@ -919,7 +942,7 @@ printf("\n\tinlining_methodinfo for:"); fflush(stdout);
 
 if (r->method != NULL) {
   utf_display(r->method->class->name); printf("."); fflush(stdout); \
-  method_display(r->method); fflush(stdout); \
+  method_println(r->method); fflush(stdout); \
   }
 else {
   printf(" NULL!!!!!\n");fflush(stdout);