1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
32 $Id: stack.c 2038 2005-03-20 11:22:40Z twisti $
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "toolbox/logging.h"
45 #include "vm/global.h"
46 #include "vm/builtin.h"
47 #include "vm/options.h"
48 #include "vm/statistics.h"
49 #include "vm/tables.h"
50 #include "vm/jit/codegen.inc.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/reg.h"
53 #include "vm/jit/stack.h"
56 /**********************************************************************/
58 /**********************************************************************/
60 /* analyse_stack uses the intermediate code created by parse.c to
61 * build a model of the JVM operand stack for the current method.
63 * The following checks are performed:
64 * - check for operand stack underflow (before each instruction)
65 * - check for operand stack overflow (after[1] each instruction)
66 * - check for matching stack depth at merging points
67 * - check for matching basic types[2] at merging points
68 * - check basic types for instruction input (except for BUILTIN*
69 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
71 * [1]) Checking this after the instruction should be ok. parse.c
72 * counts the number of required stack slots in such a way that it is
73 * only vital that we don't exceed `maxstack` at basic block
76 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
77 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
78 * types are not discerned.
81 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
89 int opcode, i, len, loops;
90 int superblockend, repeat, deadcode;
98 argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */
99 for (i = 0; i < cd->maxlocals; i++)
102 rd->arguments_num = 0;
105 m->basicblocks[0].flags = BBREACHED;
106 m->basicblocks[0].instack = 0;
107 m->basicblocks[0].indepth = 0;
109 for (i = 0; i < cd->exceptiontablelength; i++) {
110 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
111 bptr->flags = BBREACHED;
112 bptr->type = BBTYPE_EXH;
115 bptr->pre_count = 10000;
120 #ifdef CONDITIONAL_LOADCONST
121 b_count = m->basicblockcount;
122 bptr = m->basicblocks;
123 while (--b_count >= 0) {
124 if (bptr->icount != 0) {
125 iptr = bptr->iinstr + bptr->icount - 1;
158 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
161 case ICMD_TABLESWITCH:
163 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
164 i = *s4ptr++; /* low */
165 i = *s4ptr++ - i + 1; /* high */
167 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
171 case ICMD_LOOKUPSWITCH:
173 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
174 i = *s4ptr++; /* count */
176 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
192 b_count = m->basicblockcount;
193 bptr = m->basicblocks;
194 superblockend = true;
198 while (--b_count >= 0) {
199 if (bptr->flags == BBDELETED) {
202 else if (superblockend && (bptr->flags < BBREACHED))
204 else if (bptr->flags <= BBREACHED) {
206 stackdepth = bptr->indepth;
207 else if (bptr->flags < BBREACHED) {
209 bptr->instack = copy;
210 bptr->indepth = stackdepth;
212 else if (bptr->indepth != stackdepth) {
213 show_icmd_method(m, cd, rd);
214 printf("Block: %d, required depth: %d, current depth: %d\n", bptr->debug_nr, bptr->indepth, stackdepth);
215 panic("Stack depth mismatch");
218 curstack = bptr->instack;
220 superblockend = false;
221 bptr->flags = BBFINISHED;
224 b_index = bptr - m->basicblocks;
229 /* dolog("p: %04d op: %s stack: %p", iptr - instr, icmd_names[opcode], curstack); */
231 #if defined(USEBUILTINTABLE)
234 stdopdescriptor *breplace;
235 breplace = find_builtin(opcode);
237 if (breplace && opcode == breplace->opcode) {
238 iptr[0].opc = breplace->icmd;
239 iptr[0].op1 = breplace->type_d;
240 iptr[0].val.fp = breplace->builtin;
241 m->isleafmethod = false;
242 switch (breplace->icmd) {
250 builtin_descriptor *breplace;
251 breplace = find_builtin(opcode);
253 if (breplace && opcode == breplace->opcode) {
254 iptr[0].opc = breplace->icmd;
255 iptr[0].op1 = breplace->type_d;
256 iptr[0].val.fp = breplace->builtin;
257 m->isleafmethod = false;
258 switch (breplace->icmd) {
266 #endif /* defined(USEBUILTINTABLE) */
273 case ICMD_CHECKASIZE:
274 case ICMD_CHECKEXCEPTION:
276 case ICMD_IFEQ_ICONST:
277 case ICMD_IFNE_ICONST:
278 case ICMD_IFLT_ICONST:
279 case ICMD_IFGE_ICONST:
280 case ICMD_IFGT_ICONST:
281 case ICMD_IFLE_ICONST:
282 case ICMD_ELSE_ICONST:
287 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
289 COUNT(count_pcmd_return);
291 superblockend = true;
294 /* pop 0 push 1 const */
297 COUNT(count_pcmd_load);
299 switch (iptr[1].opc) {
301 iptr[0].opc = ICMD_IADDCONST;
303 iptr[1].opc = ICMD_NOP;
304 OP1_1(TYPE_INT,TYPE_INT);
305 COUNT(count_pcmd_op);
308 iptr[0].opc = ICMD_ISUBCONST;
309 goto icmd_iconst_tail;
310 #if SUPPORT_CONST_MUL
312 iptr[0].opc = ICMD_IMULCONST;
313 goto icmd_iconst_tail;
314 #else /* SUPPORT_CONST_MUL */
316 if (iptr[0].val.i == 0x00000002)
318 else if (iptr[0].val.i == 0x00000004)
320 else if (iptr[0].val.i == 0x00000008)
322 else if (iptr[0].val.i == 0x00000010)
324 else if (iptr[0].val.i == 0x00000020)
326 else if (iptr[0].val.i == 0x00000040)
328 else if (iptr[0].val.i == 0x00000080)
330 else if (iptr[0].val.i == 0x00000100)
332 else if (iptr[0].val.i == 0x00000200)
334 else if (iptr[0].val.i == 0x00000400)
336 else if (iptr[0].val.i == 0x00000800)
338 else if (iptr[0].val.i == 0x00001000)
340 else if (iptr[0].val.i == 0x00002000)
342 else if (iptr[0].val.i == 0x00004000)
344 else if (iptr[0].val.i == 0x00008000)
346 else if (iptr[0].val.i == 0x00010000)
348 else if (iptr[0].val.i == 0x00020000)
350 else if (iptr[0].val.i == 0x00040000)
352 else if (iptr[0].val.i == 0x00080000)
354 else if (iptr[0].val.i == 0x00100000)
356 else if (iptr[0].val.i == 0x00200000)
358 else if (iptr[0].val.i == 0x00400000)
360 else if (iptr[0].val.i == 0x00800000)
362 else if (iptr[0].val.i == 0x01000000)
364 else if (iptr[0].val.i == 0x02000000)
366 else if (iptr[0].val.i == 0x04000000)
368 else if (iptr[0].val.i == 0x08000000)
370 else if (iptr[0].val.i == 0x10000000)
372 else if (iptr[0].val.i == 0x20000000)
374 else if (iptr[0].val.i == 0x40000000)
376 else if (iptr[0].val.i == 0x80000000)
382 iptr[0].opc = ICMD_IMULPOW2;
383 goto icmd_iconst_tail;
384 #endif /* SUPPORT_CONST_MUL */
386 if (iptr[0].val.i == 0x00000002)
388 else if (iptr[0].val.i == 0x00000004)
390 else if (iptr[0].val.i == 0x00000008)
392 else if (iptr[0].val.i == 0x00000010)
394 else if (iptr[0].val.i == 0x00000020)
396 else if (iptr[0].val.i == 0x00000040)
398 else if (iptr[0].val.i == 0x00000080)
400 else if (iptr[0].val.i == 0x00000100)
402 else if (iptr[0].val.i == 0x00000200)
404 else if (iptr[0].val.i == 0x00000400)
406 else if (iptr[0].val.i == 0x00000800)
408 else if (iptr[0].val.i == 0x00001000)
410 else if (iptr[0].val.i == 0x00002000)
412 else if (iptr[0].val.i == 0x00004000)
414 else if (iptr[0].val.i == 0x00008000)
416 else if (iptr[0].val.i == 0x00010000)
418 else if (iptr[0].val.i == 0x00020000)
420 else if (iptr[0].val.i == 0x00040000)
422 else if (iptr[0].val.i == 0x00080000)
424 else if (iptr[0].val.i == 0x00100000)
426 else if (iptr[0].val.i == 0x00200000)
428 else if (iptr[0].val.i == 0x00400000)
430 else if (iptr[0].val.i == 0x00800000)
432 else if (iptr[0].val.i == 0x01000000)
434 else if (iptr[0].val.i == 0x02000000)
436 else if (iptr[0].val.i == 0x04000000)
438 else if (iptr[0].val.i == 0x08000000)
440 else if (iptr[0].val.i == 0x10000000)
442 else if (iptr[0].val.i == 0x20000000)
444 else if (iptr[0].val.i == 0x40000000)
446 else if (iptr[0].val.i == 0x80000000)
452 iptr[0].opc = ICMD_IDIVPOW2;
453 goto icmd_iconst_tail;
455 if ((iptr[0].val.i == 0x00000002) ||
456 (iptr[0].val.i == 0x00000004) ||
457 (iptr[0].val.i == 0x00000008) ||
458 (iptr[0].val.i == 0x00000010) ||
459 (iptr[0].val.i == 0x00000020) ||
460 (iptr[0].val.i == 0x00000040) ||
461 (iptr[0].val.i == 0x00000080) ||
462 (iptr[0].val.i == 0x00000100) ||
463 (iptr[0].val.i == 0x00000200) ||
464 (iptr[0].val.i == 0x00000400) ||
465 (iptr[0].val.i == 0x00000800) ||
466 (iptr[0].val.i == 0x00001000) ||
467 (iptr[0].val.i == 0x00002000) ||
468 (iptr[0].val.i == 0x00004000) ||
469 (iptr[0].val.i == 0x00008000) ||
470 (iptr[0].val.i == 0x00010000) ||
471 (iptr[0].val.i == 0x00020000) ||
472 (iptr[0].val.i == 0x00040000) ||
473 (iptr[0].val.i == 0x00080000) ||
474 (iptr[0].val.i == 0x00100000) ||
475 (iptr[0].val.i == 0x00200000) ||
476 (iptr[0].val.i == 0x00400000) ||
477 (iptr[0].val.i == 0x00800000) ||
478 (iptr[0].val.i == 0x01000000) ||
479 (iptr[0].val.i == 0x02000000) ||
480 (iptr[0].val.i == 0x04000000) ||
481 (iptr[0].val.i == 0x08000000) ||
482 (iptr[0].val.i == 0x10000000) ||
483 (iptr[0].val.i == 0x20000000) ||
484 (iptr[0].val.i == 0x40000000) ||
485 (iptr[0].val.i == 0x80000000)) {
486 iptr[0].opc = ICMD_IREMPOW2;
488 goto icmd_iconst_tail;
492 #if SUPPORT_CONST_LOGICAL
494 iptr[0].opc = ICMD_IANDCONST;
495 goto icmd_iconst_tail;
497 iptr[0].opc = ICMD_IORCONST;
498 goto icmd_iconst_tail;
500 iptr[0].opc = ICMD_IXORCONST;
501 goto icmd_iconst_tail;
502 #endif /* SUPPORT_CONST_LOGICAL */
504 iptr[0].opc = ICMD_ISHLCONST;
505 goto icmd_iconst_tail;
507 iptr[0].opc = ICMD_ISHRCONST;
508 goto icmd_iconst_tail;
510 iptr[0].opc = ICMD_IUSHRCONST;
511 goto icmd_iconst_tail;
512 #if SUPPORT_LONG_SHIFT
514 iptr[0].opc = ICMD_LSHLCONST;
515 goto icmd_lconst_tail;
517 iptr[0].opc = ICMD_LSHRCONST;
518 goto icmd_lconst_tail;
520 iptr[0].opc = ICMD_LUSHRCONST;
521 goto icmd_lconst_tail;
522 #endif /* SUPPORT_LONG_SHIFT */
524 iptr[0].opc = ICMD_IFEQ;
526 iptr[0].op1 = iptr[1].op1;
529 /* iptr[1].opc = ICMD_NOP; */
531 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
533 iptr[0].target = (void *) tbptr;
535 MARKREACHED(tbptr, copy);
536 COUNT(count_pcmd_bra);
539 iptr[0].opc = ICMD_IFLT;
540 goto icmd_if_icmp_tail;
542 iptr[0].opc = ICMD_IFLE;
543 goto icmd_if_icmp_tail;
545 iptr[0].opc = ICMD_IFNE;
546 goto icmd_if_icmp_tail;
548 iptr[0].opc = ICMD_IFGT;
549 goto icmd_if_icmp_tail;
551 iptr[0].opc = ICMD_IFGE;
552 goto icmd_if_icmp_tail;
554 #if SUPPORT_CONST_STORE
561 #if SUPPORT_CONST_STORE_ZERO_ONLY
562 if (iptr[0].val.i == 0) {
563 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
564 switch (iptr[1].opc) {
566 iptr[0].opc = ICMD_IASTORECONST;
569 iptr[0].opc = ICMD_BASTORECONST;
572 iptr[0].opc = ICMD_CASTORECONST;
575 iptr[0].opc = ICMD_SASTORECONST;
578 iptr[0].opc = ICMD_PUTSTATICCONST;
581 iptr[0].opc = ICMD_PUTFIELDCONST;
585 iptr[1].opc = ICMD_NOP;
586 OPTT2_0(TYPE_INT, TYPE_ADR);
587 COUNT(count_pcmd_op);
588 #if SUPPORT_CONST_STORE_ZERO_ONLY
591 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
593 #endif /* SUPPORT_CONST_STORE */
604 COUNT(count_pcmd_load);
606 switch (iptr[1].opc) {
609 iptr[0].opc = ICMD_LADDCONST;
611 iptr[1].opc = ICMD_NOP;
612 OP1_1(TYPE_LNG,TYPE_LNG);
613 COUNT(count_pcmd_op);
616 iptr[0].opc = ICMD_LSUBCONST;
617 goto icmd_lconst_tail;
618 #endif /* SUPPORT_LONG_ADD */
619 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
621 iptr[0].opc = ICMD_LMULCONST;
622 goto icmd_lconst_tail;
623 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
624 # if SUPPORT_LONG_SHIFT
626 if (iptr[0].val.l == 0x00000002)
628 else if (iptr[0].val.l == 0x00000004)
630 else if (iptr[0].val.l == 0x00000008)
632 else if (iptr[0].val.l == 0x00000010)
634 else if (iptr[0].val.l == 0x00000020)
636 else if (iptr[0].val.l == 0x00000040)
638 else if (iptr[0].val.l == 0x00000080)
640 else if (iptr[0].val.l == 0x00000100)
642 else if (iptr[0].val.l == 0x00000200)
644 else if (iptr[0].val.l == 0x00000400)
646 else if (iptr[0].val.l == 0x00000800)
648 else if (iptr[0].val.l == 0x00001000)
650 else if (iptr[0].val.l == 0x00002000)
652 else if (iptr[0].val.l == 0x00004000)
654 else if (iptr[0].val.l == 0x00008000)
656 else if (iptr[0].val.l == 0x00010000)
658 else if (iptr[0].val.l == 0x00020000)
660 else if (iptr[0].val.l == 0x00040000)
662 else if (iptr[0].val.l == 0x00080000)
664 else if (iptr[0].val.l == 0x00100000)
666 else if (iptr[0].val.l == 0x00200000)
668 else if (iptr[0].val.l == 0x00400000)
670 else if (iptr[0].val.l == 0x00800000)
672 else if (iptr[0].val.l == 0x01000000)
674 else if (iptr[0].val.l == 0x02000000)
676 else if (iptr[0].val.l == 0x04000000)
678 else if (iptr[0].val.l == 0x08000000)
680 else if (iptr[0].val.l == 0x10000000)
682 else if (iptr[0].val.l == 0x20000000)
684 else if (iptr[0].val.l == 0x40000000)
686 else if (iptr[0].val.l == 0x80000000)
692 iptr[0].opc = ICMD_LMULPOW2;
693 goto icmd_lconst_tail;
694 # endif /* SUPPORT_LONG_SHIFT */
695 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
698 if (iptr[0].val.l == 0x00000002)
700 else if (iptr[0].val.l == 0x00000004)
702 else if (iptr[0].val.l == 0x00000008)
704 else if (iptr[0].val.l == 0x00000010)
706 else if (iptr[0].val.l == 0x00000020)
708 else if (iptr[0].val.l == 0x00000040)
710 else if (iptr[0].val.l == 0x00000080)
712 else if (iptr[0].val.l == 0x00000100)
714 else if (iptr[0].val.l == 0x00000200)
716 else if (iptr[0].val.l == 0x00000400)
718 else if (iptr[0].val.l == 0x00000800)
720 else if (iptr[0].val.l == 0x00001000)
722 else if (iptr[0].val.l == 0x00002000)
724 else if (iptr[0].val.l == 0x00004000)
726 else if (iptr[0].val.l == 0x00008000)
728 else if (iptr[0].val.l == 0x00010000)
730 else if (iptr[0].val.l == 0x00020000)
732 else if (iptr[0].val.l == 0x00040000)
734 else if (iptr[0].val.l == 0x00080000)
736 else if (iptr[0].val.l == 0x00100000)
738 else if (iptr[0].val.l == 0x00200000)
740 else if (iptr[0].val.l == 0x00400000)
742 else if (iptr[0].val.l == 0x00800000)
744 else if (iptr[0].val.l == 0x01000000)
746 else if (iptr[0].val.l == 0x02000000)
748 else if (iptr[0].val.l == 0x04000000)
750 else if (iptr[0].val.l == 0x08000000)
752 else if (iptr[0].val.l == 0x10000000)
754 else if (iptr[0].val.l == 0x20000000)
756 else if (iptr[0].val.l == 0x40000000)
758 else if (iptr[0].val.l == 0x80000000)
764 iptr[0].opc = ICMD_LDIVPOW2;
765 goto icmd_lconst_tail;
767 if ((iptr[0].val.l == 0x00000002) ||
768 (iptr[0].val.l == 0x00000004) ||
769 (iptr[0].val.l == 0x00000008) ||
770 (iptr[0].val.l == 0x00000010) ||
771 (iptr[0].val.l == 0x00000020) ||
772 (iptr[0].val.l == 0x00000040) ||
773 (iptr[0].val.l == 0x00000080) ||
774 (iptr[0].val.l == 0x00000100) ||
775 (iptr[0].val.l == 0x00000200) ||
776 (iptr[0].val.l == 0x00000400) ||
777 (iptr[0].val.l == 0x00000800) ||
778 (iptr[0].val.l == 0x00001000) ||
779 (iptr[0].val.l == 0x00002000) ||
780 (iptr[0].val.l == 0x00004000) ||
781 (iptr[0].val.l == 0x00008000) ||
782 (iptr[0].val.l == 0x00010000) ||
783 (iptr[0].val.l == 0x00020000) ||
784 (iptr[0].val.l == 0x00040000) ||
785 (iptr[0].val.l == 0x00080000) ||
786 (iptr[0].val.l == 0x00100000) ||
787 (iptr[0].val.l == 0x00200000) ||
788 (iptr[0].val.l == 0x00400000) ||
789 (iptr[0].val.l == 0x00800000) ||
790 (iptr[0].val.l == 0x01000000) ||
791 (iptr[0].val.l == 0x02000000) ||
792 (iptr[0].val.l == 0x04000000) ||
793 (iptr[0].val.l == 0x08000000) ||
794 (iptr[0].val.l == 0x10000000) ||
795 (iptr[0].val.l == 0x20000000) ||
796 (iptr[0].val.l == 0x40000000) ||
797 (iptr[0].val.l == 0x80000000)) {
798 iptr[0].opc = ICMD_LREMPOW2;
800 goto icmd_lconst_tail;
804 #endif /* SUPPORT_LONG_DIV */
805 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
808 iptr[0].opc = ICMD_LANDCONST;
809 goto icmd_lconst_tail;
811 iptr[0].opc = ICMD_LORCONST;
812 goto icmd_lconst_tail;
814 iptr[0].opc = ICMD_LXORCONST;
815 goto icmd_lconst_tail;
816 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
817 #if !defined(NOLONG_CONDITIONAL)
819 if ((len > 1) && (iptr[2].val.i == 0)) {
820 switch (iptr[2].opc) {
822 iptr[0].opc = ICMD_IF_LEQ;
823 icmd_lconst_lcmp_tail:
824 iptr[0].op1 = iptr[2].op1;
827 /* iptr[1].opc = ICMD_NOP;
828 iptr[2].opc = ICMD_NOP; */
830 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
832 iptr[0].target = (void *) tbptr;
834 MARKREACHED(tbptr, copy);
835 COUNT(count_pcmd_bra);
836 COUNT(count_pcmd_op);
839 iptr[0].opc = ICMD_IF_LNE;
840 goto icmd_lconst_lcmp_tail;
842 iptr[0].opc = ICMD_IF_LLT;
843 goto icmd_lconst_lcmp_tail;
845 iptr[0].opc = ICMD_IF_LGT;
846 goto icmd_lconst_lcmp_tail;
848 iptr[0].opc = ICMD_IF_LLE;
849 goto icmd_lconst_lcmp_tail;
851 iptr[0].opc = ICMD_IF_LGE;
852 goto icmd_lconst_lcmp_tail;
855 } /* switch (iptr[2].opc) */
856 } /* if (iptr[2].val.i == 0) */
860 #endif /* !defined(NOLONG_CONDITIONAL) */
862 #if SUPPORT_CONST_STORE
866 #if SUPPORT_CONST_STORE_ZERO_ONLY
867 if (iptr[0].val.l == 0) {
868 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
869 switch (iptr[1].opc) {
871 iptr[0].opc = ICMD_LASTORECONST;
874 iptr[0].opc = ICMD_PUTSTATICCONST;
877 iptr[0].opc = ICMD_PUTFIELDCONST;
881 iptr[1].opc = ICMD_NOP;
882 OPTT2_0(TYPE_INT, TYPE_ADR);
883 COUNT(count_pcmd_op);
884 #if SUPPORT_CONST_STORE_ZERO_ONLY
887 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
889 #endif /* SUPPORT_CONST_STORE */
900 COUNT(count_pcmd_load);
905 COUNT(count_pcmd_load);
910 COUNT(count_pcmd_load);
911 #if SUPPORT_CONST_STORE
912 if (len > 0 && iptr->val.a == 0) {
913 switch (iptr[1].opc) {
915 if (iptr[1].val.fp != BUILTIN_aastore) {
922 switch (iptr[1].opc) {
924 iptr[0].opc = ICMD_AASTORECONST;
927 iptr[0].opc = ICMD_PUTSTATICCONST;
930 iptr[0].opc = ICMD_PUTFIELDCONST;
934 iptr[1].opc = ICMD_NOP;
935 OPTT2_0(TYPE_INT, TYPE_ADR);
936 COUNT(count_pcmd_op);
943 #endif /* SUPPORT_CONST_STORE */
947 /* pop 0 push 1 load */
954 COUNT(count_load_instruction);
955 i = opcode-ICMD_ILOAD;
956 iptr->op1 = argren[iptr->op1];
957 rd->locals[iptr->op1][i].type = i;
958 LOAD(i, LOCALVAR, iptr->op1);
968 COUNT(count_check_null);
969 COUNT(count_check_bound);
970 COUNT(count_pcmd_mem);
971 OP2IAT_1(opcode-ICMD_IALOAD);
977 COUNT(count_check_null);
978 COUNT(count_check_bound);
979 COUNT(count_pcmd_mem);
983 /* pop 0 push 0 iinc */
986 #if defined(STATISTICS)
990 count_store_depth[10]++;
992 count_store_depth[i]++;
998 if ((copy->varkind == LOCALVAR) &&
999 (copy->varnum == iptr->op1)) {
1000 copy->varkind = TEMPVAR;
1009 /* pop 1 push 0 store */
1019 i = opcode - ICMD_ISTORE;
1020 rd->locals[iptr->op1][i].type = i;
1021 #if defined(STATISTICS)
1026 count_store_length[20]++;
1028 count_store_length[i]++;
1031 count_store_depth[10]++;
1033 count_store_depth[i]++;
1036 copy = curstack->prev;
1039 if ((copy->varkind == LOCALVAR) &&
1040 (copy->varnum == iptr->op1)) {
1041 copy->varkind = TEMPVAR;
1047 if ((new - curstack) == 1) {
1048 curstack->varkind = LOCALVAR;
1049 curstack->varnum = iptr->op1;
1051 STORE(opcode-ICMD_ISTORE);
1061 COUNT(count_check_null);
1062 COUNT(count_check_bound);
1063 COUNT(count_pcmd_mem);
1064 OP3TIA_0(opcode-ICMD_IASTORE);
1070 COUNT(count_check_null);
1071 COUNT(count_check_bound);
1072 COUNT(count_pcmd_mem);
1079 #ifdef TYPECHECK_STACK_COMPCAT
1082 if (IS_2_WORD_TYPE(curstack->type)) {
1083 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1096 COUNT(count_pcmd_return);
1097 OP1_0(opcode-ICMD_IRETURN);
1098 superblockend = true;
1102 COUNT(count_check_null);
1106 superblockend = true;
1109 case ICMD_PUTSTATIC:
1110 COUNT(count_pcmd_mem);
1114 /* pop 1 push 0 branch */
1117 case ICMD_IFNONNULL:
1118 COUNT(count_pcmd_bra);
1120 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1122 iptr[0].target = (void *) tbptr;
1124 MARKREACHED(tbptr, copy);
1133 COUNT(count_pcmd_bra);
1134 #ifdef CONDITIONAL_LOADCONST
1136 tbptr = m->basicblocks + b_index;
1137 if ((b_count >= 3) &&
1138 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1139 (tbptr[1].pre_count == 1) &&
1140 (iptr[1].opc == ICMD_ICONST) &&
1141 (iptr[2].opc == ICMD_GOTO) &&
1142 ((b_index + 3) == m->basicblockindex[iptr[2].op1]) &&
1143 (tbptr[2].pre_count == 1) &&
1144 (iptr[3].opc == ICMD_ICONST)) {
1145 OP1_1(TYPE_INT, TYPE_INT);
1146 switch (iptr[0].opc) {
1148 iptr[0].opc = ICMD_IFNE_ICONST;
1151 iptr[0].opc = ICMD_IFEQ_ICONST;
1154 iptr[0].opc = ICMD_IFGE_ICONST;
1157 iptr[0].opc = ICMD_IFLT_ICONST;
1160 iptr[0].opc = ICMD_IFLE_ICONST;
1163 iptr[0].opc = ICMD_IFGT_ICONST;
1166 iptr[0].val.i = iptr[1].val.i;
1167 iptr[1].opc = ICMD_ELSE_ICONST;
1168 iptr[1].val.i = iptr[3].val.i;
1169 iptr[2].opc = ICMD_NOP;
1170 iptr[3].opc = ICMD_NOP;
1171 tbptr[1].flags = BBDELETED;
1172 tbptr[2].flags = BBDELETED;
1173 tbptr[1].icount = 0;
1174 tbptr[2].icount = 0;
1175 if (tbptr[3].pre_count == 2) {
1176 len += tbptr[3].icount + 3;
1177 bptr->icount += tbptr[3].icount + 3;
1178 tbptr[3].flags = BBDELETED;
1179 tbptr[3].icount = 0;
1192 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1194 iptr[0].target = (void *) tbptr;
1196 MARKREACHED(tbptr, copy);
1199 /* pop 0 push 0 branch */
1202 COUNT(count_pcmd_bra);
1203 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1205 iptr[0].target = (void *) tbptr;
1207 MARKREACHED(tbptr, copy);
1209 superblockend = true;
1212 /* pop 1 push 0 table branch */
1214 case ICMD_TABLESWITCH:
1215 COUNT(count_pcmd_table);
1217 s4ptr = iptr->val.a;
1218 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1219 MARKREACHED(tbptr, copy);
1220 i = *s4ptr++; /* low */
1221 i = *s4ptr++ - i + 1; /* high */
1223 tptr = DMNEW(void*, i+1);
1224 iptr->target = (void *) tptr;
1226 tptr[0] = (void *) tbptr;
1230 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1232 tptr[0] = (void *) tbptr;
1235 MARKREACHED(tbptr, copy);
1238 superblockend = true;
1241 /* pop 1 push 0 table branch */
1243 case ICMD_LOOKUPSWITCH:
1244 COUNT(count_pcmd_table);
1246 s4ptr = iptr->val.a;
1247 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1248 MARKREACHED(tbptr, copy);
1249 i = *s4ptr++; /* count */
1251 tptr = DMNEW(void*, i+1);
1252 iptr->target = (void *) tptr;
1254 tptr[0] = (void *) tbptr;
1258 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1260 tptr[0] = (void *) tbptr;
1263 MARKREACHED(tbptr, copy);
1267 superblockend = true;
1270 case ICMD_NULLCHECKPOP:
1271 case ICMD_MONITORENTER:
1272 COUNT(count_check_null);
1273 case ICMD_MONITOREXIT:
1277 /* pop 2 push 0 branch */
1279 case ICMD_IF_ICMPEQ:
1280 case ICMD_IF_ICMPNE:
1281 case ICMD_IF_ICMPLT:
1282 case ICMD_IF_ICMPGE:
1283 case ICMD_IF_ICMPGT:
1284 case ICMD_IF_ICMPLE:
1285 COUNT(count_pcmd_bra);
1287 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1289 iptr[0].target = (void *) tbptr;
1291 MARKREACHED(tbptr, copy);
1294 case ICMD_IF_ACMPEQ:
1295 case ICMD_IF_ACMPNE:
1296 COUNT(count_pcmd_bra);
1298 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1300 iptr[0].target = (void *) tbptr;
1302 MARKREACHED(tbptr, copy);
1308 COUNT(count_check_null);
1309 COUNT(count_pcmd_mem);
1310 OPTT2_0(iptr->op1,TYPE_ADR);
1315 if (!IS_2_WORD_TYPE(curstack->type)) {
1317 #ifdef TYPECHECK_STACK_COMPCAT
1320 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1321 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1326 OP1_0ANY; /* second pop */
1329 iptr->opc = ICMD_POP;
1333 /* pop 0 push 1 dup */
1336 #ifdef TYPECHECK_STACK_COMPCAT
1339 if (IS_2_WORD_TYPE(curstack->type)) {
1340 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1345 COUNT(count_dup_instruction);
1351 if (IS_2_WORD_TYPE(curstack->type)) {
1353 iptr->opc = ICMD_DUP;
1358 /* ..., ????, cat1 */
1359 #ifdef TYPECHECK_STACK_COMPCAT
1361 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1362 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1368 NEWSTACK(copy->prev->type, copy->prev->varkind,
1369 copy->prev->varnum);
1370 NEWSTACK(copy->type, copy->varkind,
1377 /* pop 2 push 3 dup */
1380 #ifdef TYPECHECK_STACK_COMPCAT
1383 if (IS_2_WORD_TYPE(curstack->type) ||
1384 IS_2_WORD_TYPE(curstack->prev->type)) {
1385 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1395 if (IS_2_WORD_TYPE(curstack->type)) {
1396 /* ..., ????, cat2 */
1397 #ifdef TYPECHECK_STACK_COMPCAT
1399 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1400 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1405 iptr->opc = ICMD_DUP_X1;
1409 /* ..., ????, cat1 */
1410 #ifdef TYPECHECK_STACK_COMPCAT
1413 if (IS_2_WORD_TYPE(curstack->prev->type)
1414 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1415 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1424 /* pop 3 push 4 dup */
1428 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1429 /* ..., cat2, ???? */
1430 #ifdef TYPECHECK_STACK_COMPCAT
1432 if (IS_2_WORD_TYPE(curstack->type)) {
1433 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1438 iptr->opc = ICMD_DUP_X1;
1442 /* ..., cat1, ???? */
1443 #ifdef TYPECHECK_STACK_COMPCAT
1446 if (IS_2_WORD_TYPE(curstack->type)
1447 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1448 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1459 if (IS_2_WORD_TYPE(curstack->type)) {
1460 /* ..., ????, cat2 */
1461 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1462 /* ..., cat2, cat2 */
1463 iptr->opc = ICMD_DUP_X1;
1467 /* ..., cat1, cat2 */
1468 #ifdef TYPECHECK_STACK_COMPCAT
1471 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1472 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1477 iptr->opc = ICMD_DUP_X2;
1483 /* ..., ????, ????, cat1 */
1484 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1485 /* ..., cat2, ????, cat1 */
1486 #ifdef TYPECHECK_STACK_COMPCAT
1488 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1489 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1494 iptr->opc = ICMD_DUP2_X1;
1498 /* ..., cat1, ????, cat1 */
1499 #ifdef TYPECHECK_STACK_COMPCAT
1502 if (IS_2_WORD_TYPE(curstack->prev->type)
1503 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1504 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1514 /* pop 2 push 2 swap */
1517 #ifdef TYPECHECK_STACK_COMPCAT
1520 if (IS_2_WORD_TYPE(curstack->type)
1521 || IS_2_WORD_TYPE(curstack->prev->type)) {
1522 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1533 #if !SUPPORT_DIVISION
1534 iptr[0].opc = ICMD_BUILTIN2;
1535 iptr[0].op1 = TYPE_INT;
1536 iptr[0].val.fp = BUILTIN_idiv;
1537 m->isleafmethod = false;
1542 #if !SUPPORT_DIVISION
1543 iptr[0].opc = ICMD_BUILTIN2;
1544 iptr[0].op1 = TYPE_INT;
1545 iptr[0].val.fp = BUILTIN_irem;
1546 m->isleafmethod = false;
1559 COUNT(count_pcmd_op);
1564 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1565 iptr[0].opc = ICMD_BUILTIN2;
1566 iptr[0].op1 = TYPE_LNG;
1567 iptr[0].val.fp = BUILTIN_ldiv;
1568 m->isleafmethod = false;
1573 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1574 iptr[0].opc = ICMD_BUILTIN2;
1575 iptr[0].op1 = TYPE_LNG;
1576 iptr[0].val.fp = BUILTIN_lrem;
1577 m->isleafmethod = false;
1584 #if SUPPORT_LONG_LOGICAL
1588 #endif /* SUPPORT_LONG_LOGICAL */
1589 COUNT(count_pcmd_op);
1596 COUNT(count_pcmd_op);
1605 COUNT(count_pcmd_op);
1614 COUNT(count_pcmd_op);
1619 COUNT(count_pcmd_op);
1620 #if !defined(NOLONG_CONDITIONAL)
1621 if ((len > 0) && (iptr[1].val.i == 0)) {
1622 switch (iptr[1].opc) {
1624 iptr[0].opc = ICMD_IF_LCMPEQ;
1626 iptr[0].op1 = iptr[1].op1;
1629 /* iptr[1].opc = ICMD_NOP; */
1631 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1633 iptr[0].target = (void *) tbptr;
1635 MARKREACHED(tbptr, copy);
1636 COUNT(count_pcmd_bra);
1639 iptr[0].opc = ICMD_IF_LCMPNE;
1640 goto icmd_lcmp_if_tail;
1642 iptr[0].opc = ICMD_IF_LCMPLT;
1643 goto icmd_lcmp_if_tail;
1645 iptr[0].opc = ICMD_IF_LCMPGT;
1646 goto icmd_lcmp_if_tail;
1648 iptr[0].opc = ICMD_IF_LCMPLE;
1649 goto icmd_lcmp_if_tail;
1651 iptr[0].opc = ICMD_IF_LCMPGE;
1652 goto icmd_lcmp_if_tail;
1654 OPTT2_1(TYPE_LNG, TYPE_INT);
1659 OPTT2_1(TYPE_LNG, TYPE_INT);
1663 COUNT(count_pcmd_op);
1664 OPTT2_1(TYPE_FLT, TYPE_INT);
1668 COUNT(count_pcmd_op);
1669 OPTT2_1(TYPE_DBL, TYPE_INT);
1677 case ICMD_INT2SHORT:
1678 COUNT(count_pcmd_op);
1679 OP1_1(TYPE_INT, TYPE_INT);
1682 COUNT(count_pcmd_op);
1683 OP1_1(TYPE_LNG, TYPE_LNG);
1686 COUNT(count_pcmd_op);
1687 OP1_1(TYPE_FLT, TYPE_FLT);
1690 COUNT(count_pcmd_op);
1691 OP1_1(TYPE_DBL, TYPE_DBL);
1695 COUNT(count_pcmd_op);
1696 OP1_1(TYPE_INT, TYPE_LNG);
1699 COUNT(count_pcmd_op);
1700 OP1_1(TYPE_INT, TYPE_FLT);
1703 COUNT(count_pcmd_op);
1704 OP1_1(TYPE_INT, TYPE_DBL);
1707 COUNT(count_pcmd_op);
1708 OP1_1(TYPE_LNG, TYPE_INT);
1711 COUNT(count_pcmd_op);
1712 OP1_1(TYPE_LNG, TYPE_FLT);
1715 COUNT(count_pcmd_op);
1716 OP1_1(TYPE_LNG, TYPE_DBL);
1719 COUNT(count_pcmd_op);
1720 OP1_1(TYPE_FLT, TYPE_INT);
1723 COUNT(count_pcmd_op);
1724 OP1_1(TYPE_FLT, TYPE_LNG);
1727 COUNT(count_pcmd_op);
1728 OP1_1(TYPE_FLT, TYPE_DBL);
1731 COUNT(count_pcmd_op);
1732 OP1_1(TYPE_DBL, TYPE_INT);
1735 COUNT(count_pcmd_op);
1736 OP1_1(TYPE_DBL, TYPE_LNG);
1739 COUNT(count_pcmd_op);
1740 OP1_1(TYPE_DBL, TYPE_FLT);
1743 case ICMD_CHECKCAST:
1744 OP1_1(TYPE_ADR, TYPE_ADR);
1747 case ICMD_INSTANCEOF:
1748 case ICMD_ARRAYLENGTH:
1749 OP1_1(TYPE_ADR, TYPE_INT);
1753 case ICMD_ANEWARRAY:
1754 OP1_1(TYPE_INT, TYPE_ADR);
1758 COUNT(count_check_null);
1759 COUNT(count_pcmd_mem);
1760 OP1_1(TYPE_ADR, iptr->op1);
1765 case ICMD_GETSTATIC:
1766 COUNT(count_pcmd_mem);
1776 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1778 iptr[0].target = (void *) tbptr;
1780 /* This is a dirty hack. The typechecker
1781 * needs it because the OP1_0ANY below
1782 * overwrites iptr->dst.
1784 iptr->val.a = (void *) iptr->dst;
1786 tbptr->type = BBTYPE_SBR;
1788 /* We need to check for overflow right here because
1789 * the pushed value is poped after MARKREACHED. */
1791 MARKREACHED(tbptr, copy);
1795 /* pop many push any */
1797 case ICMD_INVOKEVIRTUAL:
1798 case ICMD_INVOKESPECIAL:
1799 case ICMD_INVOKEINTERFACE:
1800 case ICMD_INVOKESTATIC:
1801 COUNT(count_pcmd_met);
1803 methodinfo *lm = iptr->val.a;
1804 if (lm->flags & ACC_STATIC)
1805 {COUNT(count_check_null);}
1807 if (i > rd->arguments_num)
1808 rd->arguments_num = i;
1810 #if defined(__X86_64__)
1816 /* count integer and float arguments */
1820 (IS_FLT_DBL_TYPE(copy->type)) ? farg++ : iarg++;
1824 /* calculate stack space required */
1826 stackargs += (iarg < INT_ARG_CNT) ?
1827 0 : (iarg - INT_ARG_CNT);
1828 stackargs += (farg < FLT_ARG_CNT) ?
1829 0 : (farg - FLT_ARG_CNT);
1834 if (!(copy->flags & SAVEDVAR)) {
1835 copy->varkind = ARGVAR;
1837 if (IS_FLT_DBL_TYPE(copy->type)) {
1838 if (--farg < FLT_ARG_CNT)
1839 copy->varnum = farg;
1841 copy->varnum = --stackargs + FLT_ARG_CNT;
1844 if (--iarg < INT_ARG_CNT)
1845 copy->varnum = iarg;
1847 copy->varnum = --stackargs + INT_ARG_CNT;
1851 (IS_FLT_DBL_TYPE(copy->type)) ? --farg : --iarg;
1856 #else /* defined(__X86_64__) */
1859 if (!(copy->flags & SAVEDVAR)) {
1860 copy->varkind = ARGVAR;
1865 #endif /* defined(__X86_64__) */
1867 copy->flags |= SAVEDVAR;
1872 if (lm->returntype != TYPE_VOID)
1873 OP0_1(lm->returntype);
1876 case ICMD_INLINE_START:
1877 case ICMD_INLINE_END:
1882 /* DEBUG */ /*dolog("builtin3");*/
1884 if (!(curstack->flags & SAVEDVAR)) {
1885 curstack->varkind = ARGVAR;
1886 curstack->varnum = 2;
1888 if (3 > rd->arguments_num) {
1889 rd->arguments_num = 3;
1894 #if defined(USEBUILTINTABLE) || !SUPPORT_DIVISION
1895 /* Just prevent a compiler warning... */
1899 /* DEBUG */ /*dolog("builtin2");*/
1900 if (!(curstack->flags & SAVEDVAR)) {
1901 curstack->varkind = ARGVAR;
1902 curstack->varnum = 1;
1904 if (2 > rd->arguments_num) {
1905 rd->arguments_num = 2;
1910 #if defined(USEBUILTINTABLE)
1911 /* Just prevent a compiler warning... */
1915 /* DEBUG */ /*dolog("builtin1");*/
1916 if (!(curstack->flags & SAVEDVAR)) {
1917 curstack->varkind = ARGVAR;
1918 curstack->varnum = 0;
1920 if (1 > rd->arguments_num) {
1921 rd->arguments_num = 1;
1926 copy->flags |= SAVEDVAR;
1929 if (iptr->op1 != TYPE_VOID)
1933 case ICMD_MULTIANEWARRAY:
1936 if ((i + INT_ARG_CNT) > rd->arguments_num)
1937 rd->arguments_num = i + INT_ARG_CNT;
1940 /* check INT type here? Currently typecheck does this. */
1941 if (!(copy->flags & SAVEDVAR)) {
1942 copy->varkind = ARGVAR;
1943 copy->varnum = i + INT_ARG_CNT;
1948 copy->flags |= SAVEDVAR;
1956 case ICMD_CLEAR_ARGREN:
1957 for (i = iptr->op1; i < cd->maxlocals; i++)
1959 iptr->opc = opcode = ICMD_NOP;
1963 case ICMD_READONLY_ARG:
1964 case ICMD_READONLY_ARG+1:
1965 case ICMD_READONLY_ARG+2:
1966 case ICMD_READONLY_ARG+3:
1967 case ICMD_READONLY_ARG+4:
1970 if (curstack->varkind == LOCALVAR) {
1971 i = curstack->varnum;
1972 argren[iptr->op1] = i;
1975 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
1982 new_exception_message(string_java_lang_InternalError,
1989 } /* while instructions */
1991 bptr->outstack = curstack;
1992 bptr->outdepth = stackdepth;
1996 superblockend = true;
1998 } /* while blocks */
1999 } while (repeat && !deadcode);
2001 #if defined(STATISTICS)
2003 if (m->basicblockcount > count_max_basic_blocks)
2004 count_max_basic_blocks = m->basicblockcount;
2005 count_basic_blocks += m->basicblockcount;
2006 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2007 count_javainstr += m->instructioncount;
2008 if (m->stackcount > count_upper_bound_new_stack)
2009 count_upper_bound_new_stack = m->stackcount;
2010 if ((new - m->stack) > count_max_new_stack)
2011 count_max_new_stack = (new - m->stack);
2013 b_count = m->basicblockcount;
2014 bptr = m->basicblocks;
2015 while (--b_count >= 0) {
2016 if (bptr->flags > BBREACHED) {
2017 if (bptr->indepth >= 10)
2018 count_block_stack[10]++;
2020 count_block_stack[bptr->indepth]++;
2023 count_block_size_distribution[len]++;
2025 count_block_size_distribution[10]++;
2027 count_block_size_distribution[11]++;
2029 count_block_size_distribution[12]++;
2031 count_block_size_distribution[13]++;
2033 count_block_size_distribution[14]++;
2035 count_block_size_distribution[15]++;
2037 count_block_size_distribution[16]++;
2039 count_block_size_distribution[17]++;
2045 count_analyse_iterations[0]++;
2046 else if (loops == 2)
2047 count_analyse_iterations[1]++;
2048 else if (loops == 3)
2049 count_analyse_iterations[2]++;
2050 else if (loops == 4)
2051 count_analyse_iterations[3]++;
2053 count_analyse_iterations[4]++;
2055 if (m->basicblockcount <= 5)
2056 count_method_bb_distribution[0]++;
2057 else if (m->basicblockcount <= 10)
2058 count_method_bb_distribution[1]++;
2059 else if (m->basicblockcount <= 15)
2060 count_method_bb_distribution[2]++;
2061 else if (m->basicblockcount <= 20)
2062 count_method_bb_distribution[3]++;
2063 else if (m->basicblockcount <= 30)
2064 count_method_bb_distribution[4]++;
2065 else if (m->basicblockcount <= 40)
2066 count_method_bb_distribution[5]++;
2067 else if (m->basicblockcount <= 50)
2068 count_method_bb_distribution[6]++;
2069 else if (m->basicblockcount <= 75)
2070 count_method_bb_distribution[7]++;
2072 count_method_bb_distribution[8]++;
2076 /* just return methodinfo* to signal everything was ok */
2082 /**********************************************************************/
2083 /* DEBUGGING HELPERS */
2084 /**********************************************************************/
2086 void icmd_print_stack(codegendata *cd, stackptr s)
2098 j = cd->maxstack - i;
2103 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2104 if (s->flags & SAVEDVAR)
2105 switch (s->varkind) {
2107 if (s->flags & INMEMORY)
2108 printf(" M%02d", s->regoff);
2109 else if (IS_FLT_DBL_TYPE(s->type))
2110 printf(" F%02d", s->regoff);
2112 printf(" %3s", regs[s->regoff]);
2116 printf(" I%02d", s->varnum);
2119 printf(" L%02d", s->varnum);
2122 printf(" A%02d", s->varnum);
2125 printf(" !%02d", j);
2128 switch (s->varkind) {
2130 if (s->flags & INMEMORY)
2131 printf(" m%02d", s->regoff);
2132 else if (IS_FLT_DBL_TYPE(s->type))
2133 printf(" f%02d", s->regoff);
2135 printf(" %3s", regs[s->regoff]);
2139 printf(" i%02d", s->varnum);
2142 printf(" l%02d", s->varnum);
2145 printf(" a%02d", s->varnum);
2148 printf(" ?%02d", j);
2156 static void print_reg(stackptr s) {
2158 if (s->flags & SAVEDVAR)
2159 switch (s->varkind) {
2161 if (s->flags & INMEMORY)
2162 printf(" tm%02d", s->regoff);
2164 printf(" tr%02d", s->regoff);
2167 printf(" s %02d", s->varnum);
2170 printf(" l %02d", s->varnum);
2173 printf(" a %02d", s->varnum);
2176 printf(" ! %02d", s->varnum);
2179 switch (s->varkind) {
2181 if (s->flags & INMEMORY)
2182 printf(" Tm%02d", s->regoff);
2184 printf(" Tr%02d", s->regoff);
2187 printf(" S %02d", s->varnum);
2190 printf(" L %02d", s->varnum);
2193 printf(" A %02d", s->varnum);
2196 printf(" ? %02d", s->varnum);
2206 char *icmd_builtin_name(functionptr bptr)
2208 builtin_descriptor *bdesc = builtin_desc;
2209 while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
2211 return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
2215 static char *jit_type[] = {
2224 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2231 utf_fprint_classname(stdout, m->class->name);
2233 utf_fprint(stdout, m->name);
2234 utf_fprint_classname(stdout, m->descriptor);
2235 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2236 printf("Max stack: %d\n", (int) cd->maxstack);
2238 printf("Line number table length: %d\n", m->linenumbercount);
2240 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2241 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2242 printf(" L%03d ... ", ex->start->debug_nr );
2243 printf("L%03d = ", ex->end->debug_nr);
2244 printf("L%03d\n", ex->handler->debug_nr);
2247 printf("Local Table:\n");
2248 for (i = 0; i < cd->maxlocals; i++) {
2249 printf(" %3d: ", i);
2250 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2251 if (rd->locals[i][j].type >= 0) {
2252 printf(" (%s) ", jit_type[j]);
2253 if (rd->locals[i][j].flags & INMEMORY)
2254 printf("m%2d", rd->locals[i][j].regoff);
2255 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2256 printf("f%02d", rd->locals[i][j].regoff);
2258 printf("%3s", regs[rd->locals[i][j].regoff]);
2267 printf("Interface Table:\n");
2268 for (i = 0; i < cd->maxstack; i++) {
2269 if ((rd->interfaces[i][0].type >= 0) ||
2270 (rd->interfaces[i][1].type >= 0) ||
2271 (rd->interfaces[i][2].type >= 0) ||
2272 (rd->interfaces[i][3].type >= 0) ||
2273 (rd->interfaces[i][4].type >= 0)) {
2274 printf(" %3d: ", i);
2275 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2276 if (rd->interfaces[i][j].type >= 0) {
2277 printf(" (%s) ", jit_type[j]);
2278 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2279 if (rd->interfaces[i][j].flags & INMEMORY)
2280 printf("M%2d", rd->interfaces[i][j].regoff);
2281 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2282 printf("F%02d", rd->interfaces[i][j].regoff);
2284 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2288 if (rd->interfaces[i][j].flags & INMEMORY)
2289 printf("m%2d", rd->interfaces[i][j].regoff);
2290 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2291 printf("f%02d", rd->interfaces[i][j].regoff);
2293 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2304 if (showdisassemble) {
2305 #if defined(__I386__) || defined(__X86_64__)
2309 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2310 for (i = 0; i < m->basicblocks[0].mpc;) {
2311 a = disassinstr(u1ptr);
2316 #elif defined(__XDSPCORE__)
2320 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2321 for (i = 0; i < m->basicblocks[0].mpc;) {
2322 a = disassinstr(stdout, s4ptr);
2331 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2332 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2339 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2340 show_icmd_block(m, cd, bptr);
2345 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2351 if (bptr->flags != BBDELETED) {
2352 deadcode = bptr->flags <= BBREACHED;
2355 for (j = cd->maxstack; j > 0; j--)
2358 icmd_print_stack(cd, bptr->instack);
2359 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2360 iptr = bptr->iinstr;
2362 for (i = 0; i < bptr->icount; i++, iptr++) {
2365 for (j = cd->maxstack; j > 0; j--)
2369 icmd_print_stack(cd, iptr->dst);
2370 printf("] %4d ", i);
2371 show_icmd(iptr, deadcode);
2375 if (showdisassemble && (!deadcode)) {
2376 #if defined(__I386__) || defined(__X86_64__)
2382 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2384 if (bptr->next != NULL) {
2385 for (; i < bptr->next->mpc; ) {
2386 a = disassinstr(u1ptr);
2393 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2394 a = disassinstr(u1ptr);
2400 #elif defined(__XDSPCORE__)
2406 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2408 if (bptr->next != NULL) {
2409 for (; i < bptr->next->mpc;) {
2410 a = disassinstr(stdout, s4ptr);
2418 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2419 a = disassinstr(stdout, s4ptr);
2430 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2432 if (bptr->next != NULL) {
2433 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2438 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2448 void show_icmd(instruction *iptr, bool deadcode)
2454 printf("%s", icmd_names[iptr->opc]);
2456 switch (iptr->opc) {
2457 case ICMD_IADDCONST:
2458 case ICMD_ISUBCONST:
2459 case ICMD_IMULCONST:
2463 case ICMD_IANDCONST:
2465 case ICMD_IXORCONST:
2466 case ICMD_ISHLCONST:
2467 case ICMD_ISHRCONST:
2468 case ICMD_IUSHRCONST:
2469 case ICMD_LSHLCONST:
2470 case ICMD_LSHRCONST:
2471 case ICMD_LUSHRCONST:
2473 case ICMD_ELSE_ICONST:
2474 case ICMD_IFEQ_ICONST:
2475 case ICMD_IFNE_ICONST:
2476 case ICMD_IFLT_ICONST:
2477 case ICMD_IFGE_ICONST:
2478 case ICMD_IFGT_ICONST:
2479 case ICMD_IFLE_ICONST:
2480 case ICMD_IASTORECONST:
2481 case ICMD_BASTORECONST:
2482 case ICMD_CASTORECONST:
2483 case ICMD_SASTORECONST:
2484 printf(" %d", iptr->val.i);
2487 case ICMD_LADDCONST:
2488 case ICMD_LSUBCONST:
2489 case ICMD_LMULCONST:
2493 case ICMD_LANDCONST:
2495 case ICMD_LXORCONST:
2497 case ICMD_LASTORECONST:
2498 #if defined(__I386__) && defined(__POWERPC__)
2499 printf(" %lld", iptr->val.l);
2501 printf(" %ld", iptr->val.l);
2506 printf(" %f", iptr->val.f);
2510 printf(" %f", iptr->val.d);
2514 case ICMD_AASTORECONST:
2515 printf(" %p", iptr->val.a);
2520 printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
2521 case ICMD_PUTSTATIC:
2522 case ICMD_GETSTATIC:
2524 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->class->name);
2526 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->name);
2528 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->descriptor);
2532 case ICMD_PUTSTATICCONST:
2533 case ICMD_PUTFIELDCONST:
2534 switch (iptr[1].opc) {
2536 printf(" %d,", iptr->val.i);
2539 #if defined(__I386__) && defined(__POWERPC__)
2540 printf(" %lld,", iptr->val.l);
2542 printf(" %ld,", iptr->val.l);
2546 #if defined(__I386__) && defined(__POWERPC__)
2547 printf(" 0x%08x,", iptr->val.a);
2549 printf(" 0x%016lx,", iptr->val.a);
2553 printf(" %g,", iptr->val.f);
2556 printf(" %g,", iptr->val.d);
2559 if (iptr->opc == ICMD_PUTFIELDCONST)
2560 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
2561 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->class->name);
2563 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->name);
2565 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->descriptor);
2570 printf(" %d + %d", iptr->op1, iptr->val.i);
2605 printf(" %d", iptr->op1);
2611 ((classinfo *) iptr->val.a)->name);
2615 switch (iptr->op1) {
2643 case ICMD_ANEWARRAY:
2647 ((classinfo *) iptr->val.a)->name);
2651 case ICMD_MULTIANEWARRAY:
2654 printf(" %d ",iptr->op1);
2655 vft = (vftbl_t *)iptr->val.a;
2657 utf_fprint(stdout,vft->class->name);
2663 case ICMD_CHECKCAST:
2664 case ICMD_INSTANCEOF:
2666 classinfo *c = iptr->val.a;
2667 if (c->flags & ACC_INTERFACE)
2668 printf(" (INTERFACE) ");
2670 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2671 utf_fprint(stdout, c->name);
2675 case ICMD_INLINE_START:
2676 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2678 case ICMD_INLINE_END:
2684 printf(" %s", icmd_builtin_name((functionptr) iptr->val.fp));
2687 case ICMD_INVOKEVIRTUAL:
2688 case ICMD_INVOKESPECIAL:
2689 case ICMD_INVOKESTATIC:
2690 case ICMD_INVOKEINTERFACE:
2693 ((methodinfo *) iptr->val.a)->class->name);
2696 ((methodinfo *) iptr->val.a)->name);
2705 if (deadcode || !iptr->target)
2706 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2708 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2717 if (deadcode || !iptr->target)
2718 #if defined(__I386__) || defined(__POWERPC__)
2719 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2721 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2724 #if defined(__I386__) || defined(__POWERPC__)
2725 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2727 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2734 case ICMD_IFNONNULL:
2735 case ICMD_IF_ICMPEQ:
2736 case ICMD_IF_ICMPNE:
2737 case ICMD_IF_ICMPLT:
2738 case ICMD_IF_ICMPGE:
2739 case ICMD_IF_ICMPGT:
2740 case ICMD_IF_ICMPLE:
2741 case ICMD_IF_LCMPEQ:
2742 case ICMD_IF_LCMPNE:
2743 case ICMD_IF_LCMPLT:
2744 case ICMD_IF_LCMPGE:
2745 case ICMD_IF_LCMPGT:
2746 case ICMD_IF_LCMPLE:
2747 case ICMD_IF_ACMPEQ:
2748 case ICMD_IF_ACMPNE:
2749 if (deadcode || !iptr->target)
2750 printf(" op1=%d", iptr->op1);
2752 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2755 case ICMD_TABLESWITCH:
2756 s4ptr = (s4*)iptr->val.a;
2758 if (deadcode || !iptr->target) {
2759 printf(" %d;", *s4ptr);
2762 tptr = (void **) iptr->target;
2763 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2767 s4ptr++; /* skip default */
2768 j = *s4ptr++; /* low */
2769 j = *s4ptr++ - j; /* high */
2771 if (deadcode || !*tptr)
2772 printf(" %d", *s4ptr++);
2774 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2781 case ICMD_LOOKUPSWITCH:
2782 s4ptr = (s4*)iptr->val.a;
2784 if (deadcode || !iptr->target) {
2785 printf(" %d;", *s4ptr);
2788 tptr = (void **) iptr->target;
2789 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2792 s4ptr++; /* default */
2793 j = *s4ptr++; /* count */
2796 if (deadcode || !*tptr) {
2797 s4ptr++; /* skip value */
2798 printf(" %d",*s4ptr++);
2801 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2807 printf(" Line number: %d, method:",iptr->line);
2809 utf_display(iptr->method->class->name);
2811 utf_display(iptr->method->name); */
2816 * These are local overrides for various environment variables in Emacs.
2817 * Please do not remove this and leave it at the end of the file, where
2818 * Emacs will automagically detect them.
2819 * ---------------------------------------------------------------------
2822 * indent-tabs-mode: t