X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Finline%2Finline.c;h=7e69fe93e9b8b2fa143e5653c19525f814cbdc37;hb=89c0a10b633ca5dace9c4072f34078a8dd660005;hp=7afd8a6b21f78e8aa69ddd265d1ef517b5c59168;hpb=a5e50b963d8361674a679587d9d246bf9fc20d98;p=cacao.git diff --git a/src/vm/jit/inline/inline.c b/src/vm/jit/inline/inline.c index 7afd8a6b2..7e69fe93e 100644 --- a/src/vm/jit/inline/inline.c +++ b/src/vm/jit/inline/inline.c @@ -2,10 +2,10 @@ 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. @@ -28,26 +28,64 @@ globals moved to structure and passed as parameter Authors: Dieter Thuernbeck - $Id: inline.c 1494 2004-11-12 13:34:26Z twisti $ + $Id: inline.c 1744 2004-12-09 10:17:12Z carolyn $ */ +/*--- +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 #include -#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("\t", \ + (mm)->jcodelength,(mm)->maxlocals, \ + (mm)->maxstack, (mm)->paramcount); \ + method_display_w_class(mm); } + +#define METHINFOx(mm) \ + { \ + printf("\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); \ @@ -57,11 +95,13 @@ globals moved to structure and passed as parameter 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("\t",cls->classUsed); \ + utf_display(cls->name); printf("\n");fflush(stdout);} /*-----------------------------------------------------------*/ /* just initialize global structure for non-inlining */ @@ -74,7 +114,7 @@ void inlining_init0(methodinfo *m, t_inlining_globals *inline_env) 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? */ @@ -98,19 +138,25 @@ if ((utf_new_char("main") == m->name) && (useinliningm)) 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) { @@ -119,15 +165,16 @@ if (DEBUGi==true) {print_t_inlining_globals(inline_env);} 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 } } @@ -139,6 +186,20 @@ void inlining_cleanup(t_inlining_globals *inline_env) } +/*--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); @@ -194,129 +255,108 @@ void inlining_pop_compiler_variables( 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; + 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_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; -} - - -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, @@ -335,15 +375,14 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, 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 */ @@ -360,6 +399,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, 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; @@ -488,17 +528,18 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, } /* 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); @@ -506,60 +547,96 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *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("") == imi->name) || - (utf_new_char("") == imi->name)) break; - +/** Inlining has problem currently with typecheck & inlining **/ +/** Due problem with typecheck & inlining, class checks fail for s **/ + if (utf_new_char("") == 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); @@ -574,7 +651,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, || (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"); } @@ -582,6 +659,12 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, 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; } @@ -592,17 +675,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, } /* 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;istopgp); - } - + label_index[jcodelength]=gp; return newnode; } @@ -612,7 +685,7 @@ inlining_methodinfo *inlining_analyse_method(methodinfo *m, 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); @@ -631,71 +704,71 @@ printf("\tcumlocals=%i ,cummethods=%i \n", 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=0; + 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) @@ -706,21 +779,49 @@ else { } } - +/**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/ printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", - r->startgp, r->stopgp, r->firstlocal, r->label_index); -{int i; + r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index); printf ("label_index[0..%d]->", r->method->jcodelength); -for (i=0; imethod->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); +if (labellong) { +for (i=0; imethod->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); + } + } + } }