1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: stack.c 7908 2007-05-15 09:55:17Z christian $
40 #include "mm/memory.h"
42 #include "native/native.h"
44 #include "toolbox/logging.h"
46 #include "vm/global.h"
47 #include "vm/builtin.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/cfg.h"
53 #include "vm/jit/codegen-common.h"
54 #include "vm/jit/parse.h"
55 #include "vm/jit/show.h"
57 #if defined(ENABLE_DISASSEMBLER)
58 # include "vm/jit/disass.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/stack.h"
65 #if defined(ENABLE_SSA)
66 # include "vm/jit/optimizing/lsra.h"
67 # include "vm/jit/optimizing/ssa.h"
68 #elif defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/options.h"
74 #include "vm/resolve.h"
76 #if defined(ENABLE_STATISTICS)
77 # include "vmcore/statistics.h"
80 /*#define STACK_VERBOSE*/
83 /* macro for saving #ifdefs ***************************************************/
85 #if defined(ENABLE_STATISTICS)
86 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
89 if (stackdepth >= 10) \
90 count_store_depth[10]++; \
92 count_store_depth[stackdepth]++; \
95 #else /* !defined(ENABLE_STATISTICS) */
96 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
100 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
103 /* For returnAddresses we use a field of the typeinfo to store from which */
104 /* subroutine the returnAddress will return, if used. */
105 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
106 /* to need it initialised to NULL. This should be investigated. */
108 #if defined(ENABLE_VERIFIER)
109 #define SBRSTART typeinfo.elementclass.any
113 /* stackdata_t *****************************************************************
115 This struct holds internal data during stack analysis.
117 *******************************************************************************/
119 typedef struct stackdata_t stackdata_t;
122 basicblock *bptr; /* the current basic block being analysed */
123 stackptr new; /* next free stackelement */
124 s4 vartop; /* next free variable index */
125 s4 localcount; /* number of locals (at the start of var) */
126 s4 varcount; /* maximum number of variables expected */
127 s4 varsallocated; /* total number of variables allocated */
128 s4 maxlocals; /* max. number of Java locals */
129 varinfo *var; /* variable array (same as jd->var) */
130 s4 *javalocals; /* map from Java locals to jd->var indices */
131 methodinfo *m; /* the method being analysed */
132 jitdata *jd; /* current jitdata */
133 basicblock *last_real_block; /* the last block before the empty one */
134 bool repeat; /* if true, iterate the analysis again */
135 exception_entry **handlers; /* exception handlers for the current block */
136 exception_entry *extableend; /* points to the last exception entry */
137 stackelement exstack; /* instack for exception handlers */
141 /* macros for allocating/releasing variable indices *****************/
143 #define GET_NEW_INDEX(sd, new_varindex) \
145 assert((sd).vartop < (sd).varcount); \
146 (new_varindex) = ((sd).vartop)++; \
149 /* Not implemented now - could be used to reuse varindices. */
150 /* Pay attention to not release a localvar once implementing it! */
151 #define RELEASE_INDEX(sd, varindex)
153 #define GET_NEW_VAR(sd, newvarindex, newtype) \
155 GET_NEW_INDEX((sd), (newvarindex)); \
156 (sd).var[newvarindex].type = (newtype); \
160 /* macros for querying variable properties **************************/
162 #define IS_INOUT(sp) \
163 (sd.var[(sp)->varnum].flags & INOUT)
165 #define IS_PREALLOC(sp) \
166 (sd.var[(sp)->varnum].flags & PREALLOC)
168 #define IS_TEMPVAR(sp) \
169 ( ((sp)->varnum >= sd.localcount) \
170 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
173 #define IS_LOCALVAR_SD(sd, sp) \
174 ((sp)->varnum < (sd).localcount)
176 #define IS_LOCALVAR(sp) \
177 IS_LOCALVAR_SD(sd, (sp))
180 /* macros for setting variable properties ****************************/
182 #define SET_TEMPVAR(sp) \
184 if (IS_LOCALVAR((sp))) { \
185 stack_change_to_tempvar(&sd, (sp), iptr); \
187 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
190 #define SET_PREALLOC(sp) \
192 assert(!IS_LOCALVAR((sp))); \
193 sd.var[(sp)->varnum].flags |= PREALLOC; \
197 /* macros for source operands ***************************************/
200 (iptr->s1.varindex = -1)
202 #define USE_S1(type1) \
205 CHECK_BASIC_TYPE(type1, curstack->type); \
206 iptr->s1.varindex = curstack->varnum; \
212 iptr->s1.varindex = curstack->varnum; \
215 #define USE_S1_S2(type1, type2) \
218 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
219 CHECK_BASIC_TYPE(type2, curstack->type); \
220 iptr->sx.s23.s2.varindex = curstack->varnum; \
221 iptr->s1.varindex = curstack->prev->varnum; \
224 #define USE_S1_S2_ANY_ANY \
227 iptr->sx.s23.s2.varindex = curstack->varnum; \
228 iptr->s1.varindex = curstack->prev->varnum; \
231 #define USE_S1_S2_S3(type1, type2, type3) \
234 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
235 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
236 CHECK_BASIC_TYPE(type3, curstack->type); \
237 iptr->sx.s23.s3.varindex = curstack->varnum; \
238 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
239 iptr->s1.varindex = curstack->prev->prev->varnum; \
242 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
245 if (curstack->varkind == UNDEFVAR) \
246 curstack->varkind = TEMPVAR; \
247 curstack = curstack->prev; \
250 #define POP_S1(type1) \
253 if (curstack->varkind == UNDEFVAR) \
254 curstack->varkind = TEMPVAR; \
255 curstack = curstack->prev; \
261 if (curstack->varkind == UNDEFVAR) \
262 curstack->varkind = TEMPVAR; \
263 curstack = curstack->prev; \
266 #define POP_S1_S2(type1, type2) \
268 USE_S1_S2(type1, type2); \
269 if (curstack->varkind == UNDEFVAR) \
270 curstack->varkind = TEMPVAR; \
271 if (curstack->prev->varkind == UNDEFVAR) \
272 curstack->prev->varkind = TEMPVAR; \
273 curstack = curstack->prev->prev; \
276 #define POP_S1_S2_ANY_ANY \
279 if (curstack->varkind == UNDEFVAR) \
280 curstack->varkind = TEMPVAR; \
281 if (curstack->prev->varkind == UNDEFVAR) \
282 curstack->prev->varkind = TEMPVAR; \
283 curstack = curstack->prev->prev; \
286 #define POP_S1_S2_S3(type1, type2, type3) \
288 USE_S1_S2_S3(type1, type2, type3); \
289 if (curstack->varkind == UNDEFVAR) \
290 curstack->varkind = TEMPVAR; \
291 if (curstack->prev->varkind == UNDEFVAR) \
292 curstack->prev->varkind = TEMPVAR; \
293 if (curstack->prev->prev->varkind == UNDEFVAR) \
294 curstack->prev->prev->varkind = TEMPVAR; \
295 curstack = curstack->prev->prev->prev; \
302 /* macros for setting the destination operand ***********************/
305 (iptr->dst.varindex = -1)
307 #define DST(typed, index) \
309 NEWSTACKn((typed),(index)); \
310 curstack->creator = iptr; \
311 iptr->dst.varindex = (index); \
314 #define DST_LOCALVAR(typed, index) \
316 NEWSTACK((typed), LOCALVAR, (index)); \
317 curstack->creator = iptr; \
318 iptr->dst.varindex = (index); \
322 /* macro for propagating constant values ****************************/
324 #if defined(ENABLE_VERIFIER)
325 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
327 if (((dv)->type = (sv)->type) == TYPE_RET) { \
328 (dv)->vv = (sv)->vv; \
329 (dv)->SBRSTART = (sv)->SBRSTART; \
333 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
335 (dv)->type = (sv)->type; \
336 if (((dv)->type = (sv)->type) == TYPE_RET) { \
337 (dv)->vv = (sv)->vv; \
342 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
343 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
346 /* stack modelling macros *******************************************/
348 #define OP0_1(typed) \
351 GET_NEW_VAR(sd, new_index, (typed)); \
352 DST((typed), new_index); \
363 #define OP1_BRANCH(type1) \
369 #define OP1_1(type1, typed) \
372 GET_NEW_VAR(sd, new_index, (typed)); \
373 DST(typed, new_index); \
376 #define OP2_1(type1, type2, typed) \
378 POP_S1_S2(type1, type2); \
379 GET_NEW_VAR(sd, new_index, (typed)); \
380 DST(typed, new_index); \
395 #define OP1_0(type1) \
402 #define OP2_0(type1, type2) \
404 POP_S1_S2(type1, type2); \
409 #define OP2_BRANCH(type1, type2) \
411 POP_S1_S2(type1, type2); \
415 #define OP2_0_ANY_ANY \
422 #define OP3_0(type1, type2, type3) \
424 POP_S1_S2_S3(type1, type2, type3); \
429 #define LOAD(type1, index) \
431 DST_LOCALVAR(type1, index); \
435 #define STORE(type1, index) \
442 /* macros for DUP elimination ***************************************/
444 /* XXX replace NEW_VAR with NEW_INDEX */
445 #define DUP_SLOT(sp) \
447 GET_NEW_VAR(sd, new_index, (sp)->type); \
448 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
449 NEWSTACK((sp)->type, TEMPVAR, new_index); \
452 /* does not check input stackdepth */
453 #define MOVE_UP(sp) \
455 iptr->opc = ICMD_MOVE; \
456 iptr->s1.varindex = (sp)->varnum; \
458 curstack->creator = iptr; \
459 iptr->dst.varindex = curstack->varnum; \
463 /* does not check input stackdepth */
464 #define COPY_UP(sp) \
467 iptr->opc = ICMD_COPY; \
468 iptr->s1.varindex = (sp)->varnum; \
470 curstack->creator = iptr; \
471 iptr->dst.varindex = curstack->varnum; \
475 #define COPY_DOWN(s, d) \
478 iptr->opc = ICMD_COPY; \
479 iptr->s1.varindex = (s)->varnum; \
480 iptr->dst.varindex = (d)->varnum; \
481 (d)->creator = iptr; \
484 #define MOVE_TO_TEMP(sp) \
486 GET_NEW_INDEX(sd, new_index); \
487 iptr->opc = ICMD_MOVE; \
488 iptr->s1.varindex = (sp)->varnum; \
489 iptr->dst.varindex = new_index; \
490 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
491 (sp)->varnum = new_index; \
492 (sp)->varkind = TEMPVAR; \
495 /* macros for branching / reaching basic blocks *********************/
497 #define BRANCH_TARGET(bt, tempbptr) \
499 tempbptr = (bt).block; \
500 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
502 if (tempbptr == NULL) \
504 (bt).block = tempbptr; \
507 #define BRANCH(tempbptr) \
508 BRANCH_TARGET(iptr->dst, tempbptr)
511 /* forward declarations *******************************************************/
513 static void stack_create_invars(stackdata_t *sd, basicblock *b,
514 stackptr curstack, int stackdepth);
515 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
517 #if defined(STACK_VERBOSE)
518 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
519 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
520 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
521 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
522 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
523 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
528 /* stack_init ******************************************************************
530 Initialized the stack analysis subsystem (called by jit_init).
532 *******************************************************************************/
534 bool stack_init(void)
540 /* stack_grow_variable_array ***************************************************
542 Grow the variable array so the given number of additional variables fits in.
543 The number is added to `varcount`, which is the maximum number of variables
544 we expect to need at this point. The actual number of variables
545 (`varsallocated`) may be larger than that, in order to avoid too many
549 sd...........stack analysis data
550 num..........number of additional variables
552 *******************************************************************************/
554 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
560 if (sd->varcount + num > sd->varsallocated) {
561 newsize = 2*sd->varsallocated + num;
563 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
564 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
565 sd->varsallocated = newsize;
566 sd->jd->var = sd->var;
570 sd->jd->varcount += num;
572 assert(sd->varcount <= sd->varsallocated);
576 /* stack_append_block **********************************************************
578 Append the given block after the last real block of the method (before
579 the pseudo-block at the end).
582 sd...........stack analysis data
583 b............the block to append
585 *******************************************************************************/
587 static void stack_append_block(stackdata_t *sd, basicblock *b)
589 #if defined(STACK_VERBOSE)
590 printf("APPENDING BLOCK L%0d\n", b->nr);
593 b->next = sd->last_real_block->next;
594 sd->last_real_block->next = b;
595 sd->last_real_block = b;
596 b->nr = sd->jd->basicblockcount++;
597 b->next->nr = b->nr + 1;
601 /* stack_clone_block ***********************************************************
603 Create a copy of the given block and insert it at the end of the method.
605 CAUTION: This function does not copy the any variables or the instruction
606 list. It _does_, however, reserve space for the block's invars in the
610 sd...........stack analysis data
611 b............the block to clone
614 a pointer to the copy
616 *******************************************************************************/
618 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
622 clone = DNEW(basicblock);
625 clone->iinstr = NULL;
626 clone->inlocals = NULL;
627 clone->javalocals = NULL;
628 clone->invars = NULL;
630 clone->original = (b->original) ? b->original : b;
631 clone->copied_to = clone->original->copied_to;
632 clone->original->copied_to = clone;
634 clone->flags = BBREACHED;
636 stack_append_block(sd, clone);
638 /* reserve space for the invars of the clone */
640 stack_grow_variable_array(sd, b->indepth);
642 #if defined(STACK_VERBOSE)
643 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
650 /* stack_create_locals *********************************************************
652 Create the local variables for the start of the given basic block.
655 sd...........stack analysis data
656 b............block to create the locals for
658 *******************************************************************************/
660 static void stack_create_locals(stackdata_t *sd, basicblock *b)
666 /* copy the current state of the local variables */
667 /* (one extra local is needed by the verifier) */
669 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
671 for (i=0; i<sd->localcount; ++i)
674 /* the current map from java locals to cacao variables */
676 jl = DMNEW(s4, sd->maxlocals);
678 MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
682 /* stack_merge_locals **********************************************************
684 Merge local variables at the beginning of the given basic block.
687 sd...........stack analysis data
688 b............the block that is reached
690 *******************************************************************************/
692 static void stack_merge_locals(stackdata_t *sd, basicblock *b)
698 /* If a javalocal is mapped to different cacao locals along the */
699 /* incoming control-flow edges, it becomes undefined. */
701 for (i=0; i<sd->maxlocals; ++i) {
702 if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
703 b->javalocals[i] = UNUSED;
704 if (b->flags >= BBFINISHED)
705 b->flags = BBTYPECHECK_REACHED;
706 if (b->nr <= sd->bptr->nr)
711 #if defined(ENABLE_VERIFIER)
713 for (i=0; i<sd->localcount; ++i) {
714 dv = b->inlocals + i;
716 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
717 && (sv->SBRSTART != dv->SBRSTART))
719 #if defined(STACK_VERBOSE)
720 printf("JSR MISMATCH: setting variable %d to VOID\n", i);
722 dv->type = TYPE_VOID;
723 if (b->flags >= BBFINISHED)
724 b->flags = BBTYPECHECK_REACHED;
725 sd->repeat = true; /* This is very rare, so just repeat */
729 #endif /* defined(ENABLE_VERIFIER) */
733 /* stack_create_invars *********************************************************
735 Create the invars for the given basic block. Also make a copy of the locals.
738 sd...........stack analysis data
739 b............block to create the invars for
740 curstack.....current stack top
741 stackdepth...current stack depth
743 This function creates STACKDEPTH invars and sets their types to the
744 types to the types of the corresponding slot in the current stack.
746 *******************************************************************************/
748 static void stack_create_invars(stackdata_t *sd, basicblock *b,
749 stackptr curstack, int stackdepth)
757 assert(sd->vartop + stackdepth <= sd->varcount);
759 b->indepth = stackdepth;
760 b->invars = DMNEW(s4, stackdepth);
762 /* allocate the variable indices */
763 index = (sd->vartop += stackdepth);
766 for (sp = curstack; i--; sp = sp->prev) {
767 b->invars[i] = --index;
768 dv = sd->var + index;
769 sv = sd->var + sp->varnum;
771 COPY_VAL_AND_TYPE_VAR(sv, dv);
774 stack_create_locals(sd, b);
778 /* stack_create_invars_from_outvars ********************************************
780 Create the invars for the given basic block. Also make a copy of the locals.
781 Types are propagated from the outvars of the current block.
784 sd...........stack analysis data
785 b............block to create the invars for
787 *******************************************************************************/
789 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
795 n = sd->bptr->outdepth;
796 assert(sd->vartop + n <= sd->varcount);
799 b->invars = DMNEW(s4, n);
802 dv = sd->var + sd->vartop;
804 /* allocate the invars */
806 for (i=0; i<n; ++i, ++dv) {
807 sv = sd->var + sd->bptr->outvars[i];
808 b->invars[i] = sd->vartop++;
810 COPY_VAL_AND_TYPE_VAR(sv, dv);
814 stack_create_locals(sd, b);
818 /* stack_check_invars **********************************************************
820 Check the current stack against the invars of the given basic block.
821 Depth and types must match.
824 sd...........stack analysis data
825 b............block which invars to check against
826 curstack.....current stack top
827 stackdepth...current stack depth
831 NULL.........a VerifyError has been thrown
833 *******************************************************************************/
835 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
836 stackptr curstack, int stackdepth)
845 #if defined(STACK_VERBOSE)
846 printf("stack_check_invars(L%03d)\n", b->nr);
849 /* find original of b */
854 #if defined(STACK_VERBOSE)
855 printf("original is L%03d\n", orig->nr);
860 #if defined(ENABLE_VERIFIER)
861 if (i != stackdepth) {
862 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
870 #if defined(STACK_VERBOSE)
871 printf("checking against ");
872 stack_verbose_show_block(sd, b); printf("\n");
876 for (i = orig->indepth; i--; sp = sp->prev) {
877 dv = sd->var + b->invars[i];
878 sv = sd->var + sp->varnum;
880 #if defined(ENABLE_VERIFIER)
881 if (dv->type != sp->type) {
882 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
887 if (sp->type == TYPE_RET) {
888 #if defined(ENABLE_VERIFIER)
889 if (dv->SBRSTART != sv->SBRSTART) {
890 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
894 if (dv->vv.retaddr != sv->vv.retaddr) {
896 /* don't break! have to check the remaining stackslots */
902 for (i=0; i<sd->localcount; ++i) {
903 dv = b->inlocals + i;
905 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
907 #if defined(ENABLE_VERIFIER)
908 (sv->SBRSTART == dv->SBRSTART) &&
910 (sv->vv.retaddr != dv->vv.retaddr))
920 /* XXX cascading collapse? */
922 stack_merge_locals(sd, b);
924 #if defined(STACK_VERBOSE)
925 printf("------> using L%03d\n", b->nr);
929 } while ((b = b->copied_to) != NULL);
931 b = stack_clone_block(sd, orig);
935 stack_create_invars(sd, b, curstack, stackdepth);
940 /* stack_check_invars_from_outvars *********************************************
942 Check the outvars of the current block against the invars of the given block.
943 Depth and types must match.
946 sd...........stack analysis data
947 b............block which invars to check against
951 NULL.........a VerifyError has been thrown
953 *******************************************************************************/
955 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
963 #if defined(STACK_VERBOSE)
964 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
967 /* find original of b */
972 #if defined(STACK_VERBOSE)
973 printf("original is L%03d\n", orig->nr);
977 n = sd->bptr->outdepth;
979 #if defined(ENABLE_VERIFIER)
981 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
989 #if defined(STACK_VERBOSE)
990 printf("checking against ");
991 stack_verbose_show_block(sd, b); printf("\n");
995 dv = sd->var + b->invars[0];
997 for (i=0; i<n; ++i, ++dv) {
998 sv = sd->var + sd->bptr->outvars[i];
1000 #if defined(ENABLE_VERIFIER)
1001 if (sv->type != dv->type) {
1002 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1007 if (dv->type == TYPE_RET) {
1008 #if defined(ENABLE_VERIFIER)
1009 if (sv->SBRSTART != dv->SBRSTART) {
1010 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1014 if (sv->vv.retaddr != dv->vv.retaddr) {
1016 /* don't break! have to check the remaining stackslots */
1023 for (i=0; i<sd->localcount; ++i) {
1024 dv = b->inlocals + i;
1027 #if defined(ENABLE_VERIFIER)
1028 (sv->SBRSTART == dv->SBRSTART) &&
1030 (sv->type == TYPE_RET && dv->type == TYPE_RET))
1032 if (sv->vv.retaddr != dv->vv.retaddr) {
1041 /* XXX cascading collapse? */
1043 stack_merge_locals(sd, b);
1045 #if defined(STACK_VERBOSE)
1046 printf("------> using L%03d\n", b->nr);
1050 } while ((b = b->copied_to) != NULL);
1052 b = stack_clone_block(sd, orig);
1056 stack_create_invars_from_outvars(sd, b);
1061 /* stack_create_instack ********************************************************
1063 Create the instack of the current basic block.
1066 sd...........stack analysis data
1069 the current stack top at the start of the basic block.
1071 *******************************************************************************/
1073 static stackptr stack_create_instack(stackdata_t *sd)
1079 if ((depth = sd->bptr->indepth) == 0)
1082 sp = (sd->new += depth);
1086 index = sd->bptr->invars[depth];
1088 sp->type = sd->var[index].type;
1092 sp->varkind = STACKVAR;
1096 /* return the top of the created stack */
1101 /* stack_mark_reached **********************************************************
1103 Mark the given block reached and propagate the current stack and locals to
1104 it. This function specializes the target block, if necessary, and returns
1105 a pointer to the specialized target.
1108 sd...........stack analysis data
1109 b............the block to reach
1110 curstack.....the current stack top
1111 stackdepth...the current stack depth
1114 a pointer to (a specialized version of) the target
1115 NULL.........a VerifyError has been thrown
1117 *******************************************************************************/
1119 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1123 #if defined(STACK_VERBOSE)
1124 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1127 /* mark targets of backward branches */
1129 if (b->nr <= sd->bptr->nr)
1130 b->bitflags |= BBFLAG_REPLACEMENT;
1132 if (b->flags < BBREACHED) {
1133 /* b is reached for the first time. Create its invars. */
1135 #if defined(STACK_VERBOSE)
1136 printf("reached L%03d for the first time\n", b->nr);
1139 stack_create_invars(sd, b, curstack, stackdepth);
1141 b->flags = BBREACHED;
1146 /* b has been reached before. Check that its invars match. */
1148 return stack_check_invars(sd, b, curstack, stackdepth);
1153 /* stack_mark_reached_from_outvars *********************************************
1155 Mark the given block reached and propagate the outvars of the current block
1156 and the current locals to it. This function specializes the target block,
1157 if necessary, and returns a pointer to the specialized target.
1160 sd...........stack analysis data
1161 b............the block to reach
1164 a pointer to (a specialized version of) the target
1165 NULL.........a VerifyError has been thrown
1167 *******************************************************************************/
1169 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1173 #if defined(STACK_VERBOSE)
1174 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1177 /* mark targets of backward branches */
1179 if (b->nr <= sd->bptr->nr)
1180 b->bitflags |= BBFLAG_REPLACEMENT;
1182 if (b->flags < BBREACHED) {
1183 /* b is reached for the first time. Create its invars. */
1185 #if defined(STACK_VERBOSE)
1186 printf("reached L%03d for the first time\n", b->nr);
1189 stack_create_invars_from_outvars(sd, b);
1191 b->flags = BBREACHED;
1196 /* b has been reached before. Check that its invars match. */
1198 return stack_check_invars_from_outvars(sd, b);
1203 /* stack_reach_next_block ******************************************************
1205 Mark the following block reached and propagate the outvars of the
1206 current block and the current locals to it. This function
1207 specializes the target block, if necessary, and returns a pointer
1208 to the specialized target.
1211 sd...........stack analysis data
1214 a pointer to (a specialized version of) the following block
1215 NULL.........a VerifyError has been thrown
1217 *******************************************************************************/
1219 static bool stack_reach_next_block(stackdata_t *sd)
1224 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1225 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1230 if (tbptr != sd->bptr->next) {
1231 #if defined(STACK_VERBOSE)
1232 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1234 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1235 assert(iptr->opc == ICMD_NOP);
1236 iptr->opc = ICMD_GOTO;
1237 iptr->dst.block = tbptr;
1239 if (tbptr->flags < BBFINISHED)
1240 sd->repeat = true; /* XXX check if we really need to repeat */
1247 /* stack_reach_handlers ********************************************************
1249 Reach the exception handlers for the current block.
1252 sd...........stack analysis data
1255 true.........everything ok
1256 false........a VerifyError has been thrown
1258 *******************************************************************************/
1260 static bool stack_reach_handlers(stackdata_t *sd)
1265 #if defined(STACK_VERBOSE)
1266 printf("reaching exception handlers...\n");
1269 for (i=0; sd->handlers[i]; ++i) {
1270 tbptr = sd->handlers[i]->handler;
1272 tbptr->type = BBTYPE_EXH;
1273 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1275 /* reach (and specialize) the handler block */
1277 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1282 sd->handlers[i]->handler = tbptr;
1289 /* stack_reanalyse_block ******************************************************
1291 Re-analyse the current block. This is called if either the block itself
1292 has already been analysed before, or the current block is a clone of an
1293 already analysed block, and this clone is reached for the first time.
1294 In the latter case, this function does all that is necessary for fully
1295 cloning the block (cloning the instruction list and variables, etc.).
1298 sd...........stack analysis data
1301 true.........everything ok
1302 false........a VerifyError has been thrown
1304 *******************************************************************************/
1306 #define RELOCATE(index) \
1308 if ((index) >= blockvarstart) \
1309 (index) += blockvarshift; \
1310 else if ((index) >= invarstart) \
1311 (index) += invarshift; \
1314 bool stack_reanalyse_block(stackdata_t *sd)
1326 branch_target_t *table;
1327 lookup_target_t *lookup;
1329 bool cloneinstructions;
1330 exception_entry *ex;
1332 #if defined(STACK_VERBOSE)
1333 stack_verbose_block_enter(sd, true);
1340 assert(orig != NULL);
1342 /* clone the instruction list */
1344 cloneinstructions = true;
1346 assert(orig->iinstr);
1348 iptr = DMNEW(instruction, len + 1);
1350 MCOPY(iptr, orig->iinstr, instruction, len);
1351 iptr[len].opc = ICMD_NOP;
1353 iptr[len].flags.bits = 0;
1357 /* reserve space for the clone's block variables */
1359 stack_grow_variable_array(sd, orig->varcount);
1361 /* we already have the invars set */
1363 assert(b->indepth == orig->indepth);
1365 /* calculate relocation shifts for invars and block variables */
1367 if (orig->indepth) {
1368 invarstart = orig->invars[0];
1369 invarshift = b->invars[0] - invarstart;
1372 invarstart = INT_MAX;
1375 blockvarstart = orig->varstart;
1376 blockvarshift = sd->vartop - blockvarstart;
1378 /* copy block variables */
1380 b->varstart = sd->vartop;
1381 b->varcount = orig->varcount;
1382 sd->vartop += b->varcount;
1383 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1387 b->outdepth = orig->outdepth;
1388 b->outvars = DMNEW(s4, orig->outdepth);
1389 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1391 /* clone exception handlers */
1393 for (i=0; sd->handlers[i]; ++i) {
1394 ex = DNEW(exception_entry);
1395 ex->handler = sd->handlers[i]->handler;
1397 ex->end = b; /* XXX hack, see end of stack_analyse */
1398 ex->catchtype = sd->handlers[i]->catchtype;
1401 assert(sd->extableend->down == NULL);
1402 sd->extableend->down = ex;
1403 sd->extableend = ex;
1404 sd->jd->exceptiontablelength++;
1406 sd->handlers[i] = ex;
1410 cloneinstructions = false;
1413 invarstart = sd->vartop;
1414 blockvarstart = sd->vartop;
1419 /* find exception handlers for the cloned block */
1421 ex = sd->jd->exceptiontable;
1422 for (; ex != NULL; ex = ex->down) {
1423 /* XXX the cloned exception handlers have identical */
1424 /* start end end blocks. */
1425 if ((ex->start == b) && (ex->end == b)) {
1426 sd->handlers[len++] = ex;
1429 sd->handlers[len] = NULL;
1432 #if defined(STACK_VERBOSE)
1433 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1434 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1437 /* mark block as finished */
1439 b->flags = BBFINISHED;
1441 /* initialize locals at the start of this block */
1444 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1446 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1448 /* reach exception handlers for this block */
1450 if (!stack_reach_handlers(sd))
1453 superblockend = false;
1455 for (len = b->icount; len--; iptr++) {
1456 #if defined(STACK_VERBOSE)
1457 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1461 switch (iptr->opc) {
1463 varindex = iptr->s1.varindex;
1465 #if defined(ENABLE_VERIFIER)
1466 if (sd->var[varindex].type != TYPE_RET) {
1467 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1472 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1473 superblockend = true;
1477 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1478 RELOCATE(iptr->dst.varindex);
1479 superblockend = true;
1483 superblockend = true;
1486 case ICMD_CHECKNULL:
1487 case ICMD_PUTSTATICCONST:
1495 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1496 superblockend = true;
1499 /* pop 0 push 1 const */
1507 /* pop 0 push 1 load */
1514 RELOCATE(iptr->dst.varindex);
1527 RELOCATE(iptr->sx.s23.s2.varindex);
1528 RELOCATE(iptr->s1.varindex);
1529 RELOCATE(iptr->dst.varindex);
1542 RELOCATE(iptr->sx.s23.s3.varindex);
1543 RELOCATE(iptr->sx.s23.s2.varindex);
1544 RELOCATE(iptr->s1.varindex);
1547 /* pop 1 push 0 store */
1554 RELOCATE(iptr->s1.varindex);
1556 varindex = iptr->dst.varindex;
1557 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1558 i = iptr->sx.s23.s3.javaindex;
1559 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1560 iptr->sx.s23.s2.retaddrnr =
1561 JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1562 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1565 sd->javalocals[i] = varindex;
1566 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1567 sd->javalocals[i-1] = UNUSED;
1568 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1569 sd->javalocals[i+1] = UNUSED;
1580 RELOCATE(iptr->s1.varindex);
1581 superblockend = true;
1584 case ICMD_PUTSTATIC:
1585 case ICMD_PUTFIELDCONST:
1587 RELOCATE(iptr->s1.varindex);
1590 /* pop 1 push 0 branch */
1593 case ICMD_IFNONNULL:
1608 RELOCATE(iptr->s1.varindex);
1609 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1612 /* pop 1 push 0 table branch */
1614 case ICMD_TABLESWITCH:
1615 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1617 if (cloneinstructions) {
1618 table = DMNEW(branch_target_t, i);
1619 MCOPY(table, iptr->dst.table, branch_target_t, i);
1620 iptr->dst.table = table;
1623 table = iptr->dst.table;
1626 RELOCATE(iptr->s1.varindex);
1628 table->block = stack_mark_reached_from_outvars(sd, table->block);
1631 superblockend = true;
1634 case ICMD_LOOKUPSWITCH:
1635 i = iptr->sx.s23.s2.lookupcount;
1636 if (cloneinstructions) {
1637 lookup = DMNEW(lookup_target_t, i);
1638 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1639 iptr->dst.lookup = lookup;
1642 lookup = iptr->dst.lookup;
1644 RELOCATE(iptr->s1.varindex);
1646 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1649 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1650 superblockend = true;
1653 case ICMD_MONITORENTER:
1654 case ICMD_MONITOREXIT:
1655 RELOCATE(iptr->s1.varindex);
1658 /* pop 2 push 0 branch */
1660 case ICMD_IF_ICMPEQ:
1661 case ICMD_IF_ICMPNE:
1662 case ICMD_IF_ICMPLT:
1663 case ICMD_IF_ICMPGE:
1664 case ICMD_IF_ICMPGT:
1665 case ICMD_IF_ICMPLE:
1667 case ICMD_IF_LCMPEQ:
1668 case ICMD_IF_LCMPNE:
1669 case ICMD_IF_LCMPLT:
1670 case ICMD_IF_LCMPGE:
1671 case ICMD_IF_LCMPGT:
1672 case ICMD_IF_LCMPLE:
1674 case ICMD_IF_FCMPEQ:
1675 case ICMD_IF_FCMPNE:
1677 case ICMD_IF_FCMPL_LT:
1678 case ICMD_IF_FCMPL_GE:
1679 case ICMD_IF_FCMPL_GT:
1680 case ICMD_IF_FCMPL_LE:
1682 case ICMD_IF_FCMPG_LT:
1683 case ICMD_IF_FCMPG_GE:
1684 case ICMD_IF_FCMPG_GT:
1685 case ICMD_IF_FCMPG_LE:
1687 case ICMD_IF_DCMPEQ:
1688 case ICMD_IF_DCMPNE:
1690 case ICMD_IF_DCMPL_LT:
1691 case ICMD_IF_DCMPL_GE:
1692 case ICMD_IF_DCMPL_GT:
1693 case ICMD_IF_DCMPL_LE:
1695 case ICMD_IF_DCMPG_LT:
1696 case ICMD_IF_DCMPG_GE:
1697 case ICMD_IF_DCMPG_GT:
1698 case ICMD_IF_DCMPG_LE:
1700 case ICMD_IF_ACMPEQ:
1701 case ICMD_IF_ACMPNE:
1702 RELOCATE(iptr->sx.s23.s2.varindex);
1703 RELOCATE(iptr->s1.varindex);
1704 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1710 case ICMD_IASTORECONST:
1711 case ICMD_LASTORECONST:
1712 case ICMD_AASTORECONST:
1713 case ICMD_BASTORECONST:
1714 case ICMD_CASTORECONST:
1715 case ICMD_SASTORECONST:
1717 RELOCATE(iptr->sx.s23.s2.varindex);
1718 RELOCATE(iptr->s1.varindex);
1721 /* pop 0 push 1 copy */
1725 RELOCATE(iptr->dst.varindex);
1726 RELOCATE(iptr->s1.varindex);
1727 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1769 RELOCATE(iptr->sx.s23.s2.varindex);
1770 RELOCATE(iptr->s1.varindex);
1771 RELOCATE(iptr->dst.varindex);
1776 case ICMD_CHECKCAST:
1777 case ICMD_ARRAYLENGTH:
1778 case ICMD_INSTANCEOF:
1780 case ICMD_ANEWARRAY:
1782 case ICMD_IADDCONST:
1783 case ICMD_ISUBCONST:
1784 case ICMD_IMULCONST:
1788 case ICMD_IANDCONST:
1790 case ICMD_IXORCONST:
1791 case ICMD_ISHLCONST:
1792 case ICMD_ISHRCONST:
1793 case ICMD_IUSHRCONST:
1794 case ICMD_LADDCONST:
1795 case ICMD_LSUBCONST:
1796 case ICMD_LMULCONST:
1800 case ICMD_LANDCONST:
1802 case ICMD_LXORCONST:
1803 case ICMD_LSHLCONST:
1804 case ICMD_LSHRCONST:
1805 case ICMD_LUSHRCONST:
1809 case ICMD_INT2SHORT:
1825 RELOCATE(iptr->s1.varindex);
1826 RELOCATE(iptr->dst.varindex);
1831 case ICMD_GETSTATIC:
1833 RELOCATE(iptr->dst.varindex);
1836 /* pop many push any */
1838 case ICMD_INVOKESTATIC:
1839 case ICMD_INVOKESPECIAL:
1840 case ICMD_INVOKEVIRTUAL:
1841 case ICMD_INVOKEINTERFACE:
1843 case ICMD_MULTIANEWARRAY:
1844 i = iptr->s1.argcount;
1845 if (cloneinstructions) {
1846 argp = DMNEW(s4, i);
1847 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1848 iptr->sx.s23.s2.args = argp;
1851 argp = iptr->sx.s23.s2.args;
1858 RELOCATE(iptr->dst.varindex);
1862 exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1867 #if defined(STACK_VERBOSE)
1868 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1873 /* relocate outvars */
1875 for (i=0; i<b->outdepth; ++i) {
1876 RELOCATE(b->outvars[i]);
1879 #if defined(STACK_VERBOSE)
1880 stack_verbose_block_exit(sd, superblockend);
1883 /* propagate to the next block */
1886 if (!stack_reach_next_block(sd))
1893 /* stack_change_to_tempvar *****************************************************
1895 Change the given stackslot to a TEMPVAR. This includes creating a new
1896 temporary variable and changing the dst.varindex of the creator of the
1897 stacklot to the new variable index. If this stackslot has been passed
1898 through ICMDs between the point of its creation and the current point,
1899 then the variable index is also changed in these ICMDs.
1902 sd...........stack analysis data
1903 sp...........stackslot to change
1904 ilimit.......instruction up to which to look for ICMDs passing-through
1905 the stackslot (exclusive). This may point exactly after the
1906 last instruction, in which case the search is done to the
1909 *******************************************************************************/
1911 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1912 instruction *ilimit)
1920 oldindex = sp->varnum;
1922 /* create a new temporary variable */
1924 GET_NEW_VAR(*sd, newindex, sp->type);
1926 sd->var[newindex].flags = sp->flags;
1928 /* change the stackslot */
1930 sp->varnum = newindex;
1931 sp->varkind = TEMPVAR;
1933 /* change the dst.varindex of the stackslot's creator */
1936 sp->creator->dst.varindex = newindex;
1938 /* handle ICMDs this stackslot passed through, if any */
1940 if (sp->flags & PASSTHROUGH) {
1941 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1943 /* assert that the limit points to an ICMD, or after the last one */
1945 assert(ilimit >= sd->bptr->iinstr);
1946 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1948 /* find the stackdepth under sp plus one */
1949 /* Note: This number is usually known when this function is called, */
1950 /* but calculating it here is less error-prone and should not be */
1951 /* a performance problem. */
1953 for (depth = 0; sp != NULL; sp = sp->prev)
1956 /* iterate over all instructions in the range and replace */
1958 for (; iptr < ilimit; ++iptr) {
1959 switch (iptr->opc) {
1960 case ICMD_INVOKESTATIC:
1961 case ICMD_INVOKESPECIAL:
1962 case ICMD_INVOKEVIRTUAL:
1963 case ICMD_INVOKEINTERFACE:
1965 i = iptr->s1.argcount - depth;
1966 if (iptr->sx.s23.s2.args[i] == oldindex) {
1967 iptr->sx.s23.s2.args[i] = newindex;
1970 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1971 /* stackslot, it must be added in this switch! */
1978 /* stack_init_javalocals *******************************************************
1980 Initialize the mapping from Java locals to cacao variables at method entry.
1983 sd...........stack analysis data
1985 *******************************************************************************/
1987 static void stack_init_javalocals(stackdata_t *sd)
1996 jl = DMNEW(s4, sd->maxlocals);
1997 jd->basicblocks[0].javalocals = jl;
1999 for (i=0; i<sd->maxlocals; ++i)
2002 md = jd->m->parseddesc;
2004 for (i=0; i<md->paramcount; ++i) {
2005 type = md->paramtypes[i].type;
2006 jl[j] = jd->local_map[5*j + type];
2008 if (IS_2_WORD_TYPE(type))
2014 /* stack_analyse ***************************************************************
2016 Analyse_stack uses the intermediate code created by parse.c to
2017 build a model of the JVM operand stack for the current method.
2019 The following checks are performed:
2020 - check for operand stack underflow (before each instruction)
2021 - check for operand stack overflow (after[1] each instruction)
2022 - check for matching stack depth at merging points
2023 - check for matching basic types[2] at merging points
2024 - check basic types for instruction input (except for BUILTIN*
2025 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
2027 [1]) Checking this after the instruction should be ok. parse.c
2028 counts the number of required stack slots in such a way that it is
2029 only vital that we don't exceed `maxstack` at basic block
2032 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2033 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2034 types are not discerned.
2036 *******************************************************************************/
2038 bool stack_analyse(jitdata *jd)
2040 methodinfo *m; /* method being analyzed */
2044 stackptr curstack; /* current stack top */
2046 int opcode; /* opcode of current instruction */
2049 int type; /* operand type */
2050 int len; /* # of instructions after the current one */
2051 bool superblockend; /* if true, no fallthrough to next block */
2052 bool deadcode; /* true if no live code has been reached */
2053 instruction *iptr; /* the current instruction */
2055 basicblock *original;
2056 exception_entry *ex;
2058 stackptr *last_store_boundary;
2059 stackptr coalescing_boundary;
2061 stackptr src1, src2, src3, src4, dst1, dst2;
2063 branch_target_t *table;
2064 lookup_target_t *lookup;
2065 #if defined(ENABLE_VERIFIER)
2066 int expectedtype; /* used by CHECK_BASIC_TYPE */
2068 builtintable_entry *bte;
2070 constant_FMIref *fmiref;
2071 #if defined(ENABLE_STATISTICS)
2072 int iteration_count; /* number of iterations of analysis */
2074 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2076 #if defined(STACK_VERBOSE)
2077 show_method(jd, SHOW_PARSE);
2080 /* get required compiler data - initialization */
2085 /* initialize the stackdata_t struct */
2089 sd.varcount = jd->varcount;
2090 sd.vartop = jd->vartop;
2091 sd.localcount = jd->localcount;
2093 sd.varsallocated = sd.varcount;
2094 sd.maxlocals = m->maxlocals;
2095 sd.javalocals = DMNEW(s4, sd.maxlocals);
2096 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2098 /* prepare the variable for exception handler stacks */
2099 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2101 sd.exstack.type = TYPE_ADR;
2102 sd.exstack.prev = NULL;
2103 sd.exstack.varnum = sd.localcount;
2104 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2106 #if defined(ENABLE_STATISTICS)
2107 iteration_count = 0;
2110 /* find the last real basic block */
2112 sd.last_real_block = NULL;
2113 tbptr = jd->basicblocks;
2114 while (tbptr->next) {
2115 sd.last_real_block = tbptr;
2116 tbptr = tbptr->next;
2118 assert(sd.last_real_block);
2120 /* find the last exception handler */
2122 if (jd->exceptiontablelength)
2123 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2125 sd.extableend = NULL;
2127 /* init jd->interface_map */
2129 jd->maxinterfaces = m->maxstack;
2130 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2131 for (i = 0; i < m->maxstack * 5; i++)
2132 jd->interface_map[i].flags = UNUSED;
2134 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2136 /* initialize flags and invars (none) of first block */
2138 jd->basicblocks[0].flags = BBREACHED;
2139 jd->basicblocks[0].invars = NULL;
2140 jd->basicblocks[0].indepth = 0;
2141 jd->basicblocks[0].inlocals =
2142 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2143 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2144 jd->localcount + VERIFIER_EXTRA_LOCALS);
2146 /* initialize java local mapping of first block */
2148 stack_init_javalocals(&sd);
2150 /* stack analysis loop (until fixpoint reached) **************************/
2153 #if defined(ENABLE_STATISTICS)
2157 /* initialize loop over basic blocks */
2159 sd.bptr = jd->basicblocks;
2160 superblockend = true;
2166 /* iterate over basic blocks *****************************************/
2168 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2170 if (sd.bptr->flags == BBDELETED) {
2171 /* This block has been deleted - do nothing. */
2176 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2177 /* re-analyse a block because its input changed */
2181 if (!stack_reanalyse_block(&sd))
2184 superblockend = true; /* XXX */
2188 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2189 /* This block has not been reached so far, and we
2190 don't fall into it, so we'll have to iterate
2197 if (sd.bptr->flags > BBREACHED) {
2198 /* This block is already finished. */
2200 superblockend = true;
2204 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2205 /* This block is a clone and the original has not been
2206 analysed, yet. Analyse it on the next
2210 /* XXX superblockend? */
2214 /* This block has to be analysed now. */
2218 /* XXX The rest of this block is still indented one level too */
2219 /* much in order to avoid a giant diff by changing that. */
2221 /* We know that sd.bptr->flags == BBREACHED. */
2222 /* This block has been reached before. */
2224 assert(sd.bptr->flags == BBREACHED);
2225 stackdepth = sd.bptr->indepth;
2227 /* find exception handlers for this block */
2229 /* determine the active exception handlers for this block */
2230 /* XXX could use a faster algorithm with sorted lists or */
2233 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2236 ex = jd->exceptiontable;
2237 for (; ex != NULL; ex = ex->down) {
2238 if ((ex->start <= original) && (ex->end > original)) {
2239 sd.handlers[len++] = ex;
2242 sd.handlers[len] = NULL;
2245 /* reanalyse cloned block */
2247 if (sd.bptr->original) {
2248 if (!stack_reanalyse_block(&sd))
2253 /* reset the new pointer for allocating stackslots */
2257 /* create the instack of this block */
2259 curstack = stack_create_instack(&sd);
2261 /* initialize locals at the start of this block */
2263 if (sd.bptr->inlocals)
2264 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2266 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2268 /* set up local variables for analyzing this block */
2270 superblockend = false;
2271 len = sd.bptr->icount;
2272 iptr = sd.bptr->iinstr;
2274 /* mark the block as analysed */
2276 sd.bptr->flags = BBFINISHED;
2278 /* reset variables for dependency checking */
2280 coalescing_boundary = sd.new;
2281 for( i = 0; i < m->maxlocals; i++)
2282 last_store_boundary[i] = sd.new;
2284 /* remember the start of this block's variables */
2286 sd.bptr->varstart = sd.vartop;
2288 #if defined(STACK_VERBOSE)
2289 stack_verbose_block_enter(&sd, false);
2292 /* reach exception handlers for this block */
2294 if (!stack_reach_handlers(&sd))
2297 /* iterate over ICMDs ****************************************/
2299 while (--len >= 0) {
2301 #if defined(STACK_VERBOSE)
2302 stack_verbose_show_state(&sd, iptr, curstack);
2305 /* fetch the current opcode */
2309 /* automatically replace some ICMDs with builtins */
2311 bte = builtintable_get_automatic(opcode);
2313 if ((bte != NULL) && (bte->opcode == opcode)) {
2314 iptr->opc = ICMD_BUILTIN;
2315 iptr->flags.bits &= INS_FLAG_ID_MASK;
2316 iptr->sx.s23.s3.bte = bte;
2317 /* iptr->line is already set */
2318 jd->isleafmethod = false;
2322 /* main opcode switch *************************************/
2334 case ICMD_CHECKNULL:
2335 coalescing_boundary = sd.new;
2336 COUNT(count_check_null);
2339 iptr->dst.varindex = iptr->s1.varindex;
2343 varindex = iptr->s1.varindex =
2344 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2346 #if defined(ENABLE_VERIFIER)
2347 if (sd.var[varindex].type != TYPE_RET) {
2348 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2355 iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2356 superblockend = true;
2360 COUNT(count_pcmd_return);
2363 superblockend = true;
2364 sd.jd->returncount++;
2365 sd.jd->returnblock = sd.bptr;
2369 /* pop 0 push 1 const */
2371 /************************** ICONST OPTIMIZATIONS **************************/
2374 COUNT(count_pcmd_load);
2378 switch (iptr[1].opc) {
2380 iptr->opc = ICMD_IADDCONST;
2384 iptr[1].opc = ICMD_NOP;
2385 OP1_1(TYPE_INT, TYPE_INT);
2386 COUNT(count_pcmd_op);
2390 iptr->opc = ICMD_ISUBCONST;
2391 goto icmd_iconst_tail;
2392 #if SUPPORT_CONST_MUL
2394 iptr->opc = ICMD_IMULCONST;
2395 goto icmd_iconst_tail;
2396 #else /* SUPPORT_CONST_MUL */
2398 if (iptr->sx.val.i == 0x00000002)
2400 else if (iptr->sx.val.i == 0x00000004)
2402 else if (iptr->sx.val.i == 0x00000008)
2404 else if (iptr->sx.val.i == 0x00000010)
2406 else if (iptr->sx.val.i == 0x00000020)
2408 else if (iptr->sx.val.i == 0x00000040)
2410 else if (iptr->sx.val.i == 0x00000080)
2412 else if (iptr->sx.val.i == 0x00000100)
2414 else if (iptr->sx.val.i == 0x00000200)
2416 else if (iptr->sx.val.i == 0x00000400)
2417 iptr->sx.val.i = 10;
2418 else if (iptr->sx.val.i == 0x00000800)
2419 iptr->sx.val.i = 11;
2420 else if (iptr->sx.val.i == 0x00001000)
2421 iptr->sx.val.i = 12;
2422 else if (iptr->sx.val.i == 0x00002000)
2423 iptr->sx.val.i = 13;
2424 else if (iptr->sx.val.i == 0x00004000)
2425 iptr->sx.val.i = 14;
2426 else if (iptr->sx.val.i == 0x00008000)
2427 iptr->sx.val.i = 15;
2428 else if (iptr->sx.val.i == 0x00010000)
2429 iptr->sx.val.i = 16;
2430 else if (iptr->sx.val.i == 0x00020000)
2431 iptr->sx.val.i = 17;
2432 else if (iptr->sx.val.i == 0x00040000)
2433 iptr->sx.val.i = 18;
2434 else if (iptr->sx.val.i == 0x00080000)
2435 iptr->sx.val.i = 19;
2436 else if (iptr->sx.val.i == 0x00100000)
2437 iptr->sx.val.i = 20;
2438 else if (iptr->sx.val.i == 0x00200000)
2439 iptr->sx.val.i = 21;
2440 else if (iptr->sx.val.i == 0x00400000)
2441 iptr->sx.val.i = 22;
2442 else if (iptr->sx.val.i == 0x00800000)
2443 iptr->sx.val.i = 23;
2444 else if (iptr->sx.val.i == 0x01000000)
2445 iptr->sx.val.i = 24;
2446 else if (iptr->sx.val.i == 0x02000000)
2447 iptr->sx.val.i = 25;
2448 else if (iptr->sx.val.i == 0x04000000)
2449 iptr->sx.val.i = 26;
2450 else if (iptr->sx.val.i == 0x08000000)
2451 iptr->sx.val.i = 27;
2452 else if (iptr->sx.val.i == 0x10000000)
2453 iptr->sx.val.i = 28;
2454 else if (iptr->sx.val.i == 0x20000000)
2455 iptr->sx.val.i = 29;
2456 else if (iptr->sx.val.i == 0x40000000)
2457 iptr->sx.val.i = 30;
2458 else if (iptr->sx.val.i == 0x80000000)
2459 iptr->sx.val.i = 31;
2463 iptr->opc = ICMD_IMULPOW2;
2464 goto icmd_iconst_tail;
2465 #endif /* SUPPORT_CONST_MUL */
2467 if (iptr->sx.val.i == 0x00000002)
2469 else if (iptr->sx.val.i == 0x00000004)
2471 else if (iptr->sx.val.i == 0x00000008)
2473 else if (iptr->sx.val.i == 0x00000010)
2475 else if (iptr->sx.val.i == 0x00000020)
2477 else if (iptr->sx.val.i == 0x00000040)
2479 else if (iptr->sx.val.i == 0x00000080)
2481 else if (iptr->sx.val.i == 0x00000100)
2483 else if (iptr->sx.val.i == 0x00000200)
2485 else if (iptr->sx.val.i == 0x00000400)
2486 iptr->sx.val.i = 10;
2487 else if (iptr->sx.val.i == 0x00000800)
2488 iptr->sx.val.i = 11;
2489 else if (iptr->sx.val.i == 0x00001000)
2490 iptr->sx.val.i = 12;
2491 else if (iptr->sx.val.i == 0x00002000)
2492 iptr->sx.val.i = 13;
2493 else if (iptr->sx.val.i == 0x00004000)
2494 iptr->sx.val.i = 14;
2495 else if (iptr->sx.val.i == 0x00008000)
2496 iptr->sx.val.i = 15;
2497 else if (iptr->sx.val.i == 0x00010000)
2498 iptr->sx.val.i = 16;
2499 else if (iptr->sx.val.i == 0x00020000)
2500 iptr->sx.val.i = 17;
2501 else if (iptr->sx.val.i == 0x00040000)
2502 iptr->sx.val.i = 18;
2503 else if (iptr->sx.val.i == 0x00080000)
2504 iptr->sx.val.i = 19;
2505 else if (iptr->sx.val.i == 0x00100000)
2506 iptr->sx.val.i = 20;
2507 else if (iptr->sx.val.i == 0x00200000)
2508 iptr->sx.val.i = 21;
2509 else if (iptr->sx.val.i == 0x00400000)
2510 iptr->sx.val.i = 22;
2511 else if (iptr->sx.val.i == 0x00800000)
2512 iptr->sx.val.i = 23;
2513 else if (iptr->sx.val.i == 0x01000000)
2514 iptr->sx.val.i = 24;
2515 else if (iptr->sx.val.i == 0x02000000)
2516 iptr->sx.val.i = 25;
2517 else if (iptr->sx.val.i == 0x04000000)
2518 iptr->sx.val.i = 26;
2519 else if (iptr->sx.val.i == 0x08000000)
2520 iptr->sx.val.i = 27;
2521 else if (iptr->sx.val.i == 0x10000000)
2522 iptr->sx.val.i = 28;
2523 else if (iptr->sx.val.i == 0x20000000)
2524 iptr->sx.val.i = 29;
2525 else if (iptr->sx.val.i == 0x40000000)
2526 iptr->sx.val.i = 30;
2527 else if (iptr->sx.val.i == 0x80000000)
2528 iptr->sx.val.i = 31;
2532 iptr->opc = ICMD_IDIVPOW2;
2533 goto icmd_iconst_tail;
2536 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2537 if ((iptr->sx.val.i == 0x00000002) ||
2538 (iptr->sx.val.i == 0x00000004) ||
2539 (iptr->sx.val.i == 0x00000008) ||
2540 (iptr->sx.val.i == 0x00000010) ||
2541 (iptr->sx.val.i == 0x00000020) ||
2542 (iptr->sx.val.i == 0x00000040) ||
2543 (iptr->sx.val.i == 0x00000080) ||
2544 (iptr->sx.val.i == 0x00000100) ||
2545 (iptr->sx.val.i == 0x00000200) ||
2546 (iptr->sx.val.i == 0x00000400) ||
2547 (iptr->sx.val.i == 0x00000800) ||
2548 (iptr->sx.val.i == 0x00001000) ||
2549 (iptr->sx.val.i == 0x00002000) ||
2550 (iptr->sx.val.i == 0x00004000) ||
2551 (iptr->sx.val.i == 0x00008000) ||
2552 (iptr->sx.val.i == 0x00010000) ||
2553 (iptr->sx.val.i == 0x00020000) ||
2554 (iptr->sx.val.i == 0x00040000) ||
2555 (iptr->sx.val.i == 0x00080000) ||
2556 (iptr->sx.val.i == 0x00100000) ||
2557 (iptr->sx.val.i == 0x00200000) ||
2558 (iptr->sx.val.i == 0x00400000) ||
2559 (iptr->sx.val.i == 0x00800000) ||
2560 (iptr->sx.val.i == 0x01000000) ||
2561 (iptr->sx.val.i == 0x02000000) ||
2562 (iptr->sx.val.i == 0x04000000) ||
2563 (iptr->sx.val.i == 0x08000000) ||
2564 (iptr->sx.val.i == 0x10000000) ||
2565 (iptr->sx.val.i == 0x20000000) ||
2566 (iptr->sx.val.i == 0x40000000) ||
2567 (iptr->sx.val.i == 0x80000000))
2569 iptr->opc = ICMD_IREMPOW2;
2570 iptr->sx.val.i -= 1;
2571 goto icmd_iconst_tail;
2574 #if SUPPORT_CONST_LOGICAL
2576 iptr->opc = ICMD_IANDCONST;
2577 goto icmd_iconst_tail;
2580 iptr->opc = ICMD_IORCONST;
2581 goto icmd_iconst_tail;
2584 iptr->opc = ICMD_IXORCONST;
2585 goto icmd_iconst_tail;
2587 #endif /* SUPPORT_CONST_LOGICAL */
2589 iptr->opc = ICMD_ISHLCONST;
2590 goto icmd_iconst_tail;
2593 iptr->opc = ICMD_ISHRCONST;
2594 goto icmd_iconst_tail;
2597 iptr->opc = ICMD_IUSHRCONST;
2598 goto icmd_iconst_tail;
2599 #if SUPPORT_LONG_SHIFT
2601 iptr->opc = ICMD_LSHLCONST;
2602 goto icmd_lconst_tail;
2605 iptr->opc = ICMD_LSHRCONST;
2606 goto icmd_lconst_tail;
2609 iptr->opc = ICMD_LUSHRCONST;
2610 goto icmd_lconst_tail;
2611 #endif /* SUPPORT_LONG_SHIFT */
2612 case ICMD_IF_ICMPEQ:
2613 iptr[1].opc = ICMD_IFEQ;
2617 /* set the constant for the following icmd */
2618 iptr[1].sx.val.i = iptr->sx.val.i;
2620 /* this instruction becomes a nop */
2621 iptr->opc = ICMD_NOP;
2624 case ICMD_IF_ICMPLT:
2625 iptr[1].opc = ICMD_IFLT;
2626 goto icmd_if_icmp_tail;
2628 case ICMD_IF_ICMPLE:
2629 iptr[1].opc = ICMD_IFLE;
2630 goto icmd_if_icmp_tail;
2632 case ICMD_IF_ICMPNE:
2633 iptr[1].opc = ICMD_IFNE;
2634 goto icmd_if_icmp_tail;
2636 case ICMD_IF_ICMPGT:
2637 iptr[1].opc = ICMD_IFGT;
2638 goto icmd_if_icmp_tail;
2640 case ICMD_IF_ICMPGE:
2641 iptr[1].opc = ICMD_IFGE;
2642 goto icmd_if_icmp_tail;
2644 #if SUPPORT_CONST_STORE
2649 # if SUPPORT_CONST_STORE_ZERO_ONLY
2650 if (iptr->sx.val.i != 0)
2653 switch (iptr[1].opc) {
2655 iptr->opc = ICMD_IASTORECONST;
2656 iptr->flags.bits |= INS_FLAG_CHECK;
2659 iptr->opc = ICMD_BASTORECONST;
2660 iptr->flags.bits |= INS_FLAG_CHECK;
2663 iptr->opc = ICMD_CASTORECONST;
2664 iptr->flags.bits |= INS_FLAG_CHECK;
2667 iptr->opc = ICMD_SASTORECONST;
2668 iptr->flags.bits |= INS_FLAG_CHECK;
2672 iptr[1].opc = ICMD_NOP;
2674 /* copy the constant to s3 */
2675 /* XXX constval -> astoreconstval? */
2676 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2677 OP2_0(TYPE_ADR, TYPE_INT);
2678 COUNT(count_pcmd_op);
2681 case ICMD_PUTSTATIC:
2683 # if SUPPORT_CONST_STORE_ZERO_ONLY
2684 if (iptr->sx.val.i != 0)
2687 /* XXX check field type? */
2689 /* copy the constant to s2 */
2690 /* XXX constval -> fieldconstval? */
2691 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2694 /* set the field reference (s3) */
2695 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2696 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2697 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2698 fmiref = iptr->sx.s23.s3.uf->fieldref;
2701 fmiref = iptr[1].sx.s23.s3.fmiref;
2702 iptr->sx.s23.s3.fmiref = fmiref;
2705 #if defined(ENABLE_VERIFIER)
2706 expectedtype = fmiref->parseddesc.fd->type;
2707 switch (iptr[0].opc) {
2709 if (expectedtype != TYPE_INT)
2710 goto throw_stack_type_error;
2713 if (expectedtype != TYPE_LNG)
2714 goto throw_stack_type_error;
2717 if (expectedtype != TYPE_ADR)
2718 goto throw_stack_type_error;
2723 #endif /* defined(ENABLE_VERIFIER) */
2725 switch (iptr[1].opc) {
2726 case ICMD_PUTSTATIC:
2727 iptr->opc = ICMD_PUTSTATICCONST;
2731 iptr->opc = ICMD_PUTFIELDCONST;
2736 iptr[1].opc = ICMD_NOP;
2737 COUNT(count_pcmd_op);
2739 #endif /* SUPPORT_CONST_STORE */
2745 /* if we get here, the ICONST has been optimized */
2749 /* normal case of an unoptimized ICONST */
2753 /************************** LCONST OPTIMIZATIONS **************************/
2756 COUNT(count_pcmd_load);
2760 /* switch depending on the following instruction */
2762 switch (iptr[1].opc) {
2763 #if SUPPORT_LONG_ADD
2765 iptr->opc = ICMD_LADDCONST;
2769 /* instruction of type LONG -> LONG */
2770 iptr[1].opc = ICMD_NOP;
2771 OP1_1(TYPE_LNG, TYPE_LNG);
2772 COUNT(count_pcmd_op);
2776 iptr->opc = ICMD_LSUBCONST;
2777 goto icmd_lconst_tail;
2779 #endif /* SUPPORT_LONG_ADD */
2780 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2782 iptr->opc = ICMD_LMULCONST;
2783 goto icmd_lconst_tail;
2784 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2785 # if SUPPORT_LONG_SHIFT
2787 if (iptr->sx.val.l == 0x00000002)
2789 else if (iptr->sx.val.l == 0x00000004)
2791 else if (iptr->sx.val.l == 0x00000008)
2793 else if (iptr->sx.val.l == 0x00000010)
2795 else if (iptr->sx.val.l == 0x00000020)
2797 else if (iptr->sx.val.l == 0x00000040)
2799 else if (iptr->sx.val.l == 0x00000080)
2801 else if (iptr->sx.val.l == 0x00000100)
2803 else if (iptr->sx.val.l == 0x00000200)
2805 else if (iptr->sx.val.l == 0x00000400)
2806 iptr->sx.val.i = 10;
2807 else if (iptr->sx.val.l == 0x00000800)
2808 iptr->sx.val.i = 11;
2809 else if (iptr->sx.val.l == 0x00001000)
2810 iptr->sx.val.i = 12;
2811 else if (iptr->sx.val.l == 0x00002000)
2812 iptr->sx.val.i = 13;
2813 else if (iptr->sx.val.l == 0x00004000)
2814 iptr->sx.val.i = 14;
2815 else if (iptr->sx.val.l == 0x00008000)
2816 iptr->sx.val.i = 15;
2817 else if (iptr->sx.val.l == 0x00010000)
2818 iptr->sx.val.i = 16;
2819 else if (iptr->sx.val.l == 0x00020000)
2820 iptr->sx.val.i = 17;
2821 else if (iptr->sx.val.l == 0x00040000)
2822 iptr->sx.val.i = 18;
2823 else if (iptr->sx.val.l == 0x00080000)
2824 iptr->sx.val.i = 19;
2825 else if (iptr->sx.val.l == 0x00100000)
2826 iptr->sx.val.i = 20;
2827 else if (iptr->sx.val.l == 0x00200000)
2828 iptr->sx.val.i = 21;
2829 else if (iptr->sx.val.l == 0x00400000)
2830 iptr->sx.val.i = 22;
2831 else if (iptr->sx.val.l == 0x00800000)
2832 iptr->sx.val.i = 23;
2833 else if (iptr->sx.val.l == 0x01000000)
2834 iptr->sx.val.i = 24;
2835 else if (iptr->sx.val.l == 0x02000000)
2836 iptr->sx.val.i = 25;
2837 else if (iptr->sx.val.l == 0x04000000)
2838 iptr->sx.val.i = 26;
2839 else if (iptr->sx.val.l == 0x08000000)
2840 iptr->sx.val.i = 27;
2841 else if (iptr->sx.val.l == 0x10000000)
2842 iptr->sx.val.i = 28;
2843 else if (iptr->sx.val.l == 0x20000000)
2844 iptr->sx.val.i = 29;
2845 else if (iptr->sx.val.l == 0x40000000)
2846 iptr->sx.val.i = 30;
2847 else if (iptr->sx.val.l == 0x80000000)
2848 iptr->sx.val.i = 31;
2852 iptr->opc = ICMD_LMULPOW2;
2853 goto icmd_lconst_tail;
2854 # endif /* SUPPORT_LONG_SHIFT */
2855 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2856 #if SUPPORT_LONG_DIV_POW2
2858 if (iptr->sx.val.l == 0x00000002)
2860 else if (iptr->sx.val.l == 0x00000004)
2862 else if (iptr->sx.val.l == 0x00000008)
2864 else if (iptr->sx.val.l == 0x00000010)
2866 else if (iptr->sx.val.l == 0x00000020)
2868 else if (iptr->sx.val.l == 0x00000040)
2870 else if (iptr->sx.val.l == 0x00000080)
2872 else if (iptr->sx.val.l == 0x00000100)
2874 else if (iptr->sx.val.l == 0x00000200)
2876 else if (iptr->sx.val.l == 0x00000400)
2877 iptr->sx.val.i = 10;
2878 else if (iptr->sx.val.l == 0x00000800)
2879 iptr->sx.val.i = 11;
2880 else if (iptr->sx.val.l == 0x00001000)
2881 iptr->sx.val.i = 12;
2882 else if (iptr->sx.val.l == 0x00002000)
2883 iptr->sx.val.i = 13;
2884 else if (iptr->sx.val.l == 0x00004000)
2885 iptr->sx.val.i = 14;
2886 else if (iptr->sx.val.l == 0x00008000)
2887 iptr->sx.val.i = 15;
2888 else if (iptr->sx.val.l == 0x00010000)
2889 iptr->sx.val.i = 16;
2890 else if (iptr->sx.val.l == 0x00020000)
2891 iptr->sx.val.i = 17;
2892 else if (iptr->sx.val.l == 0x00040000)
2893 iptr->sx.val.i = 18;
2894 else if (iptr->sx.val.l == 0x00080000)
2895 iptr->sx.val.i = 19;
2896 else if (iptr->sx.val.l == 0x00100000)
2897 iptr->sx.val.i = 20;
2898 else if (iptr->sx.val.l == 0x00200000)
2899 iptr->sx.val.i = 21;
2900 else if (iptr->sx.val.l == 0x00400000)
2901 iptr->sx.val.i = 22;
2902 else if (iptr->sx.val.l == 0x00800000)
2903 iptr->sx.val.i = 23;
2904 else if (iptr->sx.val.l == 0x01000000)
2905 iptr->sx.val.i = 24;
2906 else if (iptr->sx.val.l == 0x02000000)
2907 iptr->sx.val.i = 25;
2908 else if (iptr->sx.val.l == 0x04000000)
2909 iptr->sx.val.i = 26;
2910 else if (iptr->sx.val.l == 0x08000000)
2911 iptr->sx.val.i = 27;
2912 else if (iptr->sx.val.l == 0x10000000)
2913 iptr->sx.val.i = 28;
2914 else if (iptr->sx.val.l == 0x20000000)
2915 iptr->sx.val.i = 29;
2916 else if (iptr->sx.val.l == 0x40000000)
2917 iptr->sx.val.i = 30;
2918 else if (iptr->sx.val.l == 0x80000000)
2919 iptr->sx.val.i = 31;
2923 iptr->opc = ICMD_LDIVPOW2;
2924 goto icmd_lconst_tail;
2925 #endif /* SUPPORT_LONG_DIV_POW2 */
2927 #if SUPPORT_LONG_REM_POW2
2929 if ((iptr->sx.val.l == 0x00000002) ||
2930 (iptr->sx.val.l == 0x00000004) ||
2931 (iptr->sx.val.l == 0x00000008) ||
2932 (iptr->sx.val.l == 0x00000010) ||
2933 (iptr->sx.val.l == 0x00000020) ||
2934 (iptr->sx.val.l == 0x00000040) ||
2935 (iptr->sx.val.l == 0x00000080) ||
2936 (iptr->sx.val.l == 0x00000100) ||
2937 (iptr->sx.val.l == 0x00000200) ||
2938 (iptr->sx.val.l == 0x00000400) ||
2939 (iptr->sx.val.l == 0x00000800) ||
2940 (iptr->sx.val.l == 0x00001000) ||
2941 (iptr->sx.val.l == 0x00002000) ||
2942 (iptr->sx.val.l == 0x00004000) ||
2943 (iptr->sx.val.l == 0x00008000) ||
2944 (iptr->sx.val.l == 0x00010000) ||
2945 (iptr->sx.val.l == 0x00020000) ||
2946 (iptr->sx.val.l == 0x00040000) ||
2947 (iptr->sx.val.l == 0x00080000) ||
2948 (iptr->sx.val.l == 0x00100000) ||
2949 (iptr->sx.val.l == 0x00200000) ||
2950 (iptr->sx.val.l == 0x00400000) ||
2951 (iptr->sx.val.l == 0x00800000) ||
2952 (iptr->sx.val.l == 0x01000000) ||
2953 (iptr->sx.val.l == 0x02000000) ||
2954 (iptr->sx.val.l == 0x04000000) ||
2955 (iptr->sx.val.l == 0x08000000) ||
2956 (iptr->sx.val.l == 0x10000000) ||
2957 (iptr->sx.val.l == 0x20000000) ||
2958 (iptr->sx.val.l == 0x40000000) ||
2959 (iptr->sx.val.l == 0x80000000))
2961 iptr->opc = ICMD_LREMPOW2;
2962 iptr->sx.val.l -= 1;
2963 goto icmd_lconst_tail;
2966 #endif /* SUPPORT_LONG_REM_POW2 */
2968 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2971 iptr->opc = ICMD_LANDCONST;
2972 goto icmd_lconst_tail;
2975 iptr->opc = ICMD_LORCONST;
2976 goto icmd_lconst_tail;
2979 iptr->opc = ICMD_LXORCONST;
2980 goto icmd_lconst_tail;
2981 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2983 #if SUPPORT_LONG_CMP_CONST
2985 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2988 /* switch on the instruction after LCONST - LCMP */
2990 switch (iptr[2].opc) {
2992 iptr->opc = ICMD_IF_LEQ;
2995 icmd_lconst_lcmp_tail:
2996 /* convert LCONST, LCMP, IFXX to IF_LXX */
2997 iptr->dst.block = iptr[2].dst.block;
2998 iptr[1].opc = ICMD_NOP;
2999 iptr[2].opc = ICMD_NOP;
3001 OP1_BRANCH(TYPE_LNG);
3003 COUNT(count_pcmd_bra);
3004 COUNT(count_pcmd_op);
3008 iptr->opc = ICMD_IF_LNE;
3009 goto icmd_lconst_lcmp_tail;
3012 iptr->opc = ICMD_IF_LLT;
3013 goto icmd_lconst_lcmp_tail;
3016 iptr->opc = ICMD_IF_LGT;
3017 goto icmd_lconst_lcmp_tail;
3020 iptr->opc = ICMD_IF_LLE;
3021 goto icmd_lconst_lcmp_tail;
3024 iptr->opc = ICMD_IF_LGE;
3025 goto icmd_lconst_lcmp_tail;
3029 } /* end switch on opcode after LCONST - LCMP */
3031 #endif /* SUPPORT_LONG_CMP_CONST */
3033 #if SUPPORT_CONST_STORE
3035 # if SUPPORT_CONST_STORE_ZERO_ONLY
3036 if (iptr->sx.val.l != 0)
3039 #if SIZEOF_VOID_P == 4
3040 /* the constant must fit into a ptrint */
3041 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3044 /* move the constant to s3 */
3045 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3047 iptr->opc = ICMD_LASTORECONST;
3048 iptr->flags.bits |= INS_FLAG_CHECK;
3049 OP2_0(TYPE_ADR, TYPE_INT);
3051 iptr[1].opc = ICMD_NOP;
3052 COUNT(count_pcmd_op);
3055 case ICMD_PUTSTATIC:
3057 # if SUPPORT_CONST_STORE_ZERO_ONLY
3058 if (iptr->sx.val.l != 0)
3061 #if SIZEOF_VOID_P == 4
3062 /* the constant must fit into a ptrint */
3063 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3066 /* XXX check field type? */
3068 /* copy the constant to s2 */
3069 /* XXX constval -> fieldconstval? */
3070 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3074 #endif /* SUPPORT_CONST_STORE */
3078 } /* end switch opcode after LCONST */
3080 /* if we get here, the LCONST has been optimized */
3084 /* the normal case of an unoptimized LCONST */
3088 /************************ END OF LCONST OPTIMIZATIONS *********************/
3091 COUNT(count_pcmd_load);
3096 COUNT(count_pcmd_load);
3100 /************************** ACONST OPTIMIZATIONS **************************/
3103 coalescing_boundary = sd.new;
3104 COUNT(count_pcmd_load);
3105 #if SUPPORT_CONST_STORE
3106 /* We can only optimize if the ACONST is resolved
3107 * and there is an instruction after it. */
3109 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3112 switch (iptr[1].opc) {
3114 /* We can only optimize for NULL values
3115 * here because otherwise a checkcast is
3117 if (iptr->sx.val.anyptr != NULL)
3120 /* copy the constant (NULL) to s3 */
3121 iptr->sx.s23.s3.constval = 0;
3122 iptr->opc = ICMD_AASTORECONST;
3123 iptr->flags.bits |= INS_FLAG_CHECK;
3124 OP2_0(TYPE_ADR, TYPE_INT);
3126 iptr[1].opc = ICMD_NOP;
3127 COUNT(count_pcmd_op);
3130 case ICMD_PUTSTATIC:
3132 # if SUPPORT_CONST_STORE_ZERO_ONLY
3133 if (iptr->sx.val.anyptr != NULL)
3136 /* XXX check field type? */
3137 /* copy the constant to s2 */
3138 /* XXX constval -> fieldconstval? */
3139 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3147 /* if we get here the ACONST has been optimized */
3151 #endif /* SUPPORT_CONST_STORE */
3156 /* pop 0 push 1 load */
3163 COUNT(count_load_instruction);
3164 type = opcode - ICMD_ILOAD;
3166 varindex = iptr->s1.varindex =
3167 jd->local_map[iptr->s1.varindex * 5 + type];
3169 #if defined(ENABLE_VERIFIER)
3170 if (sd.var[varindex].type == TYPE_RET) {
3171 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3175 LOAD(type, varindex);
3184 coalescing_boundary = sd.new;
3185 iptr->flags.bits |= INS_FLAG_CHECK;
3186 COUNT(count_check_null);
3187 COUNT(count_check_bound);
3188 COUNT(count_pcmd_mem);
3189 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3196 coalescing_boundary = sd.new;
3197 iptr->flags.bits |= INS_FLAG_CHECK;
3198 COUNT(count_check_null);
3199 COUNT(count_check_bound);
3200 COUNT(count_pcmd_mem);
3201 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3204 /* pop 0 push 0 iinc */
3207 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3208 last_store_boundary[iptr->s1.varindex] = sd.new;
3211 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3216 if ((copy->varkind == LOCALVAR) &&
3217 (copy->varnum == iptr->s1.varindex))
3219 assert(IS_LOCALVAR(copy));
3226 iptr->dst.varindex = iptr->s1.varindex;
3229 /* pop 1 push 0 store */
3238 type = opcode - ICMD_ISTORE;
3239 javaindex = iptr->dst.varindex;
3240 varindex = iptr->dst.varindex =
3241 jd->local_map[javaindex * 5 + type];
3243 COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3245 iptr->sx.s23.s3.javaindex = javaindex;
3247 if (curstack->type == TYPE_RET) {
3248 iptr->flags.bits |= INS_FLAG_RETADDR;
3249 iptr->sx.s23.s2.retaddrnr =
3250 JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3251 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3254 sd.javalocals[javaindex] = varindex;
3256 /* invalidate the following javalocal for 2-word types */
3258 if (IS_2_WORD_TYPE(type)) {
3259 sd.javalocals[javaindex+1] = UNUSED;
3260 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3263 /* invalidate 2-word types if second half was overwritten */
3265 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
3266 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3267 sd.javalocals[javaindex-1] = UNUSED;
3268 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3272 #if defined(ENABLE_STATISTICS)
3275 i = sd.new - curstack;
3277 count_store_length[20]++;
3279 count_store_length[i]++;
3282 count_store_depth[10]++;
3284 count_store_depth[i]++;
3288 /* check for conflicts as described in Figure 5.2 */
3290 copy = curstack->prev;
3293 if ((copy->varkind == LOCALVAR) &&
3294 (copy->varnum == varindex))
3296 copy->varkind = TEMPVAR;
3297 assert(IS_LOCALVAR(copy));
3304 /* if the variable is already coalesced, don't bother */
3306 /* We do not need to check against INOUT, as invars */
3307 /* are always before the coalescing boundary. */
3309 if (curstack->varkind == LOCALVAR)
3312 /* there is no STORE Lj while curstack is live */
3314 if (curstack < last_store_boundary[javaindex])
3315 goto assume_conflict;
3317 /* curstack must be after the coalescing boundary */
3319 if (curstack < coalescing_boundary)
3320 goto assume_conflict;
3322 /* there is no DEF LOCALVAR(varindex) while curstack is live */
3324 copy = sd.new; /* most recent stackslot created + 1 */
3325 while (--copy > curstack) {
3326 if (copy->varkind == LOCALVAR && copy->varnum == varindex)
3327 goto assume_conflict;
3330 /* coalesce the temporary variable with Lj */
3331 assert((curstack->varkind == TEMPVAR)
3332 || (curstack->varkind == UNDEFVAR));
3333 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3334 assert(!IS_INOUT(curstack));
3335 assert(!IS_PREALLOC(curstack));
3337 assert(curstack->creator);
3338 assert(curstack->creator->dst.varindex == curstack->varnum);
3339 assert(!(curstack->flags & PASSTHROUGH));
3340 RELEASE_INDEX(sd, curstack);
3341 curstack->varkind = LOCALVAR;
3342 curstack->varnum = varindex;
3343 curstack->creator->dst.varindex = varindex;
3346 /* revert the coalescing, if it has been done earlier */
3348 if ((curstack->varkind == LOCALVAR)
3349 && (curstack->varnum == varindex))
3351 assert(IS_LOCALVAR(curstack));
3352 SET_TEMPVAR(curstack);
3355 /* remember the stack boundary at this store */
3357 last_store_boundary[javaindex] = sd.new;
3359 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3360 STORE(TYPE_RET, varindex);
3362 STORE(opcode - ICMD_ISTORE, varindex);
3368 coalescing_boundary = sd.new;
3369 iptr->flags.bits |= INS_FLAG_CHECK;
3370 COUNT(count_check_null);
3371 COUNT(count_check_bound);
3372 COUNT(count_pcmd_mem);
3374 bte = builtintable_get_internal(BUILTIN_canstore);
3377 if (md->memuse > rd->memuse)
3378 rd->memuse = md->memuse;
3379 if (md->argintreguse > rd->argintreguse)
3380 rd->argintreguse = md->argintreguse;
3381 /* XXX non-leaf method? */
3383 /* make all stack variables saved */
3387 sd.var[copy->varnum].flags |= SAVEDVAR;
3388 /* in case copy->varnum is/will be a LOCALVAR */
3389 /* once and set back to a non LOCALVAR */
3390 /* the correct SAVEDVAR flag has to be */
3391 /* remembered in copy->flags, too */
3392 copy->flags |= SAVEDVAR;
3396 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3403 coalescing_boundary = sd.new;
3404 iptr->flags.bits |= INS_FLAG_CHECK;
3405 COUNT(count_check_null);
3406 COUNT(count_check_bound);
3407 COUNT(count_pcmd_mem);
3408 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3415 coalescing_boundary = sd.new;
3416 iptr->flags.bits |= INS_FLAG_CHECK;
3417 COUNT(count_check_null);
3418 COUNT(count_check_bound);
3419 COUNT(count_pcmd_mem);
3420 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3426 #ifdef ENABLE_VERIFIER
3429 if (IS_2_WORD_TYPE(curstack->type))
3430 goto throw_stack_category_error;
3441 coalescing_boundary = sd.new;
3442 /* Assert here that no LOCAL or INOUTS get */
3443 /* preallocated, since tha macros are not */
3444 /* available in md-abi.c! */
3445 if (IS_TEMPVAR(curstack))
3446 md_return_alloc(jd, curstack);
3447 COUNT(count_pcmd_return);
3448 OP1_0(opcode - ICMD_IRETURN);
3449 superblockend = true;
3450 sd.jd->returncount++;
3451 sd.jd->returnblock = sd.bptr;
3455 coalescing_boundary = sd.new;
3456 COUNT(count_check_null);
3458 curstack = NULL; stackdepth = 0;
3459 superblockend = true;
3462 case ICMD_PUTSTATIC:
3463 coalescing_boundary = sd.new;
3464 COUNT(count_pcmd_mem);
3465 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3466 OP1_0(fmiref->parseddesc.fd->type);
3469 /* pop 1 push 0 branch */
3472 case ICMD_IFNONNULL:
3473 COUNT(count_pcmd_bra);
3474 OP1_BRANCH(TYPE_ADR);
3484 COUNT(count_pcmd_bra);
3485 /* iptr->sx.val.i is set implicitly in parse by
3486 clearing the memory or from IF_ICMPxx
3489 OP1_BRANCH(TYPE_INT);
3490 /* iptr->sx.val.i = 0; */
3494 /* pop 0 push 0 branch */
3497 COUNT(count_pcmd_bra);
3500 superblockend = true;
3503 /* pop 1 push 0 table branch */
3505 case ICMD_TABLESWITCH:
3506 COUNT(count_pcmd_table);
3507 OP1_BRANCH(TYPE_INT);
3509 table = iptr->dst.table;
3510 BRANCH_TARGET(*table, tbptr);
3513 i = iptr->sx.s23.s3.tablehigh
3514 - iptr->sx.s23.s2.tablelow + 1;
3517 BRANCH_TARGET(*table, tbptr);
3520 superblockend = true;
3523 /* pop 1 push 0 table branch */
3525 case ICMD_LOOKUPSWITCH:
3526 COUNT(count_pcmd_table);
3527 OP1_BRANCH(TYPE_INT);
3529 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3531 lookup = iptr->dst.lookup;
3533 i = iptr->sx.s23.s2.lookupcount;
3536 BRANCH_TARGET(lookup->target, tbptr);
3539 superblockend = true;
3542 case ICMD_MONITORENTER:
3543 case ICMD_MONITOREXIT:
3544 coalescing_boundary = sd.new;
3545 COUNT(count_check_null);
3549 /* pop 2 push 0 branch */
3551 case ICMD_IF_ICMPEQ:
3552 case ICMD_IF_ICMPNE:
3553 case ICMD_IF_ICMPLT:
3554 case ICMD_IF_ICMPGE:
3555 case ICMD_IF_ICMPGT:
3556 case ICMD_IF_ICMPLE:
3557 COUNT(count_pcmd_bra);
3558 OP2_BRANCH(TYPE_INT, TYPE_INT);
3562 case ICMD_IF_ACMPEQ:
3563 case ICMD_IF_ACMPNE:
3564 COUNT(count_pcmd_bra);
3565 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3572 coalescing_boundary = sd.new;
3573 COUNT(count_check_null);
3574 COUNT(count_pcmd_mem);
3575 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3576 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3581 if (!IS_2_WORD_TYPE(curstack->type)) {
3583 #ifdef ENABLE_VERIFIER
3586 if (IS_2_WORD_TYPE(curstack->prev->type))
3587 goto throw_stack_category_error;
3590 OP2_0_ANY_ANY; /* pop two slots */
3593 iptr->opc = ICMD_POP;
3594 OP1_0_ANY; /* pop one (two-word) slot */
3598 /* pop 0 push 1 dup */
3601 #ifdef ENABLE_VERIFIER
3604 if (IS_2_WORD_TYPE(curstack->type))
3605 goto throw_stack_category_error;
3608 COUNT(count_dup_instruction);
3614 coalescing_boundary = sd.new - 1;
3619 if (IS_2_WORD_TYPE(curstack->type)) {
3621 iptr->opc = ICMD_DUP;
3626 /* ..., ????, cat1 */
3627 #ifdef ENABLE_VERIFIER
3629 if (IS_2_WORD_TYPE(curstack->prev->type))
3630 goto throw_stack_category_error;
3633 src1 = curstack->prev;
3636 COPY_UP(src1); iptr++; len--;
3639 coalescing_boundary = sd.new;
3643 /* pop 2 push 3 dup */
3646 #ifdef ENABLE_VERIFIER
3649 if (IS_2_WORD_TYPE(curstack->type) ||
3650 IS_2_WORD_TYPE(curstack->prev->type))
3651 goto throw_stack_category_error;
3656 src1 = curstack->prev;
3661 /* move non-temporary sources out of the way */
3662 if (!IS_TEMPVAR(src2)) {
3663 MOVE_TO_TEMP(src2); iptr++; len--;
3666 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3668 MOVE_UP(src1); iptr++; len--;
3669 MOVE_UP(src2); iptr++; len--;
3671 COPY_DOWN(curstack, dst1);
3673 coalescing_boundary = sd.new;
3678 if (IS_2_WORD_TYPE(curstack->type)) {
3679 /* ..., ????, cat2 */
3680 #ifdef ENABLE_VERIFIER
3682 if (IS_2_WORD_TYPE(curstack->prev->type))
3683 goto throw_stack_category_error;
3686 iptr->opc = ICMD_DUP_X1;
3690 /* ..., ????, cat1 */
3691 #ifdef ENABLE_VERIFIER
3694 if (IS_2_WORD_TYPE(curstack->prev->type)
3695 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3696 goto throw_stack_category_error;
3701 src1 = curstack->prev->prev;
3702 src2 = curstack->prev;
3704 POPANY; POPANY; POPANY;
3707 /* move non-temporary sources out of the way */
3708 if (!IS_TEMPVAR(src2)) {
3709 MOVE_TO_TEMP(src2); iptr++; len--;
3711 if (!IS_TEMPVAR(src3)) {
3712 MOVE_TO_TEMP(src3); iptr++; len--;
3715 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3716 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3718 MOVE_UP(src1); iptr++; len--;
3719 MOVE_UP(src2); iptr++; len--;
3720 MOVE_UP(src3); iptr++; len--;
3722 COPY_DOWN(curstack, dst2); iptr++; len--;
3723 COPY_DOWN(curstack->prev, dst1);
3725 coalescing_boundary = sd.new;
3729 /* pop 3 push 4 dup */
3733 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3734 /* ..., cat2, ???? */
3735 #ifdef ENABLE_VERIFIER
3737 if (IS_2_WORD_TYPE(curstack->type))
3738 goto throw_stack_category_error;
3741 iptr->opc = ICMD_DUP_X1;
3745 /* ..., cat1, ???? */
3746 #ifdef ENABLE_VERIFIER
3749 if (IS_2_WORD_TYPE(curstack->type)
3750 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3751 goto throw_stack_category_error;
3755 src1 = curstack->prev->prev;
3756 src2 = curstack->prev;
3758 POPANY; POPANY; POPANY;
3761 /* move non-temporary sources out of the way */
3762 if (!IS_TEMPVAR(src2)) {
3763 MOVE_TO_TEMP(src2); iptr++; len--;
3765 if (!IS_TEMPVAR(src3)) {
3766 MOVE_TO_TEMP(src3); iptr++; len--;
3769 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3771 MOVE_UP(src1); iptr++; len--;
3772 MOVE_UP(src2); iptr++; len--;
3773 MOVE_UP(src3); iptr++; len--;
3775 COPY_DOWN(curstack, dst1);
3777 coalescing_boundary = sd.new;
3783 if (IS_2_WORD_TYPE(curstack->type)) {
3784 /* ..., ????, cat2 */
3785 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3786 /* ..., cat2, cat2 */
3787 iptr->opc = ICMD_DUP_X1;
3791 /* ..., cat1, cat2 */
3792 #ifdef ENABLE_VERIFIER
3795 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3796 goto throw_stack_category_error;
3799 iptr->opc = ICMD_DUP_X2;
3805 /* ..., ????, ????, cat1 */
3807 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3808 /* ..., cat2, ????, cat1 */
3809 #ifdef ENABLE_VERIFIER
3811 if (IS_2_WORD_TYPE(curstack->prev->type))
3812 goto throw_stack_category_error;
3815 iptr->opc = ICMD_DUP2_X1;
3819 /* ..., cat1, ????, cat1 */
3820 #ifdef ENABLE_VERIFIER
3823 if (IS_2_WORD_TYPE(curstack->prev->type)
3824 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3825 goto throw_stack_category_error;
3829 src1 = curstack->prev->prev->prev;
3830 src2 = curstack->prev->prev;
3831 src3 = curstack->prev;
3833 POPANY; POPANY; POPANY; POPANY;
3836 /* move non-temporary sources out of the way */
3837 if (!IS_TEMPVAR(src2)) {
3838 MOVE_TO_TEMP(src2); iptr++; len--;
3840 if (!IS_TEMPVAR(src3)) {
3841 MOVE_TO_TEMP(src3); iptr++; len--;
3843 if (!IS_TEMPVAR(src4)) {
3844 MOVE_TO_TEMP(src4); iptr++; len--;
3847 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3848 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3850 MOVE_UP(src1); iptr++; len--;
3851 MOVE_UP(src2); iptr++; len--;
3852 MOVE_UP(src3); iptr++; len--;
3853 MOVE_UP(src4); iptr++; len--;
3855 COPY_DOWN(curstack, dst2); iptr++; len--;
3856 COPY_DOWN(curstack->prev, dst1);
3858 coalescing_boundary = sd.new;
3862 /* pop 2 push 2 swap */
3865 #ifdef ENABLE_VERIFIER
3868 if (IS_2_WORD_TYPE(curstack->type)
3869 || IS_2_WORD_TYPE(curstack->prev->type))
3870 goto throw_stack_category_error;
3874 src1 = curstack->prev;
3879 /* move non-temporary sources out of the way */
3880 if (!IS_TEMPVAR(src1)) {
3881 MOVE_TO_TEMP(src1); iptr++; len--;
3884 MOVE_UP(src2); iptr++; len--;
3887 coalescing_boundary = sd.new;
3894 coalescing_boundary = sd.new;
3895 #if !SUPPORT_DIVISION
3896 bte = iptr->sx.s23.s3.bte;
3899 if (md->memuse > rd->memuse)
3900 rd->memuse = md->memuse;
3901 if (md->argintreguse > rd->argintreguse)
3902 rd->argintreguse = md->argintreguse;
3904 /* make all stack variables saved */
3908 sd.var[copy->varnum].flags |= SAVEDVAR;
3909 copy->flags |= SAVEDVAR;
3914 #endif /* !SUPPORT_DIVISION */
3925 COUNT(count_pcmd_op);
3926 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3931 coalescing_boundary = sd.new;
3932 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3933 bte = iptr->sx.s23.s3.bte;
3936 if (md->memuse > rd->memuse)
3937 rd->memuse = md->memuse;
3938 if (md->argintreguse > rd->argintreguse)
3939 rd->argintreguse = md->argintreguse;
3940 /* XXX non-leaf method? */
3942 /* make all stack variables saved */
3946 sd.var[copy->varnum].flags |= SAVEDVAR;
3947 copy->flags |= SAVEDVAR;
3952 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3957 #if SUPPORT_LONG_LOGICAL
3961 #endif /* SUPPORT_LONG_LOGICAL */
3962 COUNT(count_pcmd_op);
3963 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3969 COUNT(count_pcmd_op);
3970 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3978 COUNT(count_pcmd_op);
3979 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3987 COUNT(count_pcmd_op);
3988 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3992 COUNT(count_pcmd_op);
3993 #if SUPPORT_LONG_CMP_CONST
3994 if ((len == 0) || (iptr[1].sx.val.i != 0))
3997 switch (iptr[1].opc) {
3999 iptr->opc = ICMD_IF_LCMPEQ;
4001 iptr->dst.block = iptr[1].dst.block;
4002 iptr[1].opc = ICMD_NOP;
4004 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
4007 COUNT(count_pcmd_bra);
4010 iptr->opc = ICMD_IF_LCMPNE;
4011 goto icmd_lcmp_if_tail;
4013 iptr->opc = ICMD_IF_LCMPLT;
4014 goto icmd_lcmp_if_tail;
4016 iptr->opc = ICMD_IF_LCMPGT;
4017 goto icmd_lcmp_if_tail;
4019 iptr->opc = ICMD_IF_LCMPLE;
4020 goto icmd_lcmp_if_tail;
4022 iptr->opc = ICMD_IF_LCMPGE;
4023 goto icmd_lcmp_if_tail;
4029 #endif /* SUPPORT_LONG_CMP_CONST */
4030 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4033 /* XXX why is this deactivated? */
4036 COUNT(count_pcmd_op);
4037 if ((len == 0) || (iptr[1].sx.val.i != 0))
4040 switch (iptr[1].opc) {
4042 iptr->opc = ICMD_IF_FCMPEQ;
4044 iptr->dst.block = iptr[1].dst.block;
4045 iptr[1].opc = ICMD_NOP;
4047 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
4050 COUNT(count_pcmd_bra);
4053 iptr->opc = ICMD_IF_FCMPNE;
4054 goto icmd_if_fcmpl_tail;
4056 iptr->opc = ICMD_IF_FCMPL_LT;
4057 goto icmd_if_fcmpl_tail;
4059 iptr->opc = ICMD_IF_FCMPL_GT;
4060 goto icmd_if_fcmpl_tail;
4062 iptr->opc = ICMD_IF_FCMPL_LE;
4063 goto icmd_if_fcmpl_tail;
4065 iptr->opc = ICMD_IF_FCMPL_GE;
4066 goto icmd_if_fcmpl_tail;
4073 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4077 COUNT(count_pcmd_op);
4078 if ((len == 0) || (iptr[1].sx.val.i != 0))
4081 switch (iptr[1].opc) {
4083 iptr->opc = ICMD_IF_FCMPEQ;
4085 iptr->dst.block = iptr[1].dst.block;
4086 iptr[1].opc = ICMD_NOP;
4088 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
4091 COUNT(count_pcmd_bra);
4094 iptr->opc = ICMD_IF_FCMPNE;
4095 goto icmd_if_fcmpg_tail;
4097 iptr->opc = ICMD_IF_FCMPG_LT;
4098 goto icmd_if_fcmpg_tail;
4100 iptr->opc = ICMD_IF_FCMPG_GT;
4101 goto icmd_if_fcmpg_tail;
4103 iptr->opc = ICMD_IF_FCMPG_LE;
4104 goto icmd_if_fcmpg_tail;
4106 iptr->opc = ICMD_IF_FCMPG_GE;
4107 goto icmd_if_fcmpg_tail;
4114 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4118 COUNT(count_pcmd_op);
4119 if ((len == 0) || (iptr[1].sx.val.i != 0))
4122 switch (iptr[1].opc) {
4124 iptr->opc = ICMD_IF_DCMPEQ;
4126 iptr->dst.block = iptr[1].dst.block;
4127 iptr[1].opc = ICMD_NOP;
4129 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4132 COUNT(count_pcmd_bra);
4135 iptr->opc = ICMD_IF_DCMPNE;
4136 goto icmd_if_dcmpl_tail;
4138 iptr->opc = ICMD_IF_DCMPL_LT;
4139 goto icmd_if_dcmpl_tail;
4141 iptr->opc = ICMD_IF_DCMPL_GT;
4142 goto icmd_if_dcmpl_tail;
4144 iptr->opc = ICMD_IF_DCMPL_LE;
4145 goto icmd_if_dcmpl_tail;
4147 iptr->opc = ICMD_IF_DCMPL_GE;
4148 goto icmd_if_dcmpl_tail;
4155 OPTT2_1(TYPE_DBL, TYPE_INT);
4159 COUNT(count_pcmd_op);
4160 if ((len == 0) || (iptr[1].sx.val.i != 0))
4163 switch (iptr[1].opc) {
4165 iptr->opc = ICMD_IF_DCMPEQ;
4167 iptr->dst.block = iptr[1].dst.block;
4168 iptr[1].opc = ICMD_NOP;
4170 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4173 COUNT(count_pcmd_bra);
4176 iptr->opc = ICMD_IF_DCMPNE;
4177 goto icmd_if_dcmpg_tail;
4179 iptr->opc = ICMD_IF_DCMPG_LT;
4180 goto icmd_if_dcmpg_tail;
4182 iptr->opc = ICMD_IF_DCMPG_GT;
4183 goto icmd_if_dcmpg_tail;
4185 iptr->opc = ICMD_IF_DCMPG_LE;
4186 goto icmd_if_dcmpg_tail;
4188 iptr->opc = ICMD_IF_DCMPG_GE;
4189 goto icmd_if_dcmpg_tail;
4196 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4201 COUNT(count_pcmd_op);
4202 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4207 COUNT(count_pcmd_op);
4208 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4217 case ICMD_INT2SHORT:
4218 COUNT(count_pcmd_op);
4219 OP1_1(TYPE_INT, TYPE_INT);
4222 COUNT(count_pcmd_op);
4223 OP1_1(TYPE_LNG, TYPE_LNG);
4226 COUNT(count_pcmd_op);
4227 OP1_1(TYPE_FLT, TYPE_FLT);
4230 COUNT(count_pcmd_op);
4231 OP1_1(TYPE_DBL, TYPE_DBL);
4235 COUNT(count_pcmd_op);
4236 OP1_1(TYPE_INT, TYPE_LNG);
4239 COUNT(count_pcmd_op);
4240 OP1_1(TYPE_INT, TYPE_FLT);
4243 COUNT(count_pcmd_op);
4244 OP1_1(TYPE_INT, TYPE_DBL);
4247 COUNT(count_pcmd_op);
4248 OP1_1(TYPE_LNG, TYPE_INT);
4251 COUNT(count_pcmd_op);
4252 OP1_1(TYPE_LNG, TYPE_FLT);
4255 COUNT(count_pcmd_op);
4256 OP1_1(TYPE_LNG, TYPE_DBL);
4259 COUNT(count_pcmd_op);
4260 OP1_1(TYPE_FLT, TYPE_INT);
4263 COUNT(count_pcmd_op);
4264 OP1_1(TYPE_FLT, TYPE_LNG);
4267 COUNT(count_pcmd_op);
4268 OP1_1(TYPE_FLT, TYPE_DBL);
4271 COUNT(count_pcmd_op);
4272 OP1_1(TYPE_DBL, TYPE_INT);
4275 COUNT(count_pcmd_op);
4276 OP1_1(TYPE_DBL, TYPE_LNG);
4279 COUNT(count_pcmd_op);
4280 OP1_1(TYPE_DBL, TYPE_FLT);
4283 case ICMD_CHECKCAST:
4284 coalescing_boundary = sd.new;
4285 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4286 /* array type cast-check */
4288 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4291 if (md->memuse > rd->memuse)
4292 rd->memuse = md->memuse;
4293 if (md->argintreguse > rd->argintreguse)
4294 rd->argintreguse = md->argintreguse;
4296 /* make all stack variables saved */
4300 sd.var[copy->varnum].flags |= SAVEDVAR;
4301 copy->flags |= SAVEDVAR;
4305 OP1_1(TYPE_ADR, TYPE_ADR);
4308 case ICMD_INSTANCEOF:
4309 case ICMD_ARRAYLENGTH:
4310 coalescing_boundary = sd.new;
4311 OP1_1(TYPE_ADR, TYPE_INT);
4315 case ICMD_ANEWARRAY:
4316 coalescing_boundary = sd.new;
4317 OP1_1(TYPE_INT, TYPE_ADR);
4321 coalescing_boundary = sd.new;
4322 COUNT(count_check_null);
4323 COUNT(count_pcmd_mem);
4324 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4325 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4330 case ICMD_GETSTATIC:
4331 coalescing_boundary = sd.new;
4332 COUNT(count_pcmd_mem);
4333 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4334 OP0_1(fmiref->parseddesc.fd->type);
4338 coalescing_boundary = sd.new;
4345 tbptr = iptr->sx.s23.s3.jsrtarget.block;
4346 tbptr->type = BBTYPE_SBR;
4348 assert(sd.bptr->next); /* XXX exception */
4349 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4350 #if defined(ENABLE_VERIFIER)
4351 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4354 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4358 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4360 /* We need to check for overflow right here because
4361 * the pushed value is poped afterwards */
4364 superblockend = true;
4365 /* XXX should not be marked as interface, as it does not need to be */
4366 /* allocated. Same for the invar of the target. */
4369 /* pop many push any */
4373 bte = iptr->sx.s23.s3.bte;
4377 case ICMD_INVOKESTATIC:
4378 case ICMD_INVOKESPECIAL:
4379 case ICMD_INVOKEVIRTUAL:
4380 case ICMD_INVOKEINTERFACE:
4381 COUNT(count_pcmd_met);
4383 /* Check for functions to replace with builtin
4386 if (builtintable_replace_function(iptr))
4389 INSTRUCTION_GET_METHODDESC(iptr, md);
4390 /* XXX resurrect this COUNT? */
4391 /* if (lm->flags & ACC_STATIC) */
4392 /* {COUNT(count_check_null);} */
4396 coalescing_boundary = sd.new;
4400 if (md->memuse > rd->memuse)
4401 rd->memuse = md->memuse;
4402 if (md->argintreguse > rd->argintreguse)
4403 rd->argintreguse = md->argintreguse;
4404 if (md->argfltreguse > rd->argfltreguse)
4405 rd->argfltreguse = md->argfltreguse;
4409 iptr->s1.argcount = stackdepth;
4410 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4413 for (i-- ; i >= 0; i--) {
4414 iptr->sx.s23.s2.args[i] = copy->varnum;
4416 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4417 /* -> won't help anyway */
4418 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4420 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4421 /* If we pass float arguments in integer argument registers, we
4422 * are not allowed to precolor them here. Floats have to be moved
4423 * to this regs explicitly in codegen().
4424 * Only arguments that are passed by stack anyway can be precolored
4425 * (michi 2005/07/24) */
4426 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4427 (!IS_FLT_DBL_TYPE(copy->type)
4428 || md->params[i].inmemory)) {
4430 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4435 if (md->params[i].inmemory) {
4436 sd.var[copy->varnum].vv.regoff =
4437 md->params[i].regoff;
4438 sd.var[copy->varnum].flags |=
4442 if (IS_FLT_DBL_TYPE(copy->type)) {
4443 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4444 assert(0); /* XXX is this assert ok? */
4446 sd.var[copy->varnum].vv.regoff =
4447 md->params[i].regoff;
4448 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4451 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4452 if (IS_2_WORD_TYPE(copy->type))
4453 sd.var[copy->varnum].vv.regoff =
4454 PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4455 GET_HIGH_REG(md->params[i].regoff));
4458 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4459 sd.var[copy->varnum].vv.regoff =
4460 md->params[i].regoff;
4468 /* deal with live-through stack slots "under" the */
4474 iptr->sx.s23.s2.args[i++] = copy->varnum;
4475 sd.var[copy->varnum].flags |= SAVEDVAR;
4476 copy->flags |= SAVEDVAR | PASSTHROUGH;
4480 /* pop the arguments */
4489 /* push the return value */
4491 if (md->returntype.type != TYPE_VOID) {
4492 GET_NEW_VAR(sd, new_index, md->returntype.type);
4493 DST(md->returntype.type, new_index);
4498 case ICMD_MULTIANEWARRAY:
4499 coalescing_boundary = sd.new;
4500 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4501 rd->argintreguse = MIN(3, INT_ARG_CNT);
4503 i = iptr->s1.argcount;
4507 iptr->sx.s23.s2.args = DMNEW(s4, i);
4509 #if defined(SPECIALMEMUSE)
4510 # if defined(__DARWIN__)
4511 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4512 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4514 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4515 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4518 # if defined(__I386__)
4519 if (rd->memuse < i + 3)
4520 rd->memuse = i + 3; /* n integer args spilled on stack */
4521 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4522 if (rd->memuse < i + 2)
4523 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4526 rd->memuse = i; /* n integer args spilled on stack */
4527 # endif /* defined(__I386__) */
4531 /* check INT type here? Currently typecheck does this. */
4532 iptr->sx.s23.s2.args[i] = copy->varnum;
4533 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4534 && (!IS_INOUT(copy))
4535 && (!IS_LOCALVAR(copy)) ) {
4536 copy->varkind = ARGVAR;
4537 sd.var[copy->varnum].flags |=
4538 INMEMORY & PREALLOC;
4539 #if defined(SPECIALMEMUSE)
4540 # if defined(__DARWIN__)
4541 sd.var[copy->varnum].vv.regoff = i +
4542 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4544 sd.var[copy->varnum].vv.regoff = i +
4545 LA_SIZE_IN_POINTERS + 3;
4548 # if defined(__I386__)
4549 sd.var[copy->varnum].vv.regoff = i + 3;
4550 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4551 sd.var[copy->varnum].vv.regoff = i + 2;
4553 sd.var[copy->varnum].vv.regoff = i;
4554 # endif /* defined(__I386__) */
4555 #endif /* defined(SPECIALMEMUSE) */
4560 sd.var[copy->varnum].flags |= SAVEDVAR;
4561 copy->flags |= SAVEDVAR;
4565 i = iptr->s1.argcount;
4570 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4571 DST(TYPE_ADR, new_index);
4576 exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4583 } /* while instructions */
4585 /* show state after last instruction */
4587 #if defined(STACK_VERBOSE)
4588 stack_verbose_show_state(&sd, NULL, curstack);
4591 /* stack slots at basic block end become interfaces */
4593 sd.bptr->outdepth = stackdepth;
4594 sd.bptr->outvars = DMNEW(s4, stackdepth);
4597 for (copy = curstack; copy; i--, copy = copy->prev) {
4600 /* with the new vars rd->interfaces will be removed */
4601 /* and all in and outvars have to be STACKVARS! */
4602 /* in the moment i.e. SWAP with in and out vars can */
4603 /* create an unresolvable conflict */
4608 v = sd.var + copy->varnum;
4611 /* do not allocate variables for returnAddresses */
4613 if (type != TYPE_RET) {
4614 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4615 /* no interface var until now for this depth and */
4617 jd->interface_map[i*5 + type].flags = v->flags;
4620 jd->interface_map[i*5 + type].flags |= v->flags;
4624 sd.bptr->outvars[i] = copy->varnum;
4627 /* check if interface slots at basic block begin must be saved */
4629 for (i=0; i<sd.bptr->indepth; ++i) {
4630 varinfo *v = sd.var + sd.bptr->invars[i];
4634 if (type != TYPE_RET) {
4635 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4636 /* no interface var until now for this depth and */
4638 jd->interface_map[i*5 + type].flags = v->flags;
4641 jd->interface_map[i*5 + type].flags |= v->flags;
4646 /* store the number of this block's variables */
4648 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4650 #if defined(STACK_VERBOSE)
4651 stack_verbose_block_exit(&sd, superblockend);
4654 /* reach the following block, if any */
4657 if (!stack_reach_next_block(&sd))
4662 } while (sd.repeat && !deadcode);
4664 /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4666 /* A local variable may be used as both a returnAddress and a reference */
4667 /* type variable, as we do not split variables between these types when */
4668 /* renaming locals. While returnAddresses have been eliminated now, we */
4669 /* must assume that the variable is still used as TYPE_ADR. */
4670 /* The only way that a local can be TYPE_VOID at this point, is that it */
4671 /* was a TYPE_RET variable for which incompatible returnAddresses were */
4672 /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4674 /* XXX: It would be nice to remove otherwise unused returnAddress */
4675 /* variables from the local variable array, so they are not */
4676 /* allocated by simplereg. (For LSRA this is not needed). */
4678 for (i=0; i<sd.localcount; ++i) {
4679 if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4680 sd.var[i].type = TYPE_ADR;
4683 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4685 for (i=sd.localcount; i<sd.vartop; ++i) {
4686 if (sd.var[i].type == TYPE_RET)
4687 sd.var[i].flags |= PREALLOC;
4690 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4692 ex = jd->exceptiontable;
4693 for (; ex != NULL; ex = ex->down) {
4694 if (ex->start == ex->end) {
4695 assert(ex->end->next);
4696 ex->end = ex->end->next;
4700 /* store number of created variables */
4702 jd->vartop = sd.vartop;
4704 /* gather statistics *****************************************************/
4706 #if defined(ENABLE_STATISTICS)
4708 if (jd->basicblockcount > count_max_basic_blocks)
4709 count_max_basic_blocks = jd->basicblockcount;
4710 count_basic_blocks += jd->basicblockcount;
4711 if (jd->instructioncount > count_max_javainstr)
4712 count_max_javainstr = jd->instructioncount;
4713 count_javainstr += jd->instructioncount;
4714 if (jd->stackcount > count_upper_bound_new_stack)
4715 count_upper_bound_new_stack = jd->stackcount;
4716 if ((sd.new - jd->stack) > count_max_new_stack)
4717 count_max_new_stack = (sd.new - jd->stack);
4719 sd.bptr = jd->basicblocks;
4720 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4721 if (sd.bptr->flags > BBREACHED) {
4722 if (sd.bptr->indepth >= 10)
4723 count_block_stack[10]++;
4725 count_block_stack[sd.bptr->indepth]++;
4726 len = sd.bptr->icount;
4728 count_block_size_distribution[len]++;
4730 count_block_size_distribution[10]++;
4732 count_block_size_distribution[11]++;
4734 count_block_size_distribution[12]++;
4736 count_block_size_distribution[13]++;
4738 count_block_size_distribution[14]++;
4740 count_block_size_distribution[15]++;
4742 count_block_size_distribution[16]++;
4744 count_block_size_distribution[17]++;
4748 if (iteration_count == 1)
4749 count_analyse_iterations[0]++;
4750 else if (iteration_count == 2)
4751 count_analyse_iterations[1]++;
4752 else if (iteration_count == 3)
4753 count_analyse_iterations[2]++;
4754 else if (iteration_count == 4)
4755 count_analyse_iterations[3]++;
4757 count_analyse_iterations[4]++;
4759 if (jd->basicblockcount <= 5)
4760 count_method_bb_distribution[0]++;
4761 else if (jd->basicblockcount <= 10)
4762 count_method_bb_distribution[1]++;
4763 else if (jd->basicblockcount <= 15)
4764 count_method_bb_distribution[2]++;
4765 else if (jd->basicblockcount <= 20)
4766 count_method_bb_distribution[3]++;
4767 else if (jd->basicblockcount <= 30)
4768 count_method_bb_distribution[4]++;
4769 else if (jd->basicblockcount <= 40)
4770 count_method_bb_distribution[5]++;
4771 else if (jd->basicblockcount <= 50)
4772 count_method_bb_distribution[6]++;
4773 else if (jd->basicblockcount <= 75)
4774 count_method_bb_distribution[7]++;
4776 count_method_bb_distribution[8]++;
4778 #endif /* defined(ENABLE_STATISTICS) */
4780 /* everything's ok *******************************************************/
4784 /* goto labels for throwing verifier exceptions **************************/
4786 #if defined(ENABLE_VERIFIER)
4788 throw_stack_underflow:
4789 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4792 throw_stack_overflow:
4793 exceptions_throw_verifyerror(m, "Stack size too large");
4796 throw_stack_type_error:
4797 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4800 throw_stack_category_error:
4801 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4808 /* stack_javalocals_store ******************************************************
4810 Model the effect of a ?STORE instruction upon the given javalocals array.
4813 iptr.............the ?STORE instruction
4814 javalocals.......the javalocals array to modify
4816 *******************************************************************************/
4818 void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4820 s4 varindex; /* index into the jd->var array */
4821 s4 javaindex; /* java local index */
4823 varindex = iptr->dst.varindex;
4824 javaindex = iptr->sx.s23.s3.javaindex;
4826 if (javaindex != UNUSED) {
4827 assert(javaindex >= 0);
4828 if (iptr->flags.bits & INS_FLAG_RETADDR)
4829 javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4831 javalocals[javaindex] = varindex;
4833 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4834 javalocals[javaindex-1] = UNUSED;
4836 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4837 javalocals[javaindex+1] = UNUSED;
4842 /* functions for verbose stack analysis output ********************************/
4844 #if defined(STACK_VERBOSE)
4845 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4847 printf("%c", show_jit_type_letters[v->type]);
4848 if (v->type == TYPE_RET) {
4849 printf("{L%03d}", v->vv.retaddr->nr);
4850 #if defined(ENABLE_VERIFIER)
4851 printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4857 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4859 assert(index >= 0 && index < sd->vartop);
4860 stack_verbose_show_varinfo(sd, sd->var + index);
4864 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4868 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4870 for (i=0; i<bptr->indepth; ++i) {
4873 stack_verbose_show_variable(sd, bptr->invars[i]);
4878 printf("] javalocals ");
4879 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4880 printf(" inlocals [");
4881 if (bptr->inlocals) {
4882 for (i=0; i<sd->localcount; ++i) {
4885 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4890 printf("] out:%d [", bptr->outdepth);
4891 if (bptr->outvars) {
4892 for (i=0; i<bptr->outdepth; ++i) {
4895 stack_verbose_show_variable(sd, bptr->outvars[i]);
4903 printf(" (clone of L%03d)", bptr->original->nr);
4905 basicblock *b = bptr->copied_to;
4907 printf(" (copied to ");
4908 for (; b; b = b->copied_to)
4909 printf("L%03d ", b->nr);
4916 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4920 printf("======================================== STACK %sANALYSE BLOCK ",
4921 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4922 stack_verbose_show_block(sd, sd->bptr);
4925 if (sd->handlers[0]) {
4926 printf("HANDLERS: ");
4927 for (i=0; sd->handlers[i]; ++i) {
4928 printf("L%03d ", sd->handlers[i]->handler->nr);
4936 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4938 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4939 stack_verbose_show_block(sd, sd->bptr);
4943 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
4951 printf(" javalocals ");
4952 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4955 for(i = 0, sp = curstack; sp; sp = sp->prev)
4959 stack = MNEW(stackptr, depth);
4960 for(sp = curstack; sp; sp = sp->prev)
4963 for(i=0; i<depth; ++i) {
4967 v = &(sd->var[sp->varnum]);
4969 if (v->flags & INOUT)
4971 if (v->flags & PREALLOC)
4973 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4974 if (v->type == TYPE_RET) {
4975 printf("(L%03d)", v->vv.retaddr->nr);
4980 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4987 * These are local overrides for various environment variables in Emacs.
4988 * Please do not remove this and leave it at the end of the file, where
4989 * Emacs will automagically detect them.
4990 * ---------------------------------------------------------------------
4993 * indent-tabs-mode: t
4997 * vim:noexpandtab:sw=4:ts=4: