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 2041 2005-03-20 13:42:18Z 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
559 #if SUPPORT_CONST_STORE_ZERO_ONLY
560 if (iptr[0].val.i == 0) {
561 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
562 switch (iptr[1].opc) {
564 iptr[0].opc = ICMD_IASTORECONST;
567 iptr[0].opc = ICMD_BASTORECONST;
570 iptr[0].opc = ICMD_CASTORECONST;
573 iptr[0].opc = ICMD_SASTORECONST;
577 iptr[1].opc = ICMD_NOP;
578 OPTT2_0(TYPE_INT, TYPE_ADR);
579 COUNT(count_pcmd_op);
580 #if SUPPORT_CONST_STORE_ZERO_ONLY
583 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
588 #if SUPPORT_CONST_STORE_ZERO_ONLY
589 if (iptr[0].val.i == 0) {
590 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
591 switch (iptr[1].opc) {
593 iptr[0].opc = ICMD_PUTSTATICCONST;
597 iptr[0].opc = ICMD_PUTFIELDCONST;
602 iptr[1].opc = ICMD_NOP;
603 COUNT(count_pcmd_op);
604 #if SUPPORT_CONST_STORE_ZERO_ONLY
607 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
609 #endif /* SUPPORT_CONST_STORE */
619 COUNT(count_pcmd_load);
621 switch (iptr[1].opc) {
624 iptr[0].opc = ICMD_LADDCONST;
626 iptr[1].opc = ICMD_NOP;
627 OP1_1(TYPE_LNG,TYPE_LNG);
628 COUNT(count_pcmd_op);
631 iptr[0].opc = ICMD_LSUBCONST;
632 goto icmd_lconst_tail;
633 #endif /* SUPPORT_LONG_ADD */
634 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
636 iptr[0].opc = ICMD_LMULCONST;
637 goto icmd_lconst_tail;
638 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
639 # if SUPPORT_LONG_SHIFT
641 if (iptr[0].val.l == 0x00000002)
643 else if (iptr[0].val.l == 0x00000004)
645 else if (iptr[0].val.l == 0x00000008)
647 else if (iptr[0].val.l == 0x00000010)
649 else if (iptr[0].val.l == 0x00000020)
651 else if (iptr[0].val.l == 0x00000040)
653 else if (iptr[0].val.l == 0x00000080)
655 else if (iptr[0].val.l == 0x00000100)
657 else if (iptr[0].val.l == 0x00000200)
659 else if (iptr[0].val.l == 0x00000400)
661 else if (iptr[0].val.l == 0x00000800)
663 else if (iptr[0].val.l == 0x00001000)
665 else if (iptr[0].val.l == 0x00002000)
667 else if (iptr[0].val.l == 0x00004000)
669 else if (iptr[0].val.l == 0x00008000)
671 else if (iptr[0].val.l == 0x00010000)
673 else if (iptr[0].val.l == 0x00020000)
675 else if (iptr[0].val.l == 0x00040000)
677 else if (iptr[0].val.l == 0x00080000)
679 else if (iptr[0].val.l == 0x00100000)
681 else if (iptr[0].val.l == 0x00200000)
683 else if (iptr[0].val.l == 0x00400000)
685 else if (iptr[0].val.l == 0x00800000)
687 else if (iptr[0].val.l == 0x01000000)
689 else if (iptr[0].val.l == 0x02000000)
691 else if (iptr[0].val.l == 0x04000000)
693 else if (iptr[0].val.l == 0x08000000)
695 else if (iptr[0].val.l == 0x10000000)
697 else if (iptr[0].val.l == 0x20000000)
699 else if (iptr[0].val.l == 0x40000000)
701 else if (iptr[0].val.l == 0x80000000)
707 iptr[0].opc = ICMD_LMULPOW2;
708 goto icmd_lconst_tail;
709 # endif /* SUPPORT_LONG_SHIFT */
710 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
713 if (iptr[0].val.l == 0x00000002)
715 else if (iptr[0].val.l == 0x00000004)
717 else if (iptr[0].val.l == 0x00000008)
719 else if (iptr[0].val.l == 0x00000010)
721 else if (iptr[0].val.l == 0x00000020)
723 else if (iptr[0].val.l == 0x00000040)
725 else if (iptr[0].val.l == 0x00000080)
727 else if (iptr[0].val.l == 0x00000100)
729 else if (iptr[0].val.l == 0x00000200)
731 else if (iptr[0].val.l == 0x00000400)
733 else if (iptr[0].val.l == 0x00000800)
735 else if (iptr[0].val.l == 0x00001000)
737 else if (iptr[0].val.l == 0x00002000)
739 else if (iptr[0].val.l == 0x00004000)
741 else if (iptr[0].val.l == 0x00008000)
743 else if (iptr[0].val.l == 0x00010000)
745 else if (iptr[0].val.l == 0x00020000)
747 else if (iptr[0].val.l == 0x00040000)
749 else if (iptr[0].val.l == 0x00080000)
751 else if (iptr[0].val.l == 0x00100000)
753 else if (iptr[0].val.l == 0x00200000)
755 else if (iptr[0].val.l == 0x00400000)
757 else if (iptr[0].val.l == 0x00800000)
759 else if (iptr[0].val.l == 0x01000000)
761 else if (iptr[0].val.l == 0x02000000)
763 else if (iptr[0].val.l == 0x04000000)
765 else if (iptr[0].val.l == 0x08000000)
767 else if (iptr[0].val.l == 0x10000000)
769 else if (iptr[0].val.l == 0x20000000)
771 else if (iptr[0].val.l == 0x40000000)
773 else if (iptr[0].val.l == 0x80000000)
779 iptr[0].opc = ICMD_LDIVPOW2;
780 goto icmd_lconst_tail;
782 if ((iptr[0].val.l == 0x00000002) ||
783 (iptr[0].val.l == 0x00000004) ||
784 (iptr[0].val.l == 0x00000008) ||
785 (iptr[0].val.l == 0x00000010) ||
786 (iptr[0].val.l == 0x00000020) ||
787 (iptr[0].val.l == 0x00000040) ||
788 (iptr[0].val.l == 0x00000080) ||
789 (iptr[0].val.l == 0x00000100) ||
790 (iptr[0].val.l == 0x00000200) ||
791 (iptr[0].val.l == 0x00000400) ||
792 (iptr[0].val.l == 0x00000800) ||
793 (iptr[0].val.l == 0x00001000) ||
794 (iptr[0].val.l == 0x00002000) ||
795 (iptr[0].val.l == 0x00004000) ||
796 (iptr[0].val.l == 0x00008000) ||
797 (iptr[0].val.l == 0x00010000) ||
798 (iptr[0].val.l == 0x00020000) ||
799 (iptr[0].val.l == 0x00040000) ||
800 (iptr[0].val.l == 0x00080000) ||
801 (iptr[0].val.l == 0x00100000) ||
802 (iptr[0].val.l == 0x00200000) ||
803 (iptr[0].val.l == 0x00400000) ||
804 (iptr[0].val.l == 0x00800000) ||
805 (iptr[0].val.l == 0x01000000) ||
806 (iptr[0].val.l == 0x02000000) ||
807 (iptr[0].val.l == 0x04000000) ||
808 (iptr[0].val.l == 0x08000000) ||
809 (iptr[0].val.l == 0x10000000) ||
810 (iptr[0].val.l == 0x20000000) ||
811 (iptr[0].val.l == 0x40000000) ||
812 (iptr[0].val.l == 0x80000000)) {
813 iptr[0].opc = ICMD_LREMPOW2;
815 goto icmd_lconst_tail;
819 #endif /* SUPPORT_LONG_DIV */
820 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
823 iptr[0].opc = ICMD_LANDCONST;
824 goto icmd_lconst_tail;
826 iptr[0].opc = ICMD_LORCONST;
827 goto icmd_lconst_tail;
829 iptr[0].opc = ICMD_LXORCONST;
830 goto icmd_lconst_tail;
831 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
832 #if !defined(NOLONG_CONDITIONAL)
834 if ((len > 1) && (iptr[2].val.i == 0)) {
835 switch (iptr[2].opc) {
837 iptr[0].opc = ICMD_IF_LEQ;
838 icmd_lconst_lcmp_tail:
839 iptr[0].op1 = iptr[2].op1;
842 /* iptr[1].opc = ICMD_NOP;
843 iptr[2].opc = ICMD_NOP; */
845 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
847 iptr[0].target = (void *) tbptr;
849 MARKREACHED(tbptr, copy);
850 COUNT(count_pcmd_bra);
851 COUNT(count_pcmd_op);
854 iptr[0].opc = ICMD_IF_LNE;
855 goto icmd_lconst_lcmp_tail;
857 iptr[0].opc = ICMD_IF_LLT;
858 goto icmd_lconst_lcmp_tail;
860 iptr[0].opc = ICMD_IF_LGT;
861 goto icmd_lconst_lcmp_tail;
863 iptr[0].opc = ICMD_IF_LLE;
864 goto icmd_lconst_lcmp_tail;
866 iptr[0].opc = ICMD_IF_LGE;
867 goto icmd_lconst_lcmp_tail;
870 } /* switch (iptr[2].opc) */
871 } /* if (iptr[2].val.i == 0) */
875 #endif /* !defined(NOLONG_CONDITIONAL) */
877 #if SUPPORT_CONST_STORE
879 #if SUPPORT_CONST_STORE_ZERO_ONLY
880 if (iptr[0].val.l == 0) {
881 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
882 iptr[0].opc = ICMD_LASTORECONST;
883 iptr[1].opc = ICMD_NOP;
884 OPTT2_0(TYPE_INT, TYPE_ADR);
885 COUNT(count_pcmd_op);
886 #if SUPPORT_CONST_STORE_ZERO_ONLY
889 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
894 #if SUPPORT_CONST_STORE_ZERO_ONLY
895 if (iptr[0].val.l == 0) {
896 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
897 switch (iptr[1].opc) {
899 iptr[0].opc = ICMD_PUTSTATICCONST;
903 iptr[0].opc = ICMD_PUTFIELDCONST;
908 iptr[1].opc = ICMD_NOP;
909 COUNT(count_pcmd_op);
910 #if SUPPORT_CONST_STORE_ZERO_ONLY
913 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
915 #endif /* SUPPORT_CONST_STORE */
925 COUNT(count_pcmd_load);
930 COUNT(count_pcmd_load);
935 COUNT(count_pcmd_load);
936 #if SUPPORT_CONST_STORE
937 if (len > 0 && iptr->val.a == 0) {
938 switch (iptr[1].opc) {
940 if (iptr[1].val.fp != BUILTIN_aastore) {
947 switch (iptr[1].opc) {
949 iptr[0].opc = ICMD_AASTORECONST;
950 OPTT2_0(TYPE_INT, TYPE_ADR);
953 iptr[0].opc = ICMD_PUTSTATICCONST;
957 iptr[0].opc = ICMD_PUTFIELDCONST;
962 iptr[1].opc = ICMD_NOP;
963 COUNT(count_pcmd_op);
970 #endif /* SUPPORT_CONST_STORE */
974 /* pop 0 push 1 load */
981 COUNT(count_load_instruction);
982 i = opcode-ICMD_ILOAD;
983 iptr->op1 = argren[iptr->op1];
984 rd->locals[iptr->op1][i].type = i;
985 LOAD(i, LOCALVAR, iptr->op1);
995 COUNT(count_check_null);
996 COUNT(count_check_bound);
997 COUNT(count_pcmd_mem);
998 OP2IAT_1(opcode-ICMD_IALOAD);
1004 COUNT(count_check_null);
1005 COUNT(count_check_bound);
1006 COUNT(count_pcmd_mem);
1010 /* pop 0 push 0 iinc */
1013 #if defined(STATISTICS)
1017 count_store_depth[10]++;
1019 count_store_depth[i]++;
1025 if ((copy->varkind == LOCALVAR) &&
1026 (copy->varnum == iptr->op1)) {
1027 copy->varkind = TEMPVAR;
1036 /* pop 1 push 0 store */
1046 i = opcode - ICMD_ISTORE;
1047 rd->locals[iptr->op1][i].type = i;
1048 #if defined(STATISTICS)
1053 count_store_length[20]++;
1055 count_store_length[i]++;
1058 count_store_depth[10]++;
1060 count_store_depth[i]++;
1063 copy = curstack->prev;
1066 if ((copy->varkind == LOCALVAR) &&
1067 (copy->varnum == iptr->op1)) {
1068 copy->varkind = TEMPVAR;
1074 if ((new - curstack) == 1) {
1075 curstack->varkind = LOCALVAR;
1076 curstack->varnum = iptr->op1;
1078 STORE(opcode-ICMD_ISTORE);
1088 COUNT(count_check_null);
1089 COUNT(count_check_bound);
1090 COUNT(count_pcmd_mem);
1091 OP3TIA_0(opcode-ICMD_IASTORE);
1097 COUNT(count_check_null);
1098 COUNT(count_check_bound);
1099 COUNT(count_pcmd_mem);
1106 #ifdef TYPECHECK_STACK_COMPCAT
1109 if (IS_2_WORD_TYPE(curstack->type)) {
1110 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1123 COUNT(count_pcmd_return);
1124 OP1_0(opcode-ICMD_IRETURN);
1125 superblockend = true;
1129 COUNT(count_check_null);
1133 superblockend = true;
1136 case ICMD_PUTSTATIC:
1137 COUNT(count_pcmd_mem);
1141 /* pop 1 push 0 branch */
1144 case ICMD_IFNONNULL:
1145 COUNT(count_pcmd_bra);
1147 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1149 iptr[0].target = (void *) tbptr;
1151 MARKREACHED(tbptr, copy);
1160 COUNT(count_pcmd_bra);
1161 #ifdef CONDITIONAL_LOADCONST
1163 tbptr = m->basicblocks + b_index;
1164 if ((b_count >= 3) &&
1165 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1166 (tbptr[1].pre_count == 1) &&
1167 (iptr[1].opc == ICMD_ICONST) &&
1168 (iptr[2].opc == ICMD_GOTO) &&
1169 ((b_index + 3) == m->basicblockindex[iptr[2].op1]) &&
1170 (tbptr[2].pre_count == 1) &&
1171 (iptr[3].opc == ICMD_ICONST)) {
1172 OP1_1(TYPE_INT, TYPE_INT);
1173 switch (iptr[0].opc) {
1175 iptr[0].opc = ICMD_IFNE_ICONST;
1178 iptr[0].opc = ICMD_IFEQ_ICONST;
1181 iptr[0].opc = ICMD_IFGE_ICONST;
1184 iptr[0].opc = ICMD_IFLT_ICONST;
1187 iptr[0].opc = ICMD_IFLE_ICONST;
1190 iptr[0].opc = ICMD_IFGT_ICONST;
1193 iptr[0].val.i = iptr[1].val.i;
1194 iptr[1].opc = ICMD_ELSE_ICONST;
1195 iptr[1].val.i = iptr[3].val.i;
1196 iptr[2].opc = ICMD_NOP;
1197 iptr[3].opc = ICMD_NOP;
1198 tbptr[1].flags = BBDELETED;
1199 tbptr[2].flags = BBDELETED;
1200 tbptr[1].icount = 0;
1201 tbptr[2].icount = 0;
1202 if (tbptr[3].pre_count == 2) {
1203 len += tbptr[3].icount + 3;
1204 bptr->icount += tbptr[3].icount + 3;
1205 tbptr[3].flags = BBDELETED;
1206 tbptr[3].icount = 0;
1219 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1221 iptr[0].target = (void *) tbptr;
1223 MARKREACHED(tbptr, copy);
1226 /* pop 0 push 0 branch */
1229 COUNT(count_pcmd_bra);
1230 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1232 iptr[0].target = (void *) tbptr;
1234 MARKREACHED(tbptr, copy);
1236 superblockend = true;
1239 /* pop 1 push 0 table branch */
1241 case ICMD_TABLESWITCH:
1242 COUNT(count_pcmd_table);
1244 s4ptr = iptr->val.a;
1245 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1246 MARKREACHED(tbptr, copy);
1247 i = *s4ptr++; /* low */
1248 i = *s4ptr++ - i + 1; /* high */
1250 tptr = DMNEW(void*, i+1);
1251 iptr->target = (void *) tptr;
1253 tptr[0] = (void *) tbptr;
1257 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1259 tptr[0] = (void *) tbptr;
1262 MARKREACHED(tbptr, copy);
1265 superblockend = true;
1268 /* pop 1 push 0 table branch */
1270 case ICMD_LOOKUPSWITCH:
1271 COUNT(count_pcmd_table);
1273 s4ptr = iptr->val.a;
1274 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1275 MARKREACHED(tbptr, copy);
1276 i = *s4ptr++; /* count */
1278 tptr = DMNEW(void*, i+1);
1279 iptr->target = (void *) tptr;
1281 tptr[0] = (void *) tbptr;
1285 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1287 tptr[0] = (void *) tbptr;
1290 MARKREACHED(tbptr, copy);
1294 superblockend = true;
1297 case ICMD_NULLCHECKPOP:
1298 case ICMD_MONITORENTER:
1299 COUNT(count_check_null);
1300 case ICMD_MONITOREXIT:
1304 /* pop 2 push 0 branch */
1306 case ICMD_IF_ICMPEQ:
1307 case ICMD_IF_ICMPNE:
1308 case ICMD_IF_ICMPLT:
1309 case ICMD_IF_ICMPGE:
1310 case ICMD_IF_ICMPGT:
1311 case ICMD_IF_ICMPLE:
1312 COUNT(count_pcmd_bra);
1314 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1316 iptr[0].target = (void *) tbptr;
1318 MARKREACHED(tbptr, copy);
1321 case ICMD_IF_ACMPEQ:
1322 case ICMD_IF_ACMPNE:
1323 COUNT(count_pcmd_bra);
1325 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1327 iptr[0].target = (void *) tbptr;
1329 MARKREACHED(tbptr, copy);
1335 COUNT(count_check_null);
1336 COUNT(count_pcmd_mem);
1337 OPTT2_0(iptr->op1,TYPE_ADR);
1342 if (!IS_2_WORD_TYPE(curstack->type)) {
1344 #ifdef TYPECHECK_STACK_COMPCAT
1347 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1348 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1353 OP1_0ANY; /* second pop */
1356 iptr->opc = ICMD_POP;
1360 /* pop 0 push 1 dup */
1363 #ifdef TYPECHECK_STACK_COMPCAT
1366 if (IS_2_WORD_TYPE(curstack->type)) {
1367 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1372 COUNT(count_dup_instruction);
1378 if (IS_2_WORD_TYPE(curstack->type)) {
1380 iptr->opc = ICMD_DUP;
1385 /* ..., ????, cat1 */
1386 #ifdef TYPECHECK_STACK_COMPCAT
1388 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1389 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1395 NEWSTACK(copy->prev->type, copy->prev->varkind,
1396 copy->prev->varnum);
1397 NEWSTACK(copy->type, copy->varkind,
1404 /* pop 2 push 3 dup */
1407 #ifdef TYPECHECK_STACK_COMPCAT
1410 if (IS_2_WORD_TYPE(curstack->type) ||
1411 IS_2_WORD_TYPE(curstack->prev->type)) {
1412 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1422 if (IS_2_WORD_TYPE(curstack->type)) {
1423 /* ..., ????, cat2 */
1424 #ifdef TYPECHECK_STACK_COMPCAT
1426 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1427 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1432 iptr->opc = ICMD_DUP_X1;
1436 /* ..., ????, cat1 */
1437 #ifdef TYPECHECK_STACK_COMPCAT
1440 if (IS_2_WORD_TYPE(curstack->prev->type)
1441 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1442 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1451 /* pop 3 push 4 dup */
1455 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1456 /* ..., cat2, ???? */
1457 #ifdef TYPECHECK_STACK_COMPCAT
1459 if (IS_2_WORD_TYPE(curstack->type)) {
1460 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1465 iptr->opc = ICMD_DUP_X1;
1469 /* ..., cat1, ???? */
1470 #ifdef TYPECHECK_STACK_COMPCAT
1473 if (IS_2_WORD_TYPE(curstack->type)
1474 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1475 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1486 if (IS_2_WORD_TYPE(curstack->type)) {
1487 /* ..., ????, cat2 */
1488 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1489 /* ..., cat2, cat2 */
1490 iptr->opc = ICMD_DUP_X1;
1494 /* ..., cat1, cat2 */
1495 #ifdef TYPECHECK_STACK_COMPCAT
1498 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1499 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1504 iptr->opc = ICMD_DUP_X2;
1510 /* ..., ????, ????, cat1 */
1511 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1512 /* ..., cat2, ????, cat1 */
1513 #ifdef TYPECHECK_STACK_COMPCAT
1515 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1516 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1521 iptr->opc = ICMD_DUP2_X1;
1525 /* ..., cat1, ????, cat1 */
1526 #ifdef TYPECHECK_STACK_COMPCAT
1529 if (IS_2_WORD_TYPE(curstack->prev->type)
1530 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1531 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1541 /* pop 2 push 2 swap */
1544 #ifdef TYPECHECK_STACK_COMPCAT
1547 if (IS_2_WORD_TYPE(curstack->type)
1548 || IS_2_WORD_TYPE(curstack->prev->type)) {
1549 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1560 #if !SUPPORT_DIVISION
1561 iptr[0].opc = ICMD_BUILTIN2;
1562 iptr[0].op1 = TYPE_INT;
1563 iptr[0].val.fp = BUILTIN_idiv;
1564 m->isleafmethod = false;
1569 #if !SUPPORT_DIVISION
1570 iptr[0].opc = ICMD_BUILTIN2;
1571 iptr[0].op1 = TYPE_INT;
1572 iptr[0].val.fp = BUILTIN_irem;
1573 m->isleafmethod = false;
1586 COUNT(count_pcmd_op);
1591 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1592 iptr[0].opc = ICMD_BUILTIN2;
1593 iptr[0].op1 = TYPE_LNG;
1594 iptr[0].val.fp = BUILTIN_ldiv;
1595 m->isleafmethod = false;
1600 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1601 iptr[0].opc = ICMD_BUILTIN2;
1602 iptr[0].op1 = TYPE_LNG;
1603 iptr[0].val.fp = BUILTIN_lrem;
1604 m->isleafmethod = false;
1611 #if SUPPORT_LONG_LOGICAL
1615 #endif /* SUPPORT_LONG_LOGICAL */
1616 COUNT(count_pcmd_op);
1623 COUNT(count_pcmd_op);
1632 COUNT(count_pcmd_op);
1641 COUNT(count_pcmd_op);
1646 COUNT(count_pcmd_op);
1647 #if !defined(NOLONG_CONDITIONAL)
1648 if ((len > 0) && (iptr[1].val.i == 0)) {
1649 switch (iptr[1].opc) {
1651 iptr[0].opc = ICMD_IF_LCMPEQ;
1653 iptr[0].op1 = iptr[1].op1;
1656 /* iptr[1].opc = ICMD_NOP; */
1658 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1660 iptr[0].target = (void *) tbptr;
1662 MARKREACHED(tbptr, copy);
1663 COUNT(count_pcmd_bra);
1666 iptr[0].opc = ICMD_IF_LCMPNE;
1667 goto icmd_lcmp_if_tail;
1669 iptr[0].opc = ICMD_IF_LCMPLT;
1670 goto icmd_lcmp_if_tail;
1672 iptr[0].opc = ICMD_IF_LCMPGT;
1673 goto icmd_lcmp_if_tail;
1675 iptr[0].opc = ICMD_IF_LCMPLE;
1676 goto icmd_lcmp_if_tail;
1678 iptr[0].opc = ICMD_IF_LCMPGE;
1679 goto icmd_lcmp_if_tail;
1681 OPTT2_1(TYPE_LNG, TYPE_INT);
1686 OPTT2_1(TYPE_LNG, TYPE_INT);
1690 COUNT(count_pcmd_op);
1691 OPTT2_1(TYPE_FLT, TYPE_INT);
1695 COUNT(count_pcmd_op);
1696 OPTT2_1(TYPE_DBL, TYPE_INT);
1704 case ICMD_INT2SHORT:
1705 COUNT(count_pcmd_op);
1706 OP1_1(TYPE_INT, TYPE_INT);
1709 COUNT(count_pcmd_op);
1710 OP1_1(TYPE_LNG, TYPE_LNG);
1713 COUNT(count_pcmd_op);
1714 OP1_1(TYPE_FLT, TYPE_FLT);
1717 COUNT(count_pcmd_op);
1718 OP1_1(TYPE_DBL, TYPE_DBL);
1722 COUNT(count_pcmd_op);
1723 OP1_1(TYPE_INT, TYPE_LNG);
1726 COUNT(count_pcmd_op);
1727 OP1_1(TYPE_INT, TYPE_FLT);
1730 COUNT(count_pcmd_op);
1731 OP1_1(TYPE_INT, TYPE_DBL);
1734 COUNT(count_pcmd_op);
1735 OP1_1(TYPE_LNG, TYPE_INT);
1738 COUNT(count_pcmd_op);
1739 OP1_1(TYPE_LNG, TYPE_FLT);
1742 COUNT(count_pcmd_op);
1743 OP1_1(TYPE_LNG, TYPE_DBL);
1746 COUNT(count_pcmd_op);
1747 OP1_1(TYPE_FLT, TYPE_INT);
1750 COUNT(count_pcmd_op);
1751 OP1_1(TYPE_FLT, TYPE_LNG);
1754 COUNT(count_pcmd_op);
1755 OP1_1(TYPE_FLT, TYPE_DBL);
1758 COUNT(count_pcmd_op);
1759 OP1_1(TYPE_DBL, TYPE_INT);
1762 COUNT(count_pcmd_op);
1763 OP1_1(TYPE_DBL, TYPE_LNG);
1766 COUNT(count_pcmd_op);
1767 OP1_1(TYPE_DBL, TYPE_FLT);
1770 case ICMD_CHECKCAST:
1771 OP1_1(TYPE_ADR, TYPE_ADR);
1774 case ICMD_INSTANCEOF:
1775 case ICMD_ARRAYLENGTH:
1776 OP1_1(TYPE_ADR, TYPE_INT);
1780 case ICMD_ANEWARRAY:
1781 OP1_1(TYPE_INT, TYPE_ADR);
1785 COUNT(count_check_null);
1786 COUNT(count_pcmd_mem);
1787 OP1_1(TYPE_ADR, iptr->op1);
1792 case ICMD_GETSTATIC:
1793 COUNT(count_pcmd_mem);
1803 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1805 iptr[0].target = (void *) tbptr;
1807 /* This is a dirty hack. The typechecker
1808 * needs it because the OP1_0ANY below
1809 * overwrites iptr->dst.
1811 iptr->val.a = (void *) iptr->dst;
1813 tbptr->type = BBTYPE_SBR;
1815 /* We need to check for overflow right here because
1816 * the pushed value is poped after MARKREACHED. */
1818 MARKREACHED(tbptr, copy);
1822 /* pop many push any */
1824 case ICMD_INVOKEVIRTUAL:
1825 case ICMD_INVOKESPECIAL:
1826 case ICMD_INVOKEINTERFACE:
1827 case ICMD_INVOKESTATIC:
1828 COUNT(count_pcmd_met);
1830 methodinfo *lm = iptr->val.a;
1831 if (lm->flags & ACC_STATIC)
1832 {COUNT(count_check_null);}
1834 if (i > rd->arguments_num)
1835 rd->arguments_num = i;
1837 #if defined(__X86_64__)
1843 /* count integer and float arguments */
1847 (IS_FLT_DBL_TYPE(copy->type)) ? farg++ : iarg++;
1851 /* calculate stack space required */
1853 stackargs += (iarg < INT_ARG_CNT) ?
1854 0 : (iarg - INT_ARG_CNT);
1855 stackargs += (farg < FLT_ARG_CNT) ?
1856 0 : (farg - FLT_ARG_CNT);
1861 if (!(copy->flags & SAVEDVAR)) {
1862 copy->varkind = ARGVAR;
1864 if (IS_FLT_DBL_TYPE(copy->type)) {
1865 if (--farg < FLT_ARG_CNT)
1866 copy->varnum = farg;
1868 copy->varnum = --stackargs + FLT_ARG_CNT;
1871 if (--iarg < INT_ARG_CNT)
1872 copy->varnum = iarg;
1874 copy->varnum = --stackargs + INT_ARG_CNT;
1878 (IS_FLT_DBL_TYPE(copy->type)) ? --farg : --iarg;
1883 #else /* defined(__X86_64__) */
1886 if (!(copy->flags & SAVEDVAR)) {
1887 copy->varkind = ARGVAR;
1892 #endif /* defined(__X86_64__) */
1894 copy->flags |= SAVEDVAR;
1899 if (lm->returntype != TYPE_VOID)
1900 OP0_1(lm->returntype);
1903 case ICMD_INLINE_START:
1904 case ICMD_INLINE_END:
1909 /* DEBUG */ /*dolog("builtin3");*/
1911 if (!(curstack->flags & SAVEDVAR)) {
1912 curstack->varkind = ARGVAR;
1913 curstack->varnum = 2;
1915 if (3 > rd->arguments_num) {
1916 rd->arguments_num = 3;
1921 #if defined(USEBUILTINTABLE) || !SUPPORT_DIVISION
1922 /* Just prevent a compiler warning... */
1926 /* DEBUG */ /*dolog("builtin2");*/
1927 if (!(curstack->flags & SAVEDVAR)) {
1928 curstack->varkind = ARGVAR;
1929 curstack->varnum = 1;
1931 if (2 > rd->arguments_num) {
1932 rd->arguments_num = 2;
1937 #if defined(USEBUILTINTABLE)
1938 /* Just prevent a compiler warning... */
1942 /* DEBUG */ /*dolog("builtin1");*/
1943 if (!(curstack->flags & SAVEDVAR)) {
1944 curstack->varkind = ARGVAR;
1945 curstack->varnum = 0;
1947 if (1 > rd->arguments_num) {
1948 rd->arguments_num = 1;
1953 copy->flags |= SAVEDVAR;
1956 if (iptr->op1 != TYPE_VOID)
1960 case ICMD_MULTIANEWARRAY:
1963 if ((i + INT_ARG_CNT) > rd->arguments_num)
1964 rd->arguments_num = i + INT_ARG_CNT;
1967 /* check INT type here? Currently typecheck does this. */
1968 if (!(copy->flags & SAVEDVAR)) {
1969 copy->varkind = ARGVAR;
1970 copy->varnum = i + INT_ARG_CNT;
1975 copy->flags |= SAVEDVAR;
1983 case ICMD_CLEAR_ARGREN:
1984 for (i = iptr->op1; i < cd->maxlocals; i++)
1986 iptr->opc = opcode = ICMD_NOP;
1990 case ICMD_READONLY_ARG:
1991 case ICMD_READONLY_ARG+1:
1992 case ICMD_READONLY_ARG+2:
1993 case ICMD_READONLY_ARG+3:
1994 case ICMD_READONLY_ARG+4:
1997 if (curstack->varkind == LOCALVAR) {
1998 i = curstack->varnum;
1999 argren[iptr->op1] = i;
2002 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2009 new_exception_message(string_java_lang_InternalError,
2016 } /* while instructions */
2018 bptr->outstack = curstack;
2019 bptr->outdepth = stackdepth;
2023 superblockend = true;
2025 } /* while blocks */
2026 } while (repeat && !deadcode);
2028 #if defined(STATISTICS)
2030 if (m->basicblockcount > count_max_basic_blocks)
2031 count_max_basic_blocks = m->basicblockcount;
2032 count_basic_blocks += m->basicblockcount;
2033 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2034 count_javainstr += m->instructioncount;
2035 if (m->stackcount > count_upper_bound_new_stack)
2036 count_upper_bound_new_stack = m->stackcount;
2037 if ((new - m->stack) > count_max_new_stack)
2038 count_max_new_stack = (new - m->stack);
2040 b_count = m->basicblockcount;
2041 bptr = m->basicblocks;
2042 while (--b_count >= 0) {
2043 if (bptr->flags > BBREACHED) {
2044 if (bptr->indepth >= 10)
2045 count_block_stack[10]++;
2047 count_block_stack[bptr->indepth]++;
2050 count_block_size_distribution[len]++;
2052 count_block_size_distribution[10]++;
2054 count_block_size_distribution[11]++;
2056 count_block_size_distribution[12]++;
2058 count_block_size_distribution[13]++;
2060 count_block_size_distribution[14]++;
2062 count_block_size_distribution[15]++;
2064 count_block_size_distribution[16]++;
2066 count_block_size_distribution[17]++;
2072 count_analyse_iterations[0]++;
2073 else if (loops == 2)
2074 count_analyse_iterations[1]++;
2075 else if (loops == 3)
2076 count_analyse_iterations[2]++;
2077 else if (loops == 4)
2078 count_analyse_iterations[3]++;
2080 count_analyse_iterations[4]++;
2082 if (m->basicblockcount <= 5)
2083 count_method_bb_distribution[0]++;
2084 else if (m->basicblockcount <= 10)
2085 count_method_bb_distribution[1]++;
2086 else if (m->basicblockcount <= 15)
2087 count_method_bb_distribution[2]++;
2088 else if (m->basicblockcount <= 20)
2089 count_method_bb_distribution[3]++;
2090 else if (m->basicblockcount <= 30)
2091 count_method_bb_distribution[4]++;
2092 else if (m->basicblockcount <= 40)
2093 count_method_bb_distribution[5]++;
2094 else if (m->basicblockcount <= 50)
2095 count_method_bb_distribution[6]++;
2096 else if (m->basicblockcount <= 75)
2097 count_method_bb_distribution[7]++;
2099 count_method_bb_distribution[8]++;
2103 /* just return methodinfo* to signal everything was ok */
2109 /**********************************************************************/
2110 /* DEBUGGING HELPERS */
2111 /**********************************************************************/
2113 void icmd_print_stack(codegendata *cd, stackptr s)
2125 j = cd->maxstack - i;
2130 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2131 if (s->flags & SAVEDVAR)
2132 switch (s->varkind) {
2134 if (s->flags & INMEMORY)
2135 printf(" M%02d", s->regoff);
2136 else if (IS_FLT_DBL_TYPE(s->type))
2137 printf(" F%02d", s->regoff);
2139 printf(" %3s", regs[s->regoff]);
2143 printf(" I%02d", s->varnum);
2146 printf(" L%02d", s->varnum);
2149 printf(" A%02d", s->varnum);
2152 printf(" !%02d", j);
2155 switch (s->varkind) {
2157 if (s->flags & INMEMORY)
2158 printf(" m%02d", s->regoff);
2159 else if (IS_FLT_DBL_TYPE(s->type))
2160 printf(" f%02d", s->regoff);
2162 printf(" %3s", regs[s->regoff]);
2166 printf(" i%02d", s->varnum);
2169 printf(" l%02d", s->varnum);
2172 printf(" a%02d", s->varnum);
2175 printf(" ?%02d", j);
2183 static void print_reg(stackptr s) {
2185 if (s->flags & SAVEDVAR)
2186 switch (s->varkind) {
2188 if (s->flags & INMEMORY)
2189 printf(" tm%02d", s->regoff);
2191 printf(" tr%02d", s->regoff);
2194 printf(" s %02d", s->varnum);
2197 printf(" l %02d", s->varnum);
2200 printf(" a %02d", s->varnum);
2203 printf(" ! %02d", s->varnum);
2206 switch (s->varkind) {
2208 if (s->flags & INMEMORY)
2209 printf(" Tm%02d", s->regoff);
2211 printf(" Tr%02d", s->regoff);
2214 printf(" S %02d", s->varnum);
2217 printf(" L %02d", s->varnum);
2220 printf(" A %02d", s->varnum);
2223 printf(" ? %02d", s->varnum);
2233 char *icmd_builtin_name(functionptr bptr)
2235 builtin_descriptor *bdesc = builtin_desc;
2236 while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
2238 return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
2242 static char *jit_type[] = {
2251 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2258 utf_fprint_classname(stdout, m->class->name);
2260 utf_fprint(stdout, m->name);
2261 utf_fprint_classname(stdout, m->descriptor);
2262 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2263 printf("Max stack: %d\n", (int) cd->maxstack);
2265 printf("Line number table length: %d\n", m->linenumbercount);
2267 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2268 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2269 printf(" L%03d ... ", ex->start->debug_nr );
2270 printf("L%03d = ", ex->end->debug_nr);
2271 printf("L%03d\n", ex->handler->debug_nr);
2274 printf("Local Table:\n");
2275 for (i = 0; i < cd->maxlocals; i++) {
2276 printf(" %3d: ", i);
2277 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2278 if (rd->locals[i][j].type >= 0) {
2279 printf(" (%s) ", jit_type[j]);
2280 if (rd->locals[i][j].flags & INMEMORY)
2281 printf("m%2d", rd->locals[i][j].regoff);
2282 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2283 printf("f%02d", rd->locals[i][j].regoff);
2285 printf("%3s", regs[rd->locals[i][j].regoff]);
2294 printf("Interface Table:\n");
2295 for (i = 0; i < cd->maxstack; i++) {
2296 if ((rd->interfaces[i][0].type >= 0) ||
2297 (rd->interfaces[i][1].type >= 0) ||
2298 (rd->interfaces[i][2].type >= 0) ||
2299 (rd->interfaces[i][3].type >= 0) ||
2300 (rd->interfaces[i][4].type >= 0)) {
2301 printf(" %3d: ", i);
2302 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2303 if (rd->interfaces[i][j].type >= 0) {
2304 printf(" (%s) ", jit_type[j]);
2305 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2306 if (rd->interfaces[i][j].flags & INMEMORY)
2307 printf("M%2d", rd->interfaces[i][j].regoff);
2308 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2309 printf("F%02d", rd->interfaces[i][j].regoff);
2311 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2315 if (rd->interfaces[i][j].flags & INMEMORY)
2316 printf("m%2d", rd->interfaces[i][j].regoff);
2317 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2318 printf("f%02d", rd->interfaces[i][j].regoff);
2320 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2331 if (showdisassemble) {
2332 #if defined(__I386__) || defined(__X86_64__)
2336 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2337 for (i = 0; i < m->basicblocks[0].mpc;) {
2338 a = disassinstr(u1ptr);
2343 #elif defined(__XDSPCORE__)
2347 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2348 for (i = 0; i < m->basicblocks[0].mpc;) {
2349 a = disassinstr(stdout, s4ptr);
2358 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2359 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2366 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2367 show_icmd_block(m, cd, bptr);
2372 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2378 if (bptr->flags != BBDELETED) {
2379 deadcode = bptr->flags <= BBREACHED;
2382 for (j = cd->maxstack; j > 0; j--)
2385 icmd_print_stack(cd, bptr->instack);
2386 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2387 iptr = bptr->iinstr;
2389 for (i = 0; i < bptr->icount; i++, iptr++) {
2392 for (j = cd->maxstack; j > 0; j--)
2396 icmd_print_stack(cd, iptr->dst);
2397 printf("] %4d ", i);
2398 show_icmd(iptr, deadcode);
2402 if (showdisassemble && (!deadcode)) {
2403 #if defined(__I386__) || defined(__X86_64__)
2409 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2411 if (bptr->next != NULL) {
2412 for (; i < bptr->next->mpc; ) {
2413 a = disassinstr(u1ptr);
2420 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2421 a = disassinstr(u1ptr);
2427 #elif defined(__XDSPCORE__)
2433 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2435 if (bptr->next != NULL) {
2436 for (; i < bptr->next->mpc;) {
2437 a = disassinstr(stdout, s4ptr);
2445 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2446 a = disassinstr(stdout, s4ptr);
2457 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2459 if (bptr->next != NULL) {
2460 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2465 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2475 void show_icmd(instruction *iptr, bool deadcode)
2481 printf("%s", icmd_names[iptr->opc]);
2483 switch (iptr->opc) {
2484 case ICMD_IADDCONST:
2485 case ICMD_ISUBCONST:
2486 case ICMD_IMULCONST:
2490 case ICMD_IANDCONST:
2492 case ICMD_IXORCONST:
2493 case ICMD_ISHLCONST:
2494 case ICMD_ISHRCONST:
2495 case ICMD_IUSHRCONST:
2496 case ICMD_LSHLCONST:
2497 case ICMD_LSHRCONST:
2498 case ICMD_LUSHRCONST:
2500 case ICMD_ELSE_ICONST:
2501 case ICMD_IFEQ_ICONST:
2502 case ICMD_IFNE_ICONST:
2503 case ICMD_IFLT_ICONST:
2504 case ICMD_IFGE_ICONST:
2505 case ICMD_IFGT_ICONST:
2506 case ICMD_IFLE_ICONST:
2507 case ICMD_IASTORECONST:
2508 case ICMD_BASTORECONST:
2509 case ICMD_CASTORECONST:
2510 case ICMD_SASTORECONST:
2511 printf(" %d", iptr->val.i);
2514 case ICMD_LADDCONST:
2515 case ICMD_LSUBCONST:
2516 case ICMD_LMULCONST:
2520 case ICMD_LANDCONST:
2522 case ICMD_LXORCONST:
2524 case ICMD_LASTORECONST:
2525 #if defined(__I386__) || defined(__POWERPC__)
2526 printf(" %lld", iptr->val.l);
2528 printf(" %ld", iptr->val.l);
2533 printf(" %f", iptr->val.f);
2537 printf(" %f", iptr->val.d);
2541 case ICMD_AASTORECONST:
2542 printf(" %p", iptr->val.a);
2547 printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
2548 case ICMD_PUTSTATIC:
2549 case ICMD_GETSTATIC:
2551 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->class->name);
2553 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->name);
2555 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->descriptor);
2559 case ICMD_PUTSTATICCONST:
2560 case ICMD_PUTFIELDCONST:
2561 switch (iptr[1].opc) {
2563 printf(" %d,", iptr->val.i);
2566 #if defined(__I386__) || defined(__POWERPC__)
2567 printf(" %lld,", iptr->val.l);
2569 printf(" %ld,", iptr->val.l);
2573 printf(" %p,", iptr->val.a);
2576 printf(" %g,", iptr->val.f);
2579 printf(" %g,", iptr->val.d);
2582 if (iptr->opc == ICMD_PUTFIELDCONST)
2583 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
2585 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->class->name);
2587 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->name);
2589 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->descriptor);
2594 printf(" %d + %d", iptr->op1, iptr->val.i);
2629 printf(" %d", iptr->op1);
2635 ((classinfo *) iptr->val.a)->name);
2639 switch (iptr->op1) {
2667 case ICMD_ANEWARRAY:
2671 ((classinfo *) iptr->val.a)->name);
2675 case ICMD_MULTIANEWARRAY:
2678 printf(" %d ",iptr->op1);
2679 vft = (vftbl_t *)iptr->val.a;
2681 utf_fprint(stdout,vft->class->name);
2687 case ICMD_CHECKCAST:
2688 case ICMD_INSTANCEOF:
2690 classinfo *c = iptr->val.a;
2691 if (c->flags & ACC_INTERFACE)
2692 printf(" (INTERFACE) ");
2694 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2695 utf_fprint(stdout, c->name);
2699 case ICMD_INLINE_START:
2700 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2702 case ICMD_INLINE_END:
2708 printf(" %s", icmd_builtin_name((functionptr) iptr->val.fp));
2711 case ICMD_INVOKEVIRTUAL:
2712 case ICMD_INVOKESPECIAL:
2713 case ICMD_INVOKESTATIC:
2714 case ICMD_INVOKEINTERFACE:
2717 ((methodinfo *) iptr->val.a)->class->name);
2720 ((methodinfo *) iptr->val.a)->name);
2729 if (deadcode || !iptr->target)
2730 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2732 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2741 if (deadcode || !iptr->target)
2742 #if defined(__I386__) || defined(__POWERPC__)
2743 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2745 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2748 #if defined(__I386__) || defined(__POWERPC__)
2749 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2751 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2758 case ICMD_IFNONNULL:
2759 case ICMD_IF_ICMPEQ:
2760 case ICMD_IF_ICMPNE:
2761 case ICMD_IF_ICMPLT:
2762 case ICMD_IF_ICMPGE:
2763 case ICMD_IF_ICMPGT:
2764 case ICMD_IF_ICMPLE:
2765 case ICMD_IF_LCMPEQ:
2766 case ICMD_IF_LCMPNE:
2767 case ICMD_IF_LCMPLT:
2768 case ICMD_IF_LCMPGE:
2769 case ICMD_IF_LCMPGT:
2770 case ICMD_IF_LCMPLE:
2771 case ICMD_IF_ACMPEQ:
2772 case ICMD_IF_ACMPNE:
2773 if (deadcode || !iptr->target)
2774 printf(" op1=%d", iptr->op1);
2776 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2779 case ICMD_TABLESWITCH:
2780 s4ptr = (s4*)iptr->val.a;
2782 if (deadcode || !iptr->target) {
2783 printf(" %d;", *s4ptr);
2786 tptr = (void **) iptr->target;
2787 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2791 s4ptr++; /* skip default */
2792 j = *s4ptr++; /* low */
2793 j = *s4ptr++ - j; /* high */
2795 if (deadcode || !*tptr)
2796 printf(" %d", *s4ptr++);
2798 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2805 case ICMD_LOOKUPSWITCH:
2806 s4ptr = (s4*)iptr->val.a;
2808 if (deadcode || !iptr->target) {
2809 printf(" %d;", *s4ptr);
2812 tptr = (void **) iptr->target;
2813 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2816 s4ptr++; /* default */
2817 j = *s4ptr++; /* count */
2820 if (deadcode || !*tptr) {
2821 s4ptr++; /* skip value */
2822 printf(" %d",*s4ptr++);
2825 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2831 printf(" Line number: %d, method:",iptr->line);
2833 utf_display(iptr->method->class->name);
2835 utf_display(iptr->method->name); */
2840 * These are local overrides for various environment variables in Emacs.
2841 * Please do not remove this and leave it at the end of the file, where
2842 * Emacs will automagically detect them.
2843 * ---------------------------------------------------------------------
2846 * indent-tabs-mode: t