1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
32 $Id: stack.c 2297 2005-04-13 12:50:07Z christian $
43 #include "mm/memory.h"
44 #include "native/native.h"
45 #include "toolbox/logging.h"
46 #include "vm/global.h"
47 #include "vm/builtin.h"
48 #include "vm/options.h"
49 #include "vm/statistics.h"
50 #include "vm/tables.h"
51 #include "vm/jit/codegen.inc.h"
52 #include "vm/jit/jit.h"
53 #include "vm/jit/reg.h"
54 #include "vm/jit/stack.h"
55 #include "vm/jit/lsra.h"
58 /**********************************************************************/
60 /**********************************************************************/
62 /* analyse_stack uses the intermediate code created by parse.c to
63 * build a model of the JVM operand stack for the current method.
65 * The following checks are performed:
66 * - check for operand stack underflow (before each instruction)
67 * - check for operand stack overflow (after[1] each instruction)
68 * - check for matching stack depth at merging points
69 * - check for matching basic types[2] at merging points
70 * - check basic types for instruction input (except for BUILTIN*
71 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
73 * [1]) Checking this after the instruction should be ok. parse.c
74 * counts the number of required stack slots in such a way that it is
75 * only vital that we don't exceed `maxstack` at basic block
78 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
79 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
80 * types are not discerned.
83 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
91 int opcode, i, len, loops;
92 int superblockend, repeat, deadcode;
107 argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */
108 for (i = 0; i < cd->maxlocals; i++)
111 rd->arguments_num = 0;
114 m->basicblocks[0].flags = BBREACHED;
115 m->basicblocks[0].instack = 0;
116 m->basicblocks[0].indepth = 0;
118 for (i = 0; i < cd->exceptiontablelength; i++) {
119 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
120 bptr->flags = BBREACHED;
121 bptr->type = BBTYPE_EXH;
124 bptr->pre_count = 10000;
129 #ifdef CONDITIONAL_LOADCONST
130 b_count = m->basicblockcount;
131 bptr = m->basicblocks;
132 while (--b_count >= 0) {
133 if (bptr->icount != 0) {
134 iptr = bptr->iinstr + bptr->icount - 1;
167 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
170 case ICMD_TABLESWITCH:
172 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
173 i = *s4ptr++; /* low */
174 i = *s4ptr++ - i + 1; /* high */
176 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
180 case ICMD_LOOKUPSWITCH:
182 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
183 i = *s4ptr++; /* count */
185 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
201 b_count = m->basicblockcount;
202 bptr = m->basicblocks;
203 superblockend = true;
207 while (--b_count >= 0) {
208 if (bptr->flags == BBDELETED) {
211 else if (superblockend && (bptr->flags < BBREACHED))
213 else if (bptr->flags <= BBREACHED) {
215 stackdepth = bptr->indepth;
216 else if (bptr->flags < BBREACHED) {
218 bptr->instack = copy;
219 bptr->indepth = stackdepth;
221 else if (bptr->indepth != stackdepth) {
222 show_icmd_method(m, cd, rd);
223 printf("Block: %d, required depth: %d, current depth: %d\n", bptr->debug_nr, bptr->indepth, stackdepth);
224 panic("Stack depth mismatch");
227 curstack = bptr->instack;
229 superblockend = false;
230 bptr->flags = BBFINISHED;
233 b_index = bptr - m->basicblocks;
238 /* dolog("p: %04d op: %s stack: %p", iptr - instr, icmd_names[opcode], curstack); */
240 #if defined(USEBUILTINTABLE)
243 stdopdescriptor *breplace;
244 breplace = find_builtin(opcode);
246 if (breplace && opcode == breplace->opcode) {
247 iptr[0].opc = breplace->icmd;
248 iptr[0].op1 = breplace->type_d;
249 iptr[0].val.fp = breplace->builtin;
250 m->isleafmethod = false;
251 switch (breplace->icmd) {
259 builtin_descriptor *breplace;
260 breplace = find_builtin(opcode);
262 if (breplace && opcode == breplace->opcode) {
263 iptr[0].opc = breplace->icmd;
264 iptr[0].op1 = breplace->type_d;
265 iptr[0].val.fp = breplace->builtin;
266 m->isleafmethod = false;
267 switch (breplace->icmd) {
275 #endif /* defined(USEBUILTINTABLE) */
282 case ICMD_CHECKASIZE:
283 case ICMD_CHECKEXCEPTION:
285 case ICMD_IFEQ_ICONST:
286 case ICMD_IFNE_ICONST:
287 case ICMD_IFLT_ICONST:
288 case ICMD_IFGE_ICONST:
289 case ICMD_IFGT_ICONST:
290 case ICMD_IFLE_ICONST:
291 case ICMD_ELSE_ICONST:
296 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
298 COUNT(count_pcmd_return);
300 superblockend = true;
303 /* pop 0 push 1 const */
306 COUNT(count_pcmd_load);
308 switch (iptr[1].opc) {
310 iptr[0].opc = ICMD_IADDCONST;
312 iptr[1].opc = ICMD_NOP;
313 OP1_1(TYPE_INT, TYPE_INT);
314 COUNT(count_pcmd_op);
317 iptr[0].opc = ICMD_ISUBCONST;
318 goto icmd_iconst_tail;
319 #if SUPPORT_CONST_MUL
321 iptr[0].opc = ICMD_IMULCONST;
322 goto icmd_iconst_tail;
323 #else /* SUPPORT_CONST_MUL */
325 if (iptr[0].val.i == 0x00000002)
327 else if (iptr[0].val.i == 0x00000004)
329 else if (iptr[0].val.i == 0x00000008)
331 else if (iptr[0].val.i == 0x00000010)
333 else if (iptr[0].val.i == 0x00000020)
335 else if (iptr[0].val.i == 0x00000040)
337 else if (iptr[0].val.i == 0x00000080)
339 else if (iptr[0].val.i == 0x00000100)
341 else if (iptr[0].val.i == 0x00000200)
343 else if (iptr[0].val.i == 0x00000400)
345 else if (iptr[0].val.i == 0x00000800)
347 else if (iptr[0].val.i == 0x00001000)
349 else if (iptr[0].val.i == 0x00002000)
351 else if (iptr[0].val.i == 0x00004000)
353 else if (iptr[0].val.i == 0x00008000)
355 else if (iptr[0].val.i == 0x00010000)
357 else if (iptr[0].val.i == 0x00020000)
359 else if (iptr[0].val.i == 0x00040000)
361 else if (iptr[0].val.i == 0x00080000)
363 else if (iptr[0].val.i == 0x00100000)
365 else if (iptr[0].val.i == 0x00200000)
367 else if (iptr[0].val.i == 0x00400000)
369 else if (iptr[0].val.i == 0x00800000)
371 else if (iptr[0].val.i == 0x01000000)
373 else if (iptr[0].val.i == 0x02000000)
375 else if (iptr[0].val.i == 0x04000000)
377 else if (iptr[0].val.i == 0x08000000)
379 else if (iptr[0].val.i == 0x10000000)
381 else if (iptr[0].val.i == 0x20000000)
383 else if (iptr[0].val.i == 0x40000000)
385 else if (iptr[0].val.i == 0x80000000)
391 iptr[0].opc = ICMD_IMULPOW2;
392 goto icmd_iconst_tail;
393 #endif /* SUPPORT_CONST_MUL */
395 if (iptr[0].val.i == 0x00000002)
397 else if (iptr[0].val.i == 0x00000004)
399 else if (iptr[0].val.i == 0x00000008)
401 else if (iptr[0].val.i == 0x00000010)
403 else if (iptr[0].val.i == 0x00000020)
405 else if (iptr[0].val.i == 0x00000040)
407 else if (iptr[0].val.i == 0x00000080)
409 else if (iptr[0].val.i == 0x00000100)
411 else if (iptr[0].val.i == 0x00000200)
413 else if (iptr[0].val.i == 0x00000400)
415 else if (iptr[0].val.i == 0x00000800)
417 else if (iptr[0].val.i == 0x00001000)
419 else if (iptr[0].val.i == 0x00002000)
421 else if (iptr[0].val.i == 0x00004000)
423 else if (iptr[0].val.i == 0x00008000)
425 else if (iptr[0].val.i == 0x00010000)
427 else if (iptr[0].val.i == 0x00020000)
429 else if (iptr[0].val.i == 0x00040000)
431 else if (iptr[0].val.i == 0x00080000)
433 else if (iptr[0].val.i == 0x00100000)
435 else if (iptr[0].val.i == 0x00200000)
437 else if (iptr[0].val.i == 0x00400000)
439 else if (iptr[0].val.i == 0x00800000)
441 else if (iptr[0].val.i == 0x01000000)
443 else if (iptr[0].val.i == 0x02000000)
445 else if (iptr[0].val.i == 0x04000000)
447 else if (iptr[0].val.i == 0x08000000)
449 else if (iptr[0].val.i == 0x10000000)
451 else if (iptr[0].val.i == 0x20000000)
453 else if (iptr[0].val.i == 0x40000000)
455 else if (iptr[0].val.i == 0x80000000)
461 iptr[0].opc = ICMD_IDIVPOW2;
462 goto icmd_iconst_tail;
464 if ((iptr[0].val.i == 0x00000002) ||
465 (iptr[0].val.i == 0x00000004) ||
466 (iptr[0].val.i == 0x00000008) ||
467 (iptr[0].val.i == 0x00000010) ||
468 (iptr[0].val.i == 0x00000020) ||
469 (iptr[0].val.i == 0x00000040) ||
470 (iptr[0].val.i == 0x00000080) ||
471 (iptr[0].val.i == 0x00000100) ||
472 (iptr[0].val.i == 0x00000200) ||
473 (iptr[0].val.i == 0x00000400) ||
474 (iptr[0].val.i == 0x00000800) ||
475 (iptr[0].val.i == 0x00001000) ||
476 (iptr[0].val.i == 0x00002000) ||
477 (iptr[0].val.i == 0x00004000) ||
478 (iptr[0].val.i == 0x00008000) ||
479 (iptr[0].val.i == 0x00010000) ||
480 (iptr[0].val.i == 0x00020000) ||
481 (iptr[0].val.i == 0x00040000) ||
482 (iptr[0].val.i == 0x00080000) ||
483 (iptr[0].val.i == 0x00100000) ||
484 (iptr[0].val.i == 0x00200000) ||
485 (iptr[0].val.i == 0x00400000) ||
486 (iptr[0].val.i == 0x00800000) ||
487 (iptr[0].val.i == 0x01000000) ||
488 (iptr[0].val.i == 0x02000000) ||
489 (iptr[0].val.i == 0x04000000) ||
490 (iptr[0].val.i == 0x08000000) ||
491 (iptr[0].val.i == 0x10000000) ||
492 (iptr[0].val.i == 0x20000000) ||
493 (iptr[0].val.i == 0x40000000) ||
494 (iptr[0].val.i == 0x80000000)) {
495 iptr[0].opc = ICMD_IREMPOW2;
497 goto icmd_iconst_tail;
501 #if SUPPORT_CONST_LOGICAL
503 iptr[0].opc = ICMD_IANDCONST;
504 goto icmd_iconst_tail;
506 iptr[0].opc = ICMD_IORCONST;
507 goto icmd_iconst_tail;
509 iptr[0].opc = ICMD_IXORCONST;
510 goto icmd_iconst_tail;
511 #endif /* SUPPORT_CONST_LOGICAL */
513 iptr[0].opc = ICMD_ISHLCONST;
514 goto icmd_iconst_tail;
516 iptr[0].opc = ICMD_ISHRCONST;
517 goto icmd_iconst_tail;
519 iptr[0].opc = ICMD_IUSHRCONST;
520 goto icmd_iconst_tail;
521 #if SUPPORT_LONG_SHIFT
523 iptr[0].opc = ICMD_LSHLCONST;
524 goto icmd_lconst_tail;
526 iptr[0].opc = ICMD_LSHRCONST;
527 goto icmd_lconst_tail;
529 iptr[0].opc = ICMD_LUSHRCONST;
530 goto icmd_lconst_tail;
531 #endif /* SUPPORT_LONG_SHIFT */
533 iptr[0].opc = ICMD_IFEQ;
535 iptr[0].op1 = iptr[1].op1;
538 /* iptr[1].opc = ICMD_NOP; */
540 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
542 iptr[0].target = (void *) tbptr;
544 MARKREACHED(tbptr, copy);
545 COUNT(count_pcmd_bra);
548 iptr[0].opc = ICMD_IFLT;
549 goto icmd_if_icmp_tail;
551 iptr[0].opc = ICMD_IFLE;
552 goto icmd_if_icmp_tail;
554 iptr[0].opc = ICMD_IFNE;
555 goto icmd_if_icmp_tail;
557 iptr[0].opc = ICMD_IFGT;
558 goto icmd_if_icmp_tail;
560 iptr[0].opc = ICMD_IFGE;
561 goto icmd_if_icmp_tail;
563 #if SUPPORT_CONST_STORE
568 #if SUPPORT_CONST_STORE_ZERO_ONLY
569 if (iptr[0].val.i == 0) {
570 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
571 switch (iptr[1].opc) {
573 iptr[0].opc = ICMD_IASTORECONST;
576 iptr[0].opc = ICMD_BASTORECONST;
579 iptr[0].opc = ICMD_CASTORECONST;
582 iptr[0].opc = ICMD_SASTORECONST;
586 iptr[1].opc = ICMD_NOP;
587 OPTT2_0(TYPE_INT, TYPE_ADR);
588 COUNT(count_pcmd_op);
589 #if SUPPORT_CONST_STORE_ZERO_ONLY
592 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
597 #if SUPPORT_CONST_STORE_ZERO_ONLY
598 if (iptr[0].val.i == 0) {
599 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
600 switch (iptr[1].opc) {
602 iptr[0].opc = ICMD_PUTSTATICCONST;
606 iptr[0].opc = ICMD_PUTFIELDCONST;
611 iptr[1].opc = ICMD_NOP;
612 iptr[0].op1 = TYPE_INT;
613 COUNT(count_pcmd_op);
614 #if SUPPORT_CONST_STORE_ZERO_ONLY
617 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
619 #endif /* SUPPORT_CONST_STORE */
629 COUNT(count_pcmd_load);
631 switch (iptr[1].opc) {
634 iptr[0].opc = ICMD_LADDCONST;
636 iptr[1].opc = ICMD_NOP;
637 OP1_1(TYPE_LNG,TYPE_LNG);
638 COUNT(count_pcmd_op);
641 iptr[0].opc = ICMD_LSUBCONST;
642 goto icmd_lconst_tail;
643 #endif /* SUPPORT_LONG_ADD */
644 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
646 iptr[0].opc = ICMD_LMULCONST;
647 goto icmd_lconst_tail;
648 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
649 # if SUPPORT_LONG_SHIFT
651 if (iptr[0].val.l == 0x00000002)
653 else if (iptr[0].val.l == 0x00000004)
655 else if (iptr[0].val.l == 0x00000008)
657 else if (iptr[0].val.l == 0x00000010)
659 else if (iptr[0].val.l == 0x00000020)
661 else if (iptr[0].val.l == 0x00000040)
663 else if (iptr[0].val.l == 0x00000080)
665 else if (iptr[0].val.l == 0x00000100)
667 else if (iptr[0].val.l == 0x00000200)
669 else if (iptr[0].val.l == 0x00000400)
671 else if (iptr[0].val.l == 0x00000800)
673 else if (iptr[0].val.l == 0x00001000)
675 else if (iptr[0].val.l == 0x00002000)
677 else if (iptr[0].val.l == 0x00004000)
679 else if (iptr[0].val.l == 0x00008000)
681 else if (iptr[0].val.l == 0x00010000)
683 else if (iptr[0].val.l == 0x00020000)
685 else if (iptr[0].val.l == 0x00040000)
687 else if (iptr[0].val.l == 0x00080000)
689 else if (iptr[0].val.l == 0x00100000)
691 else if (iptr[0].val.l == 0x00200000)
693 else if (iptr[0].val.l == 0x00400000)
695 else if (iptr[0].val.l == 0x00800000)
697 else if (iptr[0].val.l == 0x01000000)
699 else if (iptr[0].val.l == 0x02000000)
701 else if (iptr[0].val.l == 0x04000000)
703 else if (iptr[0].val.l == 0x08000000)
705 else if (iptr[0].val.l == 0x10000000)
707 else if (iptr[0].val.l == 0x20000000)
709 else if (iptr[0].val.l == 0x40000000)
711 else if (iptr[0].val.l == 0x80000000)
717 iptr[0].opc = ICMD_LMULPOW2;
718 goto icmd_lconst_tail;
719 # endif /* SUPPORT_LONG_SHIFT */
720 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
723 if (iptr[0].val.l == 0x00000002)
725 else if (iptr[0].val.l == 0x00000004)
727 else if (iptr[0].val.l == 0x00000008)
729 else if (iptr[0].val.l == 0x00000010)
731 else if (iptr[0].val.l == 0x00000020)
733 else if (iptr[0].val.l == 0x00000040)
735 else if (iptr[0].val.l == 0x00000080)
737 else if (iptr[0].val.l == 0x00000100)
739 else if (iptr[0].val.l == 0x00000200)
741 else if (iptr[0].val.l == 0x00000400)
743 else if (iptr[0].val.l == 0x00000800)
745 else if (iptr[0].val.l == 0x00001000)
747 else if (iptr[0].val.l == 0x00002000)
749 else if (iptr[0].val.l == 0x00004000)
751 else if (iptr[0].val.l == 0x00008000)
753 else if (iptr[0].val.l == 0x00010000)
755 else if (iptr[0].val.l == 0x00020000)
757 else if (iptr[0].val.l == 0x00040000)
759 else if (iptr[0].val.l == 0x00080000)
761 else if (iptr[0].val.l == 0x00100000)
763 else if (iptr[0].val.l == 0x00200000)
765 else if (iptr[0].val.l == 0x00400000)
767 else if (iptr[0].val.l == 0x00800000)
769 else if (iptr[0].val.l == 0x01000000)
771 else if (iptr[0].val.l == 0x02000000)
773 else if (iptr[0].val.l == 0x04000000)
775 else if (iptr[0].val.l == 0x08000000)
777 else if (iptr[0].val.l == 0x10000000)
779 else if (iptr[0].val.l == 0x20000000)
781 else if (iptr[0].val.l == 0x40000000)
783 else if (iptr[0].val.l == 0x80000000)
789 iptr[0].opc = ICMD_LDIVPOW2;
790 goto icmd_lconst_tail;
792 if ((iptr[0].val.l == 0x00000002) ||
793 (iptr[0].val.l == 0x00000004) ||
794 (iptr[0].val.l == 0x00000008) ||
795 (iptr[0].val.l == 0x00000010) ||
796 (iptr[0].val.l == 0x00000020) ||
797 (iptr[0].val.l == 0x00000040) ||
798 (iptr[0].val.l == 0x00000080) ||
799 (iptr[0].val.l == 0x00000100) ||
800 (iptr[0].val.l == 0x00000200) ||
801 (iptr[0].val.l == 0x00000400) ||
802 (iptr[0].val.l == 0x00000800) ||
803 (iptr[0].val.l == 0x00001000) ||
804 (iptr[0].val.l == 0x00002000) ||
805 (iptr[0].val.l == 0x00004000) ||
806 (iptr[0].val.l == 0x00008000) ||
807 (iptr[0].val.l == 0x00010000) ||
808 (iptr[0].val.l == 0x00020000) ||
809 (iptr[0].val.l == 0x00040000) ||
810 (iptr[0].val.l == 0x00080000) ||
811 (iptr[0].val.l == 0x00100000) ||
812 (iptr[0].val.l == 0x00200000) ||
813 (iptr[0].val.l == 0x00400000) ||
814 (iptr[0].val.l == 0x00800000) ||
815 (iptr[0].val.l == 0x01000000) ||
816 (iptr[0].val.l == 0x02000000) ||
817 (iptr[0].val.l == 0x04000000) ||
818 (iptr[0].val.l == 0x08000000) ||
819 (iptr[0].val.l == 0x10000000) ||
820 (iptr[0].val.l == 0x20000000) ||
821 (iptr[0].val.l == 0x40000000) ||
822 (iptr[0].val.l == 0x80000000)) {
823 iptr[0].opc = ICMD_LREMPOW2;
825 goto icmd_lconst_tail;
829 #endif /* SUPPORT_LONG_DIV */
830 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
833 iptr[0].opc = ICMD_LANDCONST;
834 goto icmd_lconst_tail;
836 iptr[0].opc = ICMD_LORCONST;
837 goto icmd_lconst_tail;
839 iptr[0].opc = ICMD_LXORCONST;
840 goto icmd_lconst_tail;
841 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
842 #if !defined(NOLONG_CONDITIONAL)
844 if ((len > 1) && (iptr[2].val.i == 0)) {
845 switch (iptr[2].opc) {
847 iptr[0].opc = ICMD_IF_LEQ;
848 icmd_lconst_lcmp_tail:
849 iptr[0].op1 = iptr[2].op1;
852 /* iptr[1].opc = ICMD_NOP;
853 iptr[2].opc = ICMD_NOP; */
855 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
857 iptr[0].target = (void *) tbptr;
859 MARKREACHED(tbptr, copy);
860 COUNT(count_pcmd_bra);
861 COUNT(count_pcmd_op);
864 iptr[0].opc = ICMD_IF_LNE;
865 goto icmd_lconst_lcmp_tail;
867 iptr[0].opc = ICMD_IF_LLT;
868 goto icmd_lconst_lcmp_tail;
870 iptr[0].opc = ICMD_IF_LGT;
871 goto icmd_lconst_lcmp_tail;
873 iptr[0].opc = ICMD_IF_LLE;
874 goto icmd_lconst_lcmp_tail;
876 iptr[0].opc = ICMD_IF_LGE;
877 goto icmd_lconst_lcmp_tail;
880 } /* switch (iptr[2].opc) */
881 } /* if (iptr[2].val.i == 0) */
885 #endif /* !defined(NOLONG_CONDITIONAL) */
887 #if SUPPORT_CONST_STORE
889 #if SUPPORT_CONST_STORE_ZERO_ONLY
890 if (iptr[0].val.l == 0) {
891 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
892 iptr[0].opc = ICMD_LASTORECONST;
893 iptr[1].opc = ICMD_NOP;
894 OPTT2_0(TYPE_INT, TYPE_ADR);
895 COUNT(count_pcmd_op);
896 #if SUPPORT_CONST_STORE_ZERO_ONLY
899 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
904 #if SUPPORT_CONST_STORE_ZERO_ONLY
905 if (iptr[0].val.l == 0) {
906 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
907 switch (iptr[1].opc) {
909 iptr[0].opc = ICMD_PUTSTATICCONST;
913 iptr[0].opc = ICMD_PUTFIELDCONST;
918 iptr[1].opc = ICMD_NOP;
919 iptr[0].op1 = TYPE_LNG;
920 COUNT(count_pcmd_op);
921 #if SUPPORT_CONST_STORE_ZERO_ONLY
924 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
926 #endif /* SUPPORT_CONST_STORE */
936 COUNT(count_pcmd_load);
941 COUNT(count_pcmd_load);
946 COUNT(count_pcmd_load);
947 #if SUPPORT_CONST_STORE
948 if (len > 0 && iptr->val.a == 0) {
949 switch (iptr[1].opc) {
951 if (iptr[1].val.fp != BUILTIN_aastore) {
958 switch (iptr[1].opc) {
960 iptr[0].opc = ICMD_AASTORECONST;
961 OPTT2_0(TYPE_INT, TYPE_ADR);
964 iptr[0].opc = ICMD_PUTSTATICCONST;
965 iptr[0].op1 = TYPE_ADR;
969 iptr[0].opc = ICMD_PUTFIELDCONST;
970 iptr[0].op1 = TYPE_ADR;
975 iptr[1].opc = ICMD_NOP;
976 COUNT(count_pcmd_op);
983 #endif /* SUPPORT_CONST_STORE */
987 /* pop 0 push 1 load */
994 COUNT(count_load_instruction);
995 i = opcode-ICMD_ILOAD;
996 iptr->op1 = argren[iptr->op1];
997 rd->locals[iptr->op1][i].type = i;
998 LOAD(i, LOCALVAR, iptr->op1);
1008 COUNT(count_check_null);
1009 COUNT(count_check_bound);
1010 COUNT(count_pcmd_mem);
1011 OP2IAT_1(opcode-ICMD_IALOAD);
1017 COUNT(count_check_null);
1018 COUNT(count_check_bound);
1019 COUNT(count_pcmd_mem);
1023 /* pop 0 push 0 iinc */
1026 #if defined(STATISTICS)
1030 count_store_depth[10]++;
1032 count_store_depth[i]++;
1038 if ((copy->varkind == LOCALVAR) &&
1039 (copy->varnum == iptr->op1)) {
1040 copy->varkind = TEMPVAR;
1049 /* pop 1 push 0 store */
1059 i = opcode - ICMD_ISTORE;
1060 rd->locals[iptr->op1][i].type = i;
1061 #if defined(STATISTICS)
1066 count_store_length[20]++;
1068 count_store_length[i]++;
1071 count_store_depth[10]++;
1073 count_store_depth[i]++;
1076 copy = curstack->prev;
1079 if ((copy->varkind == LOCALVAR) &&
1080 (copy->varnum == iptr->op1)) {
1081 copy->varkind = TEMPVAR;
1087 if ((new - curstack) == 1) {
1088 curstack->varkind = LOCALVAR;
1089 curstack->varnum = iptr->op1;
1091 STORE(opcode-ICMD_ISTORE);
1101 COUNT(count_check_null);
1102 COUNT(count_check_bound);
1103 COUNT(count_pcmd_mem);
1104 OP3TIA_0(opcode-ICMD_IASTORE);
1110 COUNT(count_check_null);
1111 COUNT(count_check_bound);
1112 COUNT(count_pcmd_mem);
1119 #ifdef TYPECHECK_STACK_COMPCAT
1122 if (IS_2_WORD_TYPE(curstack->type)) {
1123 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1136 COUNT(count_pcmd_return);
1137 OP1_0(opcode-ICMD_IRETURN);
1138 superblockend = true;
1142 COUNT(count_check_null);
1146 superblockend = true;
1149 case ICMD_PUTSTATIC:
1150 COUNT(count_pcmd_mem);
1154 /* pop 1 push 0 branch */
1157 case ICMD_IFNONNULL:
1158 COUNT(count_pcmd_bra);
1160 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1162 iptr[0].target = (void *) tbptr;
1164 MARKREACHED(tbptr, copy);
1173 COUNT(count_pcmd_bra);
1174 #ifdef CONDITIONAL_LOADCONST
1176 tbptr = m->basicblocks + b_index;
1177 if ((b_count >= 3) &&
1178 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1179 (tbptr[1].pre_count == 1) &&
1180 (iptr[1].opc == ICMD_ICONST) &&
1181 (iptr[2].opc == ICMD_GOTO) &&
1182 ((b_index + 3) == m->basicblockindex[iptr[2].op1]) &&
1183 (tbptr[2].pre_count == 1) &&
1184 (iptr[3].opc == ICMD_ICONST)) {
1185 OP1_1(TYPE_INT, TYPE_INT);
1186 switch (iptr[0].opc) {
1188 iptr[0].opc = ICMD_IFNE_ICONST;
1191 iptr[0].opc = ICMD_IFEQ_ICONST;
1194 iptr[0].opc = ICMD_IFGE_ICONST;
1197 iptr[0].opc = ICMD_IFLT_ICONST;
1200 iptr[0].opc = ICMD_IFLE_ICONST;
1203 iptr[0].opc = ICMD_IFGT_ICONST;
1206 iptr[0].val.i = iptr[1].val.i;
1207 iptr[1].opc = ICMD_ELSE_ICONST;
1208 iptr[1].val.i = iptr[3].val.i;
1209 iptr[2].opc = ICMD_NOP;
1210 iptr[3].opc = ICMD_NOP;
1211 tbptr[1].flags = BBDELETED;
1212 tbptr[2].flags = BBDELETED;
1213 tbptr[1].icount = 0;
1214 tbptr[2].icount = 0;
1215 if (tbptr[3].pre_count == 2) {
1216 len += tbptr[3].icount + 3;
1217 bptr->icount += tbptr[3].icount + 3;
1218 tbptr[3].flags = BBDELETED;
1219 tbptr[3].icount = 0;
1232 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1234 iptr[0].target = (void *) tbptr;
1236 MARKREACHED(tbptr, copy);
1239 /* pop 0 push 0 branch */
1242 COUNT(count_pcmd_bra);
1243 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1245 iptr[0].target = (void *) tbptr;
1247 MARKREACHED(tbptr, copy);
1249 superblockend = true;
1252 /* pop 1 push 0 table branch */
1254 case ICMD_TABLESWITCH:
1255 COUNT(count_pcmd_table);
1257 s4ptr = iptr->val.a;
1258 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1259 MARKREACHED(tbptr, copy);
1260 i = *s4ptr++; /* low */
1261 i = *s4ptr++ - i + 1; /* high */
1263 tptr = DMNEW(void*, i+1);
1264 iptr->target = (void *) tptr;
1266 tptr[0] = (void *) tbptr;
1270 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1272 tptr[0] = (void *) tbptr;
1275 MARKREACHED(tbptr, copy);
1278 superblockend = true;
1281 /* pop 1 push 0 table branch */
1283 case ICMD_LOOKUPSWITCH:
1284 COUNT(count_pcmd_table);
1286 s4ptr = iptr->val.a;
1287 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1288 MARKREACHED(tbptr, copy);
1289 i = *s4ptr++; /* count */
1291 tptr = DMNEW(void*, i+1);
1292 iptr->target = (void *) tptr;
1294 tptr[0] = (void *) tbptr;
1298 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1300 tptr[0] = (void *) tbptr;
1303 MARKREACHED(tbptr, copy);
1307 superblockend = true;
1310 case ICMD_NULLCHECKPOP:
1311 case ICMD_MONITORENTER:
1312 COUNT(count_check_null);
1313 case ICMD_MONITOREXIT:
1317 /* pop 2 push 0 branch */
1319 case ICMD_IF_ICMPEQ:
1320 case ICMD_IF_ICMPNE:
1321 case ICMD_IF_ICMPLT:
1322 case ICMD_IF_ICMPGE:
1323 case ICMD_IF_ICMPGT:
1324 case ICMD_IF_ICMPLE:
1325 COUNT(count_pcmd_bra);
1327 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1329 iptr[0].target = (void *) tbptr;
1331 MARKREACHED(tbptr, copy);
1334 case ICMD_IF_ACMPEQ:
1335 case ICMD_IF_ACMPNE:
1336 COUNT(count_pcmd_bra);
1338 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1340 iptr[0].target = (void *) tbptr;
1342 MARKREACHED(tbptr, copy);
1348 COUNT(count_check_null);
1349 COUNT(count_pcmd_mem);
1350 OPTT2_0(iptr->op1,TYPE_ADR);
1355 if (!IS_2_WORD_TYPE(curstack->type)) {
1357 #ifdef TYPECHECK_STACK_COMPCAT
1360 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1361 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1366 OP1_0ANY; /* second pop */
1369 iptr->opc = ICMD_POP;
1373 /* pop 0 push 1 dup */
1376 #ifdef TYPECHECK_STACK_COMPCAT
1379 if (IS_2_WORD_TYPE(curstack->type)) {
1380 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1385 COUNT(count_dup_instruction);
1391 if (IS_2_WORD_TYPE(curstack->type)) {
1393 iptr->opc = ICMD_DUP;
1398 /* ..., ????, cat1 */
1399 #ifdef TYPECHECK_STACK_COMPCAT
1401 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1402 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1408 NEWSTACK(copy->prev->type, copy->prev->varkind,
1409 copy->prev->varnum);
1410 NEWSTACK(copy->type, copy->varkind,
1417 /* pop 2 push 3 dup */
1420 #ifdef TYPECHECK_STACK_COMPCAT
1423 if (IS_2_WORD_TYPE(curstack->type) ||
1424 IS_2_WORD_TYPE(curstack->prev->type)) {
1425 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1435 if (IS_2_WORD_TYPE(curstack->type)) {
1436 /* ..., ????, cat2 */
1437 #ifdef TYPECHECK_STACK_COMPCAT
1439 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1440 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1445 iptr->opc = ICMD_DUP_X1;
1449 /* ..., ????, cat1 */
1450 #ifdef TYPECHECK_STACK_COMPCAT
1453 if (IS_2_WORD_TYPE(curstack->prev->type)
1454 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1455 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1464 /* pop 3 push 4 dup */
1468 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1469 /* ..., cat2, ???? */
1470 #ifdef TYPECHECK_STACK_COMPCAT
1472 if (IS_2_WORD_TYPE(curstack->type)) {
1473 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1478 iptr->opc = ICMD_DUP_X1;
1482 /* ..., cat1, ???? */
1483 #ifdef TYPECHECK_STACK_COMPCAT
1486 if (IS_2_WORD_TYPE(curstack->type)
1487 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1488 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1499 if (IS_2_WORD_TYPE(curstack->type)) {
1500 /* ..., ????, cat2 */
1501 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1502 /* ..., cat2, cat2 */
1503 iptr->opc = ICMD_DUP_X1;
1507 /* ..., cat1, cat2 */
1508 #ifdef TYPECHECK_STACK_COMPCAT
1511 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1512 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1517 iptr->opc = ICMD_DUP_X2;
1523 /* ..., ????, ????, cat1 */
1524 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1525 /* ..., cat2, ????, cat1 */
1526 #ifdef TYPECHECK_STACK_COMPCAT
1528 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1529 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1534 iptr->opc = ICMD_DUP2_X1;
1538 /* ..., cat1, ????, cat1 */
1539 #ifdef TYPECHECK_STACK_COMPCAT
1542 if (IS_2_WORD_TYPE(curstack->prev->type)
1543 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1544 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1554 /* pop 2 push 2 swap */
1557 #ifdef TYPECHECK_STACK_COMPCAT
1560 if (IS_2_WORD_TYPE(curstack->type)
1561 || IS_2_WORD_TYPE(curstack->prev->type)) {
1562 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1573 #if !SUPPORT_DIVISION
1574 iptr[0].opc = ICMD_BUILTIN2;
1575 iptr[0].op1 = TYPE_INT;
1576 iptr[0].val.fp = BUILTIN_idiv;
1577 m->isleafmethod = false;
1582 #if !SUPPORT_DIVISION
1583 iptr[0].opc = ICMD_BUILTIN2;
1584 iptr[0].op1 = TYPE_INT;
1585 iptr[0].val.fp = BUILTIN_irem;
1586 m->isleafmethod = false;
1599 COUNT(count_pcmd_op);
1604 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1605 iptr[0].opc = ICMD_BUILTIN2;
1606 iptr[0].op1 = TYPE_LNG;
1607 iptr[0].val.fp = BUILTIN_ldiv;
1608 m->isleafmethod = false;
1613 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1614 iptr[0].opc = ICMD_BUILTIN2;
1615 iptr[0].op1 = TYPE_LNG;
1616 iptr[0].val.fp = BUILTIN_lrem;
1617 m->isleafmethod = false;
1624 #if SUPPORT_LONG_LOGICAL
1628 #endif /* SUPPORT_LONG_LOGICAL */
1629 COUNT(count_pcmd_op);
1636 COUNT(count_pcmd_op);
1645 COUNT(count_pcmd_op);
1654 COUNT(count_pcmd_op);
1659 COUNT(count_pcmd_op);
1660 #if !defined(NOLONG_CONDITIONAL)
1661 if ((len > 0) && (iptr[1].val.i == 0)) {
1662 switch (iptr[1].opc) {
1664 iptr[0].opc = ICMD_IF_LCMPEQ;
1666 iptr[0].op1 = iptr[1].op1;
1669 /* iptr[1].opc = ICMD_NOP; */
1671 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1673 iptr[0].target = (void *) tbptr;
1675 MARKREACHED(tbptr, copy);
1676 COUNT(count_pcmd_bra);
1679 iptr[0].opc = ICMD_IF_LCMPNE;
1680 goto icmd_lcmp_if_tail;
1682 iptr[0].opc = ICMD_IF_LCMPLT;
1683 goto icmd_lcmp_if_tail;
1685 iptr[0].opc = ICMD_IF_LCMPGT;
1686 goto icmd_lcmp_if_tail;
1688 iptr[0].opc = ICMD_IF_LCMPLE;
1689 goto icmd_lcmp_if_tail;
1691 iptr[0].opc = ICMD_IF_LCMPGE;
1692 goto icmd_lcmp_if_tail;
1694 OPTT2_1(TYPE_LNG, TYPE_INT);
1699 OPTT2_1(TYPE_LNG, TYPE_INT);
1703 COUNT(count_pcmd_op);
1704 OPTT2_1(TYPE_FLT, TYPE_INT);
1708 COUNT(count_pcmd_op);
1709 OPTT2_1(TYPE_DBL, TYPE_INT);
1717 case ICMD_INT2SHORT:
1718 COUNT(count_pcmd_op);
1719 OP1_1(TYPE_INT, TYPE_INT);
1722 COUNT(count_pcmd_op);
1723 OP1_1(TYPE_LNG, TYPE_LNG);
1726 COUNT(count_pcmd_op);
1727 OP1_1(TYPE_FLT, TYPE_FLT);
1730 COUNT(count_pcmd_op);
1731 OP1_1(TYPE_DBL, TYPE_DBL);
1735 COUNT(count_pcmd_op);
1736 OP1_1(TYPE_INT, TYPE_LNG);
1739 COUNT(count_pcmd_op);
1740 OP1_1(TYPE_INT, TYPE_FLT);
1743 COUNT(count_pcmd_op);
1744 OP1_1(TYPE_INT, TYPE_DBL);
1747 COUNT(count_pcmd_op);
1748 OP1_1(TYPE_LNG, TYPE_INT);
1751 COUNT(count_pcmd_op);
1752 OP1_1(TYPE_LNG, TYPE_FLT);
1755 COUNT(count_pcmd_op);
1756 OP1_1(TYPE_LNG, TYPE_DBL);
1759 COUNT(count_pcmd_op);
1760 OP1_1(TYPE_FLT, TYPE_INT);
1763 COUNT(count_pcmd_op);
1764 OP1_1(TYPE_FLT, TYPE_LNG);
1767 COUNT(count_pcmd_op);
1768 OP1_1(TYPE_FLT, TYPE_DBL);
1771 COUNT(count_pcmd_op);
1772 OP1_1(TYPE_DBL, TYPE_INT);
1775 COUNT(count_pcmd_op);
1776 OP1_1(TYPE_DBL, TYPE_LNG);
1779 COUNT(count_pcmd_op);
1780 OP1_1(TYPE_DBL, TYPE_FLT);
1783 case ICMD_CHECKCAST:
1784 OP1_1(TYPE_ADR, TYPE_ADR);
1787 case ICMD_INSTANCEOF:
1788 case ICMD_ARRAYLENGTH:
1789 OP1_1(TYPE_ADR, TYPE_INT);
1793 case ICMD_ANEWARRAY:
1794 OP1_1(TYPE_INT, TYPE_ADR);
1798 COUNT(count_check_null);
1799 COUNT(count_pcmd_mem);
1800 OP1_1(TYPE_ADR, iptr->op1);
1805 case ICMD_GETSTATIC:
1806 COUNT(count_pcmd_mem);
1816 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1818 iptr[0].target = (void *) tbptr;
1820 /* This is a dirty hack. The typechecker
1821 * needs it because the OP1_0ANY below
1822 * overwrites iptr->dst.
1824 iptr->val.a = (void *) iptr->dst;
1826 tbptr->type = BBTYPE_SBR;
1828 /* We need to check for overflow right here because
1829 * the pushed value is poped after MARKREACHED. */
1831 MARKREACHED(tbptr, copy);
1835 /* pop many push any */
1838 call_returntype = iptr->op1;
1841 #if defined(USEBUILTINTABLE) || !SUPPORT_DIVISION
1842 /* Just prevent a compiler warning... */
1846 call_returntype = iptr->op1;
1849 #if defined(USEBUILTINTABLE)
1850 /* Just prevent a compiler warning... */
1854 call_returntype = iptr->op1;
1857 case ICMD_INVOKEVIRTUAL:
1858 case ICMD_INVOKESPECIAL:
1859 case ICMD_INVOKEINTERFACE:
1860 case ICMD_INVOKESTATIC:
1861 COUNT(count_pcmd_met);
1863 methodinfo *lm = iptr->val.a;
1864 if (lm->flags & ACC_STATIC)
1865 {COUNT(count_check_null);}
1866 call_argcount = iptr->op1;
1867 call_returntype = lm->returntype;
1872 if (i > rd->arguments_num)
1873 rd->arguments_num = i;
1876 /* Macro in codegen.h */
1880 copy->flags |= SAVEDVAR;
1886 if (call_returntype != TYPE_VOID)
1887 OP0_1(call_returntype);
1890 case ICMD_INLINE_START:
1891 case ICMD_INLINE_END:
1895 case ICMD_MULTIANEWARRAY:
1896 if (rd->argintreguse < 3)
1897 rd->argintreguse = 3;
1901 #ifdef SPECIALMEMUSE
1902 if (rd->ifmemuse < (i + rd->intreg_argnum + 6))
1903 rd->ifmemuse = i + rd->intreg_argnum + 6;
1905 if (rd->ifmemuse < i)
1906 rd->ifmemuse = i; /* n integer args spilled on stack */
1908 if ((i + INT_ARG_CNT) > rd->arguments_num)
1909 rd->arguments_num = i + INT_ARG_CNT;
1912 /* check INT type here? Currently typecheck does this. */
1913 if (!(copy->flags & SAVEDVAR)) {
1914 copy->varkind = ARGVAR;
1915 copy->varnum = i + INT_ARG_CNT;
1916 copy->flags|=INMEMORY;
1917 #ifdef SPECIALMEMUSE
1918 copy->regoff = i + rd->intreg_argnum + 6;
1926 copy->flags |= SAVEDVAR;
1934 case ICMD_CLEAR_ARGREN:
1935 for (i = iptr->op1; i < cd->maxlocals; i++)
1937 iptr->opc = opcode = ICMD_NOP;
1941 case ICMD_READONLY_ARG:
1942 case ICMD_READONLY_ARG+1:
1943 case ICMD_READONLY_ARG+2:
1944 case ICMD_READONLY_ARG+3:
1945 case ICMD_READONLY_ARG+4:
1948 if (curstack->varkind == LOCALVAR) {
1949 i = curstack->varnum;
1950 argren[iptr->op1] = i;
1953 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
1960 new_exception_message(string_java_lang_InternalError,
1967 } /* while instructions */
1969 bptr->outstack = curstack;
1970 bptr->outdepth = stackdepth;
1974 superblockend = true;
1976 } /* while blocks */
1977 } while (repeat && !deadcode);
1979 #if defined(STATISTICS)
1981 if (m->basicblockcount > count_max_basic_blocks)
1982 count_max_basic_blocks = m->basicblockcount;
1983 count_basic_blocks += m->basicblockcount;
1984 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
1985 count_javainstr += m->instructioncount;
1986 if (m->stackcount > count_upper_bound_new_stack)
1987 count_upper_bound_new_stack = m->stackcount;
1988 if ((new - m->stack) > count_max_new_stack)
1989 count_max_new_stack = (new - m->stack);
1991 b_count = m->basicblockcount;
1992 bptr = m->basicblocks;
1993 while (--b_count >= 0) {
1994 if (bptr->flags > BBREACHED) {
1995 if (bptr->indepth >= 10)
1996 count_block_stack[10]++;
1998 count_block_stack[bptr->indepth]++;
2001 count_block_size_distribution[len]++;
2003 count_block_size_distribution[10]++;
2005 count_block_size_distribution[11]++;
2007 count_block_size_distribution[12]++;
2009 count_block_size_distribution[13]++;
2011 count_block_size_distribution[14]++;
2013 count_block_size_distribution[15]++;
2015 count_block_size_distribution[16]++;
2017 count_block_size_distribution[17]++;
2023 count_analyse_iterations[0]++;
2024 else if (loops == 2)
2025 count_analyse_iterations[1]++;
2026 else if (loops == 3)
2027 count_analyse_iterations[2]++;
2028 else if (loops == 4)
2029 count_analyse_iterations[3]++;
2031 count_analyse_iterations[4]++;
2033 if (m->basicblockcount <= 5)
2034 count_method_bb_distribution[0]++;
2035 else if (m->basicblockcount <= 10)
2036 count_method_bb_distribution[1]++;
2037 else if (m->basicblockcount <= 15)
2038 count_method_bb_distribution[2]++;
2039 else if (m->basicblockcount <= 20)
2040 count_method_bb_distribution[3]++;
2041 else if (m->basicblockcount <= 30)
2042 count_method_bb_distribution[4]++;
2043 else if (m->basicblockcount <= 40)
2044 count_method_bb_distribution[5]++;
2045 else if (m->basicblockcount <= 50)
2046 count_method_bb_distribution[6]++;
2047 else if (m->basicblockcount <= 75)
2048 count_method_bb_distribution[7]++;
2050 count_method_bb_distribution[8]++;
2054 /* just return methodinfo* to signal everything was ok */
2060 /**********************************************************************/
2061 /* DEBUGGING HELPERS */
2062 /**********************************************************************/
2064 void icmd_print_stack(codegendata *cd, stackptr s)
2076 j = cd->maxstack - i;
2081 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2082 if (s->flags & SAVEDVAR)
2083 switch (s->varkind) {
2085 if (s->flags & INMEMORY)
2086 printf(" M%02d", s->regoff);
2087 #ifdef HAS_ADDRESS_REGISTER_FILE
2088 else if (s->type == TYPE_ADR)
2089 printf(" R%02d", s->regoff);
2091 else if (IS_FLT_DBL_TYPE(s->type))
2092 printf(" F%02d", s->regoff);
2094 printf(" %3s", regs[s->regoff]);
2098 printf(" I%02d", s->varnum);
2101 printf(" L%02d", s->varnum);
2104 printf(" A%02d", s->varnum);
2105 #ifdef INVOKE_NEW_DEBUG
2106 if (s->flags & INMEMORY)
2107 printf("(M%i)", s->regoff);
2109 printf("(R%i)", s->regoff);
2113 printf(" !%02d", j);
2116 switch (s->varkind) {
2118 if (s->flags & INMEMORY)
2119 printf(" m%02d", s->regoff);
2120 #ifdef HAS_ADDRESS_REGISTER_FILE
2121 else if (s->type == TYPE_ADR)
2122 printf(" r%02d", s->regoff);
2124 else if (IS_FLT_DBL_TYPE(s->type))
2125 printf(" f%02d", s->regoff);
2127 printf(" %3s", regs[s->regoff]);
2131 printf(" i%02d", s->varnum);
2134 printf(" l%02d", s->varnum);
2137 printf(" a%02d", s->varnum);
2138 #ifdef INVOKE_NEW_DEBUG
2139 if (s->flags & INMEMORY)
2140 printf("(M%i)", s->regoff);
2142 printf("(R%i)", s->regoff);
2146 printf(" ?%02d", j);
2154 static void print_reg(stackptr s) {
2156 if (s->flags & SAVEDVAR)
2157 switch (s->varkind) {
2159 if (s->flags & INMEMORY)
2160 printf(" tm%02d", s->regoff);
2162 printf(" tr%02d", s->regoff);
2165 printf(" s %02d", s->varnum);
2168 printf(" l %02d", s->varnum);
2171 printf(" a %02d", s->varnum);
2174 printf(" ! %02d", s->varnum);
2177 switch (s->varkind) {
2179 if (s->flags & INMEMORY)
2180 printf(" Tm%02d", s->regoff);
2182 printf(" Tr%02d", s->regoff);
2185 printf(" S %02d", s->varnum);
2188 printf(" L %02d", s->varnum);
2191 printf(" A %02d", s->varnum);
2194 printf(" ? %02d", s->varnum);
2204 char *icmd_builtin_name(functionptr bptr)
2206 builtin_descriptor *bdesc = builtin_desc;
2207 while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
2209 return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
2213 static char *jit_type[] = {
2222 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2229 utf_fprint_classname(stdout, m->class->name);
2231 utf_fprint(stdout, m->name);
2232 utf_fprint_classname(stdout, m->descriptor);
2233 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2234 printf("Max stack: %d\n", (int) cd->maxstack);
2236 printf("Line number table length: %d\n", m->linenumbercount);
2238 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2239 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2240 printf(" L%03d ... ", ex->start->debug_nr );
2241 printf("L%03d = ", ex->end->debug_nr);
2242 printf("L%03d\n", ex->handler->debug_nr);
2245 printf("Local Table:\n");
2246 for (i = 0; i < cd->maxlocals; i++) {
2247 printf(" %3d: ", i);
2248 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2249 if (rd->locals[i][j].type >= 0) {
2250 printf(" (%s) ", jit_type[j]);
2251 if (rd->locals[i][j].flags & INMEMORY)
2252 printf("m%2d", rd->locals[i][j].regoff);
2253 #ifdef HAS_ADDRESS_REGISTER_FILE
2254 else if (j == TYPE_ADR)
2255 printf("r%02d", rd->locals[i][j].regoff);
2257 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2258 printf("f%02d", rd->locals[i][j].regoff);
2260 printf("%3s", regs[rd->locals[i][j].regoff]);
2269 printf("Interface Table:\n");
2270 for (i = 0; i < cd->maxstack; i++) {
2271 if ((rd->interfaces[i][0].type >= 0) ||
2272 (rd->interfaces[i][1].type >= 0) ||
2273 (rd->interfaces[i][2].type >= 0) ||
2274 (rd->interfaces[i][3].type >= 0) ||
2275 (rd->interfaces[i][4].type >= 0)) {
2276 printf(" %3d: ", i);
2277 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2278 if (rd->interfaces[i][j].type >= 0) {
2279 printf(" (%s) ", jit_type[j]);
2280 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2281 if (rd->interfaces[i][j].flags & INMEMORY)
2282 printf("M%2d", rd->interfaces[i][j].regoff);
2283 #ifdef HAS_ADDRESS_REGISTER_FILE
2284 else if (j == TYPE_ADR)
2285 printf("R%02d", rd->interfaces[i][j].regoff);
2287 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2288 printf("F%02d", rd->interfaces[i][j].regoff);
2290 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2294 if (rd->interfaces[i][j].flags & INMEMORY)
2295 printf("m%2d", rd->interfaces[i][j].regoff);
2296 #ifdef HAS_ADDRESS_REGISTER_FILE
2297 else if (j == TYPE_ADR)
2298 printf("r%02d", rd->interfaces[i][j].regoff);
2300 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2301 printf("f%02d", rd->interfaces[i][j].regoff);
2303 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2314 if (showdisassemble) {
2315 #if defined(__I386__) || defined(__X86_64__)
2319 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2320 for (i = 0; i < m->basicblocks[0].mpc;) {
2321 a = disassinstr(u1ptr);
2326 #elif defined(__XDSPCORE__)
2330 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2331 for (i = 0; i < m->basicblocks[0].mpc;) {
2332 a = disassinstr(stdout, s4ptr);
2341 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2342 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2349 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2350 show_icmd_block(m, cd, bptr);
2355 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2361 if (bptr->flags != BBDELETED) {
2362 deadcode = bptr->flags <= BBREACHED;
2365 for (j = cd->maxstack; j > 0; j--)
2368 icmd_print_stack(cd, bptr->instack);
2369 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2370 iptr = bptr->iinstr;
2372 for (i = 0; i < bptr->icount; i++, iptr++) {
2375 for (j = cd->maxstack; j > 0; j--)
2379 icmd_print_stack(cd, iptr->dst);
2380 printf("] %4d ", i);
2383 if (icmd_uses_tmp[iptr->opc][0])
2387 if (icmd_uses_tmp[iptr->opc][1])
2391 if (icmd_uses_tmp[iptr->opc][2])
2397 show_icmd(iptr, deadcode);
2401 if (showdisassemble && (!deadcode)) {
2402 #if defined(__I386__) || defined(__X86_64__)
2408 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2410 if (bptr->next != NULL) {
2411 for (; i < bptr->next->mpc; ) {
2412 a = disassinstr(u1ptr);
2419 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2420 a = disassinstr(u1ptr);
2426 #elif defined(__XDSPCORE__)
2432 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2434 if (bptr->next != NULL) {
2435 for (; i < bptr->next->mpc;) {
2436 a = disassinstr(stdout, s4ptr);
2444 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2445 a = disassinstr(stdout, s4ptr);
2456 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2458 if (bptr->next != NULL) {
2459 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2464 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2474 void show_icmd(instruction *iptr, bool deadcode)
2480 printf("%s", icmd_names[iptr->opc]);
2482 switch (iptr->opc) {
2483 case ICMD_IADDCONST:
2484 case ICMD_ISUBCONST:
2485 case ICMD_IMULCONST:
2489 case ICMD_IANDCONST:
2491 case ICMD_IXORCONST:
2492 case ICMD_ISHLCONST:
2493 case ICMD_ISHRCONST:
2494 case ICMD_IUSHRCONST:
2495 case ICMD_LSHLCONST:
2496 case ICMD_LSHRCONST:
2497 case ICMD_LUSHRCONST:
2499 case ICMD_ELSE_ICONST:
2500 case ICMD_IFEQ_ICONST:
2501 case ICMD_IFNE_ICONST:
2502 case ICMD_IFLT_ICONST:
2503 case ICMD_IFGE_ICONST:
2504 case ICMD_IFGT_ICONST:
2505 case ICMD_IFLE_ICONST:
2506 case ICMD_IASTORECONST:
2507 case ICMD_BASTORECONST:
2508 case ICMD_CASTORECONST:
2509 case ICMD_SASTORECONST:
2510 printf(" %d", iptr->val.i);
2513 case ICMD_LADDCONST:
2514 case ICMD_LSUBCONST:
2515 case ICMD_LMULCONST:
2519 case ICMD_LANDCONST:
2521 case ICMD_LXORCONST:
2523 case ICMD_LASTORECONST:
2524 #if defined(__I386__) || defined(__POWERPC__)
2525 printf(" %lld", iptr->val.l);
2527 printf(" %ld", iptr->val.l);
2532 printf(" %f", iptr->val.f);
2536 printf(" %f", iptr->val.d);
2540 case ICMD_AASTORECONST:
2541 printf(" %p", iptr->val.a);
2546 printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
2547 case ICMD_PUTSTATIC:
2548 case ICMD_GETSTATIC:
2550 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->class->name);
2552 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->name);
2554 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->descriptor);
2558 case ICMD_PUTSTATICCONST:
2559 case ICMD_PUTFIELDCONST:
2560 switch (iptr[1].op1) {
2562 printf(" %d,", iptr->val.i);
2565 #if defined(__I386__) || defined(__POWERPC__)
2566 printf(" %lld,", iptr->val.l);
2568 printf(" %ld,", iptr->val.l);
2572 printf(" %p,", iptr->val.a);
2575 printf(" %g,", iptr->val.f);
2578 printf(" %g,", iptr->val.d);
2581 if (iptr->opc == ICMD_PUTFIELDCONST)
2582 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
2584 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->class->name);
2586 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->name);
2588 utf_fprint(stdout, ((fieldinfo *) iptr[1].val.a)->descriptor);
2593 printf(" %d + %d", iptr->op1, iptr->val.i);
2628 printf(" %d", iptr->op1);
2634 ((classinfo *) iptr->val.a)->name);
2638 switch (iptr->op1) {
2666 case ICMD_ANEWARRAY:
2670 ((classinfo *) iptr->val.a)->name);
2674 case ICMD_MULTIANEWARRAY:
2677 printf(" %d ",iptr->op1);
2678 vft = (vftbl_t *)iptr->val.a;
2680 utf_fprint(stdout,vft->class->name);
2686 case ICMD_CHECKCAST:
2687 case ICMD_INSTANCEOF:
2689 classinfo *c = iptr->val.a;
2690 if (c->flags & ACC_INTERFACE)
2691 printf(" (INTERFACE) ");
2693 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2694 utf_fprint(stdout, c->name);
2698 case ICMD_INLINE_START:
2699 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2701 case ICMD_INLINE_END:
2707 printf(" %s", icmd_builtin_name((functionptr) iptr->val.fp));
2710 case ICMD_INVOKEVIRTUAL:
2711 case ICMD_INVOKESPECIAL:
2712 case ICMD_INVOKESTATIC:
2713 case ICMD_INVOKEINTERFACE:
2716 ((methodinfo *) iptr->val.a)->class->name);
2719 ((methodinfo *) iptr->val.a)->name);
2728 if (deadcode || !iptr->target)
2729 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2731 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2740 if (deadcode || !iptr->target)
2741 #if defined(__I386__) || defined(__POWERPC__)
2742 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2744 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2747 #if defined(__I386__) || defined(__POWERPC__)
2748 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2750 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2757 case ICMD_IFNONNULL:
2758 case ICMD_IF_ICMPEQ:
2759 case ICMD_IF_ICMPNE:
2760 case ICMD_IF_ICMPLT:
2761 case ICMD_IF_ICMPGE:
2762 case ICMD_IF_ICMPGT:
2763 case ICMD_IF_ICMPLE:
2764 case ICMD_IF_LCMPEQ:
2765 case ICMD_IF_LCMPNE:
2766 case ICMD_IF_LCMPLT:
2767 case ICMD_IF_LCMPGE:
2768 case ICMD_IF_LCMPGT:
2769 case ICMD_IF_LCMPLE:
2770 case ICMD_IF_ACMPEQ:
2771 case ICMD_IF_ACMPNE:
2772 if (deadcode || !iptr->target)
2773 printf(" op1=%d", iptr->op1);
2775 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2778 case ICMD_TABLESWITCH:
2779 s4ptr = (s4*)iptr->val.a;
2781 if (deadcode || !iptr->target) {
2782 printf(" %d;", *s4ptr);
2785 tptr = (void **) iptr->target;
2786 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2790 s4ptr++; /* skip default */
2791 j = *s4ptr++; /* low */
2792 j = *s4ptr++ - j; /* high */
2794 if (deadcode || !*tptr)
2795 printf(" %d", *s4ptr++);
2797 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2804 case ICMD_LOOKUPSWITCH:
2805 s4ptr = (s4*)iptr->val.a;
2807 if (deadcode || !iptr->target) {
2808 printf(" %d;", *s4ptr);
2811 tptr = (void **) iptr->target;
2812 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2815 s4ptr++; /* default */
2816 j = *s4ptr++; /* count */
2819 if (deadcode || !*tptr) {
2820 s4ptr++; /* skip value */
2821 printf(" %d",*s4ptr++);
2824 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2830 printf(" Line number: %d, method:",iptr->line);
2832 utf_display(iptr->method->class->name);
2834 utf_display(iptr->method->name); */
2839 * These are local overrides for various environment variables in Emacs.
2840 * Please do not remove this and leave it at the end of the file, where
2841 * Emacs will automagically detect them.
2842 * ---------------------------------------------------------------------
2845 * indent-tabs-mode: t