1 /* jit/inline.c - code inliner
3 globals moved to structure and passed as parameter
5 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
6 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
7 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
8 Institut f. Computersprachen - TU Wien
10 This file is part of CACAO.
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2, or (at
15 your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 Contact: cacao@complang.tuwien.ac.at
29 Authors: Dieter Thuernbeck
31 $Id: inline.c 1971 2005-03-01 20:06:36Z carolyn $
36 Inlining initializes an inline structure with values of the method called
37 with. Then it recursively to MAXDEPTH analyzes by parsing the bytecode
38 looking for methods that meet the critera to be inlined.
40 Critera for inlining currently is:
41 Method to be inlined must:
42 - be less than MAXCODESIZE
43 - only MAXMETHODS can be inlined in 1 method
45 -in only STATIC, FINAL, PRIVATE methods can be inlined from method's class
46 -ino (include outsiders) all STATIC, FINAL, PRIVATE methods can be inlined
47 note: PRIVATE is always only in the same class
48 -inv include virtual methods which static analysis (currently only RTA)
49 to only have 1 definition used (INVOKEVIRTUAL/INVOKEINTERFACE)
50 Currently dynamic loading is handled by rerunning with info
51 (see parseRT). Guards need to be added.
52 -inp inline parameters - Parameters are analysed if they are
53 readonly, which is used during parsing to generate ICMD_CLEAR_ARGREN
54 and ICMD_CLEAR_ARGREN is in turn used during stack analysis to
55 replace the ISTORE with a NOP so the same local variable is used.
56 Parameters are pushed on the stack, same as normal method
57 invocation when popped the local variable of calling program is used.
58 -ine JOWENN <- please add
64 #include "mm/memory.h"
65 #include "toolbox/logging.h"
66 #include "vm/global.h"
67 #include "vm/loader.h"
68 #include "vm/tables.h"
69 #include "vm/options.h"
70 #include "vm/statistics.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/inline/inline.h"
75 #undef INVIRTDEBUG /* prints if a method was found to be
76 a unique virt/interface method definition */
79 #define METHINFOj(mm) \
81 printf("<j%i/l%i/s%i/(p)%i>\t", \
82 (mm)->jcodelength,(mm)->maxlocals, \
83 (mm)->maxstack, (mm)->paramcount); \
84 method_display_w_class(mm); }
86 #define METHINFOx(mm) \
88 printf("<c%i/m%i/p%i>\t", \
89 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
90 method_display_w_class(mm); }
93 method_display_w_class(m);
95 #define IMETHINFO(m) \
96 utf_display(m->class->name); printf("."); fflush(stdout); \
97 method_display(m); fflush(stdout); \
98 printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
99 printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
100 printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
101 printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
103 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
105 /* replace jcodelength loops with correct number after main for loop in parse()! */
107 #define CLASSINFO(cls) \
108 { printf("<c%i>\t",cls->classUsed); \
109 utf_display(cls->name); printf("\n");fflush(stdout);}
111 static bool in_stats1 = true;
112 /*-----------------------------------------------------------*/
113 /* just initialize global structure for non-inlining */
114 /*-----------------------------------------------------------*/
116 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
118 /* initialization for normal use in parse */
119 inlining_set_compiler_variables_fun(m, inline_env);
120 inline_env->isinlinedmethod = 0;
121 inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
123 inline_env->cummaxstack = m->maxstack;
124 inline_env->cumextablelength = 0;
125 inline_env->cumlocals = m->maxlocals;
126 inline_env->cummethods = 0; /* co not global or static-used only here? */
127 inline_env->inlining_stack = NULL;
128 inline_env->inlining_rootinfo = NULL;
131 for (ii=0; ii<512; ii++) count_in_not[ii]=0;
137 /*-----------------------------------------------------------*/
139 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
142 /* t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
143 inlining_init0(m,inline_env);
145 /* define in options.h; Used in main.c, jit.c & inline.c */
147 if ((utf_new_char("main") == m->name) && (useinliningm)) {
155 printf("\n-------- Inlining init for: "); fflush(stdout);
159 inline_env->cumjcodelength = 0;
160 inline_env->inlining_stack = NEW(list);
161 list_init(inline_env->inlining_stack,
162 OFFSET(t_inlining_stacknode, linkage));
163 /*------ analyze ------*/
164 inline_env->inlining_rootinfo
165 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
167 printf ("\n------------------------------ ");fflush(stdout);
168 printf ("\nComplete Result of inlining analysis of:");
171 print_t_inlining_globals(inline_env); /* init ok */
173 /*---------------------*/
175 if (inline_env->cummethods == 0) {
176 inline_env = DNEW(t_inlining_globals);
177 inlining_init0(m,inline_env);
183 printf("(l,s) (%i,%i) was (%i,%i)\n",
184 m->maxlocals, inline_env->cumlocals,
185 m->maxstack, inline_env->cummaxstack); fflush(stdout);
188 /* OK since other changes were also made, but in parse same stmt still */
189 m->maxlocals = inline_env->cumlocals; orig not used
190 m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
196 void inlining_cleanup(t_inlining_globals *inline_env)
198 FREE(inline_env->inlining_stack, t_inlining_stacknode);
202 /*--2 push the compile variables to save the method's environment --*/
204 void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
206 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
208 /**new->opcode = opcode; **/
209 new->method = inline_env->method;
210 new->inlinfo = inlinfo;
211 list_addfirst(inline_env->inlining_stack, new);
212 inline_env->isinlinedmethod++;
214 /*-- push the compile variables to save the method's environment --*/
216 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)
218 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
223 new->opcode = opcode;
224 new->method = inline_env->method;
225 new->lineindex=lineindex;
226 new->currentline=currentline;
227 new->linepcchange=linepcchange;
228 new->inlinfo = inlinfo;
229 list_addfirst(inline_env->inlining_stack, new);
230 inline_env->isinlinedmethod++;
234 void inlining_pop_compiler_variables(
235 int *i, int *p, int *nextp,
236 int *opcode, u2 *lineindex,
237 u2 *currentline,u2 *linepcchange,
238 inlining_methodinfo **inlinfo,
239 t_inlining_globals *inline_env)
241 t_inlining_stacknode *tmp
242 = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
244 if (!inline_env->isinlinedmethod) panic("Attempting to pop from inlining stack in toplevel method!\n");
249 *opcode = tmp->opcode;
251 *lineindex=tmp->lineindex;
252 *currentline=tmp->currentline;
253 *currentline=tmp->linepcchange;
255 *inlinfo = tmp->inlinfo;
257 inline_env->method = tmp->method; /*co*/
258 inline_env->class = inline_env->method->class; /*co*/
259 inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
260 inline_env->jcode = inline_env->method->jcode; /*co*/
262 list_remove(inline_env->inlining_stack, tmp);
263 FREE(tmp, t_inlining_stacknode);
264 inline_env->isinlinedmethod--;
268 void inlining_set_compiler_variables_fun(methodinfo *m,
269 t_inlining_globals *inline_env)
271 inline_env->method = m;
272 inline_env->class = m->class;
273 inline_env->jcode = m->jcode;
274 inline_env->jcodelength = m->jcodelength;
277 /* is_unique_method2 - determines if m is a unique method by looking
278 in subclasses of class that define method m
279 It counts as it goes. It also saves the method name if found.
281 returns count of # methods used up to 2
282 (since if 2 used then not unique.)
283 sets mout to method found
284 (unique in class' heirarchy)
285 It looks for subclasses with method def'd.
287 * class - where looking for method
288 * m - original method ptr
289 * mout - unique method (output)
290 Output: "cnt" of methods found up to max of 2 (then not unique)
293 int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
296 utf* desc = m->descriptor;
298 int cnt = 0; /* number of times method found in USED classes in hierarchy*/
301 if ((m->class == class) && (class->classUsed == USED)) {
302 /* found method in current class, which is used */
309 if ( ((m->flags & ACC_FINAL)
310 || (class->sub == NULL))
311 && (class->classUsed == USED)) {
312 /* if final search no further */
320 /* search for the method in its subclasses */
321 for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
323 classinfo *subs = subs1;
324 sm = class_resolveclassmethod(subs,name,desc,class,false);
326 if ((subs->classUsed == USED) &&
331 cnt = cnt + is_unique_method2(subs, sm, mout);
332 /* Not unique if more than 1 def of method in class heir */
341 /*-----------------------------------------------------------*/
343 bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
345 utf* name = mi->name;
346 utf* desc = mi->descriptor;
348 classSetNode *classImplNode;
351 for (classImplNode = mi->class->impldBy;
352 classImplNode != NULL;
353 classImplNode = classImplNode->nextClass) {
355 classinfo * classImplements = classImplNode->classType;
358 submeth = class_findmethod(classImplements,name, desc);
359 if (submeth != NULL) {
360 icnt =+ is_unique_method2(
365 if (icnt > 1) return false;
367 if (icnt == 1) return true;
371 /*-----------------------------------------------------------*/
374 t_inlining_globals *inline_env,
377 constant_FMIref *imr,
381 /* options used inlinevirtual / uniqueVirt / inlineexctions */
385 if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
386 /*** (!(imi->flags & ACC_ABSTRACT)) && /** Problem from INVOKE STATIC **/
387 (!(imi->flags & ACC_NATIVE)) &&
388 (inlineoutsiders || (m->class == imr->class)) &&
389 (imi->jcodelength < INLINING_MAXCODESIZE) &&
390 (imi->jcodelength > 0) && /* FIXME: eliminate empty methods? also abstract??*/
391 (((!inlinevirtuals) ||
393 ((opcode != JAVA_INVOKEVIRTUAL) ||
394 (opcode != JAVA_INVOKEINTERFACE)) ) &&
395 (inlineexceptions || (imi->exceptiontablelength == 0))) {
397 if (inlinevirtuals) {
398 if (opcode == JAVA_INVOKEVIRTUAL) {
399 if (uniqueVirt) count_in_uniqVirt++;
401 if (opcode == JAVA_INVOKEINTERFACE) {
402 if (uniqueVirt) count_in_uniqIntf++;
410 /*------ inline statistics ------*/
411 if ((!opt_stat) || can) return can;
416 if (imi->flags & ACC_NATIVE) return can;
417 if (imi->flags & ACC_ABSTRACT) return can;
420 {char logtext[MAXLOGTEXT];
421 sprintf(logtext, "Rejected to inline: ");
422 utf_sprint(logtext +strlen(logtext), imi->class->name);
423 strcpy(logtext + strlen(logtext), ".");
424 utf_sprint(logtext + strlen(logtext), imi->name);
425 utf_sprint(logtext + strlen(logtext), imi->descriptor);
430 if (!(inlineoutsiders) && (m->class != imr->class)) {
431 /*** if ((!mult) && (whycannot > 0)) mult = true; *** First time not needed ***/
432 count_in_outsiders++;
433 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
435 if (inline_env->cummethods >= INLINING_MAXMETHODS) {
436 if ((!mult) && (whycannot > 0)) mult = true;
438 whycannot = whycannot | IN_MAXDEPTH;
440 if (imi->jcodelength >= INLINING_MAXCODESIZE) {
441 if ((!mult) && (whycannot > 0)) mult = true;
442 whycannot = whycannot | IN_MAXCODE;
444 if (imi->jcodelength > 0) {
445 if ((!mult) && (whycannot > 0)) mult = true;
446 whycannot = whycannot | IN_JCODELENGTH;
448 if (!inlineexceptions && (imi->exceptiontablelength == 0)) {
449 whycannot = whycannot | IN_EXCEPTION;
451 /* These must be last so mult flag is set correctly */
452 if ( (inlinevirtuals) &&
453 ((opcode == JAVA_INVOKEVIRTUAL) ||
454 (opcode == JAVA_INVOKEINTERFACE)) ) {
456 /* so know why (and that) a unique virtual was rejected for another reason */
457 if (opcode == JAVA_INVOKEVIRTUAL) {
458 count_in_uniqueVirt_not_inlined++;
459 whycannot = whycannot | IN_UNIQUEVIRT;
462 count_in_uniqueInterface_not_inlined++;
463 whycannot = whycannot | IN_UNIQUE_INTERFACE;
466 else { /* not inlined because not not virtual */
467 if ((!mult) && (whycannot > 0)) mult = true;
468 if (opcode == JAVA_INVOKEVIRTUAL) {
469 whycannot = whycannot | IN_NOT_UNIQUE_VIRT;
472 whycannot = whycannot | IN_NOT_UNIQUE_INTERFACE;
477 if (inlineoutsiders && (m->class != imr->class)) {
478 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
479 count_in_outsiders++;
483 count_in_rejected_mult++;
484 if (whycannot > ((1<<IN_MAX)-1)) panic ("Inline Whynot is too large???\n");
485 count_in_not[whycannot]++;
492 /*-----------------------------------------------------------*/
495 inlining_methodinfo *inlining_analyse_method(methodinfo *m,
497 int firstlocal, int maxstackdepth,
498 t_inlining_globals *inline_env)
500 inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
501 /*u1 *jcode = m->jcode;*/
502 int jcodelength = m->jcodelength;
507 bool iswide = false, oldiswide;
508 bool *readonly = NULL;
509 int *label_index = NULL;
510 bool isnotrootlevel = (level > 0);
511 bool isnotleaflevel = (level < INLINING_MAXDEPTH);
512 bool maxdepthHit = false;
514 printf ("\n------------------------------ ");fflush(stdout);
515 printf ("\nStart of inlining analysis of: ");fflush(stdout);
517 if (isnotrootlevel) printf(" isnotrootlevel=T ");
518 else printf(" isnotrootlevel=F ");
519 print_t_inlining_globals(inline_env); /* init ok */
523 /* if (level == 0) gp = 0; */
525 if (isnotrootlevel) {
526 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary - ok FIXED also turned on*/
528 /** for (i = 0; i < m->maxlocals; readonly[i++] = true); **/
529 for (i = 0; i < m->paramcount; readonly[i++] = true);
530 /***isnotrootlevel = true; This had turned -inp off **/
536 label_index = DMNEW(int, jcodelength+200);
538 newnode->inlinedmethods = DNEW(list);
539 list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
542 newnode->level = level;
543 newnode->startgp = gp;
544 newnode->readonly = readonly;
545 newnode->label_index = label_index;
546 newnode->firstlocal = firstlocal;
547 inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
549 if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
550 inline_env->cumlocals = firstlocal + m->maxlocals;
553 if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
554 inline_env->cummaxstack = maxstackdepth + m->maxstack;
557 inline_env->cumextablelength += m->exceptiontablelength;
560 for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
561 opcode = code_get_u1 (p,m);
562 nextp = p + jcommandsize[opcode];
565 /* figure out nextp */
599 case JAVA_LOOKUPSWITCH:
600 nextp = ALIGN((p + 1), 4) + 4;
601 nextp += code_get_u4(nextp,m) * 8 + 4;
604 case JAVA_TABLESWITCH:
605 nextp = ALIGN((p + 1), 4) + 4;
606 nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
610 /* detect readonly variables in inlined methods */
612 if (isnotrootlevel) {
613 bool iswide = oldiswide;
622 i = code_get_u1(p + 1,m);
625 i = code_get_u2(p + 1,m);
660 i = code_get_u1(p + 1,m);
663 i = code_get_u2(p + 1,m);
670 /* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
671 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
673 for (i = p; i < nextp; i++) label_index[i] = gp;
676 if ((!isnotrootlevel) && !maxdepthHit) {maxdepthHit = true; count_in_maxDepth++; }
678 if (isnotleaflevel) {
682 case JAVA_INVOKEINTERFACE:
683 case JAVA_INVOKEVIRTUAL:
687 case JAVA_INVOKESPECIAL:
688 case JAVA_INVOKESTATIC:
689 i = code_get_u2(p + 1,m);
691 constant_FMIref *imr;
695 bool uniqueVirt= false;
698 if (opcode ==JAVA_INVOKEINTERFACE) {
699 imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
700 LAZYLOADING(imr->class)
701 imi = class_resolveinterfacemethod(
707 if (!imi) /* extra for debug */
708 panic("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
711 imr = class_getconstant(m->class, i, CONSTANT_Methodref);
712 LAZYLOADING(imr->class)
713 imi = class_resolveclassmethod(
719 if (!imi) /* extra for debug */
720 panic("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
723 if (!imi) /* normal-but never get here now */
724 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
726 /** Inlining has problem currently with typecheck & inlining **/
727 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
728 if (utf_new_char("<init>") == imi->name) break;
729 if (utf_new_char("finit$") == imi->name) break;
731 if (opcode == JAVA_INVOKEVIRTUAL) {
733 /* unique virt meth? then */
734 /* allow it to be inlined*/
735 if (is_unique_method2(imi->class, imi, &mout) == 1) {
742 printf("WAS unique virtual(-iv)\n");fflush(stdout);
745 } /* end is unique */
746 } /* end INVOKEVIRTUAL */
747 if (opcode == JAVA_INVOKEINTERFACE){
752 if (is_unique_interface_method (imi,&mout)) {
758 printf("WAS unique interface(-iv)\n");fflush(stdout);
763 } /* end INVOKEINTERFACE */
765 if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
766 inlining_methodinfo *tmp;
767 descriptor2types(imi);
769 inline_env->cummethods++;
772 {char logtext[MAXLOGTEXT];
773 printf("Going to inline: ");
775 printf("\nFrom "); fflush(stdout); METHINFOj(m)
776 sprintf(logtext, "Going to inline: ");
777 utf_sprint(logtext +strlen(logtext), imi->class->name);
778 strcpy(logtext + strlen(logtext), ".");
779 utf_sprint(logtext + strlen(logtext), imi->name);
780 utf_sprint(logtext + strlen(logtext), imi->descriptor);
782 sprintf(logtext,"<%i>",imi->jcodelength);
784 if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
785 (! ( (imi->flags & ACC_STATIC )
786 || ((imi->flags & ACC_PRIVATE) && (imi->class == inline_env->class))
787 || (imi->flags & ACC_FINAL ))) )
789 printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
791 log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
796 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
797 list_addlast(newnode->inlinedmethods, tmp);
799 printf("New node Right after an inline by:");fflush(stdout);
801 print_inlining_methodinfo(newnode);
802 printf("end new node\n"); fflush(stdout);
813 newnode->stopgp = gp;
814 label_index[jcodelength]=gp;
818 /* --------------------------------------------------------------------*/
819 /* print_ functions: check inline structures contain what is expected */
820 /* --------------------------------------------------------------------*/
821 void print_t_inlining_globals (t_inlining_globals *g)
823 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
824 METHINFOj(g->method);
825 printf("\tclass=");fflush(stdout);
826 utf_display(g->class->name);printf("\n");fflush(stdout);
828 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
830 if (g->isinlinedmethod==true) {
831 printf("\tisinlinedmethod=true ");fflush(stdout);
834 printf("\tisinlinedmethod=false");fflush(stdout);
837 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
838 g->cumjcodelength, g->cummaxstack, g->cumextablelength);fflush(stdout);
839 printf("\tcumlocals=%i ,cummethods=%i \n",
840 g->cumlocals, g->cummethods);fflush(stdout);
842 printf("s>s>s> ");fflush(stdout);
843 print_inlining_stack (g->inlining_stack);
844 printf("i>i>i> "); fflush(stdout);
845 print_inlining_methodinfo(g->inlining_rootinfo);
846 printf("-------------------\n");fflush(stdout);
849 /* --------------------------------------------------------------------*/
850 void print_inlining_stack ( list *s)
852 t_inlining_stacknode *is;
855 printf("\n\tinlining_stack: NULL\n");
859 /* print first element to see if get into stack */
860 printf("\n\tinlining_stack: NOT NULL\n");
864 printf("\n\tinlining_stack = init'd but EMPTY\n");
869 printf("\n\tinlining_stack: NOT NULL\n");
871 for (is=list_first(s);
873 is=list_next(s,is)) {
874 printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
875 METHINFOx(is->method);
876 printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
877 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
878 print_inlining_methodinfo(is->inlinfo);
882 /* --------------------------------------------------------------------*/
883 void print_inlining_methodinfo( inlining_methodinfo *r) {
886 inlining_methodinfo *im;
887 inlining_methodinfo *im2;
888 bool labellong = false;
891 printf("\n\tinlining_methodinfo: NULL\n");
894 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
896 if (r->method != NULL) {
897 utf_display(r->method->class->name); printf("."); fflush(stdout); \
898 method_display(r->method); fflush(stdout); \
901 printf(" NULL!!!!!\n");fflush(stdout);
904 if (r->readonly==NULL) {
905 printf("\treadonly==NULL ");fflush(stdout);
908 printf("\treadonly=");fflush(stdout);
909 for (i = 0; i < r->method->maxlocals; i++) {
910 if (r->readonly[i] == true)
918 /**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/
919 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
920 r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index);
921 printf ("label_index[0..%d]->", r->method->jcodelength);
923 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
925 printf ("%d:%d ", 0, r->label_index[i]);
927 (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
930 printf("\n:::::inlines::::::::::::::::::::\n");
931 if (list_first(r->inlinedmethods) == NULL) {
932 printf("Nothing\n");fflush(stdout);
935 for (im=list_first(r->inlinedmethods),cnt=0;
937 im=list_next(r->inlinedmethods,im),cnt++) {
938 printf("*"); fflush(stdout);
940 printf("[1L%i] ",im->firstlocal); fflush(stdout);
941 METHINFOj(im->method)
942 printf("::::: which inlines::"); fflush(stdout);
943 if (list_first(im->inlinedmethods) == NULL) {
944 printf("Nothing\n");fflush(stdout);
947 printf("##"); fflush(stdout);
948 for (im2=list_first(im->inlinedmethods),cnt2=0;
950 im2=list_next(im2->inlinedmethods,im2),cnt2++)
952 printf("\t%i::",cnt2); fflush(stdout);
953 printf("[1L%i] ",im2->firstlocal);
955 METHINFOj(im2->method)
957 printf("\n"); fflush(stdout);
965 * These are local overrides for various environment variables in Emacs.
966 * Please do not remove this and leave it at the end of the file, where
967 * Emacs will automagically detect them.
968 * ---------------------------------------------------------------------
971 * indent-tabs-mode: t