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 Changes: Christian Thalinger
31 $Id: inline.c 4309 2006-01-19 21:27:58Z edwin $
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
66 #include "mm/memory.h"
67 #include "toolbox/logging.h"
68 #include "vm/global.h"
69 #include "vm/linker.h"
70 #include "vm/loader.h"
71 #include "vm/options.h"
72 #include "vm/resolve.h"
73 #include "vm/statistics.h"
74 #include "vm/jit/jit.h"
75 #include "vm/jit/parse.h"
76 #include "vm/jit/inline/inline.h"
78 #undef INVIRTDEBUG /* prints if a method was found to be
79 a unique virt/interface method definition */
82 #define METHINFOj(mm) \
84 printf("<j%i/l%i/s%i/(p)%i>\t", \
85 (mm)->jcodelength,(mm)->maxlocals, \
86 (mm)->maxstack, (mm)->paramcount); \
89 #define METHINFOx(mm) \
91 printf("<c%i/m%i/p%i>\t", \
92 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
98 #define IMETHINFO(m) \
99 utf_display(m->class->name); printf("."); fflush(stdout); \
100 method_println(m); fflush(stdout); \
101 printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
102 printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
103 printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
104 printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
106 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
108 /* replace jcodelength loops with correct number after main for loop in parse()! */
110 #define CLASSINFO(cls) \
111 { printf("<c%i>\t",cls->classUsed); \
112 utf_display(cls->name); printf("\n");fflush(stdout);}
114 static bool in_stats1 = true;
115 /*-----------------------------------------------------------*/
116 /* just initialize global structure for non-inlining */
117 /*-----------------------------------------------------------*/
119 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
121 /* initialization for normal use in parse */
122 inlining_set_compiler_variables_fun(m, inline_env);
123 inline_env->isinlinedmethod = 0;
124 inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
126 inline_env->cummaxstack = m->maxstack;
127 inline_env->cumextablelength = 0;
128 inline_env->cumlocals = m->maxlocals;
129 inline_env->cummethods = 0; /* co not global or static-used only here? */
130 inline_env->inlining_stack = NULL;
131 inline_env->inlining_rootinfo = NULL;
133 #if defined(ENABLE_STATISTICS)
136 for (ii=0; ii<512; ii++) count_in_not[ii]=0;
143 /*-----------------------------------------------------------*/
145 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
148 /* t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
149 inlining_init0(m,inline_env);
154 printf("\n-------- Inlining init for: "); fflush(stdout);
158 inline_env->cumjcodelength = 0;
159 inline_env->inlining_stack = NEW(list);
160 list_init(inline_env->inlining_stack,
161 OFFSET(t_inlining_stacknode, linkage));
162 /*------ analyze ------*/
163 inline_env->inlining_rootinfo
164 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
166 printf ("\n------------------------------ ");fflush(stdout);
167 printf ("\nComplete Result of inlining analysis of:");
170 print_t_inlining_globals(inline_env); /* init ok */
172 /*---------------------*/
174 if (inline_env->cummethods == 0) {
175 inline_env = DNEW(t_inlining_globals);
176 inlining_init0(m,inline_env);
182 printf("(l,s) (%i,%i) was (%i,%i)\n",
183 m->maxlocals, inline_env->cumlocals,
184 m->maxstack, inline_env->cummaxstack); fflush(stdout);
187 /* OK since other changes were also made, but in parse same stmt still */
188 m->maxlocals = inline_env->cumlocals; orig not used
189 m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
195 void inlining_cleanup(t_inlining_globals *inline_env)
197 FREE(inline_env->inlining_stack, t_inlining_stacknode);
201 /*--2 push the compile variables to save the method's environment --*/
203 void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
205 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
207 /**new->opcode = opcode; **/
208 new->method = inline_env->method;
209 new->inlinfo = inlinfo;
210 list_addfirst(inline_env->inlining_stack, new);
211 inline_env->isinlinedmethod++;
213 /*-- push the compile variables to save the method's environment --*/
215 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)
217 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
222 new->opcode = opcode;
223 new->method = inline_env->method;
224 new->lineindex=lineindex;
225 new->currentline=currentline;
226 new->linepcchange=linepcchange;
227 new->inlinfo = inlinfo;
228 list_addfirst(inline_env->inlining_stack, new);
229 inline_env->isinlinedmethod++;
233 void inlining_pop_compiler_variables(
234 int *i, int *p, int *nextp,
235 int *opcode, u2 *lineindex,
236 u2 *currentline,u2 *linepcchange,
237 inlining_methodinfo **inlinfo,
238 t_inlining_globals *inline_env)
240 t_inlining_stacknode *tmp
241 = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
243 if (!inline_env->isinlinedmethod) {
244 log_text("Attempting to pop from inlining stack in toplevel method!");
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->name == imr->classref->name)) &&
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(ENABLE_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(ENABLE_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->name != imr->classref->name)) {
437 /*** if ((!mult) && (whycannot > 0)) mult = true; *** First time not needed ***/
438 #if defined(ENABLE_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(ENABLE_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(ENABLE_STATISTICS)
469 count_in_uniqueVirt_not_inlined++;
471 whycannot = whycannot | IN_UNIQUEVIRT;
474 #if defined(ENABLE_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->name != imr->classref->name)) {
492 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
493 #if defined(ENABLE_STATISTICS)
494 count_in_outsiders++;
498 #if defined(ENABLE_STATISTICS)
500 count_in_rejected_mult++;
502 if (whycannot > ((1<<IN_MAX)-1)) {
503 log_text("Inline Whynot is too large???");
506 #if defined(ENABLE_STATISTICS)
507 count_in_not[whycannot]++;
515 /*-----------------------------------------------------------*/
518 inlining_methodinfo *inlining_analyse_method(methodinfo *m,
520 int firstlocal, int maxstackdepth,
521 t_inlining_globals *inline_env)
523 inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
524 /*u1 *jcode = m->jcode;*/
525 int jcodelength = m->jcodelength;
530 bool iswide = false, oldiswide;
531 bool *readonly = NULL;
532 int *label_index = NULL;
533 bool isnotrootlevel = (level > 0);
534 bool isnotleaflevel = (level < INLINING_MAXDEPTH);
535 bool maxdepthHit = false;
537 printf ("\n------------------------------ ");fflush(stdout);
538 printf ("\nStart of inlining analysis of: ");fflush(stdout);
540 if (isnotrootlevel) printf(" isnotrootlevel=T ");
541 else printf(" isnotrootlevel=F ");
542 print_t_inlining_globals(inline_env); /* init ok */
546 /* if (level == 0) gp = 0; */
548 if (isnotrootlevel) {
549 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary - ok FIXED also turned on*/
551 /** for (i = 0; i < m->maxlocals; readonly[i++] = true); **/
552 for (i = 0; i < m->paramcount; readonly[i++] = true);
553 /***isnotrootlevel = true; This had turned -inp off **/
559 label_index = DMNEW(int, jcodelength+200);
561 newnode->inlinedmethods = DNEW(list);
562 list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
565 newnode->level = level;
566 newnode->startgp = gp;
567 newnode->readonly = readonly;
568 newnode->label_index = label_index;
569 newnode->firstlocal = firstlocal;
570 inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
572 if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
573 inline_env->cumlocals = firstlocal + m->maxlocals;
576 if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
577 inline_env->cummaxstack = maxstackdepth + m->maxstack;
580 inline_env->cumextablelength += m->exceptiontablelength;
583 for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
584 opcode = code_get_u1 (p,m);
585 nextp = p + jcommandsize[opcode];
588 /* figure out nextp */
622 case JAVA_LOOKUPSWITCH:
623 nextp = ALIGN((p + 1), 4) + 4;
624 nextp += code_get_u4(nextp,m) * 8 + 4;
627 case JAVA_TABLESWITCH:
628 nextp = ALIGN((p + 1), 4) + 4;
629 nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
633 /* detect readonly variables in inlined methods */
635 if (isnotrootlevel) {
636 bool iswide = oldiswide;
645 i = code_get_u1(p + 1,m);
648 i = code_get_u2(p + 1,m);
683 i = code_get_u1(p + 1,m);
686 i = code_get_u2(p + 1,m);
693 /* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
694 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
696 for (i = p; i < nextp; i++) label_index[i] = gp;
699 if ((!isnotrootlevel) && !maxdepthHit) {
701 #if defined(ENABLE_STATISTICS)
706 if (isnotleaflevel) {
710 case JAVA_INVOKEINTERFACE:
711 case JAVA_INVOKEVIRTUAL:
715 case JAVA_INVOKESPECIAL:
716 case JAVA_INVOKESTATIC:
717 i = code_get_u2(p + 1,m);
719 constant_FMIref *imr;
724 bool uniqueVirt= false;
727 if (opcode ==JAVA_INVOKEINTERFACE) {
728 imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
731 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
732 log_text("Could not resolve class reference");
735 LAZYLOADING(imrclass)
736 imi = class_resolveinterfacemethod(
742 if (!imi) { /* extra for debug */
743 log_text("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
748 imr = class_getconstant(m->class, i, CONSTANT_Methodref);
751 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
752 log_text("Could not resolve class reference");
755 LAZYLOADING(imrclass)
756 imi = class_resolveclassmethod(
762 if (!imi) { /* extra for debug */
763 log_text("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
768 if (!imi) { /* normal-but never get here now */
769 log_text("Exception thrown while parsing bytecode"); /* XXX should be passed on */
773 /** Inlining has problem currently with typecheck & inlining **/
774 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
775 if (utf_new_char("<init>") == imi->name) break;
776 if (utf_new_char("finit$") == imi->name) break;
778 if (opcode == JAVA_INVOKEVIRTUAL) {
780 /* unique virt meth? then */
781 /* allow it to be inlined*/
782 if (is_unique_method2(imi->class, imi, &mout) == 1) {
789 printf("WAS unique virtual(-iv)\n");fflush(stdout);
792 } /* end is unique */
793 } /* end INVOKEVIRTUAL */
794 if (opcode == JAVA_INVOKEINTERFACE){
799 if (is_unique_interface_method (imi,&mout)) {
805 printf("WAS unique interface(-iv)\n");fflush(stdout);
810 } /* end INVOKEINTERFACE */
812 if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
813 inlining_methodinfo *tmp;
814 method_descriptor2types(imi);
816 inline_env->cummethods++;
819 {char logtext[MAXLOGTEXT];
820 printf("Going to inline: ");
822 printf("\nFrom "); fflush(stdout); METHINFOj(m)
823 sprintf(logtext, "Going to inline: ");
824 utf_sprint(logtext +strlen(logtext), imi->class->name);
825 strcpy(logtext + strlen(logtext), ".");
826 utf_sprint(logtext + strlen(logtext), imi->name);
827 utf_sprint(logtext + strlen(logtext), imi->descriptor);
829 sprintf(logtext,"<%i>",imi->jcodelength);
831 if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
832 (! ( (imi->flags & ACC_STATIC )
833 || ((imi->flags & ACC_PRIVATE) && (imi->class == inline_env->class))
834 || (imi->flags & ACC_FINAL ))) )
836 printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
838 log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
843 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
844 list_addlast(newnode->inlinedmethods, tmp);
846 printf("New node Right after an inline by:");fflush(stdout);
848 print_inlining_methodinfo(newnode);
849 printf("end new node\n"); fflush(stdout);
860 newnode->stopgp = gp;
861 label_index[jcodelength]=gp;
865 /* --------------------------------------------------------------------*/
866 /* print_ functions: check inline structures contain what is expected */
867 /* --------------------------------------------------------------------*/
868 void print_t_inlining_globals (t_inlining_globals *g)
870 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
871 METHINFOj(g->method);
872 printf("\tclass=");fflush(stdout);
873 utf_display(g->class->name);printf("\n");fflush(stdout);
875 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
877 if (g->isinlinedmethod==true) {
878 printf("\tisinlinedmethod=true ");fflush(stdout);
881 printf("\tisinlinedmethod=false");fflush(stdout);
884 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
885 g->cumjcodelength, g->cummaxstack, g->cumextablelength);fflush(stdout);
886 printf("\tcumlocals=%i ,cummethods=%i \n",
887 g->cumlocals, g->cummethods);fflush(stdout);
889 printf("s>s>s> ");fflush(stdout);
890 print_inlining_stack (g->inlining_stack);
891 printf("i>i>i> "); fflush(stdout);
892 print_inlining_methodinfo(g->inlining_rootinfo);
893 printf("-------------------\n");fflush(stdout);
896 /* --------------------------------------------------------------------*/
897 void print_inlining_stack ( list *s)
899 t_inlining_stacknode *is;
902 printf("\n\tinlining_stack: NULL\n");
906 /* print first element to see if get into stack */
907 printf("\n\tinlining_stack: NOT NULL\n");
911 printf("\n\tinlining_stack = init'd but EMPTY\n");
916 printf("\n\tinlining_stack: NOT NULL\n");
918 for (is=list_first(s);
920 is=list_next(s,is)) {
921 printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
922 METHINFOx(is->method);
923 printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
924 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
925 print_inlining_methodinfo(is->inlinfo);
929 /* --------------------------------------------------------------------*/
930 void print_inlining_methodinfo( inlining_methodinfo *r) {
933 inlining_methodinfo *im;
934 inlining_methodinfo *im2;
935 bool labellong = false;
938 printf("\n\tinlining_methodinfo: NULL\n");
941 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
943 if (r->method != NULL) {
944 utf_display(r->method->class->name); printf("."); fflush(stdout); \
945 method_println(r->method); fflush(stdout); \
948 printf(" NULL!!!!!\n");fflush(stdout);
951 if (r->readonly==NULL) {
952 printf("\treadonly==NULL ");fflush(stdout);
955 printf("\treadonly=");fflush(stdout);
956 for (i = 0; i < r->method->maxlocals; i++) {
957 if (r->readonly[i] == true)
965 /**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/
966 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
967 r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index);
968 printf ("label_index[0..%d]->", r->method->jcodelength);
970 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
972 printf ("%d:%d ", 0, r->label_index[i]);
974 (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
977 printf("\n:::::inlines::::::::::::::::::::\n");
978 if (list_first(r->inlinedmethods) == NULL) {
979 printf("Nothing\n");fflush(stdout);
982 for (im=list_first(r->inlinedmethods),cnt=0;
984 im=list_next(r->inlinedmethods,im),cnt++) {
985 printf("*"); fflush(stdout);
987 printf("[1L%i] ",im->firstlocal); fflush(stdout);
988 METHINFOj(im->method)
989 printf("::::: which inlines::"); fflush(stdout);
990 if (list_first(im->inlinedmethods) == NULL) {
991 printf("Nothing\n");fflush(stdout);
994 printf("##"); fflush(stdout);
995 for (im2=list_first(im->inlinedmethods),cnt2=0;
997 im2=list_next(im2->inlinedmethods,im2),cnt2++)
999 printf("\t%i::",cnt2); fflush(stdout);
1000 printf("[1L%i] ",im2->firstlocal);
1002 METHINFOj(im2->method)
1004 printf("\n"); fflush(stdout);
1012 * These are local overrides for various environment variables in Emacs.
1013 * Please do not remove this and leave it at the end of the file, where
1014 * Emacs will automagically detect them.
1015 * ---------------------------------------------------------------------
1018 * indent-tabs-mode: t