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 2788 2005-06-22 16:08:51Z 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
64 #include "mm/memory.h"
65 #include "toolbox/logging.h"
66 #include "vm/global.h"
67 #include "vm/linker.h"
68 #include "vm/loader.h"
69 #include "vm/tables.h"
70 #include "vm/options.h"
71 #include "vm/resolve.h"
72 #include "vm/statistics.h"
73 #include "vm/jit/jit.h"
74 #include "vm/jit/parse.h"
75 #include "vm/jit/inline/inline.h"
77 #undef INVIRTDEBUG /* prints if a method was found to be
78 a unique virt/interface method definition */
81 #define METHINFOj(mm) \
83 printf("<j%i/l%i/s%i/(p)%i>\t", \
84 (mm)->jcodelength,(mm)->maxlocals, \
85 (mm)->maxstack, (mm)->paramcount); \
86 method_display_w_class(mm); }
88 #define METHINFOx(mm) \
90 printf("<c%i/m%i/p%i>\t", \
91 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
92 method_display_w_class(mm); }
95 method_display_w_class(m);
97 #define IMETHINFO(m) \
98 utf_display(m->class->name); printf("."); fflush(stdout); \
99 method_display(m); fflush(stdout); \
100 printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
101 printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
102 printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
103 printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
105 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
107 /* replace jcodelength loops with correct number after main for loop in parse()! */
109 #define CLASSINFO(cls) \
110 { printf("<c%i>\t",cls->classUsed); \
111 utf_display(cls->name); printf("\n");fflush(stdout);}
113 static bool in_stats1 = true;
114 /*-----------------------------------------------------------*/
115 /* just initialize global structure for non-inlining */
116 /*-----------------------------------------------------------*/
118 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
120 /* initialization for normal use in parse */
121 inlining_set_compiler_variables_fun(m, inline_env);
122 inline_env->isinlinedmethod = 0;
123 inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
125 inline_env->cummaxstack = m->maxstack;
126 inline_env->cumextablelength = 0;
127 inline_env->cumlocals = m->maxlocals;
128 inline_env->cummethods = 0; /* co not global or static-used only here? */
129 inline_env->inlining_stack = NULL;
130 inline_env->inlining_rootinfo = NULL;
132 #if defined(STATISTICS)
135 for (ii=0; ii<512; ii++) count_in_not[ii]=0;
142 /*-----------------------------------------------------------*/
144 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
147 /* t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
148 inlining_init0(m,inline_env);
150 /* define in options.h; Used in main.c, jit.c & inline.c */
152 if ((utf_new_char("main") == m->name) && (useinliningm)) {
160 printf("\n-------- Inlining init for: "); fflush(stdout);
164 inline_env->cumjcodelength = 0;
165 inline_env->inlining_stack = NEW(list);
166 list_init(inline_env->inlining_stack,
167 OFFSET(t_inlining_stacknode, linkage));
168 /*------ analyze ------*/
169 inline_env->inlining_rootinfo
170 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
172 printf ("\n------------------------------ ");fflush(stdout);
173 printf ("\nComplete Result of inlining analysis of:");
176 print_t_inlining_globals(inline_env); /* init ok */
178 /*---------------------*/
180 if (inline_env->cummethods == 0) {
181 inline_env = DNEW(t_inlining_globals);
182 inlining_init0(m,inline_env);
188 printf("(l,s) (%i,%i) was (%i,%i)\n",
189 m->maxlocals, inline_env->cumlocals,
190 m->maxstack, inline_env->cummaxstack); fflush(stdout);
193 /* OK since other changes were also made, but in parse same stmt still */
194 m->maxlocals = inline_env->cumlocals; orig not used
195 m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
201 void inlining_cleanup(t_inlining_globals *inline_env)
203 FREE(inline_env->inlining_stack, t_inlining_stacknode);
207 /*--2 push the compile variables to save the method's environment --*/
209 void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
211 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
213 /**new->opcode = opcode; **/
214 new->method = inline_env->method;
215 new->inlinfo = inlinfo;
216 list_addfirst(inline_env->inlining_stack, new);
217 inline_env->isinlinedmethod++;
219 /*-- push the compile variables to save the method's environment --*/
221 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)
223 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
228 new->opcode = opcode;
229 new->method = inline_env->method;
230 new->lineindex=lineindex;
231 new->currentline=currentline;
232 new->linepcchange=linepcchange;
233 new->inlinfo = inlinfo;
234 list_addfirst(inline_env->inlining_stack, new);
235 inline_env->isinlinedmethod++;
239 void inlining_pop_compiler_variables(
240 int *i, int *p, int *nextp,
241 int *opcode, u2 *lineindex,
242 u2 *currentline,u2 *linepcchange,
243 inlining_methodinfo **inlinfo,
244 t_inlining_globals *inline_env)
246 t_inlining_stacknode *tmp
247 = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
249 if (!inline_env->isinlinedmethod) {
250 log_text("Attempting to pop from inlining stack in toplevel method!");
257 *opcode = tmp->opcode;
259 *lineindex=tmp->lineindex;
260 *currentline=tmp->currentline;
261 *currentline=tmp->linepcchange;
263 *inlinfo = tmp->inlinfo;
265 inline_env->method = tmp->method; /*co*/
266 inline_env->class = inline_env->method->class; /*co*/
267 inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
268 inline_env->jcode = inline_env->method->jcode; /*co*/
270 list_remove(inline_env->inlining_stack, tmp);
271 FREE(tmp, t_inlining_stacknode);
272 inline_env->isinlinedmethod--;
276 void inlining_set_compiler_variables_fun(methodinfo *m,
277 t_inlining_globals *inline_env)
279 inline_env->method = m;
280 inline_env->class = m->class;
281 inline_env->jcode = m->jcode;
282 inline_env->jcodelength = m->jcodelength;
285 /* is_unique_method2 - determines if m is a unique method by looking
286 in subclasses of class that define method m
287 It counts as it goes. It also saves the method name if found.
289 returns count of # methods used up to 2
290 (since if 2 used then not unique.)
291 sets mout to method found
292 (unique in class' heirarchy)
293 It looks for subclasses with method def'd.
295 * class - where looking for method
296 * m - original method ptr
297 * mout - unique method (output)
298 Output: "cnt" of methods found up to max of 2 (then not unique)
301 int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
304 utf* desc = m->descriptor;
306 int cnt = 0; /* number of times method found in USED classes in hierarchy*/
309 if ((m->class == class) && (class->classUsed == USED)) {
310 /* found method in current class, which is used */
317 if ( ((m->flags & ACC_FINAL)
318 || (class->sub == NULL))
319 && (class->classUsed == USED)) {
320 /* if final search no further */
328 /* search for the method in its subclasses */
329 for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
331 classinfo *subs = subs1;
332 sm = class_resolveclassmethod(subs,name,desc,class,false);
334 if ((subs->classUsed == USED) &&
339 cnt = cnt + is_unique_method2(subs, sm, mout);
340 /* Not unique if more than 1 def of method in class heir */
349 /*-----------------------------------------------------------*/
351 bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
353 utf* name = mi->name;
354 utf* desc = mi->descriptor;
356 classSetNode *classImplNode;
359 for (classImplNode = mi->class->impldBy;
360 classImplNode != NULL;
361 classImplNode = classImplNode->nextClass) {
363 classinfo * classImplements = classImplNode->classType;
366 submeth = class_findmethod(classImplements,name, desc);
367 if (submeth != NULL) {
368 icnt =+ is_unique_method2(
373 if (icnt > 1) return false;
375 if (icnt == 1) return true;
379 /*-----------------------------------------------------------*/
382 t_inlining_globals *inline_env,
385 constant_FMIref *imr,
389 /* options used inlinevirtual / uniqueVirt / inlineexctions */
393 if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
394 /*** (!(imi->flags & ACC_ABSTRACT)) && ** Problem from INVOKE STATIC **/
395 (!(imi->flags & ACC_NATIVE)) &&
396 (inlineoutsiders || (m->class->name == imr->classref->name)) &&
397 (imi->jcodelength < INLINING_MAXCODESIZE) &&
398 (imi->jcodelength > 0) && /* FIXME: eliminate empty methods? also abstract??*/
399 (((!inlinevirtuals) ||
401 ((opcode != JAVA_INVOKEVIRTUAL) ||
402 (opcode != JAVA_INVOKEINTERFACE)) ) &&
403 (inlineexceptions || (imi->exceptiontablelength == 0))) {
404 #if defined(STATISTICS)
406 if (inlinevirtuals) {
407 if (opcode == JAVA_INVOKEVIRTUAL) {
408 if (uniqueVirt) count_in_uniqVirt++;
410 if (opcode == JAVA_INVOKEINTERFACE) {
411 if (uniqueVirt) count_in_uniqIntf++;
420 /*------ inline statistics ------*/
421 if ((!opt_stat) || can) return can;
426 if (imi->flags & ACC_NATIVE) return can;
427 if (imi->flags & ACC_ABSTRACT) return can;
428 #if defined(STATISTICS)
432 {char logtext[MAXLOGTEXT];
433 sprintf(logtext, "Rejected to inline: ");
434 utf_sprint(logtext +strlen(logtext), imi->class->name);
435 strcpy(logtext + strlen(logtext), ".");
436 utf_sprint(logtext + strlen(logtext), imi->name);
437 utf_sprint(logtext + strlen(logtext), imi->descriptor);
442 if (!(inlineoutsiders) && (m->class->name != imr->classref->name)) {
443 /*** if ((!mult) && (whycannot > 0)) mult = true; *** First time not needed ***/
444 #if defined(STATISTICS)
445 count_in_outsiders++;
447 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
449 if (inline_env->cummethods >= INLINING_MAXMETHODS) {
450 if ((!mult) && (whycannot > 0)) mult = true;
451 #if defined(STATISTICS)
454 whycannot = whycannot | IN_MAXDEPTH;
456 if (imi->jcodelength >= INLINING_MAXCODESIZE) {
457 if ((!mult) && (whycannot > 0)) mult = true;
458 whycannot = whycannot | IN_MAXCODE;
460 if (imi->jcodelength > 0) {
461 if ((!mult) && (whycannot > 0)) mult = true;
462 whycannot = whycannot | IN_JCODELENGTH;
464 if (!inlineexceptions && (imi->exceptiontablelength == 0)) {
465 whycannot = whycannot | IN_EXCEPTION;
467 /* These must be last so mult flag is set correctly */
468 if ( (inlinevirtuals) &&
469 ((opcode == JAVA_INVOKEVIRTUAL) ||
470 (opcode == JAVA_INVOKEINTERFACE)) ) {
472 /* so know why (and that) a unique virtual was rejected for another reason */
473 if (opcode == JAVA_INVOKEVIRTUAL) {
474 #if defined(STATISTICS)
475 count_in_uniqueVirt_not_inlined++;
477 whycannot = whycannot | IN_UNIQUEVIRT;
480 #if defined(STATISTICS)
481 count_in_uniqueInterface_not_inlined++;
483 whycannot = whycannot | IN_UNIQUE_INTERFACE;
486 else { /* not inlined because not not virtual */
487 if ((!mult) && (whycannot > 0)) mult = true;
488 if (opcode == JAVA_INVOKEVIRTUAL) {
489 whycannot = whycannot | IN_NOT_UNIQUE_VIRT;
492 whycannot = whycannot | IN_NOT_UNIQUE_INTERFACE;
497 if (inlineoutsiders && (m->class->name != imr->classref->name)) {
498 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
499 #if defined(STATISTICS)
500 count_in_outsiders++;
504 #if defined(STATISTICS)
506 count_in_rejected_mult++;
508 if (whycannot > ((1<<IN_MAX)-1)) {
509 log_text("Inline Whynot is too large???");
512 #if defined(STATISTICS)
513 count_in_not[whycannot]++;
521 /*-----------------------------------------------------------*/
524 inlining_methodinfo *inlining_analyse_method(methodinfo *m,
526 int firstlocal, int maxstackdepth,
527 t_inlining_globals *inline_env)
529 inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
530 /*u1 *jcode = m->jcode;*/
531 int jcodelength = m->jcodelength;
536 bool iswide = false, oldiswide;
537 bool *readonly = NULL;
538 int *label_index = NULL;
539 bool isnotrootlevel = (level > 0);
540 bool isnotleaflevel = (level < INLINING_MAXDEPTH);
541 bool maxdepthHit = false;
543 printf ("\n------------------------------ ");fflush(stdout);
544 printf ("\nStart of inlining analysis of: ");fflush(stdout);
546 if (isnotrootlevel) printf(" isnotrootlevel=T ");
547 else printf(" isnotrootlevel=F ");
548 print_t_inlining_globals(inline_env); /* init ok */
552 /* if (level == 0) gp = 0; */
554 if (isnotrootlevel) {
555 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary - ok FIXED also turned on*/
557 /** for (i = 0; i < m->maxlocals; readonly[i++] = true); **/
558 for (i = 0; i < m->paramcount; readonly[i++] = true);
559 /***isnotrootlevel = true; This had turned -inp off **/
565 label_index = DMNEW(int, jcodelength+200);
567 newnode->inlinedmethods = DNEW(list);
568 list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
571 newnode->level = level;
572 newnode->startgp = gp;
573 newnode->readonly = readonly;
574 newnode->label_index = label_index;
575 newnode->firstlocal = firstlocal;
576 inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
578 if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
579 inline_env->cumlocals = firstlocal + m->maxlocals;
582 if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
583 inline_env->cummaxstack = maxstackdepth + m->maxstack;
586 inline_env->cumextablelength += m->exceptiontablelength;
589 for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
590 opcode = code_get_u1 (p,m);
591 nextp = p + jcommandsize[opcode];
594 /* figure out nextp */
628 case JAVA_LOOKUPSWITCH:
629 nextp = ALIGN((p + 1), 4) + 4;
630 nextp += code_get_u4(nextp,m) * 8 + 4;
633 case JAVA_TABLESWITCH:
634 nextp = ALIGN((p + 1), 4) + 4;
635 nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
639 /* detect readonly variables in inlined methods */
641 if (isnotrootlevel) {
642 bool iswide = oldiswide;
651 i = code_get_u1(p + 1,m);
654 i = code_get_u2(p + 1,m);
689 i = code_get_u1(p + 1,m);
692 i = code_get_u2(p + 1,m);
699 /* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
700 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
702 for (i = p; i < nextp; i++) label_index[i] = gp;
705 if ((!isnotrootlevel) && !maxdepthHit) {
707 #if defined(STATISTICS)
712 if (isnotleaflevel) {
716 case JAVA_INVOKEINTERFACE:
717 case JAVA_INVOKEVIRTUAL:
721 case JAVA_INVOKESPECIAL:
722 case JAVA_INVOKESTATIC:
723 i = code_get_u2(p + 1,m);
725 constant_FMIref *imr;
730 bool uniqueVirt= false;
733 if (opcode ==JAVA_INVOKEINTERFACE) {
734 imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
735 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
736 log_text("Could not resolve class reference");
739 LAZYLOADING(imrclass)
740 imi = class_resolveinterfacemethod(
746 if (!imi) { /* extra for debug */
747 log_text("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
752 imr = class_getconstant(m->class, i, CONSTANT_Methodref);
753 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
754 log_text("Could not resolve class reference");
757 LAZYLOADING(imrclass)
758 imi = class_resolveclassmethod(
764 if (!imi) { /* extra for debug */
765 log_text("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
770 if (!imi) { /* normal-but never get here now */
771 log_text("Exception thrown while parsing bytecode"); /* XXX should be passed on */
775 /** Inlining has problem currently with typecheck & inlining **/
776 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
777 if (utf_new_char("<init>") == imi->name) break;
778 if (utf_new_char("finit$") == imi->name) break;
780 if (opcode == JAVA_INVOKEVIRTUAL) {
782 /* unique virt meth? then */
783 /* allow it to be inlined*/
784 if (is_unique_method2(imi->class, imi, &mout) == 1) {
791 printf("WAS unique virtual(-iv)\n");fflush(stdout);
794 } /* end is unique */
795 } /* end INVOKEVIRTUAL */
796 if (opcode == JAVA_INVOKEINTERFACE){
801 if (is_unique_interface_method (imi,&mout)) {
807 printf("WAS unique interface(-iv)\n");fflush(stdout);
812 } /* end INVOKEINTERFACE */
814 if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
815 inlining_methodinfo *tmp;
816 method_descriptor2types(imi);
818 inline_env->cummethods++;
821 {char logtext[MAXLOGTEXT];
822 printf("Going to inline: ");
824 printf("\nFrom "); fflush(stdout); METHINFOj(m)
825 sprintf(logtext, "Going to inline: ");
826 utf_sprint(logtext +strlen(logtext), imi->class->name);
827 strcpy(logtext + strlen(logtext), ".");
828 utf_sprint(logtext + strlen(logtext), imi->name);
829 utf_sprint(logtext + strlen(logtext), imi->descriptor);
831 sprintf(logtext,"<%i>",imi->jcodelength);
833 if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
834 (! ( (imi->flags & ACC_STATIC )
835 || ((imi->flags & ACC_PRIVATE) && (imi->class == inline_env->class))
836 || (imi->flags & ACC_FINAL ))) )
838 printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
840 log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
845 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
846 list_addlast(newnode->inlinedmethods, tmp);
848 printf("New node Right after an inline by:");fflush(stdout);
850 print_inlining_methodinfo(newnode);
851 printf("end new node\n"); fflush(stdout);
862 newnode->stopgp = gp;
863 label_index[jcodelength]=gp;
867 /* --------------------------------------------------------------------*/
868 /* print_ functions: check inline structures contain what is expected */
869 /* --------------------------------------------------------------------*/
870 void print_t_inlining_globals (t_inlining_globals *g)
872 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
873 METHINFOj(g->method);
874 printf("\tclass=");fflush(stdout);
875 utf_display(g->class->name);printf("\n");fflush(stdout);
877 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
879 if (g->isinlinedmethod==true) {
880 printf("\tisinlinedmethod=true ");fflush(stdout);
883 printf("\tisinlinedmethod=false");fflush(stdout);
886 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
887 g->cumjcodelength, g->cummaxstack, g->cumextablelength);fflush(stdout);
888 printf("\tcumlocals=%i ,cummethods=%i \n",
889 g->cumlocals, g->cummethods);fflush(stdout);
891 printf("s>s>s> ");fflush(stdout);
892 print_inlining_stack (g->inlining_stack);
893 printf("i>i>i> "); fflush(stdout);
894 print_inlining_methodinfo(g->inlining_rootinfo);
895 printf("-------------------\n");fflush(stdout);
898 /* --------------------------------------------------------------------*/
899 void print_inlining_stack ( list *s)
901 t_inlining_stacknode *is;
904 printf("\n\tinlining_stack: NULL\n");
908 /* print first element to see if get into stack */
909 printf("\n\tinlining_stack: NOT NULL\n");
913 printf("\n\tinlining_stack = init'd but EMPTY\n");
918 printf("\n\tinlining_stack: NOT NULL\n");
920 for (is=list_first(s);
922 is=list_next(s,is)) {
923 printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
924 METHINFOx(is->method);
925 printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
926 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
927 print_inlining_methodinfo(is->inlinfo);
931 /* --------------------------------------------------------------------*/
932 void print_inlining_methodinfo( inlining_methodinfo *r) {
935 inlining_methodinfo *im;
936 inlining_methodinfo *im2;
937 bool labellong = false;
940 printf("\n\tinlining_methodinfo: NULL\n");
943 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
945 if (r->method != NULL) {
946 utf_display(r->method->class->name); printf("."); fflush(stdout); \
947 method_display(r->method); fflush(stdout); \
950 printf(" NULL!!!!!\n");fflush(stdout);
953 if (r->readonly==NULL) {
954 printf("\treadonly==NULL ");fflush(stdout);
957 printf("\treadonly=");fflush(stdout);
958 for (i = 0; i < r->method->maxlocals; i++) {
959 if (r->readonly[i] == true)
967 /**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/
968 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
969 r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index);
970 printf ("label_index[0..%d]->", r->method->jcodelength);
972 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
974 printf ("%d:%d ", 0, r->label_index[i]);
976 (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
979 printf("\n:::::inlines::::::::::::::::::::\n");
980 if (list_first(r->inlinedmethods) == NULL) {
981 printf("Nothing\n");fflush(stdout);
984 for (im=list_first(r->inlinedmethods),cnt=0;
986 im=list_next(r->inlinedmethods,im),cnt++) {
987 printf("*"); fflush(stdout);
989 printf("[1L%i] ",im->firstlocal); fflush(stdout);
990 METHINFOj(im->method)
991 printf("::::: which inlines::"); fflush(stdout);
992 if (list_first(im->inlinedmethods) == NULL) {
993 printf("Nothing\n");fflush(stdout);
996 printf("##"); fflush(stdout);
997 for (im2=list_first(im->inlinedmethods),cnt2=0;
999 im2=list_next(im2->inlinedmethods,im2),cnt2++)
1001 printf("\t%i::",cnt2); fflush(stdout);
1002 printf("[1L%i] ",im2->firstlocal);
1004 METHINFOj(im2->method)
1006 printf("\n"); fflush(stdout);
1014 * These are local overrides for various environment variables in Emacs.
1015 * Please do not remove this and leave it at the end of the file, where
1016 * Emacs will automagically detect them.
1017 * ---------------------------------------------------------------------
1020 * indent-tabs-mode: t