1 /****************************** ncomp/nstack.c *********************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Parser for JavaVM to intermediate code translation
9 Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
11 Last Change: 1997/11/18
13 *******************************************************************************/
17 #define COUNT(cnt) cnt++
22 #define STACKRESET {curstack=0;stackdepth=0;}
24 #define TYPEPANIC {show_icmd_method();panic("Stack type mismatch");}
25 #define CURKIND curstack->varkind
26 #define CURTYPE curstack->type
28 #define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;\
29 new->varkind=v;new->varnum=n;curstack=new;new++;}
30 #define NEWSTACKn(s,n) NEWSTACK(s,UNDEFVAR,n)
31 #define NEWSTACK0(s) NEWSTACK(s,UNDEFVAR,0)
32 #define NEWXSTACK {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
34 #define SETDST {iptr->dst=curstack;}
35 #define POP(s) {if(s!=curstack->type){TYPEPANIC;}\
36 if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
37 curstack=curstack->prev;}
38 #define POPANY {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
39 curstack=curstack->prev;}
40 #define COPY(s,d) {(d)->flags=0;(d)->type=(s)->type;\
41 (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
43 #define CONST(s) {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
44 #define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
45 #define STORE(s) {POP(s);SETDST;stackdepth--;}
46 #define OP1_0(s) {POP(s);SETDST;stackdepth--;}
47 #define OP1_0ANY {POPANY;SETDST;stackdepth--;}
48 #define OP0_1(s) {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
49 #define OP1_1(s,d) {POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
50 #define OP2_0(s) {POP(s);POP(s);SETDST;stackdepth-=2;}
51 #define OPTT2_0(t,b){POP(t);POP(b);SETDST;stackdepth-=2;}
52 #define OP2_1(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
53 #define OP2IAT_1(s) {POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
55 #define OP2IT_1(s) {POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
57 #define OPTT2_1(s,d){POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
58 #define OP2_2(s) {POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
59 NEWSTACKn(s,stackdepth-1);SETDST;}
60 #define OP3TIA_0(s) {POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
61 #define OP3_0(s) {POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
62 #define POPMANY(i) {stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
63 #define DUP {NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST;\
65 #define SWAP {COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
66 new[0].prev=curstack;new[1].prev=new;\
67 curstack=new+1;new+=2;SETDST;}
68 #define DUP_X1 {COPY(curstack,new);COPY(curstack,new+2);POPANY;\
69 COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
70 new[1].prev=new;new[2].prev=new+1;\
71 curstack=new+2;new+=3;SETDST;stackdepth++;}
72 #define DUP2_X1 {COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
73 COPY(curstack,new);COPY(curstack,new+3);POPANY;\
74 COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
75 new[1].prev=new;new[2].prev=new+1;\
76 new[3].prev=new+2;new[4].prev=new+3;\
77 curstack=new+4;new+=5;SETDST;stackdepth+=2;}
78 #define DUP_X2 {COPY(curstack,new);COPY(curstack,new+3);POPANY;\
79 COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
80 new[0].prev=curstack;new[1].prev=new;\
81 new[2].prev=new+1;new[3].prev=new+2;\
82 curstack=new+3;new+=4;SETDST;stackdepth++;}
83 #define DUP2_X2 {COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
84 COPY(curstack,new);COPY(curstack,new+4);POPANY;\
85 COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
86 new[0].prev=curstack;new[1].prev=new;\
87 new[2].prev=new+1;new[3].prev=new+2;\
88 new[4].prev=new+3;new[5].prev=new+4;\
89 curstack=new+5;new+=6;SETDST;stackdepth+=2;}
91 #define COPYCURSTACK(copy) {\
104 copy->varkind=STACKVAR;\
120 if((copy->varkind==STACKVAR)&&(copy->varnum>i))\
121 copy->varkind=TEMPVAR;\
123 copy->varkind=STACKVAR;\
126 interfaces[i][copy->type].type = copy->type;\
127 interfaces[i][copy->type].flags |= copy->flags;\
128 i--;copy=copy->prev;\
133 interfaces[i][copy->type].type = copy->type;\
134 if(copy->varkind==STACKVAR){\
135 if (copy->flags & SAVEDVAR)\
136 interfaces[i][copy->type].flags |= SAVEDVAR;\
138 i--;copy=copy->prev;\
143 #define MARKREACHED(b,c) {\
145 {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;}\
146 else {stackptr s=curstack;stackptr t=b->instack;\
147 if(b->indepth!=stackdepth)\
148 {show_icmd_method();panic("Stack depth mismatch");}\
149 while(s){if (s->type!=t->type)\
151 s=s->prev;t=t->prev;\
157 static void show_icmd_method();
159 static void analyse_stack()
163 stackptr curstack, new, copy;
164 int opcode, i, len, loops;
165 int superblockend, repeat, deadcode;
166 instruction *iptr = instr;
167 basicblock *bptr, *tbptr;
173 block[0].flags = BBREACHED;
174 block[0].instack = 0;
175 block[0].indepth = 0;
177 for (i = 0; i < exceptiontablelength; i++) {
178 bptr = &block[block_index[extable[i].handlerpc]];
179 bptr->flags = BBREACHED;
180 bptr->type = BBTYPE_EXH;
189 b_count = block_count;
191 superblockend = true;
195 while (--b_count >= 0) {
196 if (superblockend && (bptr->flags < BBREACHED))
198 else if (bptr->flags <= BBREACHED) {
200 stackdepth = bptr->indepth;
201 else if (bptr->flags < BBREACHED) {
203 bptr->instack = copy;
204 bptr->indepth = stackdepth;
206 else if (bptr->indepth != stackdepth) {
208 panic("Stack depth mismatch");
211 curstack = bptr->instack;
213 superblockend = false;
214 bptr->flags = BBFINISHED;
216 len = bptr[1].ipc - i;
225 case ICMD_CHECKASIZE:
229 locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
231 COUNT(count_pcmd_return);
233 superblockend = true;
236 /* pop 0 push 1 const */
239 COUNT(count_pcmd_load);
241 switch (iptr[1].opc) {
243 iptr[0].opc = ICMD_IADDCONST;
245 iptr[1].opc = ICMD_NOP;
246 OP1_1(TYPE_INT,TYPE_INT);
247 COUNT(count_pcmd_op);
250 iptr[0].opc = ICMD_ISUBCONST;
251 goto icmd_iconst_tail;
253 iptr[0].opc = ICMD_IMULCONST;
254 goto icmd_iconst_tail;
256 iptr[0].opc = ICMD_IANDCONST;
257 goto icmd_iconst_tail;
259 iptr[0].opc = ICMD_IORCONST;
260 goto icmd_iconst_tail;
262 iptr[0].opc = ICMD_IXORCONST;
263 goto icmd_iconst_tail;
265 iptr[0].opc = ICMD_ISHLCONST;
266 goto icmd_iconst_tail;
268 iptr[0].opc = ICMD_ISHRCONST;
269 goto icmd_iconst_tail;
271 iptr[0].opc = ICMD_IUSHRCONST;
272 goto icmd_iconst_tail;
274 iptr[0].opc = ICMD_IFEQ;
276 iptr[0].op1 = iptr[1].op1;
277 iptr[1].opc = ICMD_NOP;
279 tbptr = block + block_index[iptr->op1];
280 MARKREACHED(tbptr, copy);
281 COUNT(count_pcmd_bra);
284 iptr[0].opc = ICMD_IFLT;
285 goto icmd_if_icmp_tail;
287 iptr[0].opc = ICMD_IFLE;
288 goto icmd_if_icmp_tail;
290 iptr[0].opc = ICMD_IFNE;
291 goto icmd_if_icmp_tail;
293 iptr[0].opc = ICMD_IFGT;
294 goto icmd_if_icmp_tail;
296 iptr[0].opc = ICMD_IFGE;
297 goto icmd_if_icmp_tail;
306 COUNT(count_pcmd_load);
308 switch (iptr[1].opc) {
310 iptr[0].opc = ICMD_LADDCONST;
312 iptr[1].opc = ICMD_NOP;
313 OP1_1(TYPE_LNG,TYPE_LNG);
314 COUNT(count_pcmd_op);
317 iptr[0].opc = ICMD_LSUBCONST;
318 goto icmd_lconst_tail;
320 iptr[0].opc = ICMD_LMULCONST;
321 goto icmd_lconst_tail;
323 iptr[0].opc = ICMD_LANDCONST;
324 goto icmd_lconst_tail;
326 iptr[0].opc = ICMD_LORCONST;
327 goto icmd_lconst_tail;
329 iptr[0].opc = ICMD_LXORCONST;
330 goto icmd_lconst_tail;
332 iptr[0].opc = ICMD_LSHLCONST;
333 goto icmd_lconst_tail;
335 iptr[0].opc = ICMD_LSHRCONST;
336 goto icmd_lconst_tail;
338 iptr[0].opc = ICMD_LUSHRCONST;
339 goto icmd_lconst_tail;
341 if ((len > 1) && (iptr[2].val.i == 0)) {
342 switch (iptr[2].opc) {
344 iptr[0].opc = ICMD_IF_LEQ;
345 icmd_lconst_lcmp_tail:
346 iptr[0].op1 = iptr[2].op1;
347 iptr[1].opc = ICMD_NOP;
348 iptr[2].opc = ICMD_NOP;
350 tbptr = block + block_index[iptr->op1];
351 MARKREACHED(tbptr, copy);
352 COUNT(count_pcmd_bra);
353 COUNT(count_pcmd_op);
356 iptr[0].opc = ICMD_IF_LNE;
357 goto icmd_lconst_lcmp_tail;
359 iptr[0].opc = ICMD_IF_LLT;
360 goto icmd_lconst_lcmp_tail;
362 iptr[0].opc = ICMD_IF_LGT;
363 goto icmd_lconst_lcmp_tail;
365 iptr[0].opc = ICMD_IF_LLE;
366 goto icmd_lconst_lcmp_tail;
368 iptr[0].opc = ICMD_IF_LGE;
369 goto icmd_lconst_lcmp_tail;
372 } /* switch (iptr[2].opc) */
373 } /* if (iptr[2].val.i == 0) */
385 COUNT(count_pcmd_load);
389 COUNT(count_pcmd_load);
393 COUNT(count_pcmd_load);
397 /* pop 0 push 1 load */
404 COUNT(count_load_instruction);
405 i = opcode-ICMD_ILOAD;
406 locals[iptr->op1][i].type = i;
407 LOAD(i, LOCALVAR, iptr->op1);
417 COUNT(count_check_null);
418 COUNT(count_check_bound);
419 COUNT(count_pcmd_mem);
420 OP2IAT_1(opcode-ICMD_IALOAD);
426 COUNT(count_check_null);
427 COUNT(count_check_bound);
428 COUNT(count_pcmd_mem);
432 /* pop 0 push 0 iinc */
438 count_store_depth[10]++;
440 count_store_depth[i]++;
445 if ((copy->varkind == LOCALVAR) &&
446 (copy->varnum == curstack->varnum)) {
447 copy->varkind = TEMPVAR;
456 /* pop 1 push 0 store */
463 i = opcode-ICMD_ISTORE;
464 locals[iptr->op1][i].type = i;
469 count_store_length[20]++;
471 count_store_length[i]++;
474 count_store_depth[10]++;
476 count_store_depth[i]++;
478 copy = curstack->prev;
481 if ((copy->varkind == LOCALVAR) &&
482 (copy->varnum == curstack->varnum)) {
483 copy->varkind = TEMPVAR;
489 if ((new - curstack) == 1) {
490 curstack->varkind = LOCALVAR;
491 curstack->varnum = iptr->op1;
493 STORE(opcode-ICMD_ISTORE);
503 COUNT(count_check_null);
504 COUNT(count_check_bound);
505 COUNT(count_pcmd_mem);
506 OP3TIA_0(opcode-ICMD_IASTORE);
511 COUNT(count_check_null);
512 COUNT(count_check_bound);
513 COUNT(count_pcmd_mem);
528 COUNT(count_pcmd_return);
529 OP1_0(opcode-ICMD_IRETURN);
530 superblockend = true;
534 COUNT(count_check_null);
538 superblockend = true;
542 COUNT(count_pcmd_mem);
546 /* pop 1 push 0 branch */
550 COUNT(count_pcmd_bra);
552 tbptr = block + block_index[iptr->op1];
553 MARKREACHED(tbptr, copy);
562 COUNT(count_pcmd_bra);
564 tbptr = block + block_index[iptr->op1];
565 MARKREACHED(tbptr, copy);
568 /* pop 0 push 0 branch */
571 COUNT(count_pcmd_bra);
572 tbptr = block + block_index[iptr->op1];
573 MARKREACHED(tbptr, copy);
575 superblockend = true;
578 /* pop 1 push 0 table branch */
580 case ICMD_TABLESWITCH:
581 COUNT(count_pcmd_table);
584 tbptr = block + block_index[*s4ptr++]; /* default */
585 MARKREACHED(tbptr, copy);
586 i = *s4ptr++; /* low */
587 i = *s4ptr++ - i + 1; /* high */
589 tbptr = block + block_index[*s4ptr++];
590 MARKREACHED(tbptr, copy);
593 superblockend = true;
596 /* pop 1 push 0 table branch */
598 case ICMD_LOOKUPSWITCH:
599 COUNT(count_pcmd_table);
602 tbptr = block + block_index[*s4ptr++]; /* default */
603 MARKREACHED(tbptr, copy);
604 i = *s4ptr++; /* count */
606 tbptr = block + block_index[s4ptr[1]];
607 MARKREACHED(tbptr, copy);
611 superblockend = true;
614 case ICMD_NULLCHECKPOP:
615 case ICMD_MONITORENTER:
616 COUNT(count_check_null);
617 case ICMD_MONITOREXIT:
621 /* pop 2 push 0 branch */
629 COUNT(count_pcmd_bra);
631 tbptr = block + block_index[iptr->op1];
632 MARKREACHED(tbptr, copy);
637 COUNT(count_pcmd_bra);
639 tbptr = block + block_index[iptr->op1];
640 MARKREACHED(tbptr, copy);
646 COUNT(count_check_null);
647 COUNT(count_pcmd_mem);
648 OPTT2_0(iptr->op1,TYPE_ADR);
652 if (! IS_2_WORD_TYPE(curstack->type)) {
653 OP1_0ANY; /* second pop */
656 iptr->opc = ICMD_POP;
660 /* pop 0 push 1 dup */
663 COUNT(count_dup_instruction);
668 if (IS_2_WORD_TYPE(curstack->type)) {
669 iptr->opc = ICMD_DUP;
674 NEWSTACK(copy[-1].type, copy[-1].varkind,
676 NEWSTACK(copy[ 0].type, copy[ 0].varkind,
683 /* pop 2 push 3 dup */
690 if (IS_2_WORD_TYPE(curstack->type)) {
691 iptr->opc = ICMD_DUP_X1;
699 /* pop 3 push 4 dup */
702 if (IS_2_WORD_TYPE(curstack[-1].type)) {
703 iptr->opc = ICMD_DUP_X1;
712 if (IS_2_WORD_TYPE(curstack->type)) {
713 if (IS_2_WORD_TYPE(curstack[-1].type)) {
714 iptr->opc = ICMD_DUP_X1;
718 iptr->opc = ICMD_DUP_X2;
723 if (IS_2_WORD_TYPE(curstack[-2].type)) {
724 iptr->opc = ICMD_DUP2_X1;
732 /* pop 2 push 2 swap */
752 COUNT(count_pcmd_op);
765 COUNT(count_pcmd_op);
772 COUNT(count_pcmd_op);
781 COUNT(count_pcmd_op);
790 COUNT(count_pcmd_op);
795 COUNT(count_pcmd_op);
796 if ((len > 0) && (iptr[1].val.i == 0)) {
797 switch (iptr[1].opc) {
799 iptr[0].opc = ICMD_IF_LCMPEQ;
801 iptr[0].op1 = iptr[1].op1;
802 iptr[1].opc = ICMD_NOP;
804 tbptr = block + block_index[iptr->op1];
805 MARKREACHED(tbptr, copy);
806 COUNT(count_pcmd_bra);
809 iptr[0].opc = ICMD_IF_LCMPNE;
810 goto icmd_lcmp_if_tail;
812 iptr[0].opc = ICMD_IF_LCMPLT;
813 goto icmd_lcmp_if_tail;
815 iptr[0].opc = ICMD_IF_LCMPGT;
816 goto icmd_lcmp_if_tail;
818 iptr[0].opc = ICMD_IF_LCMPLE;
819 goto icmd_lcmp_if_tail;
821 iptr[0].opc = ICMD_IF_LCMPGE;
822 goto icmd_lcmp_if_tail;
824 OPTT2_1(TYPE_LNG, TYPE_INT);
828 OPTT2_1(TYPE_LNG, TYPE_INT);
832 COUNT(count_pcmd_op);
833 OPTT2_1(TYPE_FLT, TYPE_INT);
837 COUNT(count_pcmd_op);
838 OPTT2_1(TYPE_DBL, TYPE_INT);
847 COUNT(count_pcmd_op);
848 OP1_1(TYPE_INT, TYPE_INT);
851 COUNT(count_pcmd_op);
852 OP1_1(TYPE_LNG, TYPE_LNG);
855 COUNT(count_pcmd_op);
856 OP1_1(TYPE_FLT, TYPE_FLT);
859 COUNT(count_pcmd_op);
860 OP1_1(TYPE_DBL, TYPE_DBL);
864 COUNT(count_pcmd_op);
865 OP1_1(TYPE_INT, TYPE_LNG);
868 COUNT(count_pcmd_op);
869 OP1_1(TYPE_INT, TYPE_FLT);
872 COUNT(count_pcmd_op);
873 OP1_1(TYPE_INT, TYPE_DBL);
876 COUNT(count_pcmd_op);
877 OP1_1(TYPE_LNG, TYPE_INT);
880 COUNT(count_pcmd_op);
881 OP1_1(TYPE_LNG, TYPE_FLT);
884 COUNT(count_pcmd_op);
885 OP1_1(TYPE_LNG, TYPE_DBL);
888 COUNT(count_pcmd_op);
889 OP1_1(TYPE_FLT, TYPE_INT);
892 COUNT(count_pcmd_op);
893 OP1_1(TYPE_FLT, TYPE_LNG);
896 COUNT(count_pcmd_op);
897 OP1_1(TYPE_FLT, TYPE_DBL);
900 COUNT(count_pcmd_op);
901 OP1_1(TYPE_DBL, TYPE_INT);
904 COUNT(count_pcmd_op);
905 OP1_1(TYPE_DBL, TYPE_LNG);
908 COUNT(count_pcmd_op);
909 OP1_1(TYPE_DBL, TYPE_FLT);
913 OP1_1(TYPE_ADR, TYPE_ADR);
916 case ICMD_ARRAYLENGTH:
917 case ICMD_INSTANCEOF:
918 OP1_1(TYPE_ADR, TYPE_INT);
923 OP1_1(TYPE_INT, TYPE_ADR);
927 COUNT(count_check_null);
928 COUNT(count_pcmd_mem);
929 OP1_1(TYPE_ADR, iptr->op1);
935 COUNT(count_pcmd_mem);
945 tbptr = block + block_index[iptr->op1];
946 tbptr->type=BBTYPE_SBR;
947 MARKREACHED(tbptr, copy);
951 /* pop many push any */
953 case ICMD_INVOKEVIRTUAL:
954 case ICMD_INVOKESPECIAL:
955 case ICMD_INVOKEINTERFACE:
956 case ICMD_INVOKESTATIC:
957 COUNT(count_pcmd_met);
959 methodinfo *m = iptr->val.a;
960 if (m->flags & ACC_STATIC)
961 {COUNT(count_check_null);}
963 if (i > arguments_num)
967 if (! (copy->flags & SAVEDVAR)) {
968 copy->varkind = ARGVAR;
974 copy->flags |= SAVEDVAR;
979 if (m->returntype != TYPE_VOID) {
980 OP0_1(m->returntype);
986 if (! (curstack->flags & SAVEDVAR)) {
987 curstack->varkind = ARGVAR;
988 curstack->varnum = 2;
992 if (! (curstack->flags & SAVEDVAR)) {
993 curstack->varkind = ARGVAR;
994 curstack->varnum = 1;
998 if (! (curstack->flags & SAVEDVAR)) {
999 curstack->varkind = ARGVAR;
1000 curstack->varnum = 0;
1005 copy->flags |= SAVEDVAR;
1008 if (iptr->op1 != TYPE_VOID)
1012 case ICMD_MULTIANEWARRAY:
1014 if ((i + intreg_argnum) > arguments_num)
1015 arguments_num = i + intreg_argnum;
1018 if (! (copy->flags & SAVEDVAR)) {
1019 copy->varkind = ARGVAR;
1020 copy->varnum = i + intreg_argnum;
1025 copy->flags |= SAVEDVAR;
1034 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
1035 panic("Missing ICMD code during stack analysis");
1038 } /* while instructions */
1039 bptr->outstack = curstack;
1040 bptr->outdepth = stackdepth;
1044 superblockend = true;
1046 } /* while blocks */
1047 } while (repeat && ! deadcode);
1050 if (block_count > count_max_basic_blocks)
1051 count_max_basic_blocks = block_count;
1052 count_basic_blocks += block_count;
1053 if (block[block_count].ipc > count_max_javainstr)
1054 count_max_javainstr = block[block_count].ipc;
1055 count_javainstr += block[block_count].ipc;
1056 if (stack_count > count_upper_bound_new_stack)
1057 count_upper_bound_new_stack = stack_count;
1058 if ((new - stack) > count_max_new_stack)
1059 count_max_new_stack = (new - stack);
1061 b_count = block_count;
1063 while (--b_count >= 0) {
1064 if (bptr->flags > BBREACHED) {
1065 if (bptr->indepth >= 10)
1066 count_block_stack[10]++;
1068 count_block_stack[bptr->indepth]++;
1069 len = bptr[1].ipc - bptr[0].ipc;
1071 count_block_size_distribution[len - 1]++;
1073 count_block_size_distribution[10]++;
1075 count_block_size_distribution[11]++;
1077 count_block_size_distribution[12]++;
1079 count_block_size_distribution[13]++;
1081 count_block_size_distribution[14]++;
1083 count_block_size_distribution[15]++;
1085 count_block_size_distribution[16]++;
1087 count_block_size_distribution[17]++;
1093 count_analyse_iterations[0]++;
1094 else if (loops == 2)
1095 count_analyse_iterations[1]++;
1096 else if (loops == 3)
1097 count_analyse_iterations[2]++;
1098 else if (loops == 4)
1099 count_analyse_iterations[3]++;
1101 count_analyse_iterations[4]++;
1103 if (block_count <= 5)
1104 count_method_bb_distribution[0]++;
1105 else if (block_count <= 10)
1106 count_method_bb_distribution[1]++;
1107 else if (block_count <= 15)
1108 count_method_bb_distribution[2]++;
1109 else if (block_count <= 20)
1110 count_method_bb_distribution[3]++;
1111 else if (block_count <= 30)
1112 count_method_bb_distribution[4]++;
1113 else if (block_count <= 40)
1114 count_method_bb_distribution[5]++;
1115 else if (block_count <= 50)
1116 count_method_bb_distribution[6]++;
1117 else if (block_count <= 75)
1118 count_method_bb_distribution[7]++;
1120 count_method_bb_distribution[8]++;
1125 static void print_stack(stackptr s) {
1141 if (s->flags & SAVEDVAR)
1142 switch (s->varkind) {
1144 if (s->flags & INMEMORY)
1145 printf(" m%02d", s->regoff);
1147 printf(" r%02d", s->regoff);
1150 printf(" s%02d", s->varnum);
1153 printf(" l%02d", s->varnum);
1156 printf(" a%02d", s->varnum);
1159 printf(" !%02d", j);
1162 switch (s->varkind) {
1164 if (s->flags & INMEMORY)
1165 printf(" M%02d", s->regoff);
1167 printf(" R%02d", s->regoff);
1170 printf(" S%02d", s->varnum);
1173 printf(" L%02d", s->varnum);
1176 printf(" A%02d", s->varnum);
1179 printf(" ?%02d", j);
1186 static void print_reg(stackptr s) {
1188 if (s->flags & SAVEDVAR)
1189 switch (s->varkind) {
1191 if (s->flags & INMEMORY)
1192 printf(" tm%02d", s->regoff);
1194 printf(" tr%02d", s->regoff);
1197 printf(" s %02d", s->varnum);
1200 printf(" l %02d", s->varnum);
1203 printf(" a %02d", s->varnum);
1206 printf(" ! %02d", s->varnum);
1209 switch (s->varkind) {
1211 if (s->flags & INMEMORY)
1212 printf(" Tm%02d", s->regoff);
1214 printf(" Tr%02d", s->regoff);
1217 printf(" S %02d", s->varnum);
1220 printf(" L %02d", s->varnum);
1223 printf(" A %02d", s->varnum);
1226 printf(" ? %02d", s->varnum);
1235 static char *builtin_name(functionptr bptr)
1237 builtin_descriptor *bdesc = builtin_desc;
1238 while ((bdesc->bptr != NULL) && (bdesc->bptr != bptr))
1244 static void show_icmd_method()
1251 unicode_fprint(stdout, class->name);
1253 unicode_fprint(stdout, method->name);
1255 unicode_fprint(stdout, method->descriptor);
1256 printf ("\n\nMax locals: %d\n", (int) maxlocals);
1257 printf ("Max stack: %d\n", (int) maxstack);
1259 printf ("Exceptions:\n");
1260 for (i = 0; i < exceptiontablelength; i++) {
1261 printf(" L%03d ... ", block_index[extable[i].startpc]);
1262 printf("L%03d = ", block_index[extable[i].endpc]);
1263 printf("L%03d\n", block_index[extable[i].handlerpc]);
1266 printf ("Local Table:\n");
1267 for (i = 0; i < maxlocals; i++) {
1268 printf(" %3d: ", i);
1269 for (j = TYPE_INT; j <= TYPE_ADR; j++)
1270 if (locals[i][j].type >= 0) {
1271 printf(" (%d) ", j);
1272 if (locals[i][j].flags)
1276 printf("%2d", locals[i][j].regoff);
1282 printf ("Interface Table:\n");
1283 for (i = 0; i < maxstack; i++) {
1284 if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
1285 (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
1286 (interfaces[i][4].type >= 0)) {
1287 printf(" %3d: ", i);
1288 for (j = TYPE_INT; j <= TYPE_ADR; j++)
1289 if (interfaces[i][j].type >= 0) {
1290 printf(" (%d) ", j);
1291 if (interfaces[i][j].flags & SAVEDVAR)
1295 if (interfaces[i][j].flags & INMEMORY)
1299 printf("%2d", interfaces[i][j].regoff);
1305 for (b = 0; b < block_count; b++) {
1306 deadcode = block[b].flags <= BBREACHED;
1309 for (j = maxstack; j > 0; j--)
1312 print_stack(block[b].instack);
1313 printf("] L%03d:\n", b);
1314 for (i = block[b].ipc; i < block[b + 1].ipc; i++) {
1317 for (j = maxstack; j > 0; j--)
1321 print_stack(instr[i].dst);
1322 printf("] %4d %s", i, icmd_names[instr[i].opc]);
1323 switch ((int) instr[i].opc) {
1324 case ICMD_IADDCONST:
1325 case ICMD_ISUBCONST:
1326 case ICMD_IMULCONST:
1327 case ICMD_IANDCONST:
1329 case ICMD_IXORCONST:
1330 case ICMD_ISHLCONST:
1331 case ICMD_ISHRCONST:
1332 case ICMD_IUSHRCONST:
1336 printf(" %d", instr[i].val.i);
1338 case ICMD_LADDCONST:
1339 case ICMD_LSUBCONST:
1340 case ICMD_LMULCONST:
1341 case ICMD_LANDCONST:
1343 case ICMD_LXORCONST:
1344 case ICMD_LSHLCONST:
1345 case ICMD_LSHRCONST:
1346 case ICMD_LUSHRCONST:
1348 printf(" %ld", instr[i].val.l);
1351 printf(" %f", instr[i].val.f);
1354 printf(" %f", instr[i].val.d);
1357 case ICMD_PUTSTATIC:
1358 case ICMD_GETSTATIC:
1359 printf(" %p", instr[i].val.a);
1362 printf(" %d + %d", instr[i].op1, instr[i].val.i);
1375 printf(" %d", instr[i].op1);
1379 unicode_fprint(stdout,
1380 ((classinfo *) instr[i].val.a)->name);
1383 switch (instr[i].op1) {
1410 case ICMD_ANEWARRAY:
1413 unicode_fprint(stdout,
1414 ((classinfo *) instr[i].val.a)->name);
1417 case ICMD_CHECKCAST:
1418 case ICMD_INSTANCEOF:
1421 unicode_fprint(stdout,
1422 ((classinfo *) instr[i].val.a)->name);
1428 printf(" %s", builtin_name((functionptr) instr[i].val.a));
1430 case ICMD_INVOKEVIRTUAL:
1431 case ICMD_INVOKESPECIAL:
1432 case ICMD_INVOKESTATIC:
1433 case ICMD_INVOKEINTERFACE:
1435 unicode_fprint(stdout,
1436 ((methodinfo *) instr[i].val.a)->class->name);
1438 unicode_fprint(stdout,
1439 ((methodinfo *) instr[i].val.a)->name);
1453 printf("(%d) L%03d", instr[i].val.i, block_index[instr[i].op1]);
1458 case ICMD_IFNONNULL:
1459 case ICMD_IF_ICMPEQ:
1460 case ICMD_IF_ICMPNE:
1461 case ICMD_IF_ICMPLT:
1462 case ICMD_IF_ICMPGE:
1463 case ICMD_IF_ICMPGT:
1464 case ICMD_IF_ICMPLE:
1465 case ICMD_IF_LCMPEQ:
1466 case ICMD_IF_LCMPNE:
1467 case ICMD_IF_LCMPLT:
1468 case ICMD_IF_LCMPGE:
1469 case ICMD_IF_LCMPGT:
1470 case ICMD_IF_LCMPLE:
1471 case ICMD_IF_ACMPEQ:
1472 case ICMD_IF_ACMPNE:
1473 printf(" L%03d", block_index[instr[i].op1]);
1475 case ICMD_TABLESWITCH:
1476 s4ptr = instr[i].val.a;
1477 printf(" L%03d;", block_index[*s4ptr++]); /* default */
1478 j = *s4ptr++; /* low */
1479 j = *s4ptr++ - j; /* high */
1481 printf(" L%03d", block_index[*s4ptr++]);
1485 case ICMD_LOOKUPSWITCH:
1486 s4ptr = instr[i].val.a;
1487 printf(" L%d", block_index[*s4ptr++]); /* default */
1488 j = *s4ptr++; /* count */
1490 printf(" L%03d", block_index[s4ptr[1]]);