-ansi -pedantic fixes.
[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 1494 2004-11-12 13:34:26Z twisti $
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
48 #define METHINFO(m) \
49   utf_display(m->class->name); printf("."); fflush(stdout); \
50   method_display(m); fflush(stdout); \
51
52 #define IMETHINFO(m) \
53   utf_display(m->class->name); printf("."); fflush(stdout); \
54   method_display(m); fflush(stdout); \
55   printf("\tm->jcodelength=%i; ",m->jcodelength); fflush(stdout); \
56   printf("m->jcode=%p;\n",m->jcode); fflush(stdout); \
57   printf("\tm->maxlocals=%i; ",m->maxlocals); fflush(stdout); \
58   printf("m->maxstack=%i;\n",m->maxstack); fflush(stdout);
59
60 bool DEBUGi = false;
61 /* checked functions and macros: LOADCONST code_get OP1 BUILTIN block_insert bound_check ALIGN */
62
63 /* replace jcodelength loops with correct number after main for loop in parse()! */
64
65
66 /*-----------------------------------------------------------*/
67 /* just initialize global structure for non-inlining         */
68 /*-----------------------------------------------------------*/
69
70 void inlining_init0(methodinfo *m, t_inlining_globals *inline_env)
71 {
72         /* initialization for normal use in parse */
73         inlining_set_compiler_variables_fun(m, inline_env);
74         inline_env->isinlinedmethod = 0;
75         inline_env->cumjcodelength = m->jcodelength; /* for not inlining */
76
77         inline_env->cummaxstack = m->maxstack; /*why has here been 0 ? */
78         inline_env->cumextablelength = 0;
79         inline_env->cumlocals = m->maxlocals;
80         inline_env->cummethods = 0; /* co not global or static-used only here? */
81         inline_env->inlining_stack = NULL;
82         inline_env->inlining_rootinfo = NULL;
83 }
84
85
86 /*-----------------------------------------------------------*/
87
88 void inlining_setup(methodinfo *m, t_inlining_globals *inline_env)
89 {
90 /*      t_inlining_globals *inline_env = DNEW(t_inlining_globals); */
91         inlining_init0(m,inline_env);
92
93 /* define in options.h; Used in main.c, jit.c & inline.c */
94 #ifdef INAFTERMAIN
95 if ((utf_new_char("main") == m->name) && (useinliningm))
96         useinlining = true;
97 #endif
98
99 if (useinlining)
100         {
101 if (DEBUGi==true) {
102                 printf("\n-------- Inlining init for: "); fflush(stdout);
103                 IMETHINFO(m)
104                 }
105         inline_env->cumjcodelength = 0;
106         inline_env->inlining_stack = NEW(list);
107         list_init(inline_env->inlining_stack, 
108                   OFFSET(t_inlining_stacknode, linkage));
109         /*------ analyze ------*/
110 if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
111         inline_env->inlining_rootinfo 
112                 = inlining_analyse_method(m, 0, 0, 0, 0, inline_env);
113 if (DEBUGi==true) {print_t_inlining_globals(inline_env);}
114         /*---------------------*/
115 /*
116  if (inline_env->cummethods == 0) {
117          inline_env = DNEW(t_inlining_globals);
118          inlining_init0(m,inline_env);
119          return inline_env;
120  }
121 */
122 if (DEBUGi==true) {
123   printf("(l,s) (%i,%i) was (%i,%i)\n",
124     m->maxlocals, inline_env->cumlocals,
125     m->maxstack,  inline_env->cummaxstack); fflush(stdout);
126   }
127 #if 0
128 /*This looks wrong*/
129         m->maxlocals = inline_env->cumlocals;   //orig not used
130         m->maxstack = inline_env->cummaxstack;  //orig global maxstack var!!
131 #endif
132         }
133 }
134
135
136 void inlining_cleanup(t_inlining_globals *inline_env)
137 {
138         FREE(inline_env->inlining_stack, t_inlining_stacknode);
139 }
140
141
142 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)
143 {
144         t_inlining_stacknode *new = NEW(t_inlining_stacknode);
145
146         new->i = i;
147         new->p = p;
148         new->nextp = nextp;
149         new->opcode = opcode;
150         new->method = inline_env->method;
151         new->lineindex=lineindex;
152         new->currentline=currentline;
153         new->linepcchange=linepcchange;
154         new->inlinfo = inlinfo;
155         list_addfirst(inline_env->inlining_stack, new);
156         inline_env->isinlinedmethod++;
157 }
158
159
160 void inlining_pop_compiler_variables(
161                                     int *i, int *p, int *nextp,
162                                     int *opcode, u2 *lineindex,
163                                     u2 *currentline,u2 *linepcchange,
164                                     inlining_methodinfo **inlinfo,
165                                     t_inlining_globals *inline_env)
166 {
167         t_inlining_stacknode *tmp 
168           = (t_inlining_stacknode *) list_first(inline_env->inlining_stack);
169
170         if (!inline_env->isinlinedmethod) panic("Attempting to pop from inlining stack in toplevel method!\n");
171
172         *i = tmp->i;
173         *p = tmp->p;
174         *nextp = tmp->nextp;
175         *opcode = tmp->opcode;
176
177         *lineindex=tmp->lineindex;
178         *currentline=tmp->currentline;
179         *currentline=tmp->linepcchange;
180
181         *inlinfo = tmp->inlinfo;
182
183         inline_env->method = tmp->method; /*co*/
184         inline_env->class = inline_env->method->class; /*co*/
185         inline_env->jcodelength = inline_env->method->jcodelength; /*co*/
186         inline_env->jcode = inline_env->method->jcode; /*co*/
187
188         list_remove(inline_env->inlining_stack, tmp);
189         FREE(tmp, t_inlining_stacknode);
190         inline_env->isinlinedmethod--;
191 }
192
193
194 void inlining_set_compiler_variables_fun(methodinfo *m,
195                                          t_inlining_globals *inline_env)
196 {
197         /* XXX TWISTI */
198         inline_env->method = m; /*co*/
199         inline_env->class  = m->class; /*co*/
200         inline_env->jcode  = m->jcode; /*co*/
201         inline_env->jcodelength = m->jcodelength; /*co*/
202 }
203
204
205 classinfo *first_occurence(classinfo* class, utf* name, utf* desc)
206 {
207         classinfo *first = class;
208         
209         for (; class->super != NULL ; class = class->super) {
210                 if (class_findmethod(class->super, name, desc) != NULL) {
211                         first = class->super;
212                 }                       
213         }
214
215         return first;
216 }
217
218
219 bool is_unique_rec(classinfo *class, methodinfo *m, utf* name, utf* desc)
220 {
221         methodinfo *tmp = class_findmethod(class, name, desc);
222         if ((tmp != NULL) && (tmp != m))
223                 return false;
224
225         for (; class != NULL; class = class->nextsub) {
226                 if ((class->sub != NULL) && !is_unique_rec(class->sub, m, name, desc)) {
227                         return false; 
228                 }
229         }
230         return true;
231 }
232
233
234 bool is_unique_method(classinfo *class, methodinfo *m, utf* name, utf* desc)
235 {
236         classinfo *firstclass;
237         
238         /*      sprintf (logtext, "First occurence of: ");
239         utf_sprint (logtext+strlen(logtext), m->class->name);
240         strcpy (logtext+strlen(logtext), ".");
241         utf_sprint (logtext+strlen(logtext), m->name);
242         utf_sprint (logtext+strlen(logtext), m->descriptor);
243         dolog (); */
244         
245         firstclass = first_occurence(class, name, desc);
246         
247         /*      sprintf (logtext, "\nis in class:");
248         utf_sprint (logtext+strlen(logtext), firstclass->name);
249         dolog (); */
250
251         if (firstclass != class) return false;
252
253         return is_unique_rec(class, m, name, desc);
254 }
255
256 /* is_unique_method2 - returns count of # methods used up to 2
257                         since if 2 used then not unique.
258                         Chose not to make an extra fn call so
259                         can return boolean instead of cnt.
260                         It looks for subclasses with method def'd.
261
262                         This replaces is_unique_method which for
263                         reasons unknown looks up the class heirarchy
264                         not down at subclasses.
265
266  * class - where looking for method
267  * m     - original method ptr
268  * name  - utf name of method
269  * desc  - utf method descriptor
270 */
271 int is_unique_method2(classinfo *class, methodinfo *m, utf* name, utf* desc)
272 {
273 int cnt = 0;  /* number of times method found in USED classes in hierarchy*/
274 classinfo *subs;
275
276 if ((m->class == class) && (class->classUsed == USED))
277         cnt++;
278
279 if ( ((m->flags & ACC_FINAL) &&
280       (m->monoPoly != POLY))
281   ||  (class->sub == NULL))
282   return cnt;
283
284 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
285         methodinfo * sm;
286
287         sm = class_resolveclassmethod(subs,name,desc,class,false);
288         if (sm != NULL) {
289                 cnt =+ is_unique_method2(subs,sm,name,desc);
290                 if (cnt > 1)
291                         return cnt;
292                 }
293         }
294
295 return cnt;
296 }
297
298 methodinfo *get_unique_method2(classinfo *class, methodinfo *m, utf* name, utf* desc)
299 {
300 methodinfo * imi;
301 classinfo *subs;
302
303 if ((m->class == class) && (class->classUsed == USED))
304         return m;
305
306 for (subs = class->sub;subs != NULL;subs = subs->nextsub) {
307         methodinfo * sm;
308
309         sm = class_resolveclassmethod(subs,name,desc,class,false);
310         if (sm != NULL) {
311                 imi = get_unique_method2(subs,sm,name,desc);
312                 if (imi != NULL)
313                         return sm;
314                 }
315         }
316
317 return NULL;
318 }
319
320
321 inlining_methodinfo *inlining_analyse_method(methodinfo *m, 
322                                           int level, int gp, 
323                                           int firstlocal, int maxstackdepth,
324                                           t_inlining_globals *inline_env)
325 {
326         inlining_methodinfo *newnode = DNEW(inlining_methodinfo);
327         /*u1 *jcode = m->jcode;*/
328         int jcodelength = m->jcodelength;
329         int p;
330         int nextp;
331         int opcode;
332         int i;
333         bool iswide = false, oldiswide;
334         bool *readonly = NULL;
335         int  *label_index = NULL;
336         bool isnotrootlevel = (level > 0);
337         bool isnotleaflevel = (level < INLINING_MAXDEPTH);
338
339         /* if (level == 0) gp = 0; */
340         /*
341         sprintf (logtext, "Performing inlining analysis of: ");
342         utf_sprint (logtext+strlen(logtext), m->class->name);
343         strcpy (logtext+strlen(logtext), ".");
344         utf_sprint (logtext+strlen(logtext), m->name);
345         utf_sprint (logtext+strlen(logtext), m->descriptor);
346         dolog (); */
347
348         if (isnotrootlevel) {
349                 newnode->readonly = readonly = DMNEW(bool, m->maxlocals); /* FIXME only paramcount entrys necessary */
350                 for (i = 0; i < m->maxlocals; readonly[i++] = true);
351                 isnotrootlevel = true;
352
353         } else {
354                 readonly = NULL;
355         }
356         
357         label_index = DMNEW(int, jcodelength+200);
358
359         newnode->inlinedmethods = DNEW(list);
360         list_init(newnode->inlinedmethods, OFFSET(inlining_methodinfo, linkage));
361
362         newnode->method = m;
363         newnode->startgp = gp;
364         newnode->readonly = readonly;
365         newnode->label_index = label_index;
366         newnode->firstlocal = firstlocal;
367         inline_env->cumjcodelength += jcodelength + m->paramcount + 1 + 5;
368
369         if ((firstlocal + m->maxlocals) > inline_env->cumlocals) {
370                 inline_env->cumlocals = firstlocal + m->maxlocals;
371         }
372
373         if ((maxstackdepth + m->maxstack) > inline_env->cummaxstack) {
374                 inline_env->cummaxstack = maxstackdepth + m->maxstack;
375         }
376
377         inline_env->cumextablelength += m->exceptiontablelength;
378    
379
380         for (p = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
381                 opcode = code_get_u1 (p,m);
382                 nextp = p + jcommandsize[opcode];
383                 oldiswide = iswide;
384
385                 /* figure out nextp */
386
387                 switch (opcode) {
388                 case JAVA_ILOAD:
389                 case JAVA_LLOAD:
390                 case JAVA_FLOAD:
391                 case JAVA_DLOAD:
392                 case JAVA_ALOAD: 
393
394                 case JAVA_ISTORE:
395                 case JAVA_LSTORE:
396                 case JAVA_FSTORE:
397                 case JAVA_DSTORE:
398                 case JAVA_ASTORE: 
399
400                 case JAVA_RET:
401                         if (iswide) {
402                                 nextp = p + 3;
403                                 iswide = false;
404                         }
405                         break;
406
407                 case JAVA_IINC:
408                         if (iswide) {
409                                 nextp = p + 5;
410                                 iswide = false;
411                         }
412                         break;
413
414                 case JAVA_WIDE:
415                         iswide = true;
416                         nextp = p + 1;
417                         break;
418
419                 case JAVA_LOOKUPSWITCH:
420                         nextp = ALIGN((p + 1), 4) + 4;
421                         nextp += code_get_u4(nextp,m) * 8 + 4;
422                         break;
423
424                 case JAVA_TABLESWITCH:
425                         nextp = ALIGN((p + 1), 4) + 4;
426                         nextp += (code_get_u4(nextp+4,m) - code_get_u4(nextp,m) + 1) * 4 + 4 +4;
427                         break;
428                 }
429
430                 /* detect readonly variables in inlined methods */
431                 
432                 if (isnotrootlevel) { 
433                         bool iswide = oldiswide;
434                         
435                         switch (opcode) {
436                         case JAVA_ISTORE:
437                         case JAVA_LSTORE:
438                         case JAVA_FSTORE:
439                         case JAVA_DSTORE:
440                         case JAVA_ASTORE: 
441                                 if (!iswide) {
442                                         i = code_get_u1(p + 1,m);
443
444                                 } else {
445                                         i = code_get_u2(p + 1,m);
446                                 }
447                                 readonly[i] = false;
448                                 break;
449
450                         case JAVA_ISTORE_0:
451                         case JAVA_LSTORE_0:
452                         case JAVA_FSTORE_0:
453                         case JAVA_ASTORE_0:
454                                 readonly[0] = false;
455                                 break;
456
457                         case JAVA_ISTORE_1:
458                         case JAVA_LSTORE_1:
459                         case JAVA_FSTORE_1:
460                         case JAVA_ASTORE_1:
461                                 readonly[1] = false;
462                                 break;
463
464                         case JAVA_ISTORE_2:
465                         case JAVA_LSTORE_2:
466                         case JAVA_FSTORE_2:
467                         case JAVA_ASTORE_2:
468                                 readonly[2] = false;
469                                 break;
470
471                         case JAVA_ISTORE_3:
472                         case JAVA_LSTORE_3:
473                         case JAVA_FSTORE_3:
474                         case JAVA_ASTORE_3:
475                                 readonly[3] = false;
476                                 break;
477
478                         case JAVA_IINC:
479                                 if (!iswide) {
480                                         i = code_get_u1(p + 1,m);
481
482                                 } else {
483                                         i = code_get_u2(p + 1,m);
484                                 }
485                                 readonly[i] = false;
486                                 break;
487                         }
488                 }
489
490                 /*              for (i=lastlabel; i<=p; i++) label_index[i] = gp; 
491                 //              printf("lastlabel=%d p=%d gp=%d\n",lastlabel, p, gp);
492                 lastlabel = p+1; */
493                 for (i = p; i < nextp; i++) label_index[i] = gp;
494
495                 if (isnotleaflevel) { 
496
497                         switch (opcode) {
498                         case JAVA_INVOKEVIRTUAL:
499                                 if (!inlinevirtuals)
500                                         break;
501                          /*log_text("\nINLINE INVOKEVIRTUAL :\t");*/
502                         case JAVA_INVOKESPECIAL:
503                         case JAVA_INVOKESTATIC:
504                                 i = code_get_u2(p + 1,m);
505                                 {
506                                         constant_FMIref *imr;
507                                         methodinfo *imi;
508
509                                         methodinfo *imi1;
510                                         bool uniqueVirt= false;
511                                         int vcnt=0;
512
513                                         imr = class_getconstant(m->class, i, CONSTANT_Methodref);
514
515                                         if (!class_load(imr->class))
516                                                 return NULL;
517
518                                         if (!class_link(imr->class))
519                                                 return NULL;
520
521                                         imi = class_resolveclassmethod(imr->class,
522                                                                                                    imr->name,
523                                                                                                    imr->descriptor,
524                                                                                                    m->class,
525                                                                                                    true);
526
527                                         if (!imi)
528                                                 panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
529
530                                         if ( (utf_new_char("<init>")   == imi->name) ||
531                                              (utf_new_char("<clinit>") == imi->name)) break; 
532
533                                         if (opcode == JAVA_INVOKEVIRTUAL) {
534                                                 vcnt = is_unique_method2(imi->class, imi, imr->name, imr->descriptor);
535                                                 if (vcnt == 1) {
536
537                                                   imi1 = get_unique_method2(imi->class, imi, imr->name, imr->descriptor);
538                                                   if (imi1 != NULL) {
539                                                         imi = imi1;
540                                                         /*log_text("WAS unique virtual\t");*/
541                                                         /**/ uniqueVirt=true; /* comment out to permanently turn off inlining virtuals*/
542                                                         }
543                                                    } /* end if vcnt */
544
545                                                 if (!is_unique_method(imi->class, imi, imr->name, imr->descriptor))
546                                                         break;
547                                         }
548
549                                         /*if (imi->flags & ACC_NATIVE) log_text("Native method,no inlining");*/
550                                         if ((inline_env->cummethods < INLINING_MAXMETHODS) &&
551                                                 (!(imi->flags & ACC_NATIVE)) &&  
552                                                 (inlineoutsiders || (m->class == imr->class)) && 
553                                                 (imi->jcodelength < INLINING_MAXCODESIZE) && 
554                                                 (imi->jcodelength > 0) && 
555                                                (((!inlinevirtuals)  || (uniqueVirt)) || (opcode != JAVA_INVOKEVIRTUAL)) &&
556                                                 (inlineexceptions || (imi->exceptiontablelength == 0))) { /* FIXME: eliminate empty methods? */
557                                                 inlining_methodinfo *tmp;
558                                                 descriptor2types(imi);
559
560                                                 inline_env->cummethods++;
561
562                                                 if (verbose) {
563                                                         char logtext[MAXLOGTEXT];
564                                                         sprintf(logtext, "Going to inline: ");
565                                                         utf_sprint(logtext  +strlen(logtext), imi->class->name);
566                                                         strcpy(logtext + strlen(logtext), ".");
567                                                         utf_sprint(logtext + strlen(logtext), imi->name);
568                                                         utf_sprint(logtext + strlen(logtext), imi->descriptor);
569                                                         log_text(logtext);
570                                                         
571                                                         if ( (!(opcode == JAVA_INVOKEVIRTUAL)) &&
572                                                              (! ( (imi->flags & ACC_STATIC )
573                                                              ||   (imi->flags & ACC_PRIVATE)
574                                                              ||   (imi->flags & ACC_FINAL  ))) )
575                                                            {
576                                                            printf("DEBUG WARNING:PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n"); fflush(stdout);
577                                                            METHINFO(imi);
578                                                            log_text("PROBABLE INLINE PROBLEM flags not static, private or final for non-virtual inlined method\n See method info after DEBUG WARNING\n");
579                                                            }
580
581                                                 }
582                                                 
583                                                 tmp =inlining_analyse_method(imi, level + 1, gp, firstlocal + m->maxlocals, maxstackdepth + m->maxstack, inline_env);
584                                                 list_addlast(newnode->inlinedmethods, tmp);
585                                                 gp = tmp->stopgp;
586                                                 p = nextp;
587                                         }
588                                 }
589                                 break;
590                         }
591                 }  
592         } /* for */
593         
594         newnode->stopgp = gp;
595
596         if (DEBUGi==true) {
597           printf ("\nResult of inlining analysis of: ");
598           IMETHINFO(m);
599           printf("was called by:\n"); fflush(stdout);
600           IMETHINFO(inline_env->method);
601           printf ("label_index[0..%d]->", jcodelength);
602           for (i=0;i<jcodelength; i++) printf ("%d:%d ", i, label_index[i]);
603           printf("stopgp : %d\n",newnode->stopgp); 
604           }
605
606     return newnode;
607 }
608
609 /* --------------------------------------------------------------------*/
610 /*  print_ functions: check inline structures contain what is expected */
611 /* --------------------------------------------------------------------*/
612 void print_t_inlining_globals (t_inlining_globals *g) 
613 {
614 printf("\n------------\nt_inlining_globals struct for: \n\t");fflush(stdout); 
615 METHINFO(g->method);
616 printf("\tclass=");fflush(stdout);
617   utf_display(g->class->name);printf("\n");fflush(stdout);
618
619 printf("\tjcodelength=%i; jcode=%p;\n",g->jcodelength, g->jcode);
620
621 if (g->isinlinedmethod==true) {
622   printf("\tisinlinedmethod=true ");fflush(stdout);  
623   }
624 else {
625   printf("\tisinlinedmethod=false");fflush(stdout);  
626   }
627
628 printf("\tcumjcodelength=%i ,cummaxstack=%i ,cumextablelength=%i ",
629  g->cumjcodelength,    g->cummaxstack,  g->cumextablelength);fflush(stdout);
630 printf("\tcumlocals=%i ,cummethods=%i \n",
631  g->cumlocals,    g->cummethods);fflush(stdout);  
632
633 printf("s>s>s> ");fflush(stdout);
634 print_inlining_stack     (g->inlining_stack);
635 printf("i>i>i> "); fflush(stdout);
636 print_inlining_methodinfo(g->inlining_rootinfo);
637 printf("-------------------\n");fflush(stdout);
638 }
639
640 /* --------------------------------------------------------------------*/
641 void print_inlining_stack     ( list                *s)
642 {
643 if (s==NULL) { 
644   printf("\n\tinlining_stack: NULL\n");
645   return;
646   }
647   
648   {/* print first  element to see if get into stack */
649   t_inlining_stacknode *is;
650   printf("\n\tinlining_stack: NOT NULL\n");
651
652   is=list_first(s); 
653   if (is==NULL) { 
654     printf("\n\tinlining_stack = init'd but EMPTY\n");
655     fflush(stdout);
656     return;
657     }
658   }
659
660   {
661   t_inlining_stacknode *is;
662   printf("\n\tinlining_stack: NOT NULL\n");
663
664
665   for (is=list_first(s); 
666        is!=NULL;
667        is=list_next(s,is)) {
668          printf("\n\ti>--->inlining_stack entry: \n"); fflush(stdout);
669          METHINFO(is->method);
670          printf("i=%i, p=%i, nextp=%i, opcode=%i;\n",
671                 is->i,is->p,is->nextp,is->opcode);fflush(stdout);
672          print_inlining_methodinfo(is->inlinfo);
673     } /*end for */
674   } 
675
676 }
677
678 /* --------------------------------------------------------------------*/
679 void print_inlining_methodinfo( inlining_methodinfo *r) {
680 if (r==NULL) { 
681   printf("\n\tinlining_methodinfo: NULL\n");
682   return;
683   }
684
685 if (r->method != NULL) {
686   utf_display(r->method->class->name); printf("."); fflush(stdout); \
687   method_display(r->method); fflush(stdout); \
688   }
689 else {
690   printf("method is NULL!!!!!\n");fflush(stdout);
691   }
692
693 printf("\n\tinlining_methodinfo for:"); fflush(stdout);
694 if (r->readonly==NULL) {
695   printf("\treadonly==NULL ");fflush(stdout);  
696   }
697 else {
698   int i;
699   printf("\treadonly=");fflush(stdout);  
700   for (i = 0; i < r->method->maxlocals; i++)  {
701     if (r->readonly[i] == true)
702       printf("[i]=T;");
703     else
704       printf("[i]=F;");
705     fflush(stdout);
706     } 
707   }
708
709
710 printf("\tstartgp=%i; stopgp=%i; firstlocal=%i; label_index=%p;\n",
711           r->startgp, r->stopgp, r->firstlocal, r->label_index);
712 {int i;
713 printf ("label_index[0..%d]->", r->method->jcodelength);
714 for (i=0; i<r->method->jcodelength; i++) printf ("%d:%d ", i, r->label_index[i]);
715 }
716
717 {
718 inlining_methodinfo *im;
719 for (im=list_first(r->inlinedmethods); 
720      im!=NULL;
721      im=list_next(r->inlinedmethods,im)) {
722   } 
723 }
724 }
725
726
727 /*
728  * These are local overrides for various environment variables in Emacs.
729  * Please do not remove this and leave it at the end of the file, where
730  * Emacs will automagically detect them.
731  * ---------------------------------------------------------------------
732  * Local variables:
733  * mode: c
734  * indent-tabs-mode: t
735  * c-basic-offset: 4
736  * tab-width: 4
737  * End:
738  */