inline interfaces
[cacao.git] / src / vm / jit / inline / inline.c
1 /* jit/inline.c - code inliner
2
3 globals moved to structure and passed as parameter
4
5    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
6    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
7    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
8    P. Tomsich, J. Wenninger
9
10    This file is part of CACAO.
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2, or (at
15    your option) any later version.
16
17    This program is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25    02111-1307, USA.
26
27    Contact: cacao@complang.tuwien.ac.at
28
29    Authors: Dieter Thuernbeck
30
31    $Id: inline.c 1557 2004-11-22 12:01:16Z carolyn $
32
33 */
34
35
36 #include <stdio.h>
37 #include <string.h>
38 #include "global.h"
39 #include "loader.h"
40 #include "tables.h"
41 #include "options.h"
42 #include "jit/inline.h"
43 #include "jit/jit.h"
44 #include "jit/parse.h"
45 #include "toolbox/logging.h"
46 #include "toolbox/memory.h"
47 #include "sets.h"
48
49 #define INVIRTDEBUG 
50 #undef  INVIRTDEBUG
51
52 #define METHINFOx(mm) \
53     { \
54         printf("<c%i/m%i/p%i>\t", \
55                 (mm)->class->classUsed,(mm)->methodUsed, (mm)->monoPoly); \
56         method_display_w_class(mm); }
57
58 #define METHINFO(m) \
59   method_display_w_class(m); 
60
61 #define IMETHINFO(m) \
62   utf_display(m->class->name); printf("."); fflush(stdout); \
63   method_display(m); fflush(stdout); \
64   printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
65   printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
66   printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
67   printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
68
69 bool DEBUGi = false;
70 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
71
72 /* replace jcodelength loops with correct number after main for loop in parse()! */
73
74 #define CLASSINFO(cls) \
75         {       printf("<c%i>\t",cls->classUsed); \
76                 utf_display(cls->name); printf("\n");fflush(stdout);}
77
78 /*-----------------------------------------------------------*/
79 /* just initialize global structure for non-inlining         */
80 /*-----------------------------------------------------------*/
81
82 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
83 {
84         /* initialization for normal use in parse */
85         inlining_set_compiler_variables_fun(m, inline_env);
86         inline_env->isinlinedmethod = 0;
87         inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
88
89         inline_env->cummaxstack = m->maxstack; 
90         inline_env->cumextablelength = 0;
91         inline_env->cumlocals = m->maxlocals;
92         inline_env->cummethods = 0; /* co not global or static-used only here? */
93         inline_env->inlining_stack = NULL;
94         inline_env->inlining_rootinfo = NULL;
95 }
96
97
98 /*-----------------------------------------------------------*/
99
100 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
101 {
102 /*      t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
103         inlining_init0(m,inline_env);
104
105 /* define in options.h; Used in main.c, jit.c & inline.c */
106 #ifdef INAFTERMAIN
107 if ((utf_new_char("main") == m->name) && (useinliningm))
108         useinlining = true;
109 #endif
110
111 if (useinlining)
112         {
113 if (DEBUGi==true) {
114                 printf("\n-------- Inlining init for: "); fflush(stdout);
115                 IMETHINFO(m)
116                 }
117         inline_env->cumjcodelength = 0;
118         inline_env->inlining_stack = NEW(list);
119         list_init(inline_env->inlining_stack, 
120                   OFFSET(t_inlining_stacknode, linkage));
121         /*------ analyze ------*/
122 if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
123         inline_env->inlining_rootinfo 
124                 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
125 if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
126         /*---------------------*/
127 /*
128  if (inline_env->cummethods == 0) {
129          inline_env = DNEW(t_inlining_globals);
130          inlining_init0(m,inline_env);
131          return inline_env;
132  }
133 */
134 if (DEBUGi==true) {
135   printf("(l,s) (%i,%i) was (%i,%i)\n",
136     m->maxlocals, inline_env->cumlocals,
137     m->maxstack,  inline_env->cummaxstack); fflush(stdout);
138   }
139 #if 0
140 /*This looks wrong*/
141         m->maxlocals = inline_env->cumlocals;   orig not used
142         m->maxstack = inline_env->cummaxstack;  orig global maxstack var!!
143 #endif
144         }
145 }
146
147
148 void inlining_cleanup(t_inlining_globals *inline_env)
149 {
150         FREE(inline_env->inlining_stack, t_inlining_stacknode);
151 }
152
153
154 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)
155 {
156         t_inlining_stacknode *new = NEW(t_inlining_stacknode);
157
158         new->i = i;
159         new->p = p;
160         new->nextp = nextp;
161         new->opcode = opcode;
162         new->method = inline_env->method;
163         new->lineindex=lineindex;
164         new->currentline=currentline;
165         new->linepcchange=linepcchange;
166         new->inlinfo = inlinfo;
167         list_addfirst(inline_env->inlining_stack, new);
168         inline_env->isinlinedmethod++;
169 }
170
171
172 void inlining_pop_compiler_variables(
173                                     int *i, int *p, int *nextp,
174                                     int *opcode, u2 *lineindex,
175                                     u2 *currentline,u2 *linepcchange,
176                                     inlining_methodinfo **inlinfo,
177                                     t_inlining_globals *inline_env)
178 {
179         t_inlining_stacknode *tmp 
180           = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
181
182         if (!inline_env->isinlinedmethod) panic("Attempting to pop from inlining stack in toplevel method!\n");
183
184         *i = tmp->i;
185         *p = tmp->p;
186         *nextp = tmp->nextp;
187         *opcode = tmp->opcode;
188
189         *lineindex=tmp->lineindex;
190         *currentline=tmp->currentline;
191         *currentline=tmp->linepcchange;
192
193         *inlinfo = tmp->inlinfo;
194
195         inline_env->method = tmp->method; /*co*/
196         inline_env->class = inline_env->method->class; /*co*/
197         inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
198         inline_env->jcode = inline_env->method->jcode; /*co*/
199
200         list_remove(inline_env->inlining_stack, tmp);
201         FREE(tmp, t_inlining_stacknode);
202         inline_env->isinlinedmethod--;
203 }
204
205
206 void inlining_set_compiler_variables_fun(methodinfo *m,
207                                          t_inlining_globals *inline_env)
208 {
209         inline_env->method = m; 
210         inline_env->class  = m->class; 
211         inline_env->jcode  = m->jcode; 
212         inline_env->jcodelength = m->jcodelength; 
213 }
214
215 /* is_unique_method2 - determines if m is a unique method by looking
216         in subclasses of class that define method m 
217         It counts as it goes. It also saves the method name if found.
218
219  returns count of # methods used up to 2
220                                 (since if 2 used then not unique.)
221                        sets mout to method found 
222                                 (unique in class' heirarchy)
223                        It looks for subclasses with method def'd.
224  Input:
225  * class - where looking for method
226  * m     - original method ptr
227  * mout  - unique method (output) 
228  Output: "cnt" of methods found up to max of 2 (then not unique)
229 */
230
231 int is_unique_method2(classinfo *class, methodinfo *m, methodinfo **mout)
232 {
233 utf* name = m->name;
234 utf* desc = m->descriptor;
235
236 int cnt = 0;  /* number of times method found in USED classes in hierarchy*/
237 classinfo *subs1;          
238
239 if ((m->class == class) && (class->classUsed == USED)) {
240         /* found method in current class, which is used */
241         if (*mout != m) {
242                 cnt++;
243                 *mout = m;
244                 }
245         }
246
247 if ( ((m->flags & ACC_FINAL)  
248 ||    (class->sub == NULL))
249 && (class->classUsed == USED)) {
250         /* if final search no further */
251         if (*mout != m) {
252                 cnt++;
253                 *mout = m;
254                 }
255          return cnt;
256         }
257
258 /* search for the method in its subclasses */
259 for (subs1 = class->sub;subs1 != NULL;subs1 = subs1->nextsub) {
260         methodinfo * sm;
261         classinfo *subs = subs1;           
262         sm = class_resolveclassmethod(subs,name,desc,class,false);
263         if (sm != NULL) {
264                 if ((subs->classUsed == USED) && 
265                     (*mout != sm)) {
266                         *mout = sm;
267                         cnt++;
268                         }
269                 cnt = cnt + is_unique_method2(subs, sm, mout);
270                 /* Not unique if more than 1 def of method in class heir */
271                 if (cnt > 1)
272                         {return cnt;}
273                 }
274
275         }
276 return cnt;
277 }
278
279 /*-----------------------------------------------------------*/
280
281 bool is_unique_interface_method (methodinfo *mi, methodinfo **mout) {
282
283 utf* name = mi->name;
284 utf* desc = mi->descriptor;
285         
286
287         classSetNode *classImplNode;
288         int icnt = 0;
289
290         for (classImplNode  = mi->class->impldBy;
291              classImplNode != NULL;                     
292              classImplNode  = classImplNode->nextClass) {
293
294                 classinfo * classImplements = classImplNode->classType;
295                 methodinfo *submeth;
296
297                 submeth = class_findmethod(classImplements,name, desc); 
298                 if (submeth != NULL) {
299                         icnt =+ is_unique_method2(
300                                     classImplements,
301                                     submeth,
302                                     mout);
303                         }       
304                 if (icnt > 1) return false;
305                 } /* end for*/
306 if (icnt == 1) return true;
307 else return false;
308
309
310 /*-----------------------------------------------------------*/
311
312 inlining_methodinfo *inlining_analyse_method(methodinfo *m, 
313                                           int level, int gp, 
314                                           int firstlocal, int maxstackdepth,
315                                           t_inlining_globals *inline_env)
316 {
317         inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
318         /*u1 *jcode = m->jcode;*/
319         int jcodelength = m->jcodelength;
320         int p;
321         int nextp;
322         int opcode;
323         int i;
324         bool iswide = false, oldiswide;
325         bool *readonly = NULL;
326         int  *label_index = NULL;
327         bool isnotrootlevel = (level > 0);
328         bool isnotleaflevel = (level < INLINING_MAXDEPTH);
329
330         /* if (level == 0) gp = 0; */
331         /*
332         sprintf (logtext, "Performing inlining analysis of: ");
333         utf_sprint (logtext+strlen(logtext), m->class->name);
334         strcpy (logtext+strlen(logtext), ".");
335         utf_sprint (logtext+strlen(logtext), m->name);
336         utf_sprint (logtext+strlen(logtext), m->descriptor);
337         dolog (); */
338
339         if (isnotrootlevel) {
340                 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary */
341                 for (i = 0; i < m->maxlocals; readonly[i++] = true);
342                 isnotrootlevel = true;
343
344         } else {
345                 readonly = NULL;
346         }
347         
348         label_index = DMNEW(int, jcodelength+200);
349
350         newnode->inlinedmethods = DNEW(list);
351         list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
352
353         newnode->method = m;
354         newnode->startgp = gp;
355         newnode->readonly = readonly;
356         newnode->label_index = label_index;
357         newnode->firstlocal = firstlocal;
358         inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
359
360         if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
361                 inline_env->cumlocals = firstlocal + m->maxlocals;
362         }
363
364         if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
365                 inline_env->cummaxstack = maxstackdepth + m->maxstack;
366         }
367
368         inline_env->cumextablelength += m->exceptiontablelength;
369    
370
371         for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
372                 opcode = code_get_u1 (p,m);
373                 nextp = p + jcommandsize[opcode];
374                 oldiswide = iswide;
375
376                 /* figure out nextp */
377
378                 switch (opcode) {
379                 case JAVA_ILOAD:
380                 case JAVA_LLOAD:
381                 case JAVA_FLOAD:
382                 case JAVA_DLOAD:
383                 case JAVA_ALOAD: 
384
385                 case JAVA_ISTORE:
386                 case JAVA_LSTORE:
387                 case JAVA_FSTORE:
388                 case JAVA_DSTORE:
389                 case JAVA_ASTORE: 
390
391                 case JAVA_RET:
392                         if (iswide) {
393                                 nextp = p + 3;
394                                 iswide = false;
395                         }
396                         break;
397
398                 case JAVA_IINC:
399                         if (iswide) {
400                                 nextp = p + 5;
401                                 iswide = false;
402                         }
403                         break;
404
405                 case JAVA_WIDE:
406                         iswide = true;
407                         nextp = p + 1;
408                         break;
409
410                 case JAVA_LOOKUPSWITCH:
411                         nextp = ALIGN((p + 1), 4) + 4;
412                         nextp += code_get_u4(nextp,m) * 8 + 4;
413                         break;
414
415                 case JAVA_TABLESWITCH:
416                         nextp = ALIGN((p + 1), 4) + 4;
417                         nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
418                         break;
419                 }
420
421                 /* detect readonly variables in inlined methods */
422                 
423                 if (isnotrootlevel) { 
424                         bool iswide = oldiswide;
425                         
426                         switch (opcode) {
427                         case JAVA_ISTORE:
428                         case JAVA_LSTORE:
429                         case JAVA_FSTORE:
430                         case JAVA_DSTORE:
431                         case JAVA_ASTORE: 
432                                 if (!iswide) {
433                                         i = code_get_u1(p + 1,m);
434
435                                 } else {
436                                         i = code_get_u2(p + 1,m);
437                                 }
438                                 readonly[i] = false;
439                                 break;
440
441                         case JAVA_ISTORE_0:
442                         case JAVA_LSTORE_0:
443                         case JAVA_FSTORE_0:
444                         case JAVA_ASTORE_0:
445                                 readonly[0] = false;
446                                 break;
447
448                         case JAVA_ISTORE_1:
449                         case JAVA_LSTORE_1:
450                         case JAVA_FSTORE_1:
451                         case JAVA_ASTORE_1:
452                                 readonly[1] = false;
453                                 break;
454
455                         case JAVA_ISTORE_2:
456                         case JAVA_LSTORE_2:
457                         case JAVA_FSTORE_2:
458                         case JAVA_ASTORE_2:
459                                 readonly[2] = false;
460                                 break;
461
462                         case JAVA_ISTORE_3:
463                         case JAVA_LSTORE_3:
464                         case JAVA_FSTORE_3:
465                         case JAVA_ASTORE_3:
466                                 readonly[3] = false;
467                                 break;
468
469                         case JAVA_IINC:
470                                 if (!iswide) {
471                                         i = code_get_u1(p + 1,m);
472
473                                 } else {
474                                         i = code_get_u2(p + 1,m);
475                                 }
476                                 readonly[i] = false;
477                                 break;
478                         }
479                 }
480
481                 /*              for (i=lastlabel; i<=p; i++) label_index[i] = gp; 
482                                 printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
483                 lastlabel = p+1; */
484                 for (i = p; i < nextp; i++) label_index[i] = gp;
485
486                 if (isnotleaflevel) { 
487
488                         switch (opcode) {
489
490                         case JAVA_INVOKEINTERFACE:
491                         case JAVA_INVOKEVIRTUAL:
492                                 if (!inlinevirtuals) 
493                                         break;
494                         case JAVA_INVOKESPECIAL:
495                         case JAVA_INVOKESTATIC:
496                                 i = code_get_u2(p + 1,m);
497                                 {
498                                         constant_FMIref *imr;
499                                         methodinfo *imi;
500
501                                         methodinfo *mout;
502                                         bool uniqueVirt= false;
503
504
505                                         if (opcode ==JAVA_INVOKEINTERFACE) {
506                                             imr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
507                                             LAZYLOADING(imr->class)
508                                             imi = class_resolveinterfacemethod(
509                                                 imr->class,
510                                                 imr->name,
511                                                 imr->descriptor,
512                                                 m->class,
513                                                 true);
514                                             if (!imi)  /* extra for debug */
515                                                 panic("ExceptionI thrown while parsing bytecode"); /* XXX should be passed on */
516                                            }
517                                         else {
518                                            imr = class_getconstant(m->class, i, CONSTANT_Methodref);
519                                            LAZYLOADING(imr->class)
520                                            imi = class_resolveclassmethod(
521                                                 imr->class,
522                                                 imr->name,
523                                                 imr->descriptor,
524                                                 m->class,
525                                                 true);
526                                             if (!imi) /* extra for debug */
527                                                 panic("Exception0 thrown while parsing bytecode"); /* XXX should be passed on */
528                                             }
529
530                                         if (!imi) /* normal-but never get here now */ 
531                                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
532
533 /** Inlining inits has problem currently **/
534                                         if (utf_new_char("<init>") == imi->name) break; 
535 /****/                                  
536                                         if (opcode == JAVA_INVOKEVIRTUAL) {
537                                                 mout = NULL;
538                                                 /* unique virt meth? then */
539                                                 /*  allow it to be inlined*/
540                                                 if (is_unique_method2(
541                                                          imi->class,
542                                                          imi, 
543                                                          &mout) == 1) {
544                                                   if (mout != NULL) {
545                                                         imi = mout;
546                                                         uniqueVirt=true; 
547 #ifdef INVIRTDEBUG
548                                                         METHINFOx(imi);
549                                                         printf("WAS unique virtual(-iv)\n");fflush(stdout);
550 #endif
551                                                         }
552                                                   } /* end is unique */
553                                                 } /* end INVOKEVIRTUAL */       
554                                         if (opcode == JAVA_INVOKEINTERFACE){
555                                                 mout = NULL; 
556 #ifdef INVIRTDEBUG
557                                                 METHINFOx(imi);
558 #endif
559                                                 if (is_unique_interface_method (
560                                                          imi, 
561                                                          &mout)) {
562                                                      if (mout != NULL) {
563                                                         imi = mout;
564                                                         uniqueVirt=true;
565 #ifdef INVIRTDEBUG
566                                                           METHINFOx(imi);
567                                                           printf("WAS unique interface(-iv)\n");fflush(stdout);
568 #endif
569                                                         }
570                                                         
571                                                      } 
572                                                 } /* end INVOKEINTERFACE */     
573
574                                         if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
575                                                 (!(imi->flags & ACC_NATIVE)) &&  
576                                                 (inlineoutsiders || (m->class == imr->class)) && 
577                                                 (imi->jcodelength < INLINING_MAXCODESIZE) && 
578                                                 (imi->jcodelength > 0) && 
579                                                (((!inlinevirtuals)  || 
580                                                  (uniqueVirt     ))   || 
581                                                 ((opcode != JAVA_INVOKEVIRTUAL) || 
582                                                  (opcode != JAVA_INVOKEINTERFACE)) ) &&
583                                                 (inlineexceptions || (imi->exceptiontablelength == 0))) { /* FIXME: eliminate empty methods? */
584                                                 inlining_methodinfo *tmp;
585                                                 descriptor2types(imi);
586
587                                                 inline_env->cummethods++;
588
589                                                 if (opt_verbose) {
590                                                         char logtext[MAXLOGTEXT];
591                                                         sprintf(logtext, "Going to inline: ");
592                                                         utf_sprint(logtext  +strlen(logtext), imi->class->name);
593                                                         strcpy(logtext + strlen(logtext), ".");
594                                                         utf_sprint(logtext + strlen(logtext), imi->name);
595                                                         utf_sprint(logtext + strlen(logtext), imi->descriptor);
596                                                         log_text(logtext);
597                                                         
598                                                         if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
599                                                              (! ( (imi->flags & ACC_STATIC )
600                                                              ||   (imi->flags & ACC_PRIVATE)
601                                                              ||   (imi->flags & ACC_FINAL  ))) )
602                                                            {
603                                                            printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
604                                                            METHINFOx(imi);
605                                                            log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
606                                                            }
607
608                                                 }
609                                                 
610                                                 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
611                                                 list_addlast(newnode->inlinedmethods, tmp);
612                                                 gp = tmp->stopgp;
613                                                 p = nextp;
614                                         }
615                                 }
616                                 break;
617                         }
618                 }  
619         } /* for */
620         
621         newnode->stopgp = gp;
622         label_index[jcodelength]=gp;
623         if (DEBUGi==true) {
624           printf ("\nResult of inlining analysis of: ");
625           IMETHINFO(m);
626           printf("was called by:\n"); fflush(stdout);
627           IMETHINFO(inline_env->method);
628           printf ("label_index[0..%d]->", jcodelength);
629           for (i=0;i<jcodelength; i++) printf ("%d:%d ", i, label_index[i]);
630           printf("stopgp : %d\n",newnode->stopgp); 
631           }
632
633     return newnode;
634 }
635
636 /* --------------------------------------------------------------------*/
637 /*  print_ functions: check inline structures contain what is expected */
638 /* --------------------------------------------------------------------*/
639 void print_t_inlining_globals (t_inlining_globals *g) 
640 {
641 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout); 
642 METHINFOx(g->method);
643 printf("\tclass=");fflush(stdout);
644   utf_display(g->class->name);printf("\n");fflush(stdout);
645
646 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
647
648 if (g->isinlinedmethod==true) {
649   printf("\tisinlinedmethod=true ");fflush(stdout);  
650   }
651 else {
652   printf("\tisinlinedmethod=false");fflush(stdout);  
653   }
654
655 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
656  g->cumjcodelength,    g->cummaxstack,  g->cumextablelength);fflush(stdout);
657 printf("\tcumlocals=%i ,cummethods=%i \n",
658  g->cumlocals,    g->cummethods);fflush(stdout);  
659
660 printf("s>s>s> ");fflush(stdout);
661 print_inlining_stack     (g->inlining_stack);
662 printf("i>i>i> "); fflush(stdout);
663 print_inlining_methodinfo(g->inlining_rootinfo);
664 printf("-------------------\n");fflush(stdout);
665 }
666
667 /* --------------------------------------------------------------------*/
668 void print_inlining_stack     ( list                *s)
669 {
670 if (s==NULL) { 
671   printf("\n\tinlining_stack: NULL\n");
672   return;
673   }
674   
675   {/* print first  element to see if get into stack */
676   t_inlining_stacknode *is;
677   printf("\n\tinlining_stack: NOT NULL\n");
678
679   is=list_first(s); 
680   if (is==NULL) { 
681     printf("\n\tinlining_stack = init'd but EMPTY\n");
682     fflush(stdout);
683     return;
684     }
685   }
686
687   {
688   t_inlining_stacknode *is;
689   printf("\n\tinlining_stack: NOT NULL\n");
690
691
692   for (is=list_first(s); 
693        is!=NULL;
694        is=list_next(s,is)) {
695          printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
696          METHINFOx(is->method);
697          printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
698                 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
699          print_inlining_methodinfo(is->inlinfo);
700     } /*end for */
701   } 
702
703 }
704
705 /* --------------------------------------------------------------------*/
706 void print_inlining_methodinfo( inlining_methodinfo *r) {
707 if (r==NULL) { 
708   printf("\n\tinlining_methodinfo: NULL\n");
709   return;
710   }
711
712 if (r->method != NULL) {
713   utf_display(r->method->class->name); printf("."); fflush(stdout); \
714   method_display(r->method); fflush(stdout); \
715   }
716 else {
717   printf("method is NULL!!!!!\n");fflush(stdout);
718   }
719
720 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
721 if (r->readonly==NULL) {
722   printf("\treadonly==NULL ");fflush(stdout);  
723   }
724 else {
725   int i;
726   printf("\treadonly=");fflush(stdout);  
727   for (i = 0; i < r->method->maxlocals; i++)  {
728     if (r->readonly[i] == true)
729       printf("[i]=T;");
730     else
731       printf("[i]=F;");
732     fflush(stdout);
733     } 
734   }
735
736
737 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
738           r->startgp, r->stopgp, r->firstlocal, r->label_index);
739 {int i;
740 printf ("label_index[0..%d]->", r->method->jcodelength);
741 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]);
742 }
743
744 {
745 inlining_methodinfo *im;
746 for (im=list_first(r->inlinedmethods); 
747      im!=NULL;
748      im=list_next(r->inlinedmethods,im)) {
749   } 
750 }
751 }
752
753
754 /*
755  * These are local overrides for various environment variables in Emacs.
756  * Please do not remove this and leave it at the end of the file, where
757  * Emacs will automagically detect them.
758  * ---------------------------------------------------------------------
759  * Local variables:
760  * mode: c
761  * indent-tabs-mode: t
762  * c-basic-offset: 4
763  * tab-width: 4
764  * End:
765  */