* src/vm/jit/inline/inline_debug.c (debug_dump_stack): Fixed warning on
[cacao.git] / src / vm / jit / inline / inline_debug.c
1 #include <ctype.h>
2
3 #define DEBUG_SLOT(slot)  ((int)((slot) ? ((slot) - iln->ctx->n_debug_stackbase) : (-1)))
4
5 #if 0
6                 printf("linenumbertable_entry %p: pc=%p line=%08x, lntsize=%d, looking for pc=%p\n",
7                                 (void*)lntentry,(void*)lntentry->pc,lntentry->line,lntsize,(void*)pc);
8 #endif
9
10 #if 0
11                                                 printf("inline entry %p: pc=%p line=%08x, lntsize=%d, looking for pc=%p\n",
12                                                                 (void*)lntinline,(void*)lntinline->pc,lntinline->line,lntsize,(void*)pc);
13                                                 printf("\trecurse %p into %p ",(void*)lntinline,(void*)lntinline->pc); method_println((methodinfo *)lntinline->pc);
14 #endif
15
16 #if 0
17         if (oa) {
18             int i;
19
20             for (i=0; i<oa->header.size; ++i) {
21                 printf("\t%i: %p ",i,(void*)oa->data[i]);
22                 if (oa->data[i])
23                     class_println((classinfo *)oa->data[i]);
24                 else
25                     printf("\n");
26             }
27         }
28         printf("GOT CLASS: %p\n",c);
29         if (c) {
30             class_println(c);
31         }
32         printf("GOT CLASSLOADER: %p\n",cl);
33         if (cl) {
34             class_println(cl->vftbl->class);
35         }
36 #endif
37
38 static void debug_dump_inline_context(inline_node *iln)
39 {
40         inline_stack_translation *tr;
41         
42         printf("inline_context @%p: stackbase=%p transstart=%p translationlimit=%p\n",
43                         (void*)iln->ctx,(void*)iln->ctx->n_debug_stackbase,
44                         (void*)iln->ctx->stacktranslationstart,(void*)iln->ctx->o_translationlimit);
45         tr = iln->ctx->stacktranslationstart;
46         while (tr >= iln->ctx->stacktranslation) {
47                 printf("\ttranslate %p -> %d (%p)\n",
48                                 (void*)tr->o_sp,DEBUG_SLOT(tr->n_sp),(void*)tr->n_sp);
49                 tr--;
50         }
51 }
52
53 static void debug_dump_stack(stackptr sp)
54 {
55         while (sp) {
56                 printf("%p (%d) (%01d:%02d:%01x) -> ",(void*)sp,sp->type,sp->varkind,sp->varnum,sp->flags);
57                 sp = sp->prev;
58         }
59         printf("%p",(void*)NULL);
60 }
61
62 static void dump_inline_tree(inline_node *iln)
63 {
64         char indent[100];
65         int i;
66         inline_node *child;
67
68         if (!iln) {
69                 printf("(inline_node *)null\n");
70                 return;
71         }
72
73         for (i=0; i<iln->depth; ++i)
74                 indent[i] = '\t';
75         indent[i] = 0;
76
77         assert(iln->m);
78         if (iln->depth) {
79                 if (!iln->parent) {
80                         printf("parent unset");
81                 }
82                 else {
83                         printf("%s[%d] L%03d %d-%d (ins %d,st %d) (sd=%d,cs=%p,lofs=%d) cum(ins %d,st %d,bb %d) ",
84                                         indent,iln->depth,iln->callerblock->debug_nr,
85                                         iln->callerpc,(int)(iln->callerblock->iinstr - iln->parent->m->basicblocks->iinstr),
86                                         iln->instructioncount,iln->stackcount,iln->n_callerstackdepth,
87                                         (void*)iln->n_callerstack,
88                                         iln->localsoffset,
89                                         iln->cumul_instructioncount,iln->cumul_stackcount,iln->cumul_basicblockcount);
90                 }
91         }
92         else {
93                 printf("%s[%d] MAIN (ins %d,st %d) (cs=%p) cum(ins %d,st %d,bb %d) ",indent,iln->depth,
94                                 iln->instructioncount,iln->stackcount,
95                                 (void*)iln->n_callerstack,
96                                 iln->cumul_instructioncount,iln->cumul_stackcount,iln->cumul_basicblockcount);
97         }
98         method_println(iln->m);
99
100         child = iln->children;
101         if (child) {
102                 do {
103                         dump_inline_tree(child);
104                 }
105                 while ((child = child->next) != iln->children);
106         }
107 }
108
109
110
111 static int stack_depth(stackptr sp)
112 {
113         int depth = 0;
114         while (sp) {
115                 depth++;
116                 sp = sp->prev;
117         }
118         return depth;
119 }
120
121 static stackptr first_stackslot_of_block(basicblock *block)
122 {
123         int len;
124         instruction *iptr;
125         stackptr sp;
126         
127         assert(block);
128         if (block->instack)
129                 return block->instack - (block->indepth-1);
130         
131         len = block->icount;
132         iptr = block->iinstr;
133         while (len--) {
134                 if (iptr->dst) {
135                         sp = iptr->dst;
136                         while (sp->prev) {
137                                 sp = sp->prev;
138                         }
139                         return sp;
140                 }
141                 iptr++;
142         }
143
144         return NULL;
145 }
146
147 static void debug_print_stack(inline_node *iln,stackptr sp,int validstackmin,int validstackmax)
148 {
149         int i;
150         int idx;
151         char typechar;
152         char kindchar;
153         
154         printf("[");
155         for (i=0; i<iln->cumul_maxstack; ++i) {
156                 if (sp) {
157                         idx = sp - iln->n_inlined_stack;
158                         switch (sp->type) {
159                                 case TYPE_ADR: typechar = 'a'; break;
160                                 case TYPE_INT: typechar = 'i'; break;
161                                 case TYPE_LNG: typechar = 'l'; break;
162                                 case TYPE_FLT: typechar = 'f'; break;
163                                 case TYPE_DBL: typechar = 'd'; break;
164                                 default:       typechar = '?';
165                         }
166             switch (sp->varkind) {
167                 case STACKVAR: kindchar = 's'; break;
168                 case LOCALVAR: kindchar = 'l'; break;
169                 case TEMPVAR : kindchar = 't'; break;
170                 case UNDEFVAR: kindchar = 'u'; break;
171                 case ARGVAR  : kindchar = 'a'; break;
172                 default:       kindchar = '_'; break;
173             }
174             if (sp->flags & SAVEDVAR)
175                 kindchar = toupper(kindchar);
176                         printf("%c%-3d(%c%-2d:%01x) ",typechar,idx,kindchar,sp->varnum,sp->flags);
177                         sp = sp->prev;
178
179                         assert(idx >= validstackmin);
180                         assert(idx <= validstackmax);
181 #if 0
182                         if (idx < validstackmin || idx > validstackmax) {
183                                 printf("INVALID STACK INDEX: %d\n",idx);
184                         }
185 #endif
186                 }
187                 else {
188                         printf("----        ");
189                 }
190         }
191         printf("] ");
192 }
193
194 static void debug_dump_inlined_code(inline_node *iln,methodinfo *newmethod,codegendata *cd,registerdata *rd)
195 {
196         basicblock *bptr;
197         instruction *iptr;
198         stackptr curstack;
199         stackptr dst;
200         basicblock *nextblock;
201         int len;
202         int validstackmin;
203         int validstackmax;
204         int i;
205         int type;
206
207         printf("INLINED CODE: maxstack=%d maxlocals=%d leafmethod=%d\n",
208                         newmethod->maxstack,newmethod->maxlocals,newmethod->isleafmethod);
209
210         for (i=0; i<newmethod->maxlocals; ++i) {
211             for (type=0; type<5; ++type) {
212                 if (rd->locals[i][type].type < 0)
213                     continue;
214                 printf("\tlocal %d type %d: flags %01x\n",i,type,rd->locals[i][type].flags);
215             }
216         }
217
218         for (i=0; i<newmethod->maxstack; ++i) {
219             for (type=0; type<5; ++type) {
220                 if (rd->interfaces[i][type].type < 0)
221                     continue;
222                 printf("\tinterface %d type %d: flags %01x\n",i,type,rd->interfaces[i][type].flags);
223             }
224         }
225
226         printf("registerdata:\n");
227         printf("\tmemuse = %d\n",rd->memuse);
228         printf("\targintreguse = %d\n",rd->argintreguse);
229         printf("\targfltreguse = %d\n",rd->argfltreguse);
230
231         validstackmin = 0;
232
233         bptr = iln->inlined_basicblocks;
234         for (; bptr; bptr = bptr->next) {
235                 curstack = bptr->instack;
236                 iptr = bptr->iinstr;
237                 len = bptr->icount;
238
239                 nextblock = bptr->next;
240 find_stackmax:
241                 if (nextblock) {
242                         dst = first_stackslot_of_block(nextblock);
243                         if (dst) {
244                                 validstackmax = (dst - iln->n_inlined_stack) - 1;
245                         }
246                         else {
247                                 nextblock = nextblock->next;
248                                 goto find_stackmax;
249                         }
250                 }
251                 else {
252                         validstackmax = 10000; /* XXX */
253                 }
254
255                 debug_print_stack(iln,curstack,validstackmin,validstackmax);
256                 printf("L%03d BLOCK %p indepth=%d outdepth=%d icount=%d stack=[%d,%d] type=%d flags=%d\n",
257                                 bptr->debug_nr,(void*)bptr,bptr->indepth,bptr->outdepth,bptr->icount,
258                                 validstackmin,validstackmax,
259                 bptr->type,bptr->flags);
260
261                 while (len--) {
262                         dst = iptr->dst;
263
264                         debug_print_stack(iln,dst,validstackmin,validstackmax);
265                         printf("     ");
266                         show_icmd(iptr,false); printf("\n");
267
268                         curstack = dst;
269                         iptr++;
270                 }
271                 printf("\n");
272
273                 /* next basic block */
274                 validstackmin = validstackmax + 1;
275         }
276 }