1 /* src/vm/jit/inline/inline.c - code inliner
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Dieter Thuernbeck
29 $Id: inline.c 2184 2005-04-01 21:19:05Z edwin $
34 Inlining initializes an inline structure with values of the method called
35 with. Then it recursively to MAXDEPTH analyzes by parsing the bytecode
36 looking for methods that meet the critera to be inlined.
38 Critera for inlining currently is:
39 Method to be inlined must:
40 - be less than MAXCODESIZE
41 - only MAXMETHODS can be inlined in 1 method
43 -in only STATIC, FINAL, PRIVATE methods can be inlined from method's class
44 -ino (include outsiders) all STATIC, FINAL, PRIVATE methods can be inlined
45 note: PRIVATE is always only in the same class
46 -inv include virtual methods which static analysis (currently only RTA)
47 to only have 1 definition used (INVOKEVIRTUAL/INVOKEINTERFACE)
48 Currently dynamic loading is handled by rerunning with info
49 (see parseRT). Guards need to be added.
50 -inp inline parameters - Parameters are analysed if they are
51 readonly, which is used during parsing to generate ICMD_CLEAR_ARGREN
52 and ICMD_CLEAR_ARGREN is in turn used during stack analysis to
53 replace the ISTORE with a NOP so the same local variable is used.
54 Parameters are pushed on the stack, same as normal method
55 invocation when popped the local variable of calling program is used.
56 -ine JOWENN <- please add
62 #include "mm/memory.h"
63 #include "toolbox/logging.h"
64 #include "vm/global.h"
65 #include "vm/linker.h"
66 #include "vm/loader.h"
67 #include "vm/tables.h"
68 #include "vm/options.h"
69 #include "vm/statistics.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/parse.h"
72 #include "vm/jit/inline/inline.h"
74 #undef INVIRTDEBUG /* prints if a method was found to be
75 a unique virt/interface method definition */
78 #define METHINFOj(mm) \
80 printf("<j%i/l%i/s%i/(p)%i>\t", \
81 (mm)->jcodelength,(mm)->maxlocals, \
82 (mm)->maxstack, (mm)->paramcount); \
83 method_display_w_class(mm); }
85 #define METHINFOx(mm) \
87 printf("<c%i/m%i/p%i>\t", \
88 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
89 method_display_w_class(mm); }
92 method_display_w_class(m);
94 #define IMETHINFO(m) \
95 utf_display(m->class->name); printf("."); fflush(stdout); \
96 method_display(m); fflush(stdout); \
97 printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
98 printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
99 printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
100 printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
102 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
104 /* replace jcodelength loops with correct number after main for loop in parse()! */
106 #define CLASSINFO(cls) \
107 { printf("<c%i>\t",cls->classUsed); \
108 utf_display(cls->name); printf("\n");fflush(stdout);}
110 static bool in_stats1 = true;
111 /*-----------------------------------------------------------*/
112 /* just initialize global structure for non-inlining */
113 /*-----------------------------------------------------------*/
115 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
117 /* initialization for normal use in parse */
118 inlining_set_compiler_variables_fun(m, inline_env);
119 inline_env->isinlinedmethod = 0;
120 inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
122 inline_env->cummaxstack = m->maxstack;
123 inline_env->cumextablelength = 0;
124 inline_env->cumlocals = m->maxlocals;
125 inline_env->cummethods = 0; /* co not global or static-used only here? */
126 inline_env->inlining_stack = NULL;
127 inline_env->inlining_rootinfo = NULL;
129 #if defined(STATISTICS)
132 for (ii=0; ii<512; ii++) count_in_not[ii]=0;
139 /*-----------------------------------------------------------*/
141 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
144 /* t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
145 inlining_init0(m,inline_env);
147 /* define in options.h; Used in main.c, jit.c & inline.c */
149 if ((utf_new_char("main") == m->name) && (useinliningm)) {
157 printf("\n-------- Inlining init for: "); fflush(stdout);
161 inline_env->cumjcodelength = 0;
162 inline_env->inlining_stack = NEW(list);
163 list_init(inline_env->inlining_stack,
164 OFFSET(t_inlining_stacknode, linkage));
165 /*------ analyze ------*/
166 inline_env->inlining_rootinfo
167 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
169 printf ("\n------------------------------ ");fflush(stdout);
170 printf ("\nComplete Result of inlining analysis of:");
173 print_t_inlining_globals(inline_env); /* init ok */
175 /*---------------------*/
177 if (inline_env->cummethods == 0) {
178 inline_env = DNEW(t_inlining_globals);
179 inlining_init0(m,inline_env);
185 printf("(l,s) (%i,%i) was (%i,%i)\n",
186 m->maxlocals, inline_env->cumlocals,
187 m->maxstack, inline_env->cummaxstack); fflush(stdout);
190 /* OK since other changes were also made, but in parse same stmt still */
191 m->maxlocals = inline_env->cumlocals; orig not used
192 m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
198 void inlining_cleanup(t_inlining_globals *inline_env)
200 FREE(inline_env->inlining_stack, t_inlining_stacknode);
204 /*--2 push the compile variables to save the method's environment --*/
206 void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
208 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
210 /**new->opcode = opcode; **/
211 new->method = inline_env->method;
212 new->inlinfo = inlinfo;
213 list_addfirst(inline_env->inlining_stack, new);
214 inline_env->isinlinedmethod++;
216 /*-- push the compile variables to save the method's environment --*/
218 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)
220 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
225 new->opcode = opcode;
226 new->method = inline_env->method;
227 new->lineindex=lineindex;
228 new->currentline=currentline;
229 new->linepcchange=linepcchange;
230 new->inlinfo = inlinfo;
231 list_addfirst(inline_env->inlining_stack, new);
232 inline_env->isinlinedmethod++;
236 void inlining_pop_compiler_variables(
237 int *i, int *p, int *nextp,
238 int *opcode, u2 *lineindex,
239 u2 *currentline,u2 *linepcchange,
240 inlining_methodinfo **inlinfo,
241 t_inlining_globals *inline_env)
243 t_inlining_stacknode *tmp
244 = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
246 if (!inline_env->isinlinedmethod) panic("Attempting to pop from inlining stack in toplevel method!\n");
251 *opcode = tmp->opcode;
253 *lineindex=tmp->lineindex;
254 *currentline=tmp->currentline;
255 *currentline=tmp->linepcchange;
257 *inlinfo = tmp->inlinfo;
259 inline_env->method = tmp->method; /*co*/
260 inline_env->class = inline_env->method->class; /*co*/
261 inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
262 inline_env->jcode = inline_env->method->jcode; /*co*/
264 list_remove(inline_env->inlining_stack, tmp);
265 FREE(tmp, t_inlining_stacknode);
266 inline_env->isinlinedmethod--;
270 void inlining_set_compiler_variables_fun(methodinfo *m,
271 t_inlining_globals *inline_env)
273 inline_env->method = m;
274 inline_env->class = m->class;
275 inline_env->jcode = m->jcode;
276 inline_env->jcodelength = m->jcodelength;
279 /* is_unique_method2 - determines if m is a unique method by looking
280 in subclasses of class that define method m
281 It counts as it goes. It also saves the method name if found.
283 returns count of # methods used up to 2
284 (since if 2 used then not unique.)
285 sets mout to method found
286 (unique in class' heirarchy)
287 It looks for subclasses with method def'd.
289 * class - where looking for method
290 * m - original method ptr
291 * mout - unique method (output)
292 Output: "cnt" of methods found up to max of 2 (then not unique)
295 int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
298 utf* desc = m->descriptor;
300 int cnt = 0; /* number of times method found in USED classes in hierarchy*/
303 if ((m->class == class) && (class->classUsed == USED)) {
304 /* found method in current class, which is used */
311 if ( ((m->flags & ACC_FINAL)
312 || (class->sub == NULL))
313 && (class->classUsed == USED)) {
314 /* if final search no further */
322 /* search for the method in its subclasses */
323 for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
325 classinfo *subs = subs1;
326 sm = class_resolveclassmethod(subs,name,desc,class,false);
328 if ((subs->classUsed == USED) &&
333 cnt = cnt + is_unique_method2(subs, sm, mout);
334 /* Not unique if more than 1 def of method in class heir */
343 /*-----------------------------------------------------------*/
345 bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
347 utf* name = mi->name;
348 utf* desc = mi->descriptor;
350 classSetNode *classImplNode;
353 for (classImplNode = mi->class->impldBy;
354 classImplNode != NULL;
355 classImplNode = classImplNode->nextClass) {
357 classinfo * classImplements = classImplNode->classType;
360 submeth = class_findmethod(classImplements,name, desc);
361 if (submeth != NULL) {
362 icnt =+ is_unique_method2(
367 if (icnt > 1) return false;
369 if (icnt == 1) return true;
373 /*-----------------------------------------------------------*/
376 t_inlining_globals *inline_env,
379 constant_FMIref *imr,
383 /* options used inlinevirtual / uniqueVirt / inlineexctions */
387 if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
388 /*** (!(imi->flags & ACC_ABSTRACT)) && /** Problem from INVOKE STATIC **/
389 (!(imi->flags & ACC_NATIVE)) &&
390 (inlineoutsiders || (m->class == imr->class)) &&
391 (imi->jcodelength < INLINING_MAXCODESIZE) &&
392 (imi->jcodelength > 0) && /* FIXME: eliminate empty methods? also abstract??*/
393 (((!inlinevirtuals) ||
395 ((opcode != JAVA_INVOKEVIRTUAL) ||
396 (opcode != JAVA_INVOKEINTERFACE)) ) &&
397 (inlineexceptions || (imi->exceptiontablelength == 0))) {
398 #if defined(STATISTICS)
400 if (inlinevirtuals) {
401 if (opcode == JAVA_INVOKEVIRTUAL) {
402 if (uniqueVirt) count_in_uniqVirt++;
404 if (opcode == JAVA_INVOKEINTERFACE) {
405 if (uniqueVirt) count_in_uniqIntf++;
414 /*------ inline statistics ------*/
415 if ((!opt_stat) || can) return can;
420 if (imi->flags & ACC_NATIVE) return can;
421 if (imi->flags & ACC_ABSTRACT) return can;
422 #if defined(STATISTICS)
426 {char logtext[MAXLOGTEXT];
427 sprintf(logtext, "Rejected to inline: ");
428 utf_sprint(logtext +strlen(logtext), imi->class->name);
429 strcpy(logtext + strlen(logtext), ".");
430 utf_sprint(logtext + strlen(logtext), imi->name);
431 utf_sprint(logtext + strlen(logtext), imi->descriptor);
436 if (!(inlineoutsiders) && (m->class != imr->class)) {
437 /*** if ((!mult) && (whycannot > 0)) mult = true; *** First time not needed ***/
438 #if defined(STATISTICS)
439 count_in_outsiders++;
441 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
443 if (inline_env->cummethods >= INLINING_MAXMETHODS) {
444 if ((!mult) && (whycannot > 0)) mult = true;
445 #if defined(STATISTICS)
448 whycannot = whycannot | IN_MAXDEPTH;
450 if (imi->jcodelength >= INLINING_MAXCODESIZE) {
451 if ((!mult) && (whycannot > 0)) mult = true;
452 whycannot = whycannot | IN_MAXCODE;
454 if (imi->jcodelength > 0) {
455 if ((!mult) && (whycannot > 0)) mult = true;
456 whycannot = whycannot | IN_JCODELENGTH;
458 if (!inlineexceptions && (imi->exceptiontablelength == 0)) {
459 whycannot = whycannot | IN_EXCEPTION;
461 /* These must be last so mult flag is set correctly */
462 if ( (inlinevirtuals) &&
463 ((opcode == JAVA_INVOKEVIRTUAL) ||
464 (opcode == JAVA_INVOKEINTERFACE)) ) {
466 /* so know why (and that) a unique virtual was rejected for another reason */
467 if (opcode == JAVA_INVOKEVIRTUAL) {
468 #if defined(STATISTICS)
469 count_in_uniqueVirt_not_inlined++;
471 whycannot = whycannot | IN_UNIQUEVIRT;
474 #if defined(STATISTICS)
475 count_in_uniqueInterface_not_inlined++;
477 whycannot = whycannot | IN_UNIQUE_INTERFACE;
480 else { /* not inlined because not not virtual */
481 if ((!mult) && (whycannot > 0)) mult = true;
482 if (opcode == JAVA_INVOKEVIRTUAL) {
483 whycannot = whycannot | IN_NOT_UNIQUE_VIRT;
486 whycannot = whycannot | IN_NOT_UNIQUE_INTERFACE;
491 if (inlineoutsiders && (m->class != imr->class)) {
492 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
493 #if defined(STATISTICS)
494 count_in_outsiders++;
498 #if defined(STATISTICS)
500 count_in_rejected_mult++;
502 if (whycannot > ((1<<IN_MAX)-1)) panic ("Inline Whynot is too large???\n");
503 #if defined(STATISTICS)
504 count_in_not[whycannot]++;
512 /*-----------------------------------------------------------*/
515 inlining_methodinfo *inlining_analyse_method(methodinfo *m,
517 int firstlocal, int maxstackdepth,
518 t_inlining_globals *inline_env)
520 inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
521 /*u1 *jcode = m->jcode;*/
522 int jcodelength = m->jcodelength;
527 bool iswide = false, oldiswide;
528 bool *readonly = NULL;
529 int *label_index = NULL;
530 bool isnotrootlevel = (level > 0);
531 bool isnotleaflevel = (level < INLINING_MAXDEPTH);
532 bool maxdepthHit = false;
534 printf ("\n------------------------------ ");fflush(stdout);
535 printf ("\nStart of inlining analysis of: ");fflush(stdout);
537 if (isnotrootlevel) printf(" isnotrootlevel=T ");
538 else printf(" isnotrootlevel=F ");
539 print_t_inlining_globals(inline_env); /* init ok */
543 /* if (level == 0) gp = 0; */
545 if (isnotrootlevel) {
546 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary - ok FIXED also turned on*/
548 /** for (i = 0; i < m->maxlocals; readonly[i++] = true); **/
549 for (i = 0; i < m->paramcount; readonly[i++] = true);
550 /***isnotrootlevel = true; This had turned -inp off **/
556 label_index = DMNEW(int, jcodelength+200);
558 newnode->inlinedmethods = DNEW(list);
559 list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
562 newnode->level = level;
563 newnode->startgp = gp;
564 newnode->readonly = readonly;
565 newnode->label_index = label_index;
566 newnode->firstlocal = firstlocal;
567 inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
569 if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
570 inline_env->cumlocals = firstlocal + m->maxlocals;
573 if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
574 inline_env->cummaxstack = maxstackdepth + m->maxstack;
577 inline_env->cumextablelength += m->exceptiontablelength;
580 for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
581 opcode = code_get_u1 (p,m);
582 nextp = p + jcommandsize[opcode];
585 /* figure out nextp */
619 case JAVA_LOOKUPSWITCH:
620 nextp = ALIGN((p + 1), 4) + 4;
621 nextp += code_get_u4(nextp,m) * 8 + 4;
624 case JAVA_TABLESWITCH:
625 nextp = ALIGN((p + 1), 4) + 4;
626 nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
630 /* detect readonly variables in inlined methods */
632 if (isnotrootlevel) {
633 bool iswide = oldiswide;
642 i = code_get_u1(p + 1,m);
645 i = code_get_u2(p + 1,m);
680 i = code_get_u1(p + 1,m);
683 i = code_get_u2(p + 1,m);
690 /* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
691 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
693 for (i = p; i < nextp; i++) label_index[i] = gp;
696 if ((!isnotrootlevel) && !maxdepthHit) {
698 #if defined(STATISTICS)
703 if (isnotleaflevel) {
707 case JAVA_INVOKEINTERFACE:
708 case JAVA_INVOKEVIRTUAL:
712 case JAVA_INVOKESPECIAL:
713 case JAVA_INVOKESTATIC:
714 i = code_get_u2(p + 1,m);
716 constant_FMIref *imr;
720 bool uniqueVirt= false;
723 if (opcode ==JAVA_INVOKEINTERFACE) {
724 imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
725 LAZYLOADING(imr->class)
726 imi = class_resolveinterfacemethod(
732 if (!imi) /* extra for debug */
733 panic("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
736 imr = class_getconstant(m->class, i, CONSTANT_Methodref);
737 LAZYLOADING(imr->class)
738 imi = class_resolveclassmethod(
744 if (!imi) /* extra for debug */
745 panic("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
748 if (!imi) /* normal-but never get here now */
749 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
751 /** Inlining has problem currently with typecheck & inlining **/
752 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
753 if (utf_new_char("<init>") == imi->name) break;
754 if (utf_new_char("finit$") == imi->name) break;
756 if (opcode == JAVA_INVOKEVIRTUAL) {
758 /* unique virt meth? then */
759 /* allow it to be inlined*/
760 if (is_unique_method2(imi->class, imi, &mout) == 1) {
767 printf("WAS unique virtual(-iv)\n");fflush(stdout);
770 } /* end is unique */
771 } /* end INVOKEVIRTUAL */
772 if (opcode == JAVA_INVOKEINTERFACE){
777 if (is_unique_interface_method (imi,&mout)) {
783 printf("WAS unique interface(-iv)\n");fflush(stdout);
788 } /* end INVOKEINTERFACE */
790 if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
791 inlining_methodinfo *tmp;
792 method_descriptor2types(imi);
794 inline_env->cummethods++;
797 {char logtext[MAXLOGTEXT];
798 printf("Going to inline: ");
800 printf("\nFrom "); fflush(stdout); METHINFOj(m)
801 sprintf(logtext, "Going to inline: ");
802 utf_sprint(logtext +strlen(logtext), imi->class->name);
803 strcpy(logtext + strlen(logtext), ".");
804 utf_sprint(logtext + strlen(logtext), imi->name);
805 utf_sprint(logtext + strlen(logtext), imi->descriptor);
807 sprintf(logtext,"<%i>",imi->jcodelength);
809 if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
810 (! ( (imi->flags & ACC_STATIC )
811 || ((imi->flags & ACC_PRIVATE) && (imi->class == inline_env->class))
812 || (imi->flags & ACC_FINAL ))) )
814 printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
816 log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
821 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
822 list_addlast(newnode->inlinedmethods, tmp);
824 printf("New node Right after an inline by:");fflush(stdout);
826 print_inlining_methodinfo(newnode);
827 printf("end new node\n"); fflush(stdout);
838 newnode->stopgp = gp;
839 label_index[jcodelength]=gp;
843 /* --------------------------------------------------------------------*/
844 /* print_ functions: check inline structures contain what is expected */
845 /* --------------------------------------------------------------------*/
846 void print_t_inlining_globals (t_inlining_globals *g)
848 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
849 METHINFOj(g->method);
850 printf("\tclass=");fflush(stdout);
851 utf_display(g->class->name);printf("\n");fflush(stdout);
853 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
855 if (g->isinlinedmethod==true) {
856 printf("\tisinlinedmethod=true ");fflush(stdout);
859 printf("\tisinlinedmethod=false");fflush(stdout);
862 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
863 g->cumjcodelength, g->cummaxstack, g->cumextablelength);fflush(stdout);
864 printf("\tcumlocals=%i ,cummethods=%i \n",
865 g->cumlocals, g->cummethods);fflush(stdout);
867 printf("s>s>s> ");fflush(stdout);
868 print_inlining_stack (g->inlining_stack);
869 printf("i>i>i> "); fflush(stdout);
870 print_inlining_methodinfo(g->inlining_rootinfo);
871 printf("-------------------\n");fflush(stdout);
874 /* --------------------------------------------------------------------*/
875 void print_inlining_stack ( list *s)
877 t_inlining_stacknode *is;
880 printf("\n\tinlining_stack: NULL\n");
884 /* print first element to see if get into stack */
885 printf("\n\tinlining_stack: NOT NULL\n");
889 printf("\n\tinlining_stack = init'd but EMPTY\n");
894 printf("\n\tinlining_stack: NOT NULL\n");
896 for (is=list_first(s);
898 is=list_next(s,is)) {
899 printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
900 METHINFOx(is->method);
901 printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
902 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
903 print_inlining_methodinfo(is->inlinfo);
907 /* --------------------------------------------------------------------*/
908 void print_inlining_methodinfo( inlining_methodinfo *r) {
911 inlining_methodinfo *im;
912 inlining_methodinfo *im2;
913 bool labellong = false;
916 printf("\n\tinlining_methodinfo: NULL\n");
919 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
921 if (r->method != NULL) {
922 utf_display(r->method->class->name); printf("."); fflush(stdout); \
923 method_display(r->method); fflush(stdout); \
926 printf(" NULL!!!!!\n");fflush(stdout);
929 if (r->readonly==NULL) {
930 printf("\treadonly==NULL ");fflush(stdout);
933 printf("\treadonly=");fflush(stdout);
934 for (i = 0; i < r->method->maxlocals; i++) {
935 if (r->readonly[i] == true)
943 /**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/
944 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
945 r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index);
946 printf ("label_index[0..%d]->", r->method->jcodelength);
948 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
950 printf ("%d:%d ", 0, r->label_index[i]);
952 (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
955 printf("\n:::::inlines::::::::::::::::::::\n");
956 if (list_first(r->inlinedmethods) == NULL) {
957 printf("Nothing\n");fflush(stdout);
960 for (im=list_first(r->inlinedmethods),cnt=0;
962 im=list_next(r->inlinedmethods,im),cnt++) {
963 printf("*"); fflush(stdout);
965 printf("[1L%i] ",im->firstlocal); fflush(stdout);
966 METHINFOj(im->method)
967 printf("::::: which inlines::"); fflush(stdout);
968 if (list_first(im->inlinedmethods) == NULL) {
969 printf("Nothing\n");fflush(stdout);
972 printf("##"); fflush(stdout);
973 for (im2=list_first(im->inlinedmethods),cnt2=0;
975 im2=list_next(im2->inlinedmethods,im2),cnt2++)
977 printf("\t%i::",cnt2); fflush(stdout);
978 printf("[1L%i] ",im2->firstlocal);
980 METHINFOj(im2->method)
982 printf("\n"); fflush(stdout);
990 * These are local overrides for various environment variables in Emacs.
991 * Please do not remove this and leave it at the end of the file, where
992 * Emacs will automagically detect them.
993 * ---------------------------------------------------------------------
996 * indent-tabs-mode: t