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
33 $Id: stack.c 2811 2005-06-23 14:19:18Z christian $
47 #include "mm/memory.h"
48 #include "native/native.h"
49 #include "toolbox/logging.h"
50 #include "vm/global.h"
51 #include "vm/builtin.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/statistics.h"
55 #include "vm/stringlocal.h"
56 #include "vm/tables.h"
57 #include "vm/jit/codegen.inc.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/stack.h"
61 #include "vm/jit/lsra.h"
64 /**********************************************************************/
66 /**********************************************************************/
68 /* analyse_stack uses the intermediate code created by parse.c to
69 * build a model of the JVM operand stack for the current method.
71 * The following checks are performed:
72 * - check for operand stack underflow (before each instruction)
73 * - check for operand stack overflow (after[1] each instruction)
74 * - check for matching stack depth at merging points
75 * - check for matching basic types[2] at merging points
76 * - check basic types for instruction input (except for BUILTIN*
77 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
79 * [1]) Checking this after the instruction should be ok. parse.c
80 * counts the number of required stack slots in such a way that it is
81 * only vital that we don't exceed `maxstack` at basic block
84 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
85 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
86 * types are not discerned.
89 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
97 int opcode, i, len, loops;
98 int superblockend, repeat, deadcode;
106 builtintable_entry *bte;
107 unresolved_method *um;
114 argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */
115 for (i = 0; i < cd->maxlocals; i++)
120 m->basicblocks[0].flags = BBREACHED;
121 m->basicblocks[0].instack = 0;
122 m->basicblocks[0].indepth = 0;
124 for (i = 0; i < cd->exceptiontablelength; i++) {
125 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
126 bptr->flags = BBREACHED;
127 bptr->type = BBTYPE_EXH;
130 bptr->pre_count = 10000;
135 #if CONDITIONAL_LOADCONST
136 b_count = m->basicblockcount;
137 bptr = m->basicblocks;
138 while (--b_count >= 0) {
139 if (bptr->icount != 0) {
140 iptr = bptr->iinstr + bptr->icount - 1;
173 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
176 case ICMD_TABLESWITCH:
178 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
179 i = *s4ptr++; /* low */
180 i = *s4ptr++ - i + 1; /* high */
182 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
186 case ICMD_LOOKUPSWITCH:
188 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
189 i = *s4ptr++; /* count */
191 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
202 #endif /* CONDITIONAL_LOADCONST */
207 b_count = m->basicblockcount;
208 bptr = m->basicblocks;
209 superblockend = true;
214 while (--b_count >= 0) {
215 if (bptr->flags == BBDELETED) {
218 } else if (superblockend && (bptr->flags < BBREACHED)) {
221 } else if (bptr->flags <= BBREACHED) {
223 stackdepth = bptr->indepth;
225 } else if (bptr->flags < BBREACHED) {
227 bptr->instack = copy;
228 bptr->indepth = stackdepth;
230 } else if (bptr->indepth != stackdepth) {
231 show_icmd_method(m, cd, rd);
232 printf("Block: %d, required depth: %d, current depth: %d\n", bptr->debug_nr, bptr->indepth, stackdepth);
233 log_text("Stack depth mismatch");
237 curstack = bptr->instack;
239 superblockend = false;
240 bptr->flags = BBFINISHED;
243 b_index = bptr - m->basicblocks;
247 /* XXX TWISTI: why is this set to NULL here? */
248 /* iptr->target = NULL; */
250 #if defined(USEBUILTINTABLE)
251 bte = builtintable_get_automatic(opcode);
253 if (bte && bte->opcode == opcode) {
254 iptr->opc = ICMD_BUILTIN;
255 iptr->op1 = bte->md->paramcount;
257 m->isleafmethod = false;
260 #endif /* defined(USEBUILTINTABLE) */
267 COUNT(count_check_null);
269 case ICMD_CHECKASIZE:
270 case ICMD_CHECKEXCEPTION:
272 case ICMD_IFEQ_ICONST:
273 case ICMD_IFNE_ICONST:
274 case ICMD_IFLT_ICONST:
275 case ICMD_IFGE_ICONST:
276 case ICMD_IFGT_ICONST:
277 case ICMD_IFLE_ICONST:
278 case ICMD_ELSE_ICONST:
283 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
285 COUNT(count_pcmd_return);
287 superblockend = true;
290 /* pop 0 push 1 const */
293 COUNT(count_pcmd_load);
295 switch (iptr[1].opc) {
297 iptr[0].opc = ICMD_IADDCONST;
299 iptr[1].opc = ICMD_NOP;
300 OP1_1(TYPE_INT, TYPE_INT);
301 COUNT(count_pcmd_op);
304 iptr[0].opc = ICMD_ISUBCONST;
305 goto icmd_iconst_tail;
306 #if SUPPORT_CONST_MUL
308 iptr[0].opc = ICMD_IMULCONST;
309 goto icmd_iconst_tail;
310 #else /* SUPPORT_CONST_MUL */
312 if (iptr[0].val.i == 0x00000002)
314 else if (iptr[0].val.i == 0x00000004)
316 else if (iptr[0].val.i == 0x00000008)
318 else if (iptr[0].val.i == 0x00000010)
320 else if (iptr[0].val.i == 0x00000020)
322 else if (iptr[0].val.i == 0x00000040)
324 else if (iptr[0].val.i == 0x00000080)
326 else if (iptr[0].val.i == 0x00000100)
328 else if (iptr[0].val.i == 0x00000200)
330 else if (iptr[0].val.i == 0x00000400)
332 else if (iptr[0].val.i == 0x00000800)
334 else if (iptr[0].val.i == 0x00001000)
336 else if (iptr[0].val.i == 0x00002000)
338 else if (iptr[0].val.i == 0x00004000)
340 else if (iptr[0].val.i == 0x00008000)
342 else if (iptr[0].val.i == 0x00010000)
344 else if (iptr[0].val.i == 0x00020000)
346 else if (iptr[0].val.i == 0x00040000)
348 else if (iptr[0].val.i == 0x00080000)
350 else if (iptr[0].val.i == 0x00100000)
352 else if (iptr[0].val.i == 0x00200000)
354 else if (iptr[0].val.i == 0x00400000)
356 else if (iptr[0].val.i == 0x00800000)
358 else if (iptr[0].val.i == 0x01000000)
360 else if (iptr[0].val.i == 0x02000000)
362 else if (iptr[0].val.i == 0x04000000)
364 else if (iptr[0].val.i == 0x08000000)
366 else if (iptr[0].val.i == 0x10000000)
368 else if (iptr[0].val.i == 0x20000000)
370 else if (iptr[0].val.i == 0x40000000)
372 else if (iptr[0].val.i == 0x80000000)
378 iptr[0].opc = ICMD_IMULPOW2;
379 goto icmd_iconst_tail;
380 #endif /* SUPPORT_CONST_MUL */
382 if (iptr[0].val.i == 0x00000002)
384 else if (iptr[0].val.i == 0x00000004)
386 else if (iptr[0].val.i == 0x00000008)
388 else if (iptr[0].val.i == 0x00000010)
390 else if (iptr[0].val.i == 0x00000020)
392 else if (iptr[0].val.i == 0x00000040)
394 else if (iptr[0].val.i == 0x00000080)
396 else if (iptr[0].val.i == 0x00000100)
398 else if (iptr[0].val.i == 0x00000200)
400 else if (iptr[0].val.i == 0x00000400)
402 else if (iptr[0].val.i == 0x00000800)
404 else if (iptr[0].val.i == 0x00001000)
406 else if (iptr[0].val.i == 0x00002000)
408 else if (iptr[0].val.i == 0x00004000)
410 else if (iptr[0].val.i == 0x00008000)
412 else if (iptr[0].val.i == 0x00010000)
414 else if (iptr[0].val.i == 0x00020000)
416 else if (iptr[0].val.i == 0x00040000)
418 else if (iptr[0].val.i == 0x00080000)
420 else if (iptr[0].val.i == 0x00100000)
422 else if (iptr[0].val.i == 0x00200000)
424 else if (iptr[0].val.i == 0x00400000)
426 else if (iptr[0].val.i == 0x00800000)
428 else if (iptr[0].val.i == 0x01000000)
430 else if (iptr[0].val.i == 0x02000000)
432 else if (iptr[0].val.i == 0x04000000)
434 else if (iptr[0].val.i == 0x08000000)
436 else if (iptr[0].val.i == 0x10000000)
438 else if (iptr[0].val.i == 0x20000000)
440 else if (iptr[0].val.i == 0x40000000)
442 else if (iptr[0].val.i == 0x80000000)
448 iptr[0].opc = ICMD_IDIVPOW2;
449 goto icmd_iconst_tail;
451 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
452 if ((iptr[0].val.i == 0x00000002) ||
453 (iptr[0].val.i == 0x00000004) ||
454 (iptr[0].val.i == 0x00000008) ||
455 (iptr[0].val.i == 0x00000010) ||
456 (iptr[0].val.i == 0x00000020) ||
457 (iptr[0].val.i == 0x00000040) ||
458 (iptr[0].val.i == 0x00000080) ||
459 (iptr[0].val.i == 0x00000100) ||
460 (iptr[0].val.i == 0x00000200) ||
461 (iptr[0].val.i == 0x00000400) ||
462 (iptr[0].val.i == 0x00000800) ||
463 (iptr[0].val.i == 0x00001000) ||
464 (iptr[0].val.i == 0x00002000) ||
465 (iptr[0].val.i == 0x00004000) ||
466 (iptr[0].val.i == 0x00008000) ||
467 (iptr[0].val.i == 0x00010000) ||
468 (iptr[0].val.i == 0x00020000) ||
469 (iptr[0].val.i == 0x00040000) ||
470 (iptr[0].val.i == 0x00080000) ||
471 (iptr[0].val.i == 0x00100000) ||
472 (iptr[0].val.i == 0x00200000) ||
473 (iptr[0].val.i == 0x00400000) ||
474 (iptr[0].val.i == 0x00800000) ||
475 (iptr[0].val.i == 0x01000000) ||
476 (iptr[0].val.i == 0x02000000) ||
477 (iptr[0].val.i == 0x04000000) ||
478 (iptr[0].val.i == 0x08000000) ||
479 (iptr[0].val.i == 0x10000000) ||
480 (iptr[0].val.i == 0x20000000) ||
481 (iptr[0].val.i == 0x40000000) ||
482 (iptr[0].val.i == 0x80000000)) {
483 iptr[0].opc = ICMD_IREMPOW2;
485 goto icmd_iconst_tail;
489 #if SUPPORT_CONST_LOGICAL
491 iptr[0].opc = ICMD_IANDCONST;
492 goto icmd_iconst_tail;
494 iptr[0].opc = ICMD_IORCONST;
495 goto icmd_iconst_tail;
497 iptr[0].opc = ICMD_IXORCONST;
498 goto icmd_iconst_tail;
499 #endif /* SUPPORT_CONST_LOGICAL */
501 iptr[0].opc = ICMD_ISHLCONST;
502 goto icmd_iconst_tail;
504 iptr[0].opc = ICMD_ISHRCONST;
505 goto icmd_iconst_tail;
507 iptr[0].opc = ICMD_IUSHRCONST;
508 goto icmd_iconst_tail;
509 #if SUPPORT_LONG_SHIFT
511 iptr[0].opc = ICMD_LSHLCONST;
512 goto icmd_lconst_tail;
514 iptr[0].opc = ICMD_LSHRCONST;
515 goto icmd_lconst_tail;
517 iptr[0].opc = ICMD_LUSHRCONST;
518 goto icmd_lconst_tail;
519 #endif /* SUPPORT_LONG_SHIFT */
521 iptr[0].opc = ICMD_IFEQ;
523 iptr[0].op1 = iptr[1].op1;
527 /* iptr[1].opc = ICMD_NOP; */
529 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
531 iptr[0].target = (void *) tbptr;
533 MARKREACHED(tbptr, copy);
534 COUNT(count_pcmd_bra);
540 iptr[0].opc = ICMD_IFLT;
541 goto icmd_if_icmp_tail;
543 iptr[0].opc = ICMD_IFLE;
544 goto icmd_if_icmp_tail;
546 iptr[0].opc = ICMD_IFNE;
547 goto icmd_if_icmp_tail;
549 iptr[0].opc = ICMD_IFGT;
550 goto icmd_if_icmp_tail;
552 iptr[0].opc = ICMD_IFGE;
553 goto icmd_if_icmp_tail;
555 #if SUPPORT_CONST_STORE
560 #if SUPPORT_CONST_STORE_ZERO_ONLY
561 if (iptr[0].val.i == 0) {
562 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
563 switch (iptr[1].opc) {
565 iptr[0].opc = ICMD_IASTORECONST;
568 iptr[0].opc = ICMD_BASTORECONST;
571 iptr[0].opc = ICMD_CASTORECONST;
574 iptr[0].opc = ICMD_SASTORECONST;
578 iptr[1].opc = ICMD_NOP;
579 OPTT2_0(TYPE_INT, TYPE_ADR);
580 COUNT(count_pcmd_op);
581 #if SUPPORT_CONST_STORE_ZERO_ONLY
584 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
589 #if SUPPORT_CONST_STORE_ZERO_ONLY
590 if (iptr[0].val.i == 0) {
591 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
592 switch (iptr[1].opc) {
594 iptr[0].opc = ICMD_PUTSTATICCONST;
598 iptr[0].opc = ICMD_PUTFIELDCONST;
603 iptr[1].opc = ICMD_NOP;
604 iptr[0].op1 = TYPE_INT;
605 COUNT(count_pcmd_op);
606 #if SUPPORT_CONST_STORE_ZERO_ONLY
609 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
611 #endif /* SUPPORT_CONST_STORE */
621 COUNT(count_pcmd_load);
623 switch (iptr[1].opc) {
626 iptr[0].opc = ICMD_LADDCONST;
628 iptr[1].opc = ICMD_NOP;
629 OP1_1(TYPE_LNG,TYPE_LNG);
630 COUNT(count_pcmd_op);
633 iptr[0].opc = ICMD_LSUBCONST;
634 goto icmd_lconst_tail;
635 #endif /* SUPPORT_LONG_ADD */
636 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
638 iptr[0].opc = ICMD_LMULCONST;
639 goto icmd_lconst_tail;
640 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
641 # if SUPPORT_LONG_SHIFT
643 if (iptr[0].val.l == 0x00000002)
645 else if (iptr[0].val.l == 0x00000004)
647 else if (iptr[0].val.l == 0x00000008)
649 else if (iptr[0].val.l == 0x00000010)
651 else if (iptr[0].val.l == 0x00000020)
653 else if (iptr[0].val.l == 0x00000040)
655 else if (iptr[0].val.l == 0x00000080)
657 else if (iptr[0].val.l == 0x00000100)
659 else if (iptr[0].val.l == 0x00000200)
661 else if (iptr[0].val.l == 0x00000400)
663 else if (iptr[0].val.l == 0x00000800)
665 else if (iptr[0].val.l == 0x00001000)
667 else if (iptr[0].val.l == 0x00002000)
669 else if (iptr[0].val.l == 0x00004000)
671 else if (iptr[0].val.l == 0x00008000)
673 else if (iptr[0].val.l == 0x00010000)
675 else if (iptr[0].val.l == 0x00020000)
677 else if (iptr[0].val.l == 0x00040000)
679 else if (iptr[0].val.l == 0x00080000)
681 else if (iptr[0].val.l == 0x00100000)
683 else if (iptr[0].val.l == 0x00200000)
685 else if (iptr[0].val.l == 0x00400000)
687 else if (iptr[0].val.l == 0x00800000)
689 else if (iptr[0].val.l == 0x01000000)
691 else if (iptr[0].val.l == 0x02000000)
693 else if (iptr[0].val.l == 0x04000000)
695 else if (iptr[0].val.l == 0x08000000)
697 else if (iptr[0].val.l == 0x10000000)
699 else if (iptr[0].val.l == 0x20000000)
701 else if (iptr[0].val.l == 0x40000000)
703 else if (iptr[0].val.l == 0x80000000)
709 iptr[0].opc = ICMD_LMULPOW2;
710 goto icmd_lconst_tail;
711 # endif /* SUPPORT_LONG_SHIFT */
712 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
715 if (iptr[0].val.l == 0x00000002)
717 else if (iptr[0].val.l == 0x00000004)
719 else if (iptr[0].val.l == 0x00000008)
721 else if (iptr[0].val.l == 0x00000010)
723 else if (iptr[0].val.l == 0x00000020)
725 else if (iptr[0].val.l == 0x00000040)
727 else if (iptr[0].val.l == 0x00000080)
729 else if (iptr[0].val.l == 0x00000100)
731 else if (iptr[0].val.l == 0x00000200)
733 else if (iptr[0].val.l == 0x00000400)
735 else if (iptr[0].val.l == 0x00000800)
737 else if (iptr[0].val.l == 0x00001000)
739 else if (iptr[0].val.l == 0x00002000)
741 else if (iptr[0].val.l == 0x00004000)
743 else if (iptr[0].val.l == 0x00008000)
745 else if (iptr[0].val.l == 0x00010000)
747 else if (iptr[0].val.l == 0x00020000)
749 else if (iptr[0].val.l == 0x00040000)
751 else if (iptr[0].val.l == 0x00080000)
753 else if (iptr[0].val.l == 0x00100000)
755 else if (iptr[0].val.l == 0x00200000)
757 else if (iptr[0].val.l == 0x00400000)
759 else if (iptr[0].val.l == 0x00800000)
761 else if (iptr[0].val.l == 0x01000000)
763 else if (iptr[0].val.l == 0x02000000)
765 else if (iptr[0].val.l == 0x04000000)
767 else if (iptr[0].val.l == 0x08000000)
769 else if (iptr[0].val.l == 0x10000000)
771 else if (iptr[0].val.l == 0x20000000)
773 else if (iptr[0].val.l == 0x40000000)
775 else if (iptr[0].val.l == 0x80000000)
781 iptr[0].opc = ICMD_LDIVPOW2;
782 goto icmd_lconst_tail;
784 if ((iptr[0].val.l == 0x00000002) ||
785 (iptr[0].val.l == 0x00000004) ||
786 (iptr[0].val.l == 0x00000008) ||
787 (iptr[0].val.l == 0x00000010) ||
788 (iptr[0].val.l == 0x00000020) ||
789 (iptr[0].val.l == 0x00000040) ||
790 (iptr[0].val.l == 0x00000080) ||
791 (iptr[0].val.l == 0x00000100) ||
792 (iptr[0].val.l == 0x00000200) ||
793 (iptr[0].val.l == 0x00000400) ||
794 (iptr[0].val.l == 0x00000800) ||
795 (iptr[0].val.l == 0x00001000) ||
796 (iptr[0].val.l == 0x00002000) ||
797 (iptr[0].val.l == 0x00004000) ||
798 (iptr[0].val.l == 0x00008000) ||
799 (iptr[0].val.l == 0x00010000) ||
800 (iptr[0].val.l == 0x00020000) ||
801 (iptr[0].val.l == 0x00040000) ||
802 (iptr[0].val.l == 0x00080000) ||
803 (iptr[0].val.l == 0x00100000) ||
804 (iptr[0].val.l == 0x00200000) ||
805 (iptr[0].val.l == 0x00400000) ||
806 (iptr[0].val.l == 0x00800000) ||
807 (iptr[0].val.l == 0x01000000) ||
808 (iptr[0].val.l == 0x02000000) ||
809 (iptr[0].val.l == 0x04000000) ||
810 (iptr[0].val.l == 0x08000000) ||
811 (iptr[0].val.l == 0x10000000) ||
812 (iptr[0].val.l == 0x20000000) ||
813 (iptr[0].val.l == 0x40000000) ||
814 (iptr[0].val.l == 0x80000000)) {
815 iptr[0].opc = ICMD_LREMPOW2;
817 goto icmd_lconst_tail;
821 #endif /* SUPPORT_LONG_DIV */
822 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
825 iptr[0].opc = ICMD_LANDCONST;
826 goto icmd_lconst_tail;
828 iptr[0].opc = ICMD_LORCONST;
829 goto icmd_lconst_tail;
831 iptr[0].opc = ICMD_LXORCONST;
832 goto icmd_lconst_tail;
833 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
834 #if !defined(NOLONG_CONDITIONAL)
836 if ((len > 1) && (iptr[2].val.i == 0)) {
837 switch (iptr[2].opc) {
839 iptr[0].opc = ICMD_IF_LEQ;
840 icmd_lconst_lcmp_tail:
841 iptr[0].op1 = iptr[2].op1;
844 /* iptr[1].opc = ICMD_NOP;
845 iptr[2].opc = ICMD_NOP; */
847 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
849 iptr[0].target = (void *) tbptr;
851 MARKREACHED(tbptr, copy);
852 COUNT(count_pcmd_bra);
853 COUNT(count_pcmd_op);
856 iptr[0].opc = ICMD_IF_LNE;
857 goto icmd_lconst_lcmp_tail;
859 iptr[0].opc = ICMD_IF_LLT;
860 goto icmd_lconst_lcmp_tail;
862 iptr[0].opc = ICMD_IF_LGT;
863 goto icmd_lconst_lcmp_tail;
865 iptr[0].opc = ICMD_IF_LLE;
866 goto icmd_lconst_lcmp_tail;
868 iptr[0].opc = ICMD_IF_LGE;
869 goto icmd_lconst_lcmp_tail;
872 } /* switch (iptr[2].opc) */
873 } /* if (iptr[2].val.i == 0) */
877 #endif /* !defined(NOLONG_CONDITIONAL) */
879 #if SUPPORT_CONST_STORE
881 #if SUPPORT_CONST_STORE_ZERO_ONLY
882 if (iptr[0].val.l == 0) {
883 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
884 iptr[0].opc = ICMD_LASTORECONST;
885 iptr[1].opc = ICMD_NOP;
886 OPTT2_0(TYPE_INT, TYPE_ADR);
887 COUNT(count_pcmd_op);
888 #if SUPPORT_CONST_STORE_ZERO_ONLY
891 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
896 #if SUPPORT_CONST_STORE_ZERO_ONLY
897 if (iptr[0].val.l == 0) {
898 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
899 switch (iptr[1].opc) {
901 iptr[0].opc = ICMD_PUTSTATICCONST;
905 iptr[0].opc = ICMD_PUTFIELDCONST;
910 iptr[1].opc = ICMD_NOP;
911 iptr[0].op1 = TYPE_LNG;
912 COUNT(count_pcmd_op);
913 #if SUPPORT_CONST_STORE_ZERO_ONLY
916 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
918 #endif /* SUPPORT_CONST_STORE */
928 COUNT(count_pcmd_load);
933 COUNT(count_pcmd_load);
938 COUNT(count_pcmd_load);
939 #if SUPPORT_CONST_STORE
940 if (len > 0 && iptr->val.a == 0) {
941 switch (iptr[1].opc) {
943 if (iptr[1].val.fp != BUILTIN_aastore) {
950 switch (iptr[1].opc) {
952 iptr[0].opc = ICMD_AASTORECONST;
953 OPTT2_0(TYPE_INT, TYPE_ADR);
956 iptr[0].opc = ICMD_PUTSTATICCONST;
957 iptr[0].op1 = TYPE_ADR;
961 iptr[0].opc = ICMD_PUTFIELDCONST;
962 iptr[0].op1 = TYPE_ADR;
967 iptr[1].opc = ICMD_NOP;
968 COUNT(count_pcmd_op);
975 #endif /* SUPPORT_CONST_STORE */
979 /* pop 0 push 1 load */
986 COUNT(count_load_instruction);
987 i = opcode-ICMD_ILOAD;
988 iptr->op1 = argren[iptr->op1];
989 rd->locals[iptr->op1][i].type = i;
990 LOAD(i, LOCALVAR, iptr->op1);
1000 COUNT(count_check_null);
1001 COUNT(count_check_bound);
1002 COUNT(count_pcmd_mem);
1003 OP2IAT_1(opcode-ICMD_IALOAD);
1009 COUNT(count_check_null);
1010 COUNT(count_check_bound);
1011 COUNT(count_pcmd_mem);
1015 /* pop 0 push 0 iinc */
1018 #if defined(STATISTICS)
1022 count_store_depth[10]++;
1024 count_store_depth[i]++;
1030 if ((copy->varkind == LOCALVAR) &&
1031 (copy->varnum == iptr->op1)) {
1032 copy->varkind = TEMPVAR;
1041 /* pop 1 push 0 store */
1051 i = opcode - ICMD_ISTORE;
1052 rd->locals[iptr->op1][i].type = i;
1053 #if defined(STATISTICS)
1058 count_store_length[20]++;
1060 count_store_length[i]++;
1063 count_store_depth[10]++;
1065 count_store_depth[i]++;
1068 copy = curstack->prev;
1071 if ((copy->varkind == LOCALVAR) &&
1072 (copy->varnum == iptr->op1)) {
1073 copy->varkind = TEMPVAR;
1079 if ((new - curstack) == 1) {
1080 curstack->varkind = LOCALVAR;
1081 curstack->varnum = iptr->op1;
1083 STORE(opcode-ICMD_ISTORE);
1093 COUNT(count_check_null);
1094 COUNT(count_check_bound);
1095 COUNT(count_pcmd_mem);
1096 OP3TIA_0(opcode-ICMD_IASTORE);
1102 COUNT(count_check_null);
1103 COUNT(count_check_bound);
1104 COUNT(count_pcmd_mem);
1111 #ifdef TYPECHECK_STACK_COMPCAT
1114 if (IS_2_WORD_TYPE(curstack->type)) {
1115 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1128 COUNT(count_pcmd_return);
1129 OP1_0(opcode-ICMD_IRETURN);
1130 superblockend = true;
1134 COUNT(count_check_null);
1138 superblockend = true;
1141 case ICMD_PUTSTATIC:
1142 COUNT(count_pcmd_mem);
1146 /* pop 1 push 0 branch */
1149 case ICMD_IFNONNULL:
1150 COUNT(count_pcmd_bra);
1152 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1154 iptr[0].target = (void *) tbptr;
1156 MARKREACHED(tbptr, copy);
1168 COUNT(count_pcmd_bra);
1169 #if CONDITIONAL_LOADCONST
1170 tbptr = m->basicblocks + b_index;
1171 if ((b_count >= 3) &&
1172 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1173 (tbptr[1].pre_count == 1) &&
1174 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1175 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1176 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1177 (tbptr[2].pre_count == 1) &&
1178 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1179 (tbptr[2].icount==1)) {
1180 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1181 OP1_1(TYPE_INT, TYPE_INT);
1182 switch (iptr[0].opc) {
1184 iptr[0].opc = ICMD_IFNE_ICONST;
1187 iptr[0].opc = ICMD_IFEQ_ICONST;
1190 iptr[0].opc = ICMD_IFGE_ICONST;
1193 iptr[0].opc = ICMD_IFLT_ICONST;
1196 iptr[0].opc = ICMD_IFLE_ICONST;
1199 iptr[0].opc = ICMD_IFGT_ICONST;
1203 iptr[0].val.i = iptr[1].val.i;
1204 iptr[1].opc = ICMD_ELSE_ICONST;
1205 iptr[1].val.i = iptr[3].val.i;
1206 iptr[2].opc = ICMD_NOP;
1207 iptr[3].opc = ICMD_NOP;
1209 /* HACK: save compare value in iptr[1].op1 */
1210 iptr[1].op1 = iptr[0].val.i;
1211 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1212 iptr[1].opc = ICMD_ELSE_ICONST;
1213 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1214 tbptr[1].iinstr[0].opc = ICMD_NOP;
1215 tbptr[1].iinstr[1].opc = ICMD_NOP;
1216 tbptr[2].iinstr[0].opc = ICMD_NOP;
1218 tbptr[1].flags = BBDELETED;
1219 tbptr[2].flags = BBDELETED;
1220 tbptr[1].icount = 0;
1221 tbptr[2].icount = 0;
1222 if (tbptr[3].pre_count == 2) {
1223 len += tbptr[3].icount + 3;
1224 bptr->icount += tbptr[3].icount + 3;
1225 tbptr[3].flags = BBDELETED;
1226 tbptr[3].icount = 0;
1236 #endif /* CONDITIONAL_LOADCONST */
1239 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1241 iptr[0].target = (void *) tbptr;
1243 MARKREACHED(tbptr, copy);
1246 /* pop 0 push 0 branch */
1249 COUNT(count_pcmd_bra);
1250 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1252 iptr[0].target = (void *) tbptr;
1254 MARKREACHED(tbptr, copy);
1256 superblockend = true;
1259 /* pop 1 push 0 table branch */
1261 case ICMD_TABLESWITCH:
1262 COUNT(count_pcmd_table);
1264 s4ptr = iptr->val.a;
1265 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1266 MARKREACHED(tbptr, copy);
1267 i = *s4ptr++; /* low */
1268 i = *s4ptr++ - i + 1; /* high */
1270 tptr = DMNEW(void*, i+1);
1271 iptr->target = (void *) tptr;
1273 tptr[0] = (void *) tbptr;
1277 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1279 tptr[0] = (void *) tbptr;
1282 MARKREACHED(tbptr, copy);
1285 superblockend = true;
1288 /* pop 1 push 0 table branch */
1290 case ICMD_LOOKUPSWITCH:
1291 COUNT(count_pcmd_table);
1293 s4ptr = iptr->val.a;
1294 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1295 MARKREACHED(tbptr, copy);
1296 i = *s4ptr++; /* count */
1298 tptr = DMNEW(void*, i+1);
1299 iptr->target = (void *) tptr;
1301 tptr[0] = (void *) tbptr;
1305 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1307 tptr[0] = (void *) tbptr;
1310 MARKREACHED(tbptr, copy);
1314 superblockend = true;
1317 case ICMD_MONITORENTER:
1318 COUNT(count_check_null);
1319 case ICMD_MONITOREXIT:
1323 /* pop 2 push 0 branch */
1325 case ICMD_IF_ICMPEQ:
1326 case ICMD_IF_ICMPNE:
1327 case ICMD_IF_ICMPLT:
1328 case ICMD_IF_ICMPGE:
1329 case ICMD_IF_ICMPGT:
1330 case ICMD_IF_ICMPLE:
1331 COUNT(count_pcmd_bra);
1333 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1335 iptr[0].target = (void *) tbptr;
1337 MARKREACHED(tbptr, copy);
1340 case ICMD_IF_ACMPEQ:
1341 case ICMD_IF_ACMPNE:
1342 COUNT(count_pcmd_bra);
1344 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1346 iptr[0].target = (void *) tbptr;
1348 MARKREACHED(tbptr, copy);
1354 COUNT(count_check_null);
1355 COUNT(count_pcmd_mem);
1356 OPTT2_0(iptr->op1,TYPE_ADR);
1361 if (!IS_2_WORD_TYPE(curstack->type)) {
1363 #ifdef TYPECHECK_STACK_COMPCAT
1366 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1367 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1372 OP1_0ANY; /* second pop */
1375 iptr->opc = ICMD_POP;
1379 /* pop 0 push 1 dup */
1382 #ifdef TYPECHECK_STACK_COMPCAT
1385 if (IS_2_WORD_TYPE(curstack->type)) {
1386 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1391 COUNT(count_dup_instruction);
1397 if (IS_2_WORD_TYPE(curstack->type)) {
1399 iptr->opc = ICMD_DUP;
1404 /* ..., ????, cat1 */
1405 #ifdef TYPECHECK_STACK_COMPCAT
1407 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1408 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1414 NEWSTACK(copy->prev->type, copy->prev->varkind,
1415 copy->prev->varnum);
1416 NEWSTACK(copy->type, copy->varkind,
1423 /* pop 2 push 3 dup */
1426 #ifdef TYPECHECK_STACK_COMPCAT
1429 if (IS_2_WORD_TYPE(curstack->type) ||
1430 IS_2_WORD_TYPE(curstack->prev->type)) {
1431 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1441 if (IS_2_WORD_TYPE(curstack->type)) {
1442 /* ..., ????, cat2 */
1443 #ifdef TYPECHECK_STACK_COMPCAT
1445 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1446 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1451 iptr->opc = ICMD_DUP_X1;
1455 /* ..., ????, cat1 */
1456 #ifdef TYPECHECK_STACK_COMPCAT
1459 if (IS_2_WORD_TYPE(curstack->prev->type)
1460 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1461 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1470 /* pop 3 push 4 dup */
1474 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1475 /* ..., cat2, ???? */
1476 #ifdef TYPECHECK_STACK_COMPCAT
1478 if (IS_2_WORD_TYPE(curstack->type)) {
1479 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1484 iptr->opc = ICMD_DUP_X1;
1488 /* ..., cat1, ???? */
1489 #ifdef TYPECHECK_STACK_COMPCAT
1492 if (IS_2_WORD_TYPE(curstack->type)
1493 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1494 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1505 if (IS_2_WORD_TYPE(curstack->type)) {
1506 /* ..., ????, cat2 */
1507 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1508 /* ..., cat2, cat2 */
1509 iptr->opc = ICMD_DUP_X1;
1513 /* ..., cat1, cat2 */
1514 #ifdef TYPECHECK_STACK_COMPCAT
1517 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1518 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1523 iptr->opc = ICMD_DUP_X2;
1529 /* ..., ????, ????, cat1 */
1530 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1531 /* ..., cat2, ????, cat1 */
1532 #ifdef TYPECHECK_STACK_COMPCAT
1534 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1535 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1540 iptr->opc = ICMD_DUP2_X1;
1544 /* ..., cat1, ????, cat1 */
1545 #ifdef TYPECHECK_STACK_COMPCAT
1548 if (IS_2_WORD_TYPE(curstack->prev->type)
1549 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1550 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1560 /* pop 2 push 2 swap */
1563 #ifdef TYPECHECK_STACK_COMPCAT
1566 if (IS_2_WORD_TYPE(curstack->type)
1567 || IS_2_WORD_TYPE(curstack->prev->type)) {
1568 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1579 #if !SUPPORT_DIVISION
1580 bte = builtintable_get_internal(BUILTIN_idiv);
1581 iptr->opc = ICMD_BUILTIN;
1582 iptr->op1 = bte->md->paramcount;
1584 m->isleafmethod = false;
1589 #if !SUPPORT_DIVISION
1590 bte = builtintable_get_internal(BUILTIN_irem);
1591 iptr->opc = ICMD_BUILTIN;
1592 iptr->op1 = bte->md->paramcount;
1594 m->isleafmethod = false;
1607 COUNT(count_pcmd_op);
1612 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1613 bte = builtintable_get_internal(BUILTIN_ldiv);
1614 iptr->opc = ICMD_BUILTIN;
1615 iptr->op1 = bte->md->paramcount;
1617 m->isleafmethod = false;
1622 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1623 bte = builtintable_get_internal(BUILTIN_lrem);
1624 iptr->opc = ICMD_BUILTIN;
1625 iptr->op1 = bte->md->paramcount;
1627 m->isleafmethod = false;
1634 #if SUPPORT_LONG_LOGICAL
1638 #endif /* SUPPORT_LONG_LOGICAL */
1639 COUNT(count_pcmd_op);
1646 COUNT(count_pcmd_op);
1655 COUNT(count_pcmd_op);
1664 COUNT(count_pcmd_op);
1669 COUNT(count_pcmd_op);
1670 #if !defined(NOLONG_CONDITIONAL)
1671 if ((len > 0) && (iptr[1].val.i == 0)) {
1672 switch (iptr[1].opc) {
1674 iptr[0].opc = ICMD_IF_LCMPEQ;
1676 iptr[0].op1 = iptr[1].op1;
1679 /* iptr[1].opc = ICMD_NOP; */
1681 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1683 iptr[0].target = (void *) tbptr;
1685 MARKREACHED(tbptr, copy);
1686 COUNT(count_pcmd_bra);
1689 iptr[0].opc = ICMD_IF_LCMPNE;
1690 goto icmd_lcmp_if_tail;
1692 iptr[0].opc = ICMD_IF_LCMPLT;
1693 goto icmd_lcmp_if_tail;
1695 iptr[0].opc = ICMD_IF_LCMPGT;
1696 goto icmd_lcmp_if_tail;
1698 iptr[0].opc = ICMD_IF_LCMPLE;
1699 goto icmd_lcmp_if_tail;
1701 iptr[0].opc = ICMD_IF_LCMPGE;
1702 goto icmd_lcmp_if_tail;
1704 OPTT2_1(TYPE_LNG, TYPE_INT);
1709 OPTT2_1(TYPE_LNG, TYPE_INT);
1713 COUNT(count_pcmd_op);
1714 OPTT2_1(TYPE_FLT, TYPE_INT);
1718 COUNT(count_pcmd_op);
1719 OPTT2_1(TYPE_DBL, TYPE_INT);
1727 case ICMD_INT2SHORT:
1728 COUNT(count_pcmd_op);
1729 OP1_1(TYPE_INT, TYPE_INT);
1732 COUNT(count_pcmd_op);
1733 OP1_1(TYPE_LNG, TYPE_LNG);
1736 COUNT(count_pcmd_op);
1737 OP1_1(TYPE_FLT, TYPE_FLT);
1740 COUNT(count_pcmd_op);
1741 OP1_1(TYPE_DBL, TYPE_DBL);
1745 COUNT(count_pcmd_op);
1746 OP1_1(TYPE_INT, TYPE_LNG);
1749 COUNT(count_pcmd_op);
1750 OP1_1(TYPE_INT, TYPE_FLT);
1753 COUNT(count_pcmd_op);
1754 OP1_1(TYPE_INT, TYPE_DBL);
1757 COUNT(count_pcmd_op);
1758 OP1_1(TYPE_LNG, TYPE_INT);
1761 COUNT(count_pcmd_op);
1762 OP1_1(TYPE_LNG, TYPE_FLT);
1765 COUNT(count_pcmd_op);
1766 OP1_1(TYPE_LNG, TYPE_DBL);
1769 COUNT(count_pcmd_op);
1770 OP1_1(TYPE_FLT, TYPE_INT);
1773 COUNT(count_pcmd_op);
1774 OP1_1(TYPE_FLT, TYPE_LNG);
1777 COUNT(count_pcmd_op);
1778 OP1_1(TYPE_FLT, TYPE_DBL);
1781 COUNT(count_pcmd_op);
1782 OP1_1(TYPE_DBL, TYPE_INT);
1785 COUNT(count_pcmd_op);
1786 OP1_1(TYPE_DBL, TYPE_LNG);
1789 COUNT(count_pcmd_op);
1790 OP1_1(TYPE_DBL, TYPE_FLT);
1793 case ICMD_CHECKCAST:
1794 OP1_1(TYPE_ADR, TYPE_ADR);
1797 case ICMD_INSTANCEOF:
1798 case ICMD_ARRAYLENGTH:
1799 OP1_1(TYPE_ADR, TYPE_INT);
1803 case ICMD_ANEWARRAY:
1804 OP1_1(TYPE_INT, TYPE_ADR);
1808 COUNT(count_check_null);
1809 COUNT(count_pcmd_mem);
1810 OP1_1(TYPE_ADR, iptr->op1);
1815 case ICMD_GETSTATIC:
1816 COUNT(count_pcmd_mem);
1826 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1828 iptr[0].target = (void *) tbptr;
1830 /* This is a dirty hack. The typechecker
1831 * needs it because the OP1_0ANY below
1832 * overwrites iptr->dst.
1834 iptr->val.a = (void *) iptr->dst;
1836 tbptr->type = BBTYPE_SBR;
1838 /* We need to check for overflow right here because
1839 * the pushed value is poped after MARKREACHED. */
1841 MARKREACHED(tbptr, copy);
1845 /* pop many push any */
1849 bte = (builtintable_entry *) iptr->val.a;
1853 case ICMD_INVOKESTATIC:
1854 case ICMD_INVOKESPECIAL:
1855 case ICMD_INVOKEVIRTUAL:
1856 case ICMD_INVOKEINTERFACE:
1857 COUNT(count_pcmd_met);
1859 md = um->methodref->parseddesc.md;
1860 /* if (lm->flags & ACC_STATIC) */
1861 /* {COUNT(count_check_null);} */
1865 if (md->memuse > rd->memuse)
1866 rd->memuse = md->memuse;
1867 if (md->argintreguse > rd->argintreguse)
1868 rd->argintreguse = md->argintreguse;
1869 if (md->argfltreguse > rd->argintreguse)
1870 rd->argfltreguse = md->argintreguse;
1875 for (i-- ; i >= 0; i--) {
1876 if (!(copy->flags & SAVEDVAR)) {
1877 copy->varkind = ARGVAR;
1879 if (md->params[i].inmemory) {
1880 copy->flags = INMEMORY;
1881 copy->regoff = md->params[i].regoff;
1884 if (IS_FLT_DBL_TYPE(copy->type))
1886 rd->argfltregs[md->params[i].regoff];
1888 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1889 if (IS_2_WORD_TYPE(copy->type))
1890 copy->regoff = PACK_REGS(
1891 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
1892 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
1896 rd->argintregs[md->params[i].regoff];
1904 copy->flags |= SAVEDVAR;
1910 if (md->returntype.type != TYPE_VOID)
1911 OP0_1(md->returntype.type);
1914 case ICMD_INLINE_START:
1915 case ICMD_INLINE_END:
1919 case ICMD_MULTIANEWARRAY:
1920 if (rd->argintreguse < 3)
1921 rd->argintreguse = 3;
1926 #if defined(SPECIALMEMUSE)
1927 # if defined(__DARWIN__)
1928 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
1929 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
1931 if (rd->memuse < (i + LA_WORD_SIZE + 3))
1932 rd->memuse = i + LA_WORD_SIZE + 3;
1935 # if defined(__I386__)
1936 if (rd->memuse < i + 3)
1937 rd->memuse = i + 3; /* n integer args spilled on stack */
1940 rd->memuse = i; /* n integer args spilled on stack */
1941 # endif /* defined(__I386__) */
1945 /* check INT type here? Currently typecheck does this. */
1946 if (!(copy->flags & SAVEDVAR)) {
1947 copy->varkind = ARGVAR;
1948 copy->varnum = i + INT_ARG_CNT;
1949 copy->flags |= INMEMORY;
1950 #if defined(SPECIALMEMUSE)
1951 # if defined(__DARWIN__)
1952 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
1954 copy->regoff = i + LA_WORD_SIZE + 3;
1957 # if defined(__I386__)
1958 copy->regoff = i + 3;
1961 # endif /* defined(__I386__) */
1962 #endif /* defined(SPECIALMEMUSE) */
1967 copy->flags |= SAVEDVAR;
1975 case ICMD_CLEAR_ARGREN:
1976 for (i = iptr->op1; i < cd->maxlocals; i++)
1978 iptr->opc = opcode = ICMD_NOP;
1982 case ICMD_READONLY_ARG:
1983 case ICMD_READONLY_ARG+1:
1984 case ICMD_READONLY_ARG+2:
1985 case ICMD_READONLY_ARG+3:
1986 case ICMD_READONLY_ARG+4:
1989 if (curstack->varkind == LOCALVAR) {
1990 i = curstack->varnum;
1991 argren[iptr->op1] = i;
1994 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2001 new_exception_message(string_java_lang_InternalError,
2008 } /* while instructions */
2010 bptr->outstack = curstack;
2011 bptr->outdepth = stackdepth;
2015 superblockend = true;
2017 } /* while blocks */
2018 } while (repeat && !deadcode);
2020 #if defined(STATISTICS)
2022 if (m->basicblockcount > count_max_basic_blocks)
2023 count_max_basic_blocks = m->basicblockcount;
2024 count_basic_blocks += m->basicblockcount;
2025 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2026 count_javainstr += m->instructioncount;
2027 if (m->stackcount > count_upper_bound_new_stack)
2028 count_upper_bound_new_stack = m->stackcount;
2029 if ((new - m->stack) > count_max_new_stack)
2030 count_max_new_stack = (new - m->stack);
2032 b_count = m->basicblockcount;
2033 bptr = m->basicblocks;
2034 while (--b_count >= 0) {
2035 if (bptr->flags > BBREACHED) {
2036 if (bptr->indepth >= 10)
2037 count_block_stack[10]++;
2039 count_block_stack[bptr->indepth]++;
2042 count_block_size_distribution[len]++;
2044 count_block_size_distribution[10]++;
2046 count_block_size_distribution[11]++;
2048 count_block_size_distribution[12]++;
2050 count_block_size_distribution[13]++;
2052 count_block_size_distribution[14]++;
2054 count_block_size_distribution[15]++;
2056 count_block_size_distribution[16]++;
2058 count_block_size_distribution[17]++;
2064 count_analyse_iterations[0]++;
2065 else if (loops == 2)
2066 count_analyse_iterations[1]++;
2067 else if (loops == 3)
2068 count_analyse_iterations[2]++;
2069 else if (loops == 4)
2070 count_analyse_iterations[3]++;
2072 count_analyse_iterations[4]++;
2074 if (m->basicblockcount <= 5)
2075 count_method_bb_distribution[0]++;
2076 else if (m->basicblockcount <= 10)
2077 count_method_bb_distribution[1]++;
2078 else if (m->basicblockcount <= 15)
2079 count_method_bb_distribution[2]++;
2080 else if (m->basicblockcount <= 20)
2081 count_method_bb_distribution[3]++;
2082 else if (m->basicblockcount <= 30)
2083 count_method_bb_distribution[4]++;
2084 else if (m->basicblockcount <= 40)
2085 count_method_bb_distribution[5]++;
2086 else if (m->basicblockcount <= 50)
2087 count_method_bb_distribution[6]++;
2088 else if (m->basicblockcount <= 75)
2089 count_method_bb_distribution[7]++;
2091 count_method_bb_distribution[8]++;
2095 /* just return methodinfo* to signal everything was ok */
2101 /**********************************************************************/
2102 /* DEBUGGING HELPERS */
2103 /**********************************************************************/
2105 void icmd_print_stack(codegendata *cd, stackptr s)
2117 j = cd->maxstack - i;
2122 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2123 if (s->flags & SAVEDVAR)
2124 switch (s->varkind) {
2126 if (s->flags & INMEMORY)
2127 printf(" M%02d", s->regoff);
2128 #ifdef HAS_ADDRESS_REGISTER_FILE
2129 else if (s->type == TYPE_ADR)
2130 printf(" R%02d", s->regoff);
2132 else if (IS_FLT_DBL_TYPE(s->type))
2133 printf(" F%02d", s->regoff);
2135 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2136 if (IS_2_WORD_TYPE(s->type))
2137 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2138 regs[GET_HIGH_REG(s->regoff)]);
2141 printf(" %3s", regs[s->regoff]);
2145 printf(" I%02d", s->varnum);
2148 printf(" L%02d", s->varnum);
2151 printf(" A%02d", s->varnum);
2152 #ifdef INVOKE_NEW_DEBUG
2153 if (s->flags & INMEMORY)
2154 printf("(M%i)", s->regoff);
2156 printf("(R%i)", s->regoff);
2160 printf(" !%02d", j);
2163 switch (s->varkind) {
2165 if (s->flags & INMEMORY)
2166 printf(" m%02d", s->regoff);
2167 #ifdef HAS_ADDRESS_REGISTER_FILE
2168 else if (s->type == TYPE_ADR)
2169 printf(" r%02d", s->regoff);
2171 else if (IS_FLT_DBL_TYPE(s->type))
2172 printf(" f%02d", s->regoff);
2174 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2175 if (IS_2_WORD_TYPE(s->type))
2176 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2177 regs[GET_HIGH_REG(s->regoff)]);
2180 printf(" %3s", regs[s->regoff]);
2184 printf(" i%02d", s->varnum);
2187 printf(" l%02d", s->varnum);
2190 printf(" a%02d", s->varnum);
2191 #ifdef INVOKE_NEW_DEBUG
2192 if (s->flags & INMEMORY)
2193 printf("(M%i)", s->regoff);
2195 printf("(R%i)", s->regoff);
2199 printf(" ?%02d", j);
2207 static void print_reg(stackptr s) {
2209 if (s->flags & SAVEDVAR)
2210 switch (s->varkind) {
2212 if (s->flags & INMEMORY)
2213 printf(" tm%02d", s->regoff);
2215 printf(" tr%02d", s->regoff);
2218 printf(" s %02d", s->varnum);
2221 printf(" l %02d", s->varnum);
2224 printf(" a %02d", s->varnum);
2227 printf(" ! %02d", s->varnum);
2230 switch (s->varkind) {
2232 if (s->flags & INMEMORY)
2233 printf(" Tm%02d", s->regoff);
2235 printf(" Tr%02d", s->regoff);
2238 printf(" S %02d", s->varnum);
2241 printf(" L %02d", s->varnum);
2244 printf(" A %02d", s->varnum);
2247 printf(" ? %02d", s->varnum);
2257 static char *jit_type[] = {
2266 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2273 utf_fprint_classname(stdout, m->class->name);
2275 utf_fprint(stdout, m->name);
2276 utf_fprint(stdout, m->descriptor);
2277 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2278 printf("Max stack: %d\n", (int) cd->maxstack);
2280 printf("Line number table length: %d\n", m->linenumbercount);
2282 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2283 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2284 printf(" L%03d ... ", ex->start->debug_nr );
2285 printf("L%03d = ", ex->end->debug_nr);
2286 printf("L%03d", ex->handler->debug_nr);
2287 printf(" (catchtype: ");
2288 if (ex->catchtype.any)
2289 if (IS_CLASSREF(ex->catchtype))
2290 utf_display_classname(ex->catchtype.ref->name);
2292 utf_display_classname(ex->catchtype.cls->name);
2298 printf("Local Table:\n");
2299 for (i = 0; i < cd->maxlocals; i++) {
2300 printf(" %3d: ", i);
2301 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2302 if (rd->locals[i][j].type >= 0) {
2303 printf(" (%s) ", jit_type[j]);
2304 if (rd->locals[i][j].flags & INMEMORY)
2305 printf("m%2d", rd->locals[i][j].regoff);
2306 #ifdef HAS_ADDRESS_REGISTER_FILE
2307 else if (j == TYPE_ADR)
2308 printf("r%02d", rd->locals[i][j].regoff);
2310 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2311 printf("f%02d", rd->locals[i][j].regoff);
2313 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2314 if (IS_2_WORD_TYPE(j))
2316 regs[GET_LOW_REG(rd->locals[i][j].regoff)],
2317 regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
2320 printf("%3s", regs[rd->locals[i][j].regoff]);
2329 printf("Interface Table:\n");
2330 for (i = 0; i < cd->maxstack; i++) {
2331 if ((rd->interfaces[i][0].type >= 0) ||
2332 (rd->interfaces[i][1].type >= 0) ||
2333 (rd->interfaces[i][2].type >= 0) ||
2334 (rd->interfaces[i][3].type >= 0) ||
2335 (rd->interfaces[i][4].type >= 0)) {
2336 printf(" %3d: ", i);
2337 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2338 if (rd->interfaces[i][j].type >= 0) {
2339 printf(" (%s) ", jit_type[j]);
2340 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2341 if (rd->interfaces[i][j].flags & INMEMORY)
2342 printf("M%2d", rd->interfaces[i][j].regoff);
2343 #ifdef HAS_ADDRESS_REGISTER_FILE
2344 else if (j == TYPE_ADR)
2345 printf("R%02d", rd->interfaces[i][j].regoff);
2347 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2348 printf("F%02d", rd->interfaces[i][j].regoff);
2350 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2351 if (IS_2_WORD_TYPE(j))
2353 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2354 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2357 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2361 if (rd->interfaces[i][j].flags & INMEMORY)
2362 printf("m%2d", rd->interfaces[i][j].regoff);
2363 #ifdef HAS_ADDRESS_REGISTER_FILE
2364 else if (j == TYPE_ADR)
2365 printf("r%02d", rd->interfaces[i][j].regoff);
2367 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2368 printf("f%02d", rd->interfaces[i][j].regoff);
2370 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2371 if (IS_2_WORD_TYPE(j))
2373 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2374 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2377 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2388 if (showdisassemble) {
2389 #if defined(__I386__) || defined(__X86_64__)
2393 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2394 for (i = 0; i < m->basicblocks[0].mpc;) {
2395 a = disassinstr(u1ptr);
2400 #elif defined(__XDSPCORE__)
2404 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2405 for (i = 0; i < m->basicblocks[0].mpc;) {
2406 a = disassinstr(stdout, s4ptr);
2415 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2416 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2423 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2424 show_icmd_block(m, cd, bptr);
2429 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2435 if (bptr->flags != BBDELETED) {
2436 deadcode = bptr->flags <= BBREACHED;
2439 for (j = cd->maxstack; j > 0; j--)
2442 icmd_print_stack(cd, bptr->instack);
2443 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2444 iptr = bptr->iinstr;
2446 for (i = 0; i < bptr->icount; i++, iptr++) {
2449 for (j = cd->maxstack; j > 0; j--)
2453 icmd_print_stack(cd, iptr->dst);
2454 printf("] %4d ", i);
2457 if (icmd_uses_tmp[iptr->opc][0])
2461 if (icmd_uses_tmp[iptr->opc][1])
2465 if (icmd_uses_tmp[iptr->opc][2])
2471 show_icmd(iptr, deadcode);
2475 if (showdisassemble && (!deadcode)) {
2476 #if defined(__I386__) || defined(__X86_64__)
2482 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2484 if (bptr->next != NULL) {
2485 for (; i < bptr->next->mpc; ) {
2486 a = disassinstr(u1ptr);
2493 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2494 a = disassinstr(u1ptr);
2500 #elif defined(__XDSPCORE__)
2506 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2508 if (bptr->next != NULL) {
2509 for (; i < bptr->next->mpc;) {
2510 a = disassinstr(stdout, s4ptr);
2518 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2519 a = disassinstr(stdout, s4ptr);
2530 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2532 if (bptr->next != NULL) {
2533 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2538 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2548 void show_icmd(instruction *iptr, bool deadcode)
2554 printf("%s", icmd_names[iptr->opc]);
2556 switch (iptr->opc) {
2557 case ICMD_IADDCONST:
2558 case ICMD_ISUBCONST:
2559 case ICMD_IMULCONST:
2563 case ICMD_IANDCONST:
2565 case ICMD_IXORCONST:
2566 case ICMD_ISHLCONST:
2567 case ICMD_ISHRCONST:
2568 case ICMD_IUSHRCONST:
2569 case ICMD_LSHLCONST:
2570 case ICMD_LSHRCONST:
2571 case ICMD_LUSHRCONST:
2573 case ICMD_ELSE_ICONST:
2574 case ICMD_IASTORECONST:
2575 case ICMD_BASTORECONST:
2576 case ICMD_CASTORECONST:
2577 case ICMD_SASTORECONST:
2578 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2581 case ICMD_IFEQ_ICONST:
2582 case ICMD_IFNE_ICONST:
2583 case ICMD_IFLT_ICONST:
2584 case ICMD_IFGE_ICONST:
2585 case ICMD_IFGT_ICONST:
2586 case ICMD_IFLE_ICONST:
2587 printf("(%d) %d", iptr[1].op1, iptr->val.i);
2590 case ICMD_LADDCONST:
2591 case ICMD_LSUBCONST:
2592 case ICMD_LMULCONST:
2596 case ICMD_LANDCONST:
2598 case ICMD_LXORCONST:
2600 case ICMD_LASTORECONST:
2601 #if SIZEOF_VOID_P == 4
2602 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
2604 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
2609 printf(" %f", iptr->val.f);
2613 printf(" %f", iptr->val.d);
2617 case ICMD_AASTORECONST:
2618 printf(" %p", iptr->val.a);
2624 printf(" %d, ", ((fieldinfo *) iptr->val.a)->offset);
2626 printf(" (NOT RESOLVED), ");
2627 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2629 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2631 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2635 case ICMD_PUTSTATIC:
2636 case ICMD_GETSTATIC:
2640 printf(" (NOT RESOLVED) ");
2641 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2643 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2645 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2649 case ICMD_PUTSTATICCONST:
2650 case ICMD_PUTFIELDCONST:
2651 switch (iptr[1].op1) {
2653 printf(" %d,", iptr->val.i);
2656 #if SIZEOF_VOID_P == 4
2657 printf(" %lld,", iptr->val.l);
2659 printf(" %ld,", iptr->val.l);
2663 printf(" %p,", iptr->val.a);
2666 printf(" %g,", iptr->val.f);
2669 printf(" %g,", iptr->val.d);
2672 if (iptr->opc == ICMD_PUTFIELDCONST)
2673 printf(" NOT RESOLVED,");
2675 utf_display_classname(((unresolved_field *) iptr[1].target)->fieldref->classref->name);
2677 utf_display(((unresolved_field *) iptr[1].target)->fieldref->name);
2679 utf_display(((unresolved_field *) iptr[1].target)->fieldref->descriptor);
2684 printf(" %d + %d", iptr->op1, iptr->val.i);
2719 printf(" %d", iptr->op1);
2724 utf_display_classname(((classinfo *) iptr->val.a)->name);
2728 switch (iptr->op1) {
2756 case ICMD_ANEWARRAY:
2759 utf_display_classname(((classinfo *) iptr->val.a)->name);
2763 case ICMD_MULTIANEWARRAY:
2765 printf(" (NOT RESOLVED) %d ",iptr->op1);
2766 utf_display(((constant_classref *) iptr->val.a)->name);
2768 printf(" %d ",iptr->op1);
2769 utf_display_classname(((vftbl_t *) iptr->val.a)->class->name);
2773 case ICMD_CHECKCAST:
2774 case ICMD_INSTANCEOF:
2776 classinfo *c = iptr->val.a;
2778 if (c->flags & ACC_INTERFACE)
2779 printf(" (INTERFACE) ");
2781 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2783 printf(" (NOT RESOLVED) ");
2785 utf_display_classname(((constant_classref *) iptr->target)->name);
2789 case ICMD_INLINE_START:
2790 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2792 case ICMD_INLINE_END:
2796 printf(" %s", ((builtintable_entry *) iptr->val.a)->name);
2799 case ICMD_INVOKEVIRTUAL:
2800 case ICMD_INVOKESPECIAL:
2801 case ICMD_INVOKESTATIC:
2802 case ICMD_INVOKEINTERFACE:
2804 printf(" (NOT RESOLVED) ");
2807 utf_display_classname(((unresolved_method *) iptr->target)->methodref->classref->name);
2809 utf_display(((unresolved_method *) iptr->target)->methodref->name);
2810 utf_display(((unresolved_method *) iptr->target)->methodref->descriptor);
2819 if (deadcode || !iptr->target)
2820 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2822 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2831 if (deadcode || !iptr->target)
2832 #if SIZEOF_VOID_P == 4
2833 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2835 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2838 #if SIZEOF_VOID_P == 4
2839 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2841 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2848 case ICMD_IFNONNULL:
2849 case ICMD_IF_ICMPEQ:
2850 case ICMD_IF_ICMPNE:
2851 case ICMD_IF_ICMPLT:
2852 case ICMD_IF_ICMPGE:
2853 case ICMD_IF_ICMPGT:
2854 case ICMD_IF_ICMPLE:
2855 case ICMD_IF_LCMPEQ:
2856 case ICMD_IF_LCMPNE:
2857 case ICMD_IF_LCMPLT:
2858 case ICMD_IF_LCMPGE:
2859 case ICMD_IF_LCMPGT:
2860 case ICMD_IF_LCMPLE:
2861 case ICMD_IF_ACMPEQ:
2862 case ICMD_IF_ACMPNE:
2863 if (deadcode || !iptr->target)
2864 printf(" op1=%d", iptr->op1);
2866 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2869 case ICMD_TABLESWITCH:
2870 s4ptr = (s4*)iptr->val.a;
2872 if (deadcode || !iptr->target) {
2873 printf(" %d;", *s4ptr);
2876 tptr = (void **) iptr->target;
2877 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2881 s4ptr++; /* skip default */
2882 j = *s4ptr++; /* low */
2883 j = *s4ptr++ - j; /* high */
2885 if (deadcode || !*tptr)
2886 printf(" %d", *s4ptr++);
2888 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2895 case ICMD_LOOKUPSWITCH:
2896 s4ptr = (s4*)iptr->val.a;
2898 if (deadcode || !iptr->target) {
2899 printf(" %d;", *s4ptr);
2902 tptr = (void **) iptr->target;
2903 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2906 s4ptr++; /* default */
2907 j = *s4ptr++; /* count */
2910 if (deadcode || !*tptr) {
2911 s4ptr++; /* skip value */
2912 printf(" %d",*s4ptr++);
2915 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2921 printf(" Line number: %d, method:",iptr->line);
2923 utf_display(iptr->method->class->name);
2925 utf_display(iptr->method->name); */
2930 * These are local overrides for various environment variables in Emacs.
2931 * Please do not remove this and leave it at the end of the file, where
2932 * Emacs will automagically detect them.
2933 * ---------------------------------------------------------------------
2936 * indent-tabs-mode: t