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 2870 2005-06-29 12:39:31Z 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 md_return_alloc(m, rd, opcode - ICMD_IRETURN, curstack);
1129 COUNT(count_pcmd_return);
1130 OP1_0(opcode - ICMD_IRETURN);
1131 superblockend = true;
1135 COUNT(count_check_null);
1139 superblockend = true;
1142 case ICMD_PUTSTATIC:
1143 COUNT(count_pcmd_mem);
1147 /* pop 1 push 0 branch */
1150 case ICMD_IFNONNULL:
1151 COUNT(count_pcmd_bra);
1153 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1155 iptr[0].target = (void *) tbptr;
1157 MARKREACHED(tbptr, copy);
1169 COUNT(count_pcmd_bra);
1170 #if CONDITIONAL_LOADCONST
1171 tbptr = m->basicblocks + b_index;
1172 if ((b_count >= 3) &&
1173 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1174 (tbptr[1].pre_count == 1) &&
1175 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1176 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1177 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1178 (tbptr[2].pre_count == 1) &&
1179 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1180 (tbptr[2].icount==1)) {
1181 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1182 OP1_1(TYPE_INT, TYPE_INT);
1183 switch (iptr[0].opc) {
1185 iptr[0].opc = ICMD_IFNE_ICONST;
1188 iptr[0].opc = ICMD_IFEQ_ICONST;
1191 iptr[0].opc = ICMD_IFGE_ICONST;
1194 iptr[0].opc = ICMD_IFLT_ICONST;
1197 iptr[0].opc = ICMD_IFLE_ICONST;
1200 iptr[0].opc = ICMD_IFGT_ICONST;
1204 iptr[0].val.i = iptr[1].val.i;
1205 iptr[1].opc = ICMD_ELSE_ICONST;
1206 iptr[1].val.i = iptr[3].val.i;
1207 iptr[2].opc = ICMD_NOP;
1208 iptr[3].opc = ICMD_NOP;
1210 /* HACK: save compare value in iptr[1].op1 */
1211 iptr[1].op1 = iptr[0].val.i;
1212 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1213 iptr[1].opc = ICMD_ELSE_ICONST;
1214 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1215 tbptr[1].iinstr[0].opc = ICMD_NOP;
1216 tbptr[1].iinstr[1].opc = ICMD_NOP;
1217 tbptr[2].iinstr[0].opc = ICMD_NOP;
1219 tbptr[1].flags = BBDELETED;
1220 tbptr[2].flags = BBDELETED;
1221 tbptr[1].icount = 0;
1222 tbptr[2].icount = 0;
1223 if (tbptr[3].pre_count == 2) {
1224 len += tbptr[3].icount + 3;
1225 bptr->icount += tbptr[3].icount + 3;
1226 tbptr[3].flags = BBDELETED;
1227 tbptr[3].icount = 0;
1237 #endif /* CONDITIONAL_LOADCONST */
1240 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1242 iptr[0].target = (void *) tbptr;
1244 MARKREACHED(tbptr, copy);
1247 /* pop 0 push 0 branch */
1250 COUNT(count_pcmd_bra);
1251 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1253 iptr[0].target = (void *) tbptr;
1255 MARKREACHED(tbptr, copy);
1257 superblockend = true;
1260 /* pop 1 push 0 table branch */
1262 case ICMD_TABLESWITCH:
1263 COUNT(count_pcmd_table);
1265 s4ptr = iptr->val.a;
1266 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1267 MARKREACHED(tbptr, copy);
1268 i = *s4ptr++; /* low */
1269 i = *s4ptr++ - i + 1; /* high */
1271 tptr = DMNEW(void*, i+1);
1272 iptr->target = (void *) tptr;
1274 tptr[0] = (void *) tbptr;
1278 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1280 tptr[0] = (void *) tbptr;
1283 MARKREACHED(tbptr, copy);
1286 superblockend = true;
1289 /* pop 1 push 0 table branch */
1291 case ICMD_LOOKUPSWITCH:
1292 COUNT(count_pcmd_table);
1294 s4ptr = iptr->val.a;
1295 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1296 MARKREACHED(tbptr, copy);
1297 i = *s4ptr++; /* count */
1299 tptr = DMNEW(void*, i+1);
1300 iptr->target = (void *) tptr;
1302 tptr[0] = (void *) tbptr;
1306 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1308 tptr[0] = (void *) tbptr;
1311 MARKREACHED(tbptr, copy);
1315 superblockend = true;
1318 case ICMD_MONITORENTER:
1319 COUNT(count_check_null);
1320 case ICMD_MONITOREXIT:
1324 /* pop 2 push 0 branch */
1326 case ICMD_IF_ICMPEQ:
1327 case ICMD_IF_ICMPNE:
1328 case ICMD_IF_ICMPLT:
1329 case ICMD_IF_ICMPGE:
1330 case ICMD_IF_ICMPGT:
1331 case ICMD_IF_ICMPLE:
1332 COUNT(count_pcmd_bra);
1334 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1336 iptr[0].target = (void *) tbptr;
1338 MARKREACHED(tbptr, copy);
1341 case ICMD_IF_ACMPEQ:
1342 case ICMD_IF_ACMPNE:
1343 COUNT(count_pcmd_bra);
1345 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1347 iptr[0].target = (void *) tbptr;
1349 MARKREACHED(tbptr, copy);
1355 COUNT(count_check_null);
1356 COUNT(count_pcmd_mem);
1357 OPTT2_0(iptr->op1,TYPE_ADR);
1362 if (!IS_2_WORD_TYPE(curstack->type)) {
1364 #ifdef TYPECHECK_STACK_COMPCAT
1367 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1368 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1373 OP1_0ANY; /* second pop */
1376 iptr->opc = ICMD_POP;
1380 /* pop 0 push 1 dup */
1383 #ifdef TYPECHECK_STACK_COMPCAT
1386 if (IS_2_WORD_TYPE(curstack->type)) {
1387 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1392 COUNT(count_dup_instruction);
1398 if (IS_2_WORD_TYPE(curstack->type)) {
1400 iptr->opc = ICMD_DUP;
1405 /* ..., ????, cat1 */
1406 #ifdef TYPECHECK_STACK_COMPCAT
1408 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1409 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1415 NEWSTACK(copy->prev->type, copy->prev->varkind,
1416 copy->prev->varnum);
1417 NEWSTACK(copy->type, copy->varkind,
1424 /* pop 2 push 3 dup */
1427 #ifdef TYPECHECK_STACK_COMPCAT
1430 if (IS_2_WORD_TYPE(curstack->type) ||
1431 IS_2_WORD_TYPE(curstack->prev->type)) {
1432 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1442 if (IS_2_WORD_TYPE(curstack->type)) {
1443 /* ..., ????, cat2 */
1444 #ifdef TYPECHECK_STACK_COMPCAT
1446 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1447 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1452 iptr->opc = ICMD_DUP_X1;
1456 /* ..., ????, cat1 */
1457 #ifdef TYPECHECK_STACK_COMPCAT
1460 if (IS_2_WORD_TYPE(curstack->prev->type)
1461 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1462 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1471 /* pop 3 push 4 dup */
1475 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1476 /* ..., cat2, ???? */
1477 #ifdef TYPECHECK_STACK_COMPCAT
1479 if (IS_2_WORD_TYPE(curstack->type)) {
1480 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1485 iptr->opc = ICMD_DUP_X1;
1489 /* ..., cat1, ???? */
1490 #ifdef TYPECHECK_STACK_COMPCAT
1493 if (IS_2_WORD_TYPE(curstack->type)
1494 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1495 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1506 if (IS_2_WORD_TYPE(curstack->type)) {
1507 /* ..., ????, cat2 */
1508 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1509 /* ..., cat2, cat2 */
1510 iptr->opc = ICMD_DUP_X1;
1514 /* ..., cat1, cat2 */
1515 #ifdef TYPECHECK_STACK_COMPCAT
1518 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1519 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1524 iptr->opc = ICMD_DUP_X2;
1530 /* ..., ????, ????, cat1 */
1531 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1532 /* ..., cat2, ????, cat1 */
1533 #ifdef TYPECHECK_STACK_COMPCAT
1535 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1536 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1541 iptr->opc = ICMD_DUP2_X1;
1545 /* ..., cat1, ????, cat1 */
1546 #ifdef TYPECHECK_STACK_COMPCAT
1549 if (IS_2_WORD_TYPE(curstack->prev->type)
1550 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1551 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1561 /* pop 2 push 2 swap */
1564 #ifdef TYPECHECK_STACK_COMPCAT
1567 if (IS_2_WORD_TYPE(curstack->type)
1568 || IS_2_WORD_TYPE(curstack->prev->type)) {
1569 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1580 #if !SUPPORT_DIVISION
1581 bte = builtintable_get_internal(BUILTIN_idiv);
1582 iptr->opc = ICMD_BUILTIN;
1583 iptr->op1 = bte->md->paramcount;
1585 m->isleafmethod = false;
1590 #if !SUPPORT_DIVISION
1591 bte = builtintable_get_internal(BUILTIN_irem);
1592 iptr->opc = ICMD_BUILTIN;
1593 iptr->op1 = bte->md->paramcount;
1595 m->isleafmethod = false;
1608 COUNT(count_pcmd_op);
1613 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1614 bte = builtintable_get_internal(BUILTIN_ldiv);
1615 iptr->opc = ICMD_BUILTIN;
1616 iptr->op1 = bte->md->paramcount;
1618 m->isleafmethod = false;
1623 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1624 bte = builtintable_get_internal(BUILTIN_lrem);
1625 iptr->opc = ICMD_BUILTIN;
1626 iptr->op1 = bte->md->paramcount;
1628 m->isleafmethod = false;
1635 #if SUPPORT_LONG_LOGICAL
1639 #endif /* SUPPORT_LONG_LOGICAL */
1640 COUNT(count_pcmd_op);
1647 COUNT(count_pcmd_op);
1656 COUNT(count_pcmd_op);
1665 COUNT(count_pcmd_op);
1670 COUNT(count_pcmd_op);
1671 #if !defined(NOLONG_CONDITIONAL)
1672 if ((len > 0) && (iptr[1].val.i == 0)) {
1673 switch (iptr[1].opc) {
1675 iptr[0].opc = ICMD_IF_LCMPEQ;
1677 iptr[0].op1 = iptr[1].op1;
1680 /* iptr[1].opc = ICMD_NOP; */
1682 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1684 iptr[0].target = (void *) tbptr;
1686 MARKREACHED(tbptr, copy);
1687 COUNT(count_pcmd_bra);
1690 iptr[0].opc = ICMD_IF_LCMPNE;
1691 goto icmd_lcmp_if_tail;
1693 iptr[0].opc = ICMD_IF_LCMPLT;
1694 goto icmd_lcmp_if_tail;
1696 iptr[0].opc = ICMD_IF_LCMPGT;
1697 goto icmd_lcmp_if_tail;
1699 iptr[0].opc = ICMD_IF_LCMPLE;
1700 goto icmd_lcmp_if_tail;
1702 iptr[0].opc = ICMD_IF_LCMPGE;
1703 goto icmd_lcmp_if_tail;
1705 OPTT2_1(TYPE_LNG, TYPE_INT);
1710 OPTT2_1(TYPE_LNG, TYPE_INT);
1714 COUNT(count_pcmd_op);
1715 OPTT2_1(TYPE_FLT, TYPE_INT);
1719 COUNT(count_pcmd_op);
1720 OPTT2_1(TYPE_DBL, TYPE_INT);
1728 case ICMD_INT2SHORT:
1729 COUNT(count_pcmd_op);
1730 OP1_1(TYPE_INT, TYPE_INT);
1733 COUNT(count_pcmd_op);
1734 OP1_1(TYPE_LNG, TYPE_LNG);
1737 COUNT(count_pcmd_op);
1738 OP1_1(TYPE_FLT, TYPE_FLT);
1741 COUNT(count_pcmd_op);
1742 OP1_1(TYPE_DBL, TYPE_DBL);
1746 COUNT(count_pcmd_op);
1747 OP1_1(TYPE_INT, TYPE_LNG);
1750 COUNT(count_pcmd_op);
1751 OP1_1(TYPE_INT, TYPE_FLT);
1754 COUNT(count_pcmd_op);
1755 OP1_1(TYPE_INT, TYPE_DBL);
1758 COUNT(count_pcmd_op);
1759 OP1_1(TYPE_LNG, TYPE_INT);
1762 COUNT(count_pcmd_op);
1763 OP1_1(TYPE_LNG, TYPE_FLT);
1766 COUNT(count_pcmd_op);
1767 OP1_1(TYPE_LNG, TYPE_DBL);
1770 COUNT(count_pcmd_op);
1771 OP1_1(TYPE_FLT, TYPE_INT);
1774 COUNT(count_pcmd_op);
1775 OP1_1(TYPE_FLT, TYPE_LNG);
1778 COUNT(count_pcmd_op);
1779 OP1_1(TYPE_FLT, TYPE_DBL);
1782 COUNT(count_pcmd_op);
1783 OP1_1(TYPE_DBL, TYPE_INT);
1786 COUNT(count_pcmd_op);
1787 OP1_1(TYPE_DBL, TYPE_LNG);
1790 COUNT(count_pcmd_op);
1791 OP1_1(TYPE_DBL, TYPE_FLT);
1794 case ICMD_CHECKCAST:
1795 OP1_1(TYPE_ADR, TYPE_ADR);
1798 case ICMD_INSTANCEOF:
1799 case ICMD_ARRAYLENGTH:
1800 OP1_1(TYPE_ADR, TYPE_INT);
1804 case ICMD_ANEWARRAY:
1805 OP1_1(TYPE_INT, TYPE_ADR);
1809 COUNT(count_check_null);
1810 COUNT(count_pcmd_mem);
1811 OP1_1(TYPE_ADR, iptr->op1);
1816 case ICMD_GETSTATIC:
1817 COUNT(count_pcmd_mem);
1827 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1829 iptr[0].target = (void *) tbptr;
1831 /* This is a dirty hack. The typechecker
1832 * needs it because the OP1_0ANY below
1833 * overwrites iptr->dst.
1835 iptr->val.a = (void *) iptr->dst;
1837 tbptr->type = BBTYPE_SBR;
1839 /* We need to check for overflow right here because
1840 * the pushed value is poped after MARKREACHED. */
1842 MARKREACHED(tbptr, copy);
1846 /* pop many push any */
1850 bte = (builtintable_entry *) iptr->val.a;
1854 case ICMD_INVOKESTATIC:
1855 case ICMD_INVOKESPECIAL:
1856 case ICMD_INVOKEVIRTUAL:
1857 case ICMD_INVOKEINTERFACE:
1858 COUNT(count_pcmd_met);
1860 md = um->methodref->parseddesc.md;
1861 /* if (lm->flags & ACC_STATIC) */
1862 /* {COUNT(count_check_null);} */
1866 if (md->memuse > rd->memuse)
1867 rd->memuse = md->memuse;
1868 if (md->argintreguse > rd->argintreguse)
1869 rd->argintreguse = md->argintreguse;
1870 if (md->argfltreguse > rd->argfltreguse)
1871 rd->argfltreguse = md->argfltreguse;
1876 for (i-- ; i >= 0; i--) {
1877 if (!(copy->flags & SAVEDVAR)) {
1878 copy->varkind = ARGVAR;
1880 if (md->params[i].inmemory) {
1881 copy->flags = INMEMORY;
1882 copy->regoff = md->params[i].regoff;
1885 if (IS_FLT_DBL_TYPE(copy->type))
1887 rd->argfltregs[md->params[i].regoff];
1889 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1890 if (IS_2_WORD_TYPE(copy->type))
1891 copy->regoff = PACK_REGS(
1892 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
1893 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
1897 rd->argintregs[md->params[i].regoff];
1905 copy->flags |= SAVEDVAR;
1911 if (md->returntype.type != TYPE_VOID)
1912 OP0_1(md->returntype.type);
1915 case ICMD_INLINE_START:
1916 case ICMD_INLINE_END:
1920 case ICMD_MULTIANEWARRAY:
1921 if (rd->argintreguse < 3)
1922 rd->argintreguse = 3;
1927 #if defined(SPECIALMEMUSE)
1928 # if defined(__DARWIN__)
1929 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
1930 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
1932 if (rd->memuse < (i + LA_WORD_SIZE + 3))
1933 rd->memuse = i + LA_WORD_SIZE + 3;
1936 # if defined(__I386__)
1937 if (rd->memuse < i + 3)
1938 rd->memuse = i + 3; /* n integer args spilled on stack */
1941 rd->memuse = i; /* n integer args spilled on stack */
1942 # endif /* defined(__I386__) */
1946 /* check INT type here? Currently typecheck does this. */
1947 if (!(copy->flags & SAVEDVAR)) {
1948 copy->varkind = ARGVAR;
1949 copy->varnum = i + INT_ARG_CNT;
1950 copy->flags |= INMEMORY;
1951 #if defined(SPECIALMEMUSE)
1952 # if defined(__DARWIN__)
1953 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
1955 copy->regoff = i + LA_WORD_SIZE + 3;
1958 # if defined(__I386__)
1959 copy->regoff = i + 3;
1962 # endif /* defined(__I386__) */
1963 #endif /* defined(SPECIALMEMUSE) */
1968 copy->flags |= SAVEDVAR;
1976 case ICMD_CLEAR_ARGREN:
1977 for (i = iptr->op1; i < cd->maxlocals; i++)
1979 iptr->opc = opcode = ICMD_NOP;
1983 case ICMD_READONLY_ARG:
1984 case ICMD_READONLY_ARG+1:
1985 case ICMD_READONLY_ARG+2:
1986 case ICMD_READONLY_ARG+3:
1987 case ICMD_READONLY_ARG+4:
1990 if (curstack->varkind == LOCALVAR) {
1991 i = curstack->varnum;
1992 argren[iptr->op1] = i;
1995 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2002 new_exception_message(string_java_lang_InternalError,
2009 } /* while instructions */
2011 bptr->outstack = curstack;
2012 bptr->outdepth = stackdepth;
2016 superblockend = true;
2018 } /* while blocks */
2019 } while (repeat && !deadcode);
2021 #if defined(STATISTICS)
2023 if (m->basicblockcount > count_max_basic_blocks)
2024 count_max_basic_blocks = m->basicblockcount;
2025 count_basic_blocks += m->basicblockcount;
2026 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2027 count_javainstr += m->instructioncount;
2028 if (m->stackcount > count_upper_bound_new_stack)
2029 count_upper_bound_new_stack = m->stackcount;
2030 if ((new - m->stack) > count_max_new_stack)
2031 count_max_new_stack = (new - m->stack);
2033 b_count = m->basicblockcount;
2034 bptr = m->basicblocks;
2035 while (--b_count >= 0) {
2036 if (bptr->flags > BBREACHED) {
2037 if (bptr->indepth >= 10)
2038 count_block_stack[10]++;
2040 count_block_stack[bptr->indepth]++;
2043 count_block_size_distribution[len]++;
2045 count_block_size_distribution[10]++;
2047 count_block_size_distribution[11]++;
2049 count_block_size_distribution[12]++;
2051 count_block_size_distribution[13]++;
2053 count_block_size_distribution[14]++;
2055 count_block_size_distribution[15]++;
2057 count_block_size_distribution[16]++;
2059 count_block_size_distribution[17]++;
2065 count_analyse_iterations[0]++;
2066 else if (loops == 2)
2067 count_analyse_iterations[1]++;
2068 else if (loops == 3)
2069 count_analyse_iterations[2]++;
2070 else if (loops == 4)
2071 count_analyse_iterations[3]++;
2073 count_analyse_iterations[4]++;
2075 if (m->basicblockcount <= 5)
2076 count_method_bb_distribution[0]++;
2077 else if (m->basicblockcount <= 10)
2078 count_method_bb_distribution[1]++;
2079 else if (m->basicblockcount <= 15)
2080 count_method_bb_distribution[2]++;
2081 else if (m->basicblockcount <= 20)
2082 count_method_bb_distribution[3]++;
2083 else if (m->basicblockcount <= 30)
2084 count_method_bb_distribution[4]++;
2085 else if (m->basicblockcount <= 40)
2086 count_method_bb_distribution[5]++;
2087 else if (m->basicblockcount <= 50)
2088 count_method_bb_distribution[6]++;
2089 else if (m->basicblockcount <= 75)
2090 count_method_bb_distribution[7]++;
2092 count_method_bb_distribution[8]++;
2096 /* just return methodinfo* to signal everything was ok */
2102 /**********************************************************************/
2103 /* DEBUGGING HELPERS */
2104 /**********************************************************************/
2106 void icmd_print_stack(codegendata *cd, stackptr s)
2118 j = cd->maxstack - i;
2123 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2124 if (s->flags & SAVEDVAR)
2125 switch (s->varkind) {
2127 if (s->flags & INMEMORY)
2128 printf(" M%02d", s->regoff);
2129 #ifdef HAS_ADDRESS_REGISTER_FILE
2130 else if (s->type == TYPE_ADR)
2131 printf(" R%02d", s->regoff);
2133 else if (IS_FLT_DBL_TYPE(s->type))
2134 printf(" F%02d", s->regoff);
2136 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2137 if (IS_2_WORD_TYPE(s->type))
2138 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2139 regs[GET_HIGH_REG(s->regoff)]);
2142 printf(" %3s", regs[s->regoff]);
2146 printf(" I%02d", s->varnum);
2149 printf(" L%02d", s->varnum);
2152 printf(" A%02d", s->varnum);
2153 #ifdef INVOKE_NEW_DEBUG
2154 if (s->flags & INMEMORY)
2155 printf("(M%i)", s->regoff);
2157 printf("(R%i)", s->regoff);
2161 printf(" !%02d", j);
2164 switch (s->varkind) {
2166 if (s->flags & INMEMORY)
2167 printf(" m%02d", s->regoff);
2168 #ifdef HAS_ADDRESS_REGISTER_FILE
2169 else if (s->type == TYPE_ADR)
2170 printf(" r%02d", s->regoff);
2172 else if (IS_FLT_DBL_TYPE(s->type))
2173 printf(" f%02d", s->regoff);
2175 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2176 if (IS_2_WORD_TYPE(s->type))
2177 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2178 regs[GET_HIGH_REG(s->regoff)]);
2181 printf(" %3s", regs[s->regoff]);
2185 printf(" i%02d", s->varnum);
2188 printf(" l%02d", s->varnum);
2191 printf(" a%02d", s->varnum);
2192 #ifdef INVOKE_NEW_DEBUG
2193 if (s->flags & INMEMORY)
2194 printf("(M%i)", s->regoff);
2196 printf("(R%i)", s->regoff);
2200 printf(" ?%02d", j);
2208 static void print_reg(stackptr s) {
2210 if (s->flags & SAVEDVAR)
2211 switch (s->varkind) {
2213 if (s->flags & INMEMORY)
2214 printf(" tm%02d", s->regoff);
2216 printf(" tr%02d", s->regoff);
2219 printf(" s %02d", s->varnum);
2222 printf(" l %02d", s->varnum);
2225 printf(" a %02d", s->varnum);
2228 printf(" ! %02d", s->varnum);
2231 switch (s->varkind) {
2233 if (s->flags & INMEMORY)
2234 printf(" Tm%02d", s->regoff);
2236 printf(" Tr%02d", s->regoff);
2239 printf(" S %02d", s->varnum);
2242 printf(" L %02d", s->varnum);
2245 printf(" A %02d", s->varnum);
2248 printf(" ? %02d", s->varnum);
2258 static char *jit_type[] = {
2267 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2274 utf_fprint_classname(stdout, m->class->name);
2276 utf_fprint(stdout, m->name);
2277 utf_fprint(stdout, m->descriptor);
2278 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2279 printf("Max stack: %d\n", (int) cd->maxstack);
2281 printf("Line number table length: %d\n", m->linenumbercount);
2283 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2284 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2285 printf(" L%03d ... ", ex->start->debug_nr );
2286 printf("L%03d = ", ex->end->debug_nr);
2287 printf("L%03d", ex->handler->debug_nr);
2288 printf(" (catchtype: ");
2289 if (ex->catchtype.any)
2290 if (IS_CLASSREF(ex->catchtype))
2291 utf_display_classname(ex->catchtype.ref->name);
2293 utf_display_classname(ex->catchtype.cls->name);
2299 printf("Local Table:\n");
2300 for (i = 0; i < cd->maxlocals; i++) {
2301 printf(" %3d: ", i);
2302 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2303 if (rd->locals[i][j].type >= 0) {
2304 printf(" (%s) ", jit_type[j]);
2305 if (rd->locals[i][j].flags & INMEMORY)
2306 printf("m%2d", rd->locals[i][j].regoff);
2307 #ifdef HAS_ADDRESS_REGISTER_FILE
2308 else if (j == TYPE_ADR)
2309 printf("r%02d", rd->locals[i][j].regoff);
2311 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2312 printf("f%02d", rd->locals[i][j].regoff);
2314 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2315 if (IS_2_WORD_TYPE(j))
2317 regs[GET_LOW_REG(rd->locals[i][j].regoff)],
2318 regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
2321 printf("%3s", regs[rd->locals[i][j].regoff]);
2330 printf("Interface Table:\n");
2331 for (i = 0; i < cd->maxstack; i++) {
2332 if ((rd->interfaces[i][0].type >= 0) ||
2333 (rd->interfaces[i][1].type >= 0) ||
2334 (rd->interfaces[i][2].type >= 0) ||
2335 (rd->interfaces[i][3].type >= 0) ||
2336 (rd->interfaces[i][4].type >= 0)) {
2337 printf(" %3d: ", i);
2338 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2339 if (rd->interfaces[i][j].type >= 0) {
2340 printf(" (%s) ", jit_type[j]);
2341 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2342 if (rd->interfaces[i][j].flags & INMEMORY)
2343 printf("M%2d", rd->interfaces[i][j].regoff);
2344 #ifdef HAS_ADDRESS_REGISTER_FILE
2345 else if (j == TYPE_ADR)
2346 printf("R%02d", rd->interfaces[i][j].regoff);
2348 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2349 printf("F%02d", rd->interfaces[i][j].regoff);
2351 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2352 if (IS_2_WORD_TYPE(j))
2354 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2355 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2358 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2362 if (rd->interfaces[i][j].flags & INMEMORY)
2363 printf("m%2d", rd->interfaces[i][j].regoff);
2364 #ifdef HAS_ADDRESS_REGISTER_FILE
2365 else if (j == TYPE_ADR)
2366 printf("r%02d", rd->interfaces[i][j].regoff);
2368 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2369 printf("f%02d", rd->interfaces[i][j].regoff);
2371 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2372 if (IS_2_WORD_TYPE(j))
2374 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2375 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2378 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2389 if (showdisassemble) {
2390 #if defined(__I386__) || defined(__X86_64__)
2394 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2395 for (i = 0; i < m->basicblocks[0].mpc;) {
2396 a = disassinstr(u1ptr);
2401 #elif defined(__XDSPCORE__)
2405 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2406 for (i = 0; i < m->basicblocks[0].mpc;) {
2407 a = disassinstr(stdout, s4ptr);
2416 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2417 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2424 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2425 show_icmd_block(m, cd, bptr);
2430 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2436 if (bptr->flags != BBDELETED) {
2437 deadcode = bptr->flags <= BBREACHED;
2440 for (j = cd->maxstack; j > 0; j--)
2443 icmd_print_stack(cd, bptr->instack);
2444 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2445 iptr = bptr->iinstr;
2447 for (i = 0; i < bptr->icount; i++, iptr++) {
2450 for (j = cd->maxstack; j > 0; j--)
2454 icmd_print_stack(cd, iptr->dst);
2455 printf("] %4d ", i);
2458 if (icmd_uses_tmp[iptr->opc][0])
2462 if (icmd_uses_tmp[iptr->opc][1])
2466 if (icmd_uses_tmp[iptr->opc][2])
2472 show_icmd(iptr, deadcode);
2476 if (showdisassemble && (!deadcode)) {
2477 #if defined(__I386__) || defined(__X86_64__)
2483 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2485 if (bptr->next != NULL) {
2486 for (; i < bptr->next->mpc; ) {
2487 a = disassinstr(u1ptr);
2494 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2495 a = disassinstr(u1ptr);
2501 #elif defined(__XDSPCORE__)
2507 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2509 if (bptr->next != NULL) {
2510 for (; i < bptr->next->mpc;) {
2511 a = disassinstr(stdout, s4ptr);
2519 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2520 a = disassinstr(stdout, s4ptr);
2531 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2533 if (bptr->next != NULL) {
2534 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2539 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2549 void show_icmd(instruction *iptr, bool deadcode)
2555 printf("%s", icmd_names[iptr->opc]);
2557 switch (iptr->opc) {
2558 case ICMD_IADDCONST:
2559 case ICMD_ISUBCONST:
2560 case ICMD_IMULCONST:
2564 case ICMD_IANDCONST:
2566 case ICMD_IXORCONST:
2567 case ICMD_ISHLCONST:
2568 case ICMD_ISHRCONST:
2569 case ICMD_IUSHRCONST:
2570 case ICMD_LSHLCONST:
2571 case ICMD_LSHRCONST:
2572 case ICMD_LUSHRCONST:
2574 case ICMD_ELSE_ICONST:
2575 case ICMD_IASTORECONST:
2576 case ICMD_BASTORECONST:
2577 case ICMD_CASTORECONST:
2578 case ICMD_SASTORECONST:
2579 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2582 case ICMD_IFEQ_ICONST:
2583 case ICMD_IFNE_ICONST:
2584 case ICMD_IFLT_ICONST:
2585 case ICMD_IFGE_ICONST:
2586 case ICMD_IFGT_ICONST:
2587 case ICMD_IFLE_ICONST:
2588 printf("(%d) %d", iptr[1].op1, iptr->val.i);
2591 case ICMD_LADDCONST:
2592 case ICMD_LSUBCONST:
2593 case ICMD_LMULCONST:
2597 case ICMD_LANDCONST:
2599 case ICMD_LXORCONST:
2601 case ICMD_LASTORECONST:
2602 #if SIZEOF_VOID_P == 4
2603 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
2605 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
2610 printf(" %f (0x%08x)", iptr->val.f, iptr->val.i);
2614 #if SIZEOF_VOID_P == 4
2615 printf(" %g (0x%016llx)", iptr->val.d, iptr->val.l);
2617 printf(" %g (0x%016lx)", iptr->val.d, iptr->val.l);
2622 case ICMD_AASTORECONST:
2623 printf(" %p", iptr->val.a);
2629 printf(" %d, ", ((fieldinfo *) iptr->val.a)->offset);
2631 printf(" (NOT RESOLVED), ");
2632 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2634 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2636 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2640 case ICMD_PUTSTATIC:
2641 case ICMD_GETSTATIC:
2643 if (!((fieldinfo *) iptr->val.a)->class->initialized)
2644 printf(" (NOT INITIALIZED) ");
2648 printf(" (NOT RESOLVED) ");
2649 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2651 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2653 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2657 case ICMD_PUTSTATICCONST:
2658 case ICMD_PUTFIELDCONST:
2659 switch (iptr[1].op1) {
2661 printf(" %d,", iptr->val.i);
2664 #if SIZEOF_VOID_P == 4
2665 printf(" %lld,", iptr->val.l);
2667 printf(" %ld,", iptr->val.l);
2671 printf(" %p,", iptr->val.a);
2674 printf(" %g,", iptr->val.f);
2677 printf(" %g,", iptr->val.d);
2680 if (iptr->opc == ICMD_PUTFIELDCONST)
2681 printf(" NOT RESOLVED,");
2683 utf_display_classname(((unresolved_field *) iptr[1].target)->fieldref->classref->name);
2685 utf_display(((unresolved_field *) iptr[1].target)->fieldref->name);
2687 utf_display(((unresolved_field *) iptr[1].target)->fieldref->descriptor);
2692 printf(" %d + %d", iptr->op1, iptr->val.i);
2727 printf(" %d", iptr->op1);
2732 utf_display_classname(((classinfo *) iptr->val.a)->name);
2736 switch (iptr->op1) {
2764 case ICMD_ANEWARRAY:
2767 utf_display_classname(((classinfo *) iptr->val.a)->name);
2771 case ICMD_MULTIANEWARRAY:
2773 printf(" (NOT RESOLVED) %d ",iptr->op1);
2774 utf_display(((constant_classref *) iptr->val.a)->name);
2776 printf(" %d ",iptr->op1);
2777 utf_display_classname(((vftbl_t *) iptr->val.a)->class->name);
2781 case ICMD_CHECKCAST:
2782 case ICMD_INSTANCEOF:
2784 classinfo *c = iptr->val.a;
2786 if (c->flags & ACC_INTERFACE)
2787 printf(" (INTERFACE) ");
2789 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2791 printf(" (NOT RESOLVED) ");
2793 utf_display_classname(((constant_classref *) iptr->target)->name);
2797 case ICMD_INLINE_START:
2798 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2800 case ICMD_INLINE_END:
2804 printf(" %s", ((builtintable_entry *) iptr->val.a)->name);
2807 case ICMD_INVOKEVIRTUAL:
2808 case ICMD_INVOKESPECIAL:
2809 case ICMD_INVOKESTATIC:
2810 case ICMD_INVOKEINTERFACE:
2812 printf(" (NOT RESOLVED) ");
2815 utf_display_classname(((unresolved_method *) iptr->target)->methodref->classref->name);
2817 utf_display(((unresolved_method *) iptr->target)->methodref->name);
2818 utf_display(((unresolved_method *) iptr->target)->methodref->descriptor);
2827 if (deadcode || !iptr->target)
2828 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2830 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2839 if (deadcode || !iptr->target)
2840 #if SIZEOF_VOID_P == 4
2841 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2843 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2846 #if SIZEOF_VOID_P == 4
2847 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2849 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2856 case ICMD_IFNONNULL:
2857 case ICMD_IF_ICMPEQ:
2858 case ICMD_IF_ICMPNE:
2859 case ICMD_IF_ICMPLT:
2860 case ICMD_IF_ICMPGE:
2861 case ICMD_IF_ICMPGT:
2862 case ICMD_IF_ICMPLE:
2863 case ICMD_IF_LCMPEQ:
2864 case ICMD_IF_LCMPNE:
2865 case ICMD_IF_LCMPLT:
2866 case ICMD_IF_LCMPGE:
2867 case ICMD_IF_LCMPGT:
2868 case ICMD_IF_LCMPLE:
2869 case ICMD_IF_ACMPEQ:
2870 case ICMD_IF_ACMPNE:
2871 if (deadcode || !iptr->target)
2872 printf(" op1=%d", iptr->op1);
2874 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2877 case ICMD_TABLESWITCH:
2878 s4ptr = (s4*)iptr->val.a;
2880 if (deadcode || !iptr->target) {
2881 printf(" %d;", *s4ptr);
2884 tptr = (void **) iptr->target;
2885 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2889 s4ptr++; /* skip default */
2890 j = *s4ptr++; /* low */
2891 j = *s4ptr++ - j; /* high */
2893 if (deadcode || !*tptr)
2894 printf(" %d", *s4ptr++);
2896 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2903 case ICMD_LOOKUPSWITCH:
2904 s4ptr = (s4*)iptr->val.a;
2906 if (deadcode || !iptr->target) {
2907 printf(" %d;", *s4ptr);
2910 tptr = (void **) iptr->target;
2911 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2914 s4ptr++; /* default */
2915 j = *s4ptr++; /* count */
2918 if (deadcode || !*tptr) {
2919 s4ptr++; /* skip value */
2920 printf(" %d",*s4ptr++);
2923 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2929 printf(" Line number: %d, method:",iptr->line);
2931 utf_display(iptr->method->class->name);
2933 utf_display(iptr->method->name); */
2938 * These are local overrides for various environment variables in Emacs.
2939 * Please do not remove this and leave it at the end of the file, where
2940 * Emacs will automagically detect them.
2941 * ---------------------------------------------------------------------
2944 * indent-tabs-mode: t