globals moved to structure and passed as parameter
- 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: Dieter Thuernbeck
- $Id: inline.c 1494 2004-11-12 13:34:26Z twisti $
+ $Id: inline.c 1735 2004-12-07 14:33:27Z twisti $
*/
+/*---
+Inlining initializes an inline structure with values of the method called
+with. Then it recursively to MAXDEPTH analyzes by parsing the bytecode
+looking for methods that meet the critera to be inlined.
+
+Critera for inlining currently is:
+Method to be inlined must:
+- be less than MAXCODESIZE
+- only MAXMETHODS can be inlined in 1 method
+
+-in only STATIC, FINAL, PRIVATE methods can be inlined from method's class
+-ino (include outsiders) all STATIC, FINAL, PRIVATE methods can be inlined
+-inv include virtual methods which static analysis (currently only RTA)
+ to only have 1 definition used (INVOKEVIRTUAL/INVOKEINTERFACE)
+ Currently dynamic loading is handled by rerunning with info
+ (see parseRT). Guards need to be added.
+-inp inline parameters (needs work) Parameters are analysed if they are
+ readonly but the information does not seem to be used.
+-ine JOWENN <- please add
+---*/
#include <stdio.h>
#include <string.h>
-#include "global.h"
-#include "loader.h"
-#include "tables.h"
-#include "options.h"
-#include "jit/inline.h"
-#include "jit/jit.h"
-#include "jit/parse.h"
+
+#include "mm/memory.h"
#include "toolbox/logging.h"
-#include "toolbox/memory.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/tables.h"
+#include "vm/options.h"
+#include "vm/jit/jit.h"
+#include "vm/jit/parse.h"
+#include "vm/jit/inline/inline.h"
+#include "vm/jit/inline/sets.h"
+
+#undef INVIRTDEBUG /* prints if a method was found to be
+ a unique virt/interface method definition */
+#undef DEBUGi
+
+#define METHINFOj(mm) \
+ { \
+ printf("<j%i/l%i/s%i/(p)%i>\t", \
+ (mm)->jcodelength,(mm)->maxlocals, \
+ (mm)->maxstack, (mm)->paramcount); \
+ method_display_w_class(mm); }
+
+#define METHINFOx(mm) \
+ { \
+ printf("<c%i/m%i/p%i>\t", \
+ (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
+ method_display_w_class(mm); }
#define METHINFO(m) \
- utf_display(m->class->name); printf("."); fflush(stdout); \
- method_display(m); fflush(stdout); \
+ method_display_w_class(m);
#define IMETHINFO(m) \
utf_display(m->class->name); printf("."); fflush(stdout); \
printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
-bool DEBUGi = false;
/* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
/* replace jcodelength loops with correct number after main for loop in parse()! */
+#define CLASSINFO(cls) \
+ { printf("<c%i>\t",cls->classUsed); \
+ utf_display(cls->name); printf("\n");fflush(stdout);}
/*-----------------------------------------------------------*/
/* just initialize global structure for non-inlining */
inline_env->isinlinedmethod = 0;
inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
- inline_env->cummaxstack = m->maxstack; /*why has here been 0 ? */
+ inline_env->cummaxstack = m->maxstack;
inline_env->cumextablelength = 0;
inline_env->cumlocals = m->maxlocals;
inline_env->cummethods = 0; /* co not global or static-used only here? */
if (useinlining)
{
-if (DEBUGi==true) {
+ #ifdef DEBUGi
printf("\n-------- Inlining init for: "); fflush(stdout);
IMETHINFO(m)
- }
+ #endif
+
inline_env->cumjcodelength = 0;
inline_env->inlining_stack = NEW(list);
list_init(inline_env->inlining_stack,
OFFSET(t_inlining_stacknode, linkage));
/*------ analyze ------*/
-if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
inline_env->inlining_rootinfo
= inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
-if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
+ #ifdef DEBUGi
+ printf ("\n------------------------------ ");fflush(stdout);
+ printf ("\nComplete Result of inlining analysis of:");
+ fflush(stdout);
+ METHINFOj(m)
+ print_t_inlining_globals(inline_env); /* init ok */
+ #endif
/*---------------------*/
/*
if (inline_env->cummethods == 0) {
return inline_env;
}
*/
-if (DEBUGi==true) {
+#if 0
+ #ifdef DEBUGi
printf("(l,s) (%i,%i) was (%i,%i)\n",
m->maxlocals, inline_env->cumlocals,
m->maxstack, inline_env->cummaxstack); fflush(stdout);
- }
-#if 0
+ #endif
/*This looks wrong*/
- m->maxlocals = inline_env->cumlocals; //orig not used
- m->maxstack = inline_env->cummaxstack; //orig global maxstack var!!
+/* OK since other changes were also made, but in parse same stmt still */
+ m->maxlocals = inline_env->cumlocals; orig not used
+ m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
#endif
}
}
}
+/*--2 push the compile variables to save the method's environment --*/
+
+void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
+{
+ t_inlining_stacknode *new = NEW(t_inlining_stacknode);
+
+ /**new->opcode = opcode; **/
+ new->method = inline_env->method;
+ new->inlinfo = inlinfo;
+ list_addfirst(inline_env->inlining_stack, new);
+ inline_env->isinlinedmethod++;
+}
+/*-- push the compile variables to save the method's environment --*/
+
void inlining_push_compiler_variables(int i, int p, int nextp, int opcode, u2 lineindex,u2 currentline,u2 linepcchange,inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
{
t_inlining_stacknode *new = NEW(t_inlining_stacknode);
void inlining_set_compiler_variables_fun(methodinfo *m,
t_inlining_globals *inline_env)
{
- /* XXX TWISTI */
- inline_env->method = m; /*co*/
- inline_env->class = m->class; /*co*/
- inline_env->jcode = m->jcode; /*co*/
- inline_env->jcodelength = m->jcodelength; /*co*/
-}
-
-
-classinfo *first_occurence(classinfo* class, utf* name, utf* desc)
-{
- classinfo *first = class;
-
- for (; class->super != NULL ; class = class->super) {
- if (class_findmethod(class->super, name, desc) != NULL) {
- first = class->super;
- }
- }
-
- return first;
-}
-
-
-bool is_unique_rec(classinfo *class, methodinfo *m, utf* name, utf* desc)
-{
- methodinfo *tmp = class_findmethod(class, name, desc);
- if ((tmp != NULL) && (tmp != m))
- return false;
-
- for (; class != NULL; class = class->nextsub) {
- if ((class->sub != NULL) && !is_unique_rec(class->sub, m, name, desc)) {
- return false;
- }
- }
- return true;
+ inline_env->method = m;
+ inline_env->class = m->class;
+ inline_env->jcode = m->jcode;
+ inline_env->jcodelength = m->jcodelength;
}
+/* is_unique_method2 - determines if m is a unique method by looking
+ in subclasses of class that define method m
+ It counts as it goes. It also saves the method name if found.
-bool is_unique_method(classinfo *class, methodinfo *m, utf* name, utf* desc)
-{
- classinfo *firstclass;
-
- /* sprintf (logtext, "First occurence of: ");
- utf_sprint (logtext+strlen(logtext), m->class->name);
- strcpy (logtext+strlen(logtext), ".");
- utf_sprint (logtext+strlen(logtext), m->name);
- utf_sprint (logtext+strlen(logtext), m->descriptor);
- dolog (); */
-
- firstclass = first_occurence(class, name, desc);
-
- /* sprintf (logtext, "\nis in class:");
- utf_sprint (logtext+strlen(logtext), firstclass->name);
- dolog (); */
-
- if (firstclass != class) return false;
-
- return is_unique_rec(class, m, name, desc);
-}
-
-/* is_unique_method2 - returns count of # methods used up to 2
- since if 2 used then not unique.
- Chose not to make an extra fn call so
- can return boolean instead of cnt.
- It looks for subclasses with method def'd.
-
- This replaces is_unique_method which for
- reasons unknown looks up the class heirarchy
- not down at subclasses.
-
+ returns count of # methods used up to 2
+ (since if 2 used then not unique.)
+ sets mout to method found
+ (unique in class' heirarchy)
+ It looks for subclasses with method def'd.
+ Input:
* class - where looking for method
* m - original method ptr
- * name - utf name of method
- * desc - utf method descriptor
+ * mout - unique method (output)
+ Output: "cnt" of methods found up to max of 2 (then not unique)
*/
-int is_unique_method2(classinfo *class, methodinfo *m, utf* name, utf* desc)
+
+int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
{
+utf* name = m->name;
+utf* desc = m->descriptor;
+
int cnt = 0; /* number of times method found in USED classes in hierarchy*/
-classinfo *subs;
+classinfo *subs1;
-if ((m->class == class) && (class->classUsed == USED))
- cnt++;
+if ((m->class == class) && (class->classUsed == USED)) {
+ /* found method in current class, which is used */
+ if (*mout != m) {
+ cnt++;
+ *mout = m;
+ }
+ }
-if ( ((m->flags & ACC_FINAL) &&
- (m->monoPoly != POLY))
- || (class->sub == NULL))
- return cnt;
+if ( ((m->flags & ACC_FINAL)
+|| (class->sub == NULL))
+&& (class->classUsed == USED)) {
+ /* if final search no further */
+ if (*mout != m) {
+ cnt++;
+ *mout = m;
+ }
+ return cnt;
+ }
-for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
+/* search for the method in its subclasses */
+for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
methodinfo * sm;
-
+ classinfo *subs = subs1;
sm = class_resolveclassmethod(subs,name,desc,class,false);
if (sm != NULL) {
- cnt =+ is_unique_method2(subs,sm,name,desc);
+ if ((subs->classUsed == USED) &&
+ (*mout != sm)) {
+ *mout = sm;
+ cnt++;
+ }
+ cnt = cnt + is_unique_method2(subs, sm, mout);
+ /* Not unique if more than 1 def of method in class heir */
if (cnt > 1)
- return cnt;
+ {return cnt;}
}
- }
+ }
return cnt;
}
-methodinfo *get_unique_method2(classinfo *class, methodinfo *m, utf* name, utf* desc)
-{
-methodinfo * imi;
-classinfo *subs;
-
-if ((m->class == class) && (class->classUsed == USED))
- return m;
+/*-----------------------------------------------------------*/
-for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
- methodinfo * sm;
+bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
- sm = class_resolveclassmethod(subs,name,desc,class,false);
- if (sm != NULL) {
- imi = get_unique_method2(subs,sm,name,desc);
- if (imi != NULL)
- return sm;
- }
- }
+utf* name = mi->name;
+utf* desc = mi->descriptor;
+
-return NULL;
-}
+ classSetNode *classImplNode;
+ int icnt = 0;
+
+ for (classImplNode = mi->class->impldBy;
+ classImplNode != NULL;
+ classImplNode = classImplNode->nextClass) {
+
+ classinfo * classImplements = classImplNode->classType;
+ methodinfo *submeth;
+
+ submeth = class_findmethod(classImplements,name, desc);
+ if (submeth != NULL) {
+ icnt =+ is_unique_method2(
+ classImplements,
+ submeth,
+ mout);
+ }
+ if (icnt > 1) return false;
+ } /* end for*/
+if (icnt == 1) return true;
+else return false;
+}
+/*-----------------------------------------------------------*/
inlining_methodinfo *inlining_analyse_method(methodinfo *m,
int level, int gp,
int *label_index = NULL;
bool isnotrootlevel = (level > 0);
bool isnotleaflevel = (level < INLINING_MAXDEPTH);
+ #ifdef DEBUGi
+ printf ("\n------------------------------ ");fflush(stdout);
+ printf ("\nStart of inlining analysis of: ");fflush(stdout);
+ METHINFOj(m)
+ print_t_inlining_globals(inline_env); /* init ok */
+ #endif
/* if (level == 0) gp = 0; */
- /*
- sprintf (logtext, "Performing inlining analysis of: ");
- utf_sprint (logtext+strlen(logtext), m->class->name);
- strcpy (logtext+strlen(logtext), ".");
- utf_sprint (logtext+strlen(logtext), m->name);
- utf_sprint (logtext+strlen(logtext), m->descriptor);
- dolog (); */
if (isnotrootlevel) {
newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary */
list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
newnode->method = m;
+ newnode->level = level;
newnode->startgp = gp;
newnode->readonly = readonly;
newnode->label_index = label_index;
}
/* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
- // printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
+ printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
lastlabel = p+1; */
for (i = p; i < nextp; i++) label_index[i] = gp;
if (isnotleaflevel) {
switch (opcode) {
+
+ case JAVA_INVOKEINTERFACE:
case JAVA_INVOKEVIRTUAL:
- if (!inlinevirtuals)
+ if (!inlinevirtuals)
break;
- /*log_text("\nINLINE INVOKEVIRTUAL :\t");*/
case JAVA_INVOKESPECIAL:
case JAVA_INVOKESTATIC:
i = code_get_u2(p + 1,m);
constant_FMIref *imr;
methodinfo *imi;
- methodinfo *imi1;
+ methodinfo *mout;
bool uniqueVirt= false;
- int vcnt=0;
-
- imr = class_getconstant(m->class, i, CONSTANT_Methodref);
-
- if (!class_load(imr->class))
- return NULL;
- if (!class_link(imr->class))
- return NULL;
- imi = class_resolveclassmethod(imr->class,
- imr->name,
- imr->descriptor,
- m->class,
- true);
-
- if (!imi)
+ if (opcode ==JAVA_INVOKEINTERFACE) {
+ imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
+ LAZYLOADING(imr->class)
+ imi = class_resolveinterfacemethod(
+ imr->class,
+ 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)
+ imi = class_resolveclassmethod(
+ imr->class,
+ 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) /* normal-but never get here now */
panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
- if ( (utf_new_char("<init>") == imi->name) ||
- (utf_new_char("<clinit>") == imi->name)) break;
-
+/** Inlining has problem currently with typecheck & inlining **/
+/** Due problem with typecheck & inlining, class checks fail for <init>s **/
+ if (utf_new_char("<init>") == imi->name) break;
+/****/
if (opcode == JAVA_INVOKEVIRTUAL) {
- vcnt = is_unique_method2(imi->class, imi, imr->name, imr->descriptor);
- if (vcnt == 1) {
-
- imi1 = get_unique_method2(imi->class, imi, imr->name, imr->descriptor);
- if (imi1 != NULL) {
- imi = imi1;
- /*log_text("WAS unique virtual\t");*/
- /**/ uniqueVirt=true; /* comment out to permanently turn off inlining virtuals*/
+ mout = NULL;
+ /* unique virt meth? then */
+ /* allow it to be inlined*/
+ if (is_unique_method2(
+ imi->class,
+ imi,
+ &mout) == 1) {
+ if (mout != NULL) {
+ imi = mout;
+ uniqueVirt=true;
+#ifdef INVIRTDEBUG
+ METHINFOx(imi);
+ printf("WAS unique virtual(-iv)\n");fflush(stdout);
+#endif
}
- } /* end if vcnt */
-
- if (!is_unique_method(imi->class, imi, imr->name, imr->descriptor))
- break;
- }
+ } /* end is unique */
+ } /* end INVOKEVIRTUAL */
+ if (opcode == JAVA_INVOKEINTERFACE){
+ mout = NULL;
+#ifdef INVIRTDEBUG
+ METHINFOx(imi);
+#endif
+ if (is_unique_interface_method (
+ imi,
+ &mout)) {
+ if (mout != NULL) {
+ imi = mout;
+ uniqueVirt=true;
+#ifdef INVIRTDEBUG
+ METHINFOx(imi);
+ printf("WAS unique interface(-iv)\n");fflush(stdout);
+#endif
+ }
+
+ }
+ } /* end INVOKEINTERFACE */
- /*if (imi->flags & ACC_NATIVE) log_text("Native method,no inlining");*/
if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
(!(imi->flags & ACC_NATIVE)) &&
(inlineoutsiders || (m->class == imr->class)) &&
(imi->jcodelength < INLINING_MAXCODESIZE) &&
(imi->jcodelength > 0) &&
- (((!inlinevirtuals) || (uniqueVirt)) || (opcode != JAVA_INVOKEVIRTUAL)) &&
+ (((!inlinevirtuals) ||
+ (uniqueVirt )) ||
+ ((opcode != JAVA_INVOKEVIRTUAL) ||
+ (opcode != JAVA_INVOKEINTERFACE)) ) &&
(inlineexceptions || (imi->exceptiontablelength == 0))) { /* FIXME: eliminate empty methods? */
inlining_methodinfo *tmp;
descriptor2types(imi);
inline_env->cummethods++;
- if (verbose) {
+ if (opt_verbose) {
char logtext[MAXLOGTEXT];
sprintf(logtext, "Going to inline: ");
utf_sprint(logtext +strlen(logtext), imi->class->name);
|| (imi->flags & ACC_FINAL ))) )
{
printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
- METHINFO(imi);
+ METHINFOx(imi);
log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
}
tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
list_addlast(newnode->inlinedmethods, tmp);
+ #ifdef DEBUGi
+printf("New node Right after an inline by:");fflush(stdout);
+METHINFOj(m)
+print_inlining_methodinfo(newnode);
+printf("end new node\n"); fflush(stdout);
+ #endif
gp = tmp->stopgp;
p = nextp;
}
} /* for */
newnode->stopgp = gp;
-
- if (DEBUGi==true) {
- printf ("\nResult of inlining analysis of: ");
- IMETHINFO(m);
- printf("was called by:\n"); fflush(stdout);
- IMETHINFO(inline_env->method);
- printf ("label_index[0..%d]->", jcodelength);
- for (i=0;i<jcodelength; i++) printf ("%d:%d ", i, label_index[i]);
- printf("stopgp : %d\n",newnode->stopgp);
- }
-
+ label_index[jcodelength]=gp;
return newnode;
}
void print_t_inlining_globals (t_inlining_globals *g)
{
printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
-METHINFO(g->method);
+METHINFOj(g->method);
printf("\tclass=");fflush(stdout);
utf_display(g->class->name);printf("\n");fflush(stdout);
g->cumlocals, g->cummethods);fflush(stdout);
printf("s>s>s> ");fflush(stdout);
-print_inlining_stack (g->inlining_stack);
+ print_inlining_stack (g->inlining_stack);
printf("i>i>i> "); fflush(stdout);
-print_inlining_methodinfo(g->inlining_rootinfo);
+ print_inlining_methodinfo(g->inlining_rootinfo);
printf("-------------------\n");fflush(stdout);
}
/* --------------------------------------------------------------------*/
void print_inlining_stack ( list *s)
{
+ t_inlining_stacknode *is;
+
if (s==NULL) {
printf("\n\tinlining_stack: NULL\n");
return;
}
-
- {/* print first element to see if get into stack */
- t_inlining_stacknode *is;
- printf("\n\tinlining_stack: NOT NULL\n");
- is=list_first(s);
- if (is==NULL) {
+/* print first element to see if get into stack */
+printf("\n\tinlining_stack: NOT NULL\n");
+
+is=list_first(s);
+if (is==NULL) {
printf("\n\tinlining_stack = init'd but EMPTY\n");
fflush(stdout);
return;
}
- }
-
- {
- t_inlining_stacknode *is;
- printf("\n\tinlining_stack: NOT NULL\n");
+printf("\n\tinlining_stack: NOT NULL\n");
- for (is=list_first(s);
+for (is=list_first(s);
is!=NULL;
is=list_next(s,is)) {
printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
- METHINFO(is->method);
+ METHINFOx(is->method);
printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
is->i,is->p,is->nextp,is->opcode);fflush(stdout);
print_inlining_methodinfo(is->inlinfo);
} /*end for */
- }
-
}
/* --------------------------------------------------------------------*/
void print_inlining_methodinfo( inlining_methodinfo *r) {
+ int i;
+ int cnt,cnt2;
+ inlining_methodinfo *im;
+ inlining_methodinfo *im2;
+ bool labellong = false;
+
if (r==NULL) {
printf("\n\tinlining_methodinfo: NULL\n");
return;
}
+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); \
}
else {
- printf("method is NULL!!!!!\n");fflush(stdout);
+ printf(" NULL!!!!!\n");fflush(stdout);
}
-printf("\n\tinlining_methodinfo for:"); fflush(stdout);
if (r->readonly==NULL) {
printf("\treadonly==NULL ");fflush(stdout);
}
else {
- int i;
printf("\treadonly=");fflush(stdout);
for (i = 0; i < r->method->maxlocals; i++) {
if (r->readonly[i] == true)
printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
r->startgp, r->stopgp, r->firstlocal, r->label_index);
-{int i;
printf ("label_index[0..%d]->", r->method->jcodelength);
-for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]);
+if (labellong) {
+for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
+else {
+printf ("%d:%d ", 0, r->label_index[i]);
+printf ("%d:%d ",
+ (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
}
-{
-inlining_methodinfo *im;
-for (im=list_first(r->inlinedmethods);
- im!=NULL;
- im=list_next(r->inlinedmethods,im)) {
- }
-}
+printf("\n:::::inlines::::::::::::::::::::\n");
+if (list_first(r->inlinedmethods) == NULL) {
+ printf("Nothing\n");fflush(stdout);
+ }
+else {
+ for (im=list_first(r->inlinedmethods),cnt=0;
+ im!=NULL;
+ im=list_next(r->inlinedmethods,im),cnt++) {
+ printf("*"); fflush(stdout);
+ printf("%i:",cnt);
+ printf("[1L%i] ",im->firstlocal); fflush(stdout);
+ METHINFOj(im->method)
+ printf("::::: which inlines::"); fflush(stdout);
+ if (list_first(im->inlinedmethods) == NULL) {
+ printf("Nothing\n");fflush(stdout);
+ }
+ else {
+ printf("##"); fflush(stdout);
+ for (im2=list_first(im->inlinedmethods),cnt2=0;
+ im2!=NULL;
+ im2=list_next(im2->inlinedmethods,im2),cnt2++)
+ {
+ printf("\t%i::",cnt2); fflush(stdout);
+ printf("[1L%i] ",im2->firstlocal);
+ fflush(stdout);
+ METHINFOj(im2->method)
+ }
+ printf("\n"); fflush(stdout);
+ }
+ }
+ }
}