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 4000 2005-12-22 14:05:01Z twisti $
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); \
87 method_display_w_class(mm); }
89 #define METHINFOx(mm) \
91 printf("<c%i/m%i/p%i>\t", \
92 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
93 method_display_w_class(mm); }
96 method_display_w_class(m);
98 #define IMETHINFO(m) \
99 utf_display(m->class->name); printf("."); fflush(stdout); \
100 method_display(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);
151 /* define in options.h; Used in main.c, jit.c & inline.c */
153 if ((utf_new_char("main") == m->name) && (useinliningm)) {
161 printf("\n-------- Inlining init for: "); fflush(stdout);
165 inline_env->cumjcodelength = 0;
166 inline_env->inlining_stack = NEW(list);
167 list_init(inline_env->inlining_stack,
168 OFFSET(t_inlining_stacknode, linkage));
169 /*------ analyze ------*/
170 inline_env->inlining_rootinfo
171 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
173 printf ("\n------------------------------ ");fflush(stdout);
174 printf ("\nComplete Result of inlining analysis of:");
177 print_t_inlining_globals(inline_env); /* init ok */
179 /*---------------------*/
181 if (inline_env->cummethods == 0) {
182 inline_env = DNEW(t_inlining_globals);
183 inlining_init0(m,inline_env);
189 printf("(l,s) (%i,%i) was (%i,%i)\n",
190 m->maxlocals, inline_env->cumlocals,
191 m->maxstack, inline_env->cummaxstack); fflush(stdout);
194 /* OK since other changes were also made, but in parse same stmt still */
195 m->maxlocals = inline_env->cumlocals; orig not used
196 m->maxstack = inline_env->cummaxstack; orig global maxstack var!!
202 void inlining_cleanup(t_inlining_globals *inline_env)
204 FREE(inline_env->inlining_stack, t_inlining_stacknode);
208 /*--2 push the compile variables to save the method's environment --*/
210 void inlining_push_compiler_variablesT(int opcode, inlining_methodinfo *inlinfo, t_inlining_globals *inline_env)
212 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
214 /**new->opcode = opcode; **/
215 new->method = inline_env->method;
216 new->inlinfo = inlinfo;
217 list_addfirst(inline_env->inlining_stack, new);
218 inline_env->isinlinedmethod++;
220 /*-- push the compile variables to save the method's environment --*/
222 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)
224 t_inlining_stacknode *new = NEW(t_inlining_stacknode);
229 new->opcode = opcode;
230 new->method = inline_env->method;
231 new->lineindex=lineindex;
232 new->currentline=currentline;
233 new->linepcchange=linepcchange;
234 new->inlinfo = inlinfo;
235 list_addfirst(inline_env->inlining_stack, new);
236 inline_env->isinlinedmethod++;
240 void inlining_pop_compiler_variables(
241 int *i, int *p, int *nextp,
242 int *opcode, u2 *lineindex,
243 u2 *currentline,u2 *linepcchange,
244 inlining_methodinfo **inlinfo,
245 t_inlining_globals *inline_env)
247 t_inlining_stacknode *tmp
248 = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
250 if (!inline_env->isinlinedmethod) {
251 log_text("Attempting to pop from inlining stack in toplevel method!");
258 *opcode = tmp->opcode;
260 *lineindex=tmp->lineindex;
261 *currentline=tmp->currentline;
262 *currentline=tmp->linepcchange;
264 *inlinfo = tmp->inlinfo;
266 inline_env->method = tmp->method; /*co*/
267 inline_env->class = inline_env->method->class; /*co*/
268 inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
269 inline_env->jcode = inline_env->method->jcode; /*co*/
271 list_remove(inline_env->inlining_stack, tmp);
272 FREE(tmp, t_inlining_stacknode);
273 inline_env->isinlinedmethod--;
277 void inlining_set_compiler_variables_fun(methodinfo *m,
278 t_inlining_globals *inline_env)
280 inline_env->method = m;
281 inline_env->class = m->class;
282 inline_env->jcode = m->jcode;
283 inline_env->jcodelength = m->jcodelength;
286 /* is_unique_method2 - determines if m is a unique method by looking
287 in subclasses of class that define method m
288 It counts as it goes. It also saves the method name if found.
290 returns count of # methods used up to 2
291 (since if 2 used then not unique.)
292 sets mout to method found
293 (unique in class' heirarchy)
294 It looks for subclasses with method def'd.
296 * class - where looking for method
297 * m - original method ptr
298 * mout - unique method (output)
299 Output: "cnt" of methods found up to max of 2 (then not unique)
302 int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
305 utf* desc = m->descriptor;
307 int cnt = 0; /* number of times method found in USED classes in hierarchy*/
310 if ((m->class == class) && (class->classUsed == USED)) {
311 /* found method in current class, which is used */
318 if ( ((m->flags & ACC_FINAL)
319 || (class->sub == NULL))
320 && (class->classUsed == USED)) {
321 /* if final search no further */
329 /* search for the method in its subclasses */
330 for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
332 classinfo *subs = subs1;
333 sm = class_resolveclassmethod(subs,name,desc,class,false);
335 if ((subs->classUsed == USED) &&
340 cnt = cnt + is_unique_method2(subs, sm, mout);
341 /* Not unique if more than 1 def of method in class heir */
350 /*-----------------------------------------------------------*/
352 bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
354 utf* name = mi->name;
355 utf* desc = mi->descriptor;
357 classSetNode *classImplNode;
360 for (classImplNode = mi->class->impldBy;
361 classImplNode != NULL;
362 classImplNode = classImplNode->nextClass) {
364 classinfo * classImplements = classImplNode->classType;
367 submeth = class_findmethod(classImplements,name, desc);
368 if (submeth != NULL) {
369 icnt =+ is_unique_method2(
374 if (icnt > 1) return false;
376 if (icnt == 1) return true;
380 /*-----------------------------------------------------------*/
383 t_inlining_globals *inline_env,
386 constant_FMIref *imr,
390 /* options used inlinevirtual / uniqueVirt / inlineexctions */
394 if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
395 /*** (!(imi->flags & ACC_ABSTRACT)) && ** Problem from INVOKE STATIC **/
396 (!(imi->flags & ACC_NATIVE)) &&
397 (inlineoutsiders || (m->class->name == imr->classref->name)) &&
398 (imi->jcodelength < INLINING_MAXCODESIZE) &&
399 (imi->jcodelength > 0) && /* FIXME: eliminate empty methods? also abstract??*/
400 (((!inlinevirtuals) ||
402 ((opcode != JAVA_INVOKEVIRTUAL) ||
403 (opcode != JAVA_INVOKEINTERFACE)) ) &&
404 (inlineexceptions || (imi->exceptiontablelength == 0))) {
405 #if defined(ENABLE_STATISTICS)
407 if (inlinevirtuals) {
408 if (opcode == JAVA_INVOKEVIRTUAL) {
409 if (uniqueVirt) count_in_uniqVirt++;
411 if (opcode == JAVA_INVOKEINTERFACE) {
412 if (uniqueVirt) count_in_uniqIntf++;
421 /*------ inline statistics ------*/
422 if ((!opt_stat) || can) return can;
427 if (imi->flags & ACC_NATIVE) return can;
428 if (imi->flags & ACC_ABSTRACT) return can;
429 #if defined(ENABLE_STATISTICS)
433 {char logtext[MAXLOGTEXT];
434 sprintf(logtext, "Rejected to inline: ");
435 utf_sprint(logtext +strlen(logtext), imi->class->name);
436 strcpy(logtext + strlen(logtext), ".");
437 utf_sprint(logtext + strlen(logtext), imi->name);
438 utf_sprint(logtext + strlen(logtext), imi->descriptor);
443 if (!(inlineoutsiders) && (m->class->name != imr->classref->name)) {
444 /*** if ((!mult) && (whycannot > 0)) mult = true; *** First time not needed ***/
445 #if defined(ENABLE_STATISTICS)
446 count_in_outsiders++;
448 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
450 if (inline_env->cummethods >= INLINING_MAXMETHODS) {
451 if ((!mult) && (whycannot > 0)) mult = true;
452 #if defined(ENABLE_STATISTICS)
455 whycannot = whycannot | IN_MAXDEPTH;
457 if (imi->jcodelength >= INLINING_MAXCODESIZE) {
458 if ((!mult) && (whycannot > 0)) mult = true;
459 whycannot = whycannot | IN_MAXCODE;
461 if (imi->jcodelength > 0) {
462 if ((!mult) && (whycannot > 0)) mult = true;
463 whycannot = whycannot | IN_JCODELENGTH;
465 if (!inlineexceptions && (imi->exceptiontablelength == 0)) {
466 whycannot = whycannot | IN_EXCEPTION;
468 /* These must be last so mult flag is set correctly */
469 if ( (inlinevirtuals) &&
470 ((opcode == JAVA_INVOKEVIRTUAL) ||
471 (opcode == JAVA_INVOKEINTERFACE)) ) {
473 /* so know why (and that) a unique virtual was rejected for another reason */
474 if (opcode == JAVA_INVOKEVIRTUAL) {
475 #if defined(ENABLE_STATISTICS)
476 count_in_uniqueVirt_not_inlined++;
478 whycannot = whycannot | IN_UNIQUEVIRT;
481 #if defined(ENABLE_STATISTICS)
482 count_in_uniqueInterface_not_inlined++;
484 whycannot = whycannot | IN_UNIQUE_INTERFACE;
487 else { /* not inlined because not not virtual */
488 if ((!mult) && (whycannot > 0)) mult = true;
489 if (opcode == JAVA_INVOKEVIRTUAL) {
490 whycannot = whycannot | IN_NOT_UNIQUE_VIRT;
493 whycannot = whycannot | IN_NOT_UNIQUE_INTERFACE;
498 if (inlineoutsiders && (m->class->name != imr->classref->name)) {
499 whycannot = whycannot | IN_OUTSIDERS; /* outsider */
500 #if defined(ENABLE_STATISTICS)
501 count_in_outsiders++;
505 #if defined(ENABLE_STATISTICS)
507 count_in_rejected_mult++;
509 if (whycannot > ((1<<IN_MAX)-1)) {
510 log_text("Inline Whynot is too large???");
513 #if defined(ENABLE_STATISTICS)
514 count_in_not[whycannot]++;
522 /*-----------------------------------------------------------*/
525 inlining_methodinfo *inlining_analyse_method(methodinfo *m,
527 int firstlocal, int maxstackdepth,
528 t_inlining_globals *inline_env)
530 inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
531 /*u1 *jcode = m->jcode;*/
532 int jcodelength = m->jcodelength;
537 bool iswide = false, oldiswide;
538 bool *readonly = NULL;
539 int *label_index = NULL;
540 bool isnotrootlevel = (level > 0);
541 bool isnotleaflevel = (level < INLINING_MAXDEPTH);
542 bool maxdepthHit = false;
544 printf ("\n------------------------------ ");fflush(stdout);
545 printf ("\nStart of inlining analysis of: ");fflush(stdout);
547 if (isnotrootlevel) printf(" isnotrootlevel=T ");
548 else printf(" isnotrootlevel=F ");
549 print_t_inlining_globals(inline_env); /* init ok */
553 /* if (level == 0) gp = 0; */
555 if (isnotrootlevel) {
556 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary - ok FIXED also turned on*/
558 /** for (i = 0; i < m->maxlocals; readonly[i++] = true); **/
559 for (i = 0; i < m->paramcount; readonly[i++] = true);
560 /***isnotrootlevel = true; This had turned -inp off **/
566 label_index = DMNEW(int, jcodelength+200);
568 newnode->inlinedmethods = DNEW(list);
569 list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
572 newnode->level = level;
573 newnode->startgp = gp;
574 newnode->readonly = readonly;
575 newnode->label_index = label_index;
576 newnode->firstlocal = firstlocal;
577 inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
579 if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
580 inline_env->cumlocals = firstlocal + m->maxlocals;
583 if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
584 inline_env->cummaxstack = maxstackdepth + m->maxstack;
587 inline_env->cumextablelength += m->exceptiontablelength;
590 for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
591 opcode = code_get_u1 (p,m);
592 nextp = p + jcommandsize[opcode];
595 /* figure out nextp */
629 case JAVA_LOOKUPSWITCH:
630 nextp = ALIGN((p + 1), 4) + 4;
631 nextp += code_get_u4(nextp,m) * 8 + 4;
634 case JAVA_TABLESWITCH:
635 nextp = ALIGN((p + 1), 4) + 4;
636 nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
640 /* detect readonly variables in inlined methods */
642 if (isnotrootlevel) {
643 bool iswide = oldiswide;
652 i = code_get_u1(p + 1,m);
655 i = code_get_u2(p + 1,m);
690 i = code_get_u1(p + 1,m);
693 i = code_get_u2(p + 1,m);
700 /* for (i=lastlabel; i<=p; i++) label_index[i] = gp;
701 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
703 for (i = p; i < nextp; i++) label_index[i] = gp;
706 if ((!isnotrootlevel) && !maxdepthHit) {
708 #if defined(ENABLE_STATISTICS)
713 if (isnotleaflevel) {
717 case JAVA_INVOKEINTERFACE:
718 case JAVA_INVOKEVIRTUAL:
722 case JAVA_INVOKESPECIAL:
723 case JAVA_INVOKESTATIC:
724 i = code_get_u2(p + 1,m);
726 constant_FMIref *imr;
731 bool uniqueVirt= false;
734 if (opcode ==JAVA_INVOKEINTERFACE) {
735 imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
738 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
739 log_text("Could not resolve class reference");
742 LAZYLOADING(imrclass)
743 imi = class_resolveinterfacemethod(
749 if (!imi) { /* extra for debug */
750 log_text("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
755 imr = class_getconstant(m->class, i, CONSTANT_Methodref);
758 if (!resolve_classref(m,imr->classref,resolveEager,true, true,&imrclass)) {
759 log_text("Could not resolve class reference");
762 LAZYLOADING(imrclass)
763 imi = class_resolveclassmethod(
769 if (!imi) { /* extra for debug */
770 log_text("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
775 if (!imi) { /* normal-but never get here now */
776 log_text("Exception thrown while parsing bytecode"); /* XXX should be passed on */
780 /** Inlining has problem currently with typecheck & inlining **/
781 /** Due problem with typecheck & inlining, class checks fail for <init>s **/
782 if (utf_new_char("<init>") == imi->name) break;
783 if (utf_new_char("finit$") == imi->name) break;
785 if (opcode == JAVA_INVOKEVIRTUAL) {
787 /* unique virt meth? then */
788 /* allow it to be inlined*/
789 if (is_unique_method2(imi->class, imi, &mout) == 1) {
796 printf("WAS unique virtual(-iv)\n");fflush(stdout);
799 } /* end is unique */
800 } /* end INVOKEVIRTUAL */
801 if (opcode == JAVA_INVOKEINTERFACE){
806 if (is_unique_interface_method (imi,&mout)) {
812 printf("WAS unique interface(-iv)\n");fflush(stdout);
817 } /* end INVOKEINTERFACE */
819 if (can_inline(inline_env, m, imi, imr, uniqueVirt, opcode)) {
820 inlining_methodinfo *tmp;
821 method_descriptor2types(imi);
823 inline_env->cummethods++;
826 {char logtext[MAXLOGTEXT];
827 printf("Going to inline: ");
829 printf("\nFrom "); fflush(stdout); METHINFOj(m)
830 sprintf(logtext, "Going to inline: ");
831 utf_sprint(logtext +strlen(logtext), imi->class->name);
832 strcpy(logtext + strlen(logtext), ".");
833 utf_sprint(logtext + strlen(logtext), imi->name);
834 utf_sprint(logtext + strlen(logtext), imi->descriptor);
836 sprintf(logtext,"<%i>",imi->jcodelength);
838 if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
839 (! ( (imi->flags & ACC_STATIC )
840 || ((imi->flags & ACC_PRIVATE) && (imi->class == inline_env->class))
841 || (imi->flags & ACC_FINAL ))) )
843 printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
845 log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
850 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
851 list_addlast(newnode->inlinedmethods, tmp);
853 printf("New node Right after an inline by:");fflush(stdout);
855 print_inlining_methodinfo(newnode);
856 printf("end new node\n"); fflush(stdout);
867 newnode->stopgp = gp;
868 label_index[jcodelength]=gp;
872 /* --------------------------------------------------------------------*/
873 /* print_ functions: check inline structures contain what is expected */
874 /* --------------------------------------------------------------------*/
875 void print_t_inlining_globals (t_inlining_globals *g)
877 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout);
878 METHINFOj(g->method);
879 printf("\tclass=");fflush(stdout);
880 utf_display(g->class->name);printf("\n");fflush(stdout);
882 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
884 if (g->isinlinedmethod==true) {
885 printf("\tisinlinedmethod=true ");fflush(stdout);
888 printf("\tisinlinedmethod=false");fflush(stdout);
891 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
892 g->cumjcodelength, g->cummaxstack, g->cumextablelength);fflush(stdout);
893 printf("\tcumlocals=%i ,cummethods=%i \n",
894 g->cumlocals, g->cummethods);fflush(stdout);
896 printf("s>s>s> ");fflush(stdout);
897 print_inlining_stack (g->inlining_stack);
898 printf("i>i>i> "); fflush(stdout);
899 print_inlining_methodinfo(g->inlining_rootinfo);
900 printf("-------------------\n");fflush(stdout);
903 /* --------------------------------------------------------------------*/
904 void print_inlining_stack ( list *s)
906 t_inlining_stacknode *is;
909 printf("\n\tinlining_stack: NULL\n");
913 /* print first element to see if get into stack */
914 printf("\n\tinlining_stack: NOT NULL\n");
918 printf("\n\tinlining_stack = init'd but EMPTY\n");
923 printf("\n\tinlining_stack: NOT NULL\n");
925 for (is=list_first(s);
927 is=list_next(s,is)) {
928 printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
929 METHINFOx(is->method);
930 printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
931 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
932 print_inlining_methodinfo(is->inlinfo);
936 /* --------------------------------------------------------------------*/
937 void print_inlining_methodinfo( inlining_methodinfo *r) {
940 inlining_methodinfo *im;
941 inlining_methodinfo *im2;
942 bool labellong = false;
945 printf("\n\tinlining_methodinfo: NULL\n");
948 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
950 if (r->method != NULL) {
951 utf_display(r->method->class->name); printf("."); fflush(stdout); \
952 method_display(r->method); fflush(stdout); \
955 printf(" NULL!!!!!\n");fflush(stdout);
958 if (r->readonly==NULL) {
959 printf("\treadonly==NULL ");fflush(stdout);
962 printf("\treadonly=");fflush(stdout);
963 for (i = 0; i < r->method->maxlocals; i++) {
964 if (r->readonly[i] == true)
972 /**printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n", **/
973 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
974 r->startgp, r->stopgp, r->firstlocal, (void *)r->label_index);
975 printf ("label_index[0..%d]->", r->method->jcodelength);
977 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]); }
979 printf ("%d:%d ", 0, r->label_index[i]);
981 (r->method->jcodelength-1), r->label_index[r->method->jcodelength-1]);
984 printf("\n:::::inlines::::::::::::::::::::\n");
985 if (list_first(r->inlinedmethods) == NULL) {
986 printf("Nothing\n");fflush(stdout);
989 for (im=list_first(r->inlinedmethods),cnt=0;
991 im=list_next(r->inlinedmethods,im),cnt++) {
992 printf("*"); fflush(stdout);
994 printf("[1L%i] ",im->firstlocal); fflush(stdout);
995 METHINFOj(im->method)
996 printf("::::: which inlines::"); fflush(stdout);
997 if (list_first(im->inlinedmethods) == NULL) {
998 printf("Nothing\n");fflush(stdout);
1001 printf("##"); fflush(stdout);
1002 for (im2=list_first(im->inlinedmethods),cnt2=0;
1004 im2=list_next(im2->inlinedmethods,im2),cnt2++)
1006 printf("\t%i::",cnt2); fflush(stdout);
1007 printf("[1L%i] ",im2->firstlocal);
1009 METHINFOj(im2->method)
1011 printf("\n"); fflush(stdout);
1019 * These are local overrides for various environment variables in Emacs.
1020 * Please do not remove this and leave it at the end of the file, where
1021 * Emacs will automagically detect them.
1022 * ---------------------------------------------------------------------
1025 * indent-tabs-mode: t