1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
33 $Id: stack.c 5866 2006-10-30 11:00:56Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/show.h"
68 #if defined(ENABLE_DISASSEMBLER)
69 # include "vm/jit/disass.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/stack.h"
75 #if defined(ENABLE_SSA)
76 # include "vm/jit/optimizing/lsra.h"
77 # include "vm/jit/optimizing/ssa.h"
78 #elif defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
82 /*#define STACK_VERBOSE*/
85 /* macro for saving #ifdefs ***************************************************/
87 #if defined(ENABLE_STATISTICS)
88 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
91 if (stackdepth >= 10) \
92 count_store_depth[10]++; \
94 count_store_depth[stackdepth]++; \
97 #else /* !defined(ENABLE_STATISTICS) */
98 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
102 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
105 /* For returnAddresses we use a field of the typeinfo to store from which */
106 /* subroutine the returnAddress will return, if used. */
107 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
108 /* to need it initialised to NULL. This should be investigated. */
110 #if defined(ENABLE_VERIFIER)
111 #define SBRSTART typeinfo.elementclass.any
115 /* stackdata_t *****************************************************************
117 This struct holds internal data during stack analysis.
119 *******************************************************************************/
121 typedef struct stackdata_t stackdata_t;
124 basicblock *bptr; /* the current basic block being analysed */
125 stackptr new; /* next free stackelement */
126 s4 vartop; /* next free variable index */
127 s4 localcount; /* number of locals (at the start of var) */
128 s4 varcount; /* maximum number of variables expected */
129 s4 varsallocated; /* total number of variables allocated */
130 varinfo *var; /* variable array (same as jd->var) */
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 (dv)->type = (sv)->type; \
328 (dv)->vv = (sv)->vv; \
329 (dv)->SBRSTART = (sv)->SBRSTART; \
332 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
334 (dv)->type = (sv)->type; \
335 (dv)->vv = (sv)->vv; \
339 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
340 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
343 /* stack modelling macros *******************************************/
345 #define OP0_1(typed) \
348 GET_NEW_VAR(sd, new_index, (typed)); \
349 DST((typed), new_index); \
360 #define OP1_BRANCH(type1) \
366 #define OP1_1(type1, typed) \
369 GET_NEW_VAR(sd, new_index, (typed)); \
370 DST(typed, new_index); \
373 #define OP2_1(type1, type2, typed) \
375 POP_S1_S2(type1, type2); \
376 GET_NEW_VAR(sd, new_index, (typed)); \
377 DST(typed, new_index); \
392 #define OP1_0(type1) \
399 #define OP2_0(type1, type2) \
401 POP_S1_S2(type1, type2); \
406 #define OP2_BRANCH(type1, type2) \
408 POP_S1_S2(type1, type2); \
412 #define OP2_0_ANY_ANY \
419 #define OP3_0(type1, type2, type3) \
421 POP_S1_S2_S3(type1, type2, type3); \
426 #define LOAD(type1, index) \
428 DST_LOCALVAR(type1, index); \
432 #define STORE(type1, index) \
439 /* macros for DUP elimination ***************************************/
441 /* XXX replace NEW_VAR with NEW_INDEX */
442 #define DUP_SLOT(sp) \
444 GET_NEW_VAR(sd, new_index, (sp)->type); \
445 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
446 NEWSTACK((sp)->type, TEMPVAR, new_index); \
449 /* does not check input stackdepth */
450 #define MOVE_UP(sp) \
452 iptr->opc = ICMD_MOVE; \
453 iptr->s1.varindex = (sp)->varnum; \
455 curstack->creator = iptr; \
456 iptr->dst.varindex = curstack->varnum; \
460 /* does not check input stackdepth */
461 #define COPY_UP(sp) \
464 iptr->opc = ICMD_COPY; \
465 iptr->s1.varindex = (sp)->varnum; \
467 curstack->creator = iptr; \
468 iptr->dst.varindex = curstack->varnum; \
472 #define COPY_DOWN(s, d) \
475 iptr->opc = ICMD_COPY; \
476 iptr->s1.varindex = (s)->varnum; \
477 iptr->dst.varindex = (d)->varnum; \
478 (d)->creator = iptr; \
481 #define MOVE_TO_TEMP(sp) \
483 GET_NEW_INDEX(sd, new_index); \
484 iptr->opc = ICMD_MOVE; \
485 iptr->s1.varindex = (sp)->varnum; \
486 iptr->dst.varindex = new_index; \
487 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
488 (sp)->varnum = new_index; \
489 (sp)->varkind = TEMPVAR; \
492 /* macros for branching / reaching basic blocks *********************/
494 #define BRANCH_TARGET(bt, tempbptr) \
496 tempbptr = BLOCK_OF((bt).insindex); \
497 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
499 if (tempbptr == NULL) \
501 (bt).block = tempbptr; \
504 #define BRANCH(tempbptr) \
505 BRANCH_TARGET(iptr->dst, tempbptr)
508 /* forward declarations *******************************************************/
510 static void stack_create_invars(stackdata_t *sd, basicblock *b,
511 stackptr curstack, int stackdepth);
512 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
514 #if defined(STACK_VERBOSE)
515 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
516 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
517 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
518 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
519 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
523 /* stack_init ******************************************************************
525 Initialized the stack analysis subsystem (called by jit_init).
527 *******************************************************************************/
529 bool stack_init(void)
535 /* stack_grow_variable_array ***************************************************
537 Grow the variable array so the given number of additional variables fits in.
538 The number is added to `varcount`, which is the maximum number of variables
539 we expect to need at this point. The actual number of variables
540 (`varsallocated`) may be larger than that, in order to avoid too many
544 sd...........stack analysis data
545 num..........number of additional variables
547 *******************************************************************************/
549 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
555 if (sd->varcount + num > sd->varsallocated) {
556 newsize = 2*sd->varsallocated + num;
558 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
559 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
560 sd->varsallocated = newsize;
561 sd->jd->var = sd->var;
565 sd->jd->varcount += num;
567 assert(sd->varcount <= sd->varsallocated);
571 /* stack_append_block **********************************************************
573 Append the given block after the last real block of the method (before
574 the pseudo-block at the end).
577 sd...........stack analysis data
578 b............the block to append
580 *******************************************************************************/
582 static void stack_append_block(stackdata_t *sd, basicblock *b)
584 #if defined(STACK_VERBOSE)
585 printf("APPENDING BLOCK L%0d\n", b->nr);
588 b->next = sd->last_real_block->next;
589 sd->last_real_block->next = b;
590 sd->last_real_block = b;
591 b->nr = sd->jd->basicblockcount++;
592 b->next->nr = b->nr + 1;
596 /* stack_clone_block ***********************************************************
598 Create a copy of the given block and insert it at the end of the method.
600 CAUTION: This function does not copy the any variables or the instruction
601 list. It _does_, however, reserve space for the block's invars in the
605 sd...........stack analysis data
606 b............the block to clone
609 a pointer to the copy
611 *******************************************************************************/
613 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
617 clone = DNEW(basicblock);
620 clone->iinstr = NULL;
621 clone->inlocals = NULL;
622 clone->invars = NULL;
624 clone->original = (b->original) ? b->original : b;
625 clone->copied_to = clone->original->copied_to;
626 clone->original->copied_to = clone;
628 clone->flags = BBREACHED;
630 stack_append_block(sd, clone);
632 /* reserve space for the invars of the clone */
634 stack_grow_variable_array(sd, b->indepth);
636 #if defined(STACK_VERBOSE)
637 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
644 /* stack_create_invars *********************************************************
646 Create the invars for the given basic block. Also make a copy of the locals.
649 sd...........stack analysis data
650 b............block to create the invars for
651 curstack.....current stack top
652 stackdepth...current stack depth
654 This function creates STACKDEPTH invars and sets their types to the
655 types to the types of the corresponding slot in the current stack.
657 *******************************************************************************/
659 static void stack_create_invars(stackdata_t *sd, basicblock *b,
660 stackptr curstack, int stackdepth)
668 assert(sd->vartop + stackdepth <= sd->varcount);
670 b->indepth = stackdepth;
671 b->invars = DMNEW(s4, stackdepth);
673 /* allocate the variable indices */
674 index = (sd->vartop += stackdepth);
677 for (sp = curstack; i--; sp = sp->prev) {
678 b->invars[i] = --index;
679 dv = sd->var + index;
680 sv = sd->var + sp->varnum;
682 COPY_VAL_AND_TYPE_VAR(sv, dv);
685 /* copy the current state of the local variables */
686 /* (one extra local is needed by the verifier) */
688 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
690 for (i=0; i<sd->localcount; ++i)
695 /* stack_create_invars_from_outvars ********************************************
697 Create the invars for the given basic block. Also make a copy of the locals.
698 Types are propagated from the outvars of the current block.
701 sd...........stack analysis data
702 b............block to create the invars for
704 *******************************************************************************/
706 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
712 n = sd->bptr->outdepth;
713 assert(sd->vartop + n <= sd->varcount);
716 b->invars = DMNEW(s4, n);
719 dv = sd->var + sd->vartop;
721 /* allocate the invars */
723 for (i=0; i<n; ++i, ++dv) {
724 sv = sd->var + sd->bptr->outvars[i];
725 b->invars[i] = sd->vartop++;
727 COPY_VAL_AND_TYPE_VAR(sv, dv);
731 /* copy the current state of the local variables */
732 /* (one extra local is needed by the verifier) */
734 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
736 for (i=0; i<sd->localcount; ++i)
741 /* stack_check_invars **********************************************************
743 Check the current stack against the invars of the given basic block.
744 Depth and types must match.
747 sd...........stack analysis data
748 b............block which invars to check against
749 curstack.....current stack top
750 stackdepth...current stack depth
754 NULL.........a VerifyError has been thrown
756 *******************************************************************************/
758 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
759 stackptr curstack, int stackdepth)
768 #if defined(STACK_VERBOSE)
769 printf("stack_check_invars(L%03d)\n", b->nr);
772 /* find original of b */
777 #if defined(STACK_VERBOSE)
778 printf("original is L%03d\n", orig->nr);
783 #if defined(ENABLE_VERIFIER)
784 if (i != stackdepth) {
785 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
793 #if defined(STACK_VERBOSE)
794 printf("checking against ");
795 stack_verbose_show_block(sd, b); printf("\n");
799 for (i = orig->indepth; i--; sp = sp->prev) {
800 dv = sd->var + b->invars[i];
801 sv = sd->var + sp->varnum;
803 #if defined(ENABLE_VERIFIER)
804 if (dv->type != sp->type) {
805 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
810 if (sp->type == TYPE_RET) {
811 #if defined(ENABLE_VERIFIER)
812 if (dv->SBRSTART != sv->SBRSTART) {
813 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
817 if (dv->vv.retaddr != sv->vv.retaddr) {
819 /* don't break! have to check the remaining stackslots */
825 for (i=0; i<sd->localcount; ++i) {
826 dv = b->inlocals + i;
828 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
830 #if defined(ENABLE_VERIFIER)
831 (sv->SBRSTART == dv->SBRSTART) &&
833 (sv->vv.retaddr != dv->vv.retaddr))
843 /* XXX mark mixed type variables void */
844 /* XXX cascading collapse? */
845 #if defined(ENABLE_VERIFIER)
847 for (i=0; i<sd->localcount; ++i) {
848 dv = b->inlocals + i;
850 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
851 && (sv->SBRSTART != dv->SBRSTART))
853 dv->type = TYPE_VOID;
854 if (b->flags >= BBFINISHED)
855 b->flags = BBTYPECHECK_REACHED;
856 sd->repeat = true; /* This is very rare, so just repeat */
862 #if defined(STACK_VERBOSE)
863 printf("------> using L%03d\n", b->nr);
867 } while ((b = b->copied_to) != NULL);
869 b = stack_clone_block(sd, orig);
873 stack_create_invars(sd, b, curstack, stackdepth);
878 /* stack_check_invars_from_outvars *********************************************
880 Check the outvars of the current block against the invars of the given block.
881 Depth and types must match.
884 sd...........stack analysis data
885 b............block which invars to check against
889 NULL.........a VerifyError has been thrown
891 *******************************************************************************/
893 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
901 #if defined(STACK_VERBOSE)
902 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
905 /* find original of b */
910 #if defined(STACK_VERBOSE)
911 printf("original is L%03d\n", orig->nr);
915 n = sd->bptr->outdepth;
917 #if defined(ENABLE_VERIFIER)
919 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
927 #if defined(STACK_VERBOSE)
928 printf("checking against ");
929 stack_verbose_show_block(sd, b); printf("\n");
933 dv = sd->var + b->invars[0];
935 for (i=0; i<n; ++i, ++dv) {
936 sv = sd->var + sd->bptr->outvars[i];
938 #if defined(ENABLE_VERIFIER)
939 if (sv->type != dv->type) {
940 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
945 if (dv->type == TYPE_RET) {
946 #if defined(ENABLE_VERIFIER)
947 if (sv->SBRSTART != dv->SBRSTART) {
948 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
952 if (sv->vv.retaddr != dv->vv.retaddr) {
954 /* don't break! have to check the remaining stackslots */
961 for (i=0; i<sd->localcount; ++i) {
962 dv = b->inlocals + i;
965 #if defined(ENABLE_VERIFIER)
966 (sv->SBRSTART == dv->SBRSTART) &&
968 (sv->type == TYPE_RET && dv->type == TYPE_RET))
970 if (sv->vv.retaddr != dv->vv.retaddr) {
979 /* XXX mark mixed type variables void */
980 /* XXX cascading collapse? */
981 #if defined(ENABLE_VERIFIER)
983 for (i=0; i<sd->localcount; ++i) {
984 dv = b->inlocals + i;
986 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
987 && (sv->SBRSTART != dv->SBRSTART))
989 dv->type = TYPE_VOID;
990 if (b->flags >= BBFINISHED)
991 b->flags = BBTYPECHECK_REACHED;
992 sd->repeat = true; /* This is very rare, so just repeat */
998 #if defined(STACK_VERBOSE)
999 printf("------> using L%03d\n", b->nr);
1003 } while ((b = b->copied_to) != NULL);
1005 b = stack_clone_block(sd, orig);
1009 stack_create_invars_from_outvars(sd, b);
1014 /* stack_create_instack ********************************************************
1016 Create the instack of the current basic block.
1019 sd...........stack analysis data
1022 the current stack top at the start of the basic block.
1024 *******************************************************************************/
1026 static stackptr stack_create_instack(stackdata_t *sd)
1032 if ((depth = sd->bptr->indepth) == 0)
1035 sp = (sd->new += depth);
1039 index = sd->bptr->invars[depth];
1041 sp->type = sd->var[index].type;
1045 sp->varkind = STACKVAR;
1049 /* return the top of the created stack */
1054 /* stack_mark_reached **********************************************************
1056 Mark the given block reached and propagate the current stack and locals to
1057 it. This function specializes the target block, if necessary, and returns
1058 a pointer to the specialized target.
1061 sd...........stack analysis data
1062 b............the block to reach
1063 curstack.....the current stack top
1064 stackdepth...the current stack depth
1067 a pointer to (a specialized version of) the target
1068 NULL.........a VerifyError has been thrown
1070 *******************************************************************************/
1072 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1074 #if defined(STACK_VERBOSE)
1075 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1077 /* mark targets of backward branches */
1079 b->bitflags |= BBFLAG_REPLACEMENT;
1081 if (b->flags < BBREACHED) {
1082 /* b is reached for the first time. Create its invars. */
1084 #if defined(STACK_VERBOSE)
1085 printf("reached L%03d for the first time\n", b->nr);
1088 stack_create_invars(sd, b, curstack, stackdepth);
1090 b->flags = BBREACHED;
1095 /* b has been reached before. Check that its invars match. */
1097 return stack_check_invars(sd, b, curstack, stackdepth);
1102 /* stack_mark_reached_from_outvars *********************************************
1104 Mark the given block reached and propagate the outvars of the current block
1105 and the current locals to it. This function specializes the target block,
1106 if necessary, and returns a pointer to the specialized target.
1109 sd...........stack analysis data
1110 b............the block to reach
1113 a pointer to (a specialized version of) the target
1114 NULL.........a VerifyError has been thrown
1116 *******************************************************************************/
1118 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1120 #if defined(STACK_VERBOSE)
1121 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1123 /* mark targets of backward branches */
1125 b->bitflags |= BBFLAG_REPLACEMENT;
1127 if (b->flags < BBREACHED) {
1128 /* b is reached for the first time. Create its invars. */
1130 #if defined(STACK_VERBOSE)
1131 printf("reached L%03d for the first time\n", b->nr);
1134 stack_create_invars_from_outvars(sd, b);
1136 b->flags = BBREACHED;
1141 /* b has been reached before. Check that its invars match. */
1143 return stack_check_invars_from_outvars(sd, b);
1148 /* stack_reach_next_block ******************************************************
1150 Mark the following block reached and propagate the outvars of the current block
1151 and the current locals to it. This function specializes the target block,
1152 if necessary, and returns a pointer to the specialized target.
1155 sd...........stack analysis data
1158 a pointer to (a specialized version of) the following block
1159 NULL.........a VerifyError has been thrown
1161 *******************************************************************************/
1163 static bool stack_reach_next_block(stackdata_t *sd)
1168 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1169 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1173 if (tbptr != sd->bptr->next) {
1174 #if defined(STACK_VERBOSE)
1175 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1177 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1178 assert(iptr->opc == ICMD_NOP);
1179 iptr->opc = ICMD_GOTO;
1180 iptr->dst.block = tbptr;
1182 if (tbptr->flags < BBFINISHED)
1183 sd->repeat = true; /* XXX check if we really need to repeat */
1190 /* stack_reach_handlers ********************************************************
1192 Reach the exception handlers for the current block.
1195 sd...........stack analysis data
1198 true.........everything ok
1199 false........a VerifyError has been thrown
1201 *******************************************************************************/
1203 static bool stack_reach_handlers(stackdata_t *sd)
1208 #if defined(STACK_VERBOSE)
1209 printf("reaching exception handlers...\n");
1212 for (i=0; sd->handlers[i]; ++i) {
1213 tbptr = sd->handlers[i]->handler;
1215 tbptr->type = BBTYPE_EXH;
1216 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1218 /* reach (and specialize) the handler block */
1220 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1225 sd->handlers[i]->handler = tbptr;
1232 /* stack_reanalyse_block ******************************************************
1234 Re-analyse the current block. This is called if either the block itself
1235 has already been analysed before, or the current block is a clone of an
1236 already analysed block, and this clone is reached for the first time.
1237 In the latter case, this function does all that is necessary for fully
1238 cloning the block (cloning the instruction list and variables, etc.).
1241 sd...........stack analysis data
1244 true.........everything ok
1245 false........a VerifyError has been thrown
1247 *******************************************************************************/
1249 #define RELOCATE(index) \
1251 if ((index) >= blockvarstart) \
1252 (index) += blockvarshift; \
1253 else if ((index) >= invarstart) \
1254 (index) += invarshift; \
1257 bool stack_reanalyse_block(stackdata_t *sd)
1269 branch_target_t *table;
1270 lookup_target_t *lookup;
1272 bool cloneinstructions;
1273 exception_entry *ex;
1275 #if defined(STACK_VERBOSE)
1276 stack_verbose_block_enter(sd, true);
1283 assert(orig != NULL);
1285 /* clone the instruction list */
1287 cloneinstructions = true;
1289 assert(orig->iinstr);
1291 iptr = DMNEW(instruction, len + 1);
1293 MCOPY(iptr, orig->iinstr, instruction, len);
1294 iptr[len].opc = ICMD_NOP;
1298 /* reserve space for the clone's block variables */
1300 stack_grow_variable_array(sd, orig->varcount);
1302 /* we already have the invars set */
1304 assert(b->indepth == orig->indepth);
1306 /* calculate relocation shifts for invars and block variables */
1308 if (orig->indepth) {
1309 invarstart = orig->invars[0];
1310 invarshift = b->invars[0] - invarstart;
1313 invarstart = INT_MAX;
1316 blockvarstart = orig->varstart;
1317 blockvarshift = sd->vartop - blockvarstart;
1319 /* copy block variables */
1321 b->varstart = sd->vartop;
1322 b->varcount = orig->varcount;
1323 sd->vartop += b->varcount;
1324 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1328 b->outdepth = orig->outdepth;
1329 b->outvars = DMNEW(s4, orig->outdepth);
1330 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1332 /* clone exception handlers */
1334 for (i=0; sd->handlers[i]; ++i) {
1335 ex = DNEW(exception_entry);
1336 ex->handler = sd->handlers[i]->handler;
1338 ex->end = b; /* XXX hack, see end of stack_analyse */
1339 ex->catchtype = sd->handlers[i]->catchtype;
1342 assert(sd->extableend->down == NULL);
1343 sd->extableend->down = ex;
1344 sd->extableend = ex;
1345 sd->jd->exceptiontablelength++;
1347 sd->handlers[i] = ex;
1351 cloneinstructions = false;
1354 invarstart = sd->vartop;
1355 blockvarstart = sd->vartop;
1360 /* find exception handlers for the cloned block */
1362 ex = sd->jd->exceptiontable;
1363 for (; ex != NULL; ex = ex->down) {
1364 /* XXX the cloned exception handlers have identical */
1365 /* start end end blocks. */
1366 if ((ex->start == b) && (ex->end == b)) {
1367 sd->handlers[len++] = ex;
1370 sd->handlers[len] = NULL;
1373 #if defined(STACK_VERBOSE)
1374 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1375 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1378 /* mark block as finished */
1380 b->flags = BBFINISHED;
1382 /* initialize locals at the start of this block */
1385 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1387 /* reach exception handlers for this block */
1389 if (!stack_reach_handlers(sd))
1392 superblockend = false;
1394 for (len = b->icount; len--; iptr++) {
1395 #if defined(STACK_VERBOSE)
1396 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1400 switch (iptr->opc) {
1402 j = iptr->s1.varindex;
1404 #if defined(ENABLE_VERIFIER)
1405 if (sd->var[j].type != TYPE_RET) {
1406 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1411 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1412 superblockend = true;
1416 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1417 superblockend = true;
1421 superblockend = true;
1424 case ICMD_CHECKNULL:
1425 case ICMD_PUTSTATICCONST:
1430 case ICMD_INLINE_START:
1431 case ICMD_INLINE_END:
1432 case ICMD_INLINE_GOTO:
1436 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1437 superblockend = true;
1440 /* pop 0 push 1 const */
1448 /* pop 0 push 1 load */
1455 RELOCATE(iptr->dst.varindex);
1468 RELOCATE(iptr->sx.s23.s2.varindex);
1469 RELOCATE(iptr->s1.varindex);
1470 RELOCATE(iptr->dst.varindex);
1483 RELOCATE(iptr->sx.s23.s3.varindex);
1484 RELOCATE(iptr->sx.s23.s2.varindex);
1485 RELOCATE(iptr->s1.varindex);
1488 /* pop 1 push 0 store */
1495 RELOCATE(iptr->s1.varindex);
1497 j = iptr->dst.varindex;
1498 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1509 RELOCATE(iptr->s1.varindex);
1510 superblockend = true;
1513 case ICMD_PUTSTATIC:
1514 case ICMD_PUTFIELDCONST:
1516 RELOCATE(iptr->s1.varindex);
1519 /* pop 1 push 0 branch */
1522 case ICMD_IFNONNULL:
1537 RELOCATE(iptr->s1.varindex);
1538 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1541 /* pop 1 push 0 table branch */
1543 case ICMD_TABLESWITCH:
1544 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1546 if (cloneinstructions) {
1547 table = DMNEW(branch_target_t, i);
1548 MCOPY(table, iptr->dst.table, branch_target_t, i);
1549 iptr->dst.table = table;
1552 table = iptr->dst.table;
1555 RELOCATE(iptr->s1.varindex);
1557 table->block = stack_mark_reached_from_outvars(sd, table->block);
1560 superblockend = true;
1563 case ICMD_LOOKUPSWITCH:
1564 i = iptr->sx.s23.s2.lookupcount;
1565 if (cloneinstructions) {
1566 lookup = DMNEW(lookup_target_t, i);
1567 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1568 iptr->dst.lookup = lookup;
1571 lookup = iptr->dst.lookup;
1573 RELOCATE(iptr->s1.varindex);
1575 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1578 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1579 superblockend = true;
1582 case ICMD_MONITORENTER:
1583 case ICMD_MONITOREXIT:
1584 RELOCATE(iptr->s1.varindex);
1587 /* pop 2 push 0 branch */
1589 case ICMD_IF_ICMPEQ:
1590 case ICMD_IF_ICMPNE:
1591 case ICMD_IF_ICMPLT:
1592 case ICMD_IF_ICMPGE:
1593 case ICMD_IF_ICMPGT:
1594 case ICMD_IF_ICMPLE:
1596 case ICMD_IF_LCMPEQ:
1597 case ICMD_IF_LCMPNE:
1598 case ICMD_IF_LCMPLT:
1599 case ICMD_IF_LCMPGE:
1600 case ICMD_IF_LCMPGT:
1601 case ICMD_IF_LCMPLE:
1603 case ICMD_IF_FCMPEQ:
1604 case ICMD_IF_FCMPNE:
1606 case ICMD_IF_FCMPL_LT:
1607 case ICMD_IF_FCMPL_GE:
1608 case ICMD_IF_FCMPL_GT:
1609 case ICMD_IF_FCMPL_LE:
1611 case ICMD_IF_FCMPG_LT:
1612 case ICMD_IF_FCMPG_GE:
1613 case ICMD_IF_FCMPG_GT:
1614 case ICMD_IF_FCMPG_LE:
1616 case ICMD_IF_DCMPEQ:
1617 case ICMD_IF_DCMPNE:
1619 case ICMD_IF_DCMPL_LT:
1620 case ICMD_IF_DCMPL_GE:
1621 case ICMD_IF_DCMPL_GT:
1622 case ICMD_IF_DCMPL_LE:
1624 case ICMD_IF_DCMPG_LT:
1625 case ICMD_IF_DCMPG_GE:
1626 case ICMD_IF_DCMPG_GT:
1627 case ICMD_IF_DCMPG_LE:
1629 case ICMD_IF_ACMPEQ:
1630 case ICMD_IF_ACMPNE:
1631 RELOCATE(iptr->sx.s23.s2.varindex);
1632 RELOCATE(iptr->s1.varindex);
1633 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1639 case ICMD_IASTORECONST:
1640 case ICMD_LASTORECONST:
1641 case ICMD_AASTORECONST:
1642 case ICMD_BASTORECONST:
1643 case ICMD_CASTORECONST:
1644 case ICMD_SASTORECONST:
1646 RELOCATE(iptr->sx.s23.s2.varindex);
1647 RELOCATE(iptr->s1.varindex);
1650 /* pop 0 push 1 copy */
1654 RELOCATE(iptr->dst.varindex);
1655 RELOCATE(iptr->s1.varindex);
1656 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1698 RELOCATE(iptr->sx.s23.s2.varindex);
1699 RELOCATE(iptr->s1.varindex);
1700 RELOCATE(iptr->dst.varindex);
1705 case ICMD_CHECKCAST:
1706 case ICMD_ARRAYLENGTH:
1707 case ICMD_INSTANCEOF:
1709 case ICMD_ANEWARRAY:
1711 case ICMD_IADDCONST:
1712 case ICMD_ISUBCONST:
1713 case ICMD_IMULCONST:
1717 case ICMD_IANDCONST:
1719 case ICMD_IXORCONST:
1720 case ICMD_ISHLCONST:
1721 case ICMD_ISHRCONST:
1722 case ICMD_IUSHRCONST:
1723 case ICMD_LADDCONST:
1724 case ICMD_LSUBCONST:
1725 case ICMD_LMULCONST:
1729 case ICMD_LANDCONST:
1731 case ICMD_LXORCONST:
1732 case ICMD_LSHLCONST:
1733 case ICMD_LSHRCONST:
1734 case ICMD_LUSHRCONST:
1738 case ICMD_INT2SHORT:
1754 RELOCATE(iptr->s1.varindex);
1755 RELOCATE(iptr->dst.varindex);
1760 case ICMD_GETSTATIC:
1762 RELOCATE(iptr->dst.varindex);
1765 /* pop many push any */
1767 case ICMD_INVOKESTATIC:
1768 case ICMD_INVOKESPECIAL:
1769 case ICMD_INVOKEVIRTUAL:
1770 case ICMD_INVOKEINTERFACE:
1772 case ICMD_MULTIANEWARRAY:
1773 i = iptr->s1.argcount;
1774 if (cloneinstructions) {
1775 argp = DMNEW(s4, i);
1776 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1777 iptr->sx.s23.s2.args = argp;
1780 argp = iptr->sx.s23.s2.args;
1787 RELOCATE(iptr->dst.varindex);
1792 new_internalerror("Unknown ICMD %d during stack re-analysis",
1797 #if defined(STACK_VERBOSE)
1798 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1803 /* relocate outvars */
1805 for (i=0; i<b->outdepth; ++i) {
1806 RELOCATE(b->outvars[i]);
1809 #if defined(STACK_VERBOSE)
1810 stack_verbose_block_exit(sd, superblockend);
1813 /* propagate to the next block */
1816 if (!stack_reach_next_block(sd))
1823 /* stack_change_to_tempvar *****************************************************
1825 Change the given stackslot to a TEMPVAR. This includes creating a new
1826 temporary variable and changing the dst.varindex of the creator of the
1827 stacklot to the new variable index. If this stackslot has been passed
1828 through ICMDs between the point of its creation and the current point,
1829 then the variable index is also changed in these ICMDs.
1832 sd...........stack analysis data
1833 sp...........stackslot to change
1834 ilimit.......instruction up to which to look for ICMDs passing-through
1835 the stackslot (exclusive). This may point exactly after the
1836 last instruction, in which case the search is done to the
1839 *******************************************************************************/
1841 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1842 instruction *ilimit)
1849 oldindex = sp->varnum;
1851 /* create a new temporary variable */
1853 GET_NEW_VAR(*sd, newindex, sp->type);
1855 sd->var[newindex].flags = sp->flags;
1857 /* change the stackslot */
1859 sp->varnum = newindex;
1860 sp->varkind = TEMPVAR;
1862 /* change the dst.varindex of the stackslot's creator */
1865 sp->creator->dst.varindex = newindex;
1867 /* handle ICMDs this stackslot passed through, if any */
1869 if (sp->flags & PASSTHROUGH) {
1870 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1872 /* asser that the limit point to an ICMD, or after the last one */
1873 assert(ilimit >= sd->bptr->iinstr);
1874 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1876 for (; iptr < ilimit; ++iptr) {
1877 switch (iptr->opc) {
1878 case ICMD_INVOKESTATIC:
1879 case ICMD_INVOKESPECIAL:
1880 case ICMD_INVOKEVIRTUAL:
1881 case ICMD_INVOKEINTERFACE:
1884 for (i=0; i<iptr->s1.argcount; ++i)
1885 if (iptr->sx.s23.s2.args[i] == oldindex) {
1886 iptr->sx.s23.s2.args[i] = newindex;
1889 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1890 /* stackslot, it must be added in this switch! */
1897 /* stack_analyse ***************************************************************
1899 Analyse_stack uses the intermediate code created by parse.c to
1900 build a model of the JVM operand stack for the current method.
1902 The following checks are performed:
1903 - check for operand stack underflow (before each instruction)
1904 - check for operand stack overflow (after[1] each instruction)
1905 - check for matching stack depth at merging points
1906 - check for matching basic types[2] at merging points
1907 - check basic types for instruction input (except for BUILTIN*
1908 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1910 [1]) Checking this after the instruction should be ok. parse.c
1911 counts the number of required stack slots in such a way that it is
1912 only vital that we don't exceed `maxstack` at basic block
1915 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1916 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1917 types are not discerned.
1919 *******************************************************************************/
1921 bool stack_analyse(jitdata *jd)
1923 methodinfo *m; /* method being analyzed */
1926 #if defined(ENABLE_SSA)
1930 stackptr curstack; /* current stack top */
1932 int opcode; /* opcode of current instruction */
1935 int len; /* # of instructions after the current one */
1936 bool superblockend; /* if true, no fallthrough to next block */
1937 bool deadcode; /* true if no live code has been reached */
1938 instruction *iptr; /* the current instruction */
1940 basicblock *original;
1941 exception_entry *ex;
1943 stackptr *last_store_boundary;
1944 stackptr coalescing_boundary;
1946 stackptr src1, src2, src3, src4, dst1, dst2;
1948 branch_target_t *table;
1949 lookup_target_t *lookup;
1950 #if defined(ENABLE_VERIFIER)
1951 int expectedtype; /* used by CHECK_BASIC_TYPE */
1953 builtintable_entry *bte;
1955 constant_FMIref *fmiref;
1956 #if defined(ENABLE_STATISTICS)
1957 int iteration_count; /* number of iterations of analysis */
1959 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1961 #if defined(STACK_VERBOSE)
1962 show_method(jd, SHOW_PARSE);
1965 /* get required compiler data - initialization */
1969 #if defined(ENABLE_SSA)
1973 /* initialize the stackdata_t struct */
1977 sd.varcount = jd->varcount;
1978 sd.vartop = jd->vartop;
1979 sd.localcount = jd->localcount;
1981 sd.varsallocated = sd.varcount;
1982 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
1984 /* prepare the variable for exception handler stacks */
1985 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
1987 sd.exstack.type = TYPE_ADR;
1988 sd.exstack.prev = NULL;
1989 sd.exstack.varnum = sd.localcount;
1990 sd.var[sd.exstack.varnum].type = TYPE_ADR;
1992 #if defined(ENABLE_LSRA)
1993 m->maxlifetimes = 0;
1996 #if defined(ENABLE_STATISTICS)
1997 iteration_count = 0;
2000 /* find the last real basic block */
2002 sd.last_real_block = NULL;
2003 tbptr = jd->basicblocks;
2004 while (tbptr->next) {
2005 sd.last_real_block = tbptr;
2006 tbptr = tbptr->next;
2008 assert(sd.last_real_block);
2010 /* find the last exception handler */
2012 if (jd->exceptiontablelength)
2013 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2015 sd.extableend = NULL;
2017 /* init jd->interface_map */
2019 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2020 for (i = 0; i < m->maxstack * 5; i++)
2021 jd->interface_map[i].flags = UNUSED;
2023 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2025 /* initialize flags and invars (none) of first block */
2027 jd->basicblocks[0].flags = BBREACHED;
2028 jd->basicblocks[0].invars = NULL;
2029 jd->basicblocks[0].indepth = 0;
2030 jd->basicblocks[0].inlocals =
2031 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2032 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2033 jd->localcount + VERIFIER_EXTRA_LOCALS);
2035 /* stack analysis loop (until fixpoint reached) **************************/
2038 #if defined(ENABLE_STATISTICS)
2042 /* initialize loop over basic blocks */
2044 sd.bptr = jd->basicblocks;
2045 superblockend = true;
2047 curstack = NULL; stackdepth = 0;
2050 /* iterate over basic blocks *****************************************/
2052 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2054 if (sd.bptr->flags == BBDELETED) {
2055 /* This block has been deleted - do nothing. */
2060 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2061 /* re-analyse a block because its input changed */
2062 if (!stack_reanalyse_block(&sd))
2064 superblockend = true; /* XXX */
2068 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2069 /* This block has not been reached so far, and we */
2070 /* don't fall into it, so we'll have to iterate again. */
2076 if (sd.bptr->flags > BBREACHED) {
2077 /* This block is already finished. */
2079 superblockend = true;
2083 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2084 /* This block is a clone and the original has not been */
2085 /* analysed, yet. Analyse it on the next iteration. */
2088 /* XXX superblockend? */
2092 /* This block has to be analysed now. */
2094 /* XXX The rest of this block is still indented one level too */
2095 /* much in order to avoid a giant diff by changing that. */
2097 /* We know that sd.bptr->flags == BBREACHED. */
2098 /* This block has been reached before. */
2100 assert(sd.bptr->flags == BBREACHED);
2101 stackdepth = sd.bptr->indepth;
2103 /* find exception handlers for this block */
2105 /* determine the active exception handlers for this block */
2106 /* XXX could use a faster algorithm with sorted lists or */
2109 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2112 ex = jd->exceptiontable;
2113 for (; ex != NULL; ex = ex->down) {
2114 if ((ex->start <= original) && (ex->end > original)) {
2115 sd.handlers[len++] = ex;
2118 sd.handlers[len] = NULL;
2121 /* reanalyse cloned block */
2123 if (sd.bptr->original) {
2124 if (!stack_reanalyse_block(&sd))
2129 /* reset the new pointer for allocating stackslots */
2133 /* create the instack of this block */
2135 curstack = stack_create_instack(&sd);
2137 /* initialize locals at the start of this block */
2139 if (sd.bptr->inlocals)
2140 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2142 /* set up local variables for analyzing this block */
2145 superblockend = false;
2146 len = sd.bptr->icount;
2147 iptr = sd.bptr->iinstr;
2149 /* mark the block as analysed */
2151 sd.bptr->flags = BBFINISHED;
2153 /* reset variables for dependency checking */
2155 coalescing_boundary = sd.new;
2156 for( i = 0; i < m->maxlocals; i++)
2157 last_store_boundary[i] = sd.new;
2159 /* remember the start of this block's variables */
2161 sd.bptr->varstart = sd.vartop;
2163 #if defined(STACK_VERBOSE)
2164 stack_verbose_block_enter(&sd, false);
2167 /* reach exception handlers for this block */
2169 if (!stack_reach_handlers(&sd))
2172 /* iterate over ICMDs ****************************************/
2174 while (--len >= 0) {
2176 #if defined(STACK_VERBOSE)
2177 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2178 for( copy = curstack; copy; copy = copy->prev ) {
2179 printf("%2d(%d", copy->varnum, copy->type);
2182 if (IS_PREALLOC(copy))
2189 /* fetch the current opcode */
2193 /* automatically replace some ICMDs with builtins */
2195 #if defined(USEBUILTINTABLE)
2196 bte = builtintable_get_automatic(opcode);
2198 if (bte && bte->opcode == opcode) {
2199 iptr->opc = ICMD_BUILTIN;
2200 iptr->flags.bits = 0;
2201 iptr->sx.s23.s3.bte = bte;
2202 /* iptr->line is already set */
2203 jd->isleafmethod = false;
2206 #endif /* defined(USEBUILTINTABLE) */
2208 /* main opcode switch *************************************/
2220 case ICMD_CHECKNULL:
2221 coalescing_boundary = sd.new;
2222 COUNT(count_check_null);
2225 iptr->dst.varindex = iptr->s1.varindex;
2229 j = iptr->s1.varindex =
2230 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2232 #if defined(ENABLE_VERIFIER)
2233 if (sd.var[j].type != TYPE_RET) {
2234 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2241 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2242 superblockend = true;
2246 COUNT(count_pcmd_return);
2249 superblockend = true;
2253 /* pop 0 push 1 const */
2255 /************************** ICONST OPTIMIZATIONS **************************/
2258 COUNT(count_pcmd_load);
2262 switch (iptr[1].opc) {
2264 iptr->opc = ICMD_IADDCONST;
2268 iptr[1].opc = ICMD_NOP;
2269 OP1_1(TYPE_INT, TYPE_INT);
2270 COUNT(count_pcmd_op);
2274 iptr->opc = ICMD_ISUBCONST;
2275 goto icmd_iconst_tail;
2276 #if SUPPORT_CONST_MUL
2278 iptr->opc = ICMD_IMULCONST;
2279 goto icmd_iconst_tail;
2280 #else /* SUPPORT_CONST_MUL */
2282 if (iptr->sx.val.i == 0x00000002)
2284 else if (iptr->sx.val.i == 0x00000004)
2286 else if (iptr->sx.val.i == 0x00000008)
2288 else if (iptr->sx.val.i == 0x00000010)
2290 else if (iptr->sx.val.i == 0x00000020)
2292 else if (iptr->sx.val.i == 0x00000040)
2294 else if (iptr->sx.val.i == 0x00000080)
2296 else if (iptr->sx.val.i == 0x00000100)
2298 else if (iptr->sx.val.i == 0x00000200)
2300 else if (iptr->sx.val.i == 0x00000400)
2301 iptr->sx.val.i = 10;
2302 else if (iptr->sx.val.i == 0x00000800)
2303 iptr->sx.val.i = 11;
2304 else if (iptr->sx.val.i == 0x00001000)
2305 iptr->sx.val.i = 12;
2306 else if (iptr->sx.val.i == 0x00002000)
2307 iptr->sx.val.i = 13;
2308 else if (iptr->sx.val.i == 0x00004000)
2309 iptr->sx.val.i = 14;
2310 else if (iptr->sx.val.i == 0x00008000)
2311 iptr->sx.val.i = 15;
2312 else if (iptr->sx.val.i == 0x00010000)
2313 iptr->sx.val.i = 16;
2314 else if (iptr->sx.val.i == 0x00020000)
2315 iptr->sx.val.i = 17;
2316 else if (iptr->sx.val.i == 0x00040000)
2317 iptr->sx.val.i = 18;
2318 else if (iptr->sx.val.i == 0x00080000)
2319 iptr->sx.val.i = 19;
2320 else if (iptr->sx.val.i == 0x00100000)
2321 iptr->sx.val.i = 20;
2322 else if (iptr->sx.val.i == 0x00200000)
2323 iptr->sx.val.i = 21;
2324 else if (iptr->sx.val.i == 0x00400000)
2325 iptr->sx.val.i = 22;
2326 else if (iptr->sx.val.i == 0x00800000)
2327 iptr->sx.val.i = 23;
2328 else if (iptr->sx.val.i == 0x01000000)
2329 iptr->sx.val.i = 24;
2330 else if (iptr->sx.val.i == 0x02000000)
2331 iptr->sx.val.i = 25;
2332 else if (iptr->sx.val.i == 0x04000000)
2333 iptr->sx.val.i = 26;
2334 else if (iptr->sx.val.i == 0x08000000)
2335 iptr->sx.val.i = 27;
2336 else if (iptr->sx.val.i == 0x10000000)
2337 iptr->sx.val.i = 28;
2338 else if (iptr->sx.val.i == 0x20000000)
2339 iptr->sx.val.i = 29;
2340 else if (iptr->sx.val.i == 0x40000000)
2341 iptr->sx.val.i = 30;
2342 else if (iptr->sx.val.i == 0x80000000)
2343 iptr->sx.val.i = 31;
2347 iptr->opc = ICMD_IMULPOW2;
2348 goto icmd_iconst_tail;
2349 #endif /* SUPPORT_CONST_MUL */
2351 if (iptr->sx.val.i == 0x00000002)
2353 else if (iptr->sx.val.i == 0x00000004)
2355 else if (iptr->sx.val.i == 0x00000008)
2357 else if (iptr->sx.val.i == 0x00000010)
2359 else if (iptr->sx.val.i == 0x00000020)
2361 else if (iptr->sx.val.i == 0x00000040)
2363 else if (iptr->sx.val.i == 0x00000080)
2365 else if (iptr->sx.val.i == 0x00000100)
2367 else if (iptr->sx.val.i == 0x00000200)
2369 else if (iptr->sx.val.i == 0x00000400)
2370 iptr->sx.val.i = 10;
2371 else if (iptr->sx.val.i == 0x00000800)
2372 iptr->sx.val.i = 11;
2373 else if (iptr->sx.val.i == 0x00001000)
2374 iptr->sx.val.i = 12;
2375 else if (iptr->sx.val.i == 0x00002000)
2376 iptr->sx.val.i = 13;
2377 else if (iptr->sx.val.i == 0x00004000)
2378 iptr->sx.val.i = 14;
2379 else if (iptr->sx.val.i == 0x00008000)
2380 iptr->sx.val.i = 15;
2381 else if (iptr->sx.val.i == 0x00010000)
2382 iptr->sx.val.i = 16;
2383 else if (iptr->sx.val.i == 0x00020000)
2384 iptr->sx.val.i = 17;
2385 else if (iptr->sx.val.i == 0x00040000)
2386 iptr->sx.val.i = 18;
2387 else if (iptr->sx.val.i == 0x00080000)
2388 iptr->sx.val.i = 19;
2389 else if (iptr->sx.val.i == 0x00100000)
2390 iptr->sx.val.i = 20;
2391 else if (iptr->sx.val.i == 0x00200000)
2392 iptr->sx.val.i = 21;
2393 else if (iptr->sx.val.i == 0x00400000)
2394 iptr->sx.val.i = 22;
2395 else if (iptr->sx.val.i == 0x00800000)
2396 iptr->sx.val.i = 23;
2397 else if (iptr->sx.val.i == 0x01000000)
2398 iptr->sx.val.i = 24;
2399 else if (iptr->sx.val.i == 0x02000000)
2400 iptr->sx.val.i = 25;
2401 else if (iptr->sx.val.i == 0x04000000)
2402 iptr->sx.val.i = 26;
2403 else if (iptr->sx.val.i == 0x08000000)
2404 iptr->sx.val.i = 27;
2405 else if (iptr->sx.val.i == 0x10000000)
2406 iptr->sx.val.i = 28;
2407 else if (iptr->sx.val.i == 0x20000000)
2408 iptr->sx.val.i = 29;
2409 else if (iptr->sx.val.i == 0x40000000)
2410 iptr->sx.val.i = 30;
2411 else if (iptr->sx.val.i == 0x80000000)
2412 iptr->sx.val.i = 31;
2416 iptr->opc = ICMD_IDIVPOW2;
2417 goto icmd_iconst_tail;
2420 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2421 if ((iptr->sx.val.i == 0x00000002) ||
2422 (iptr->sx.val.i == 0x00000004) ||
2423 (iptr->sx.val.i == 0x00000008) ||
2424 (iptr->sx.val.i == 0x00000010) ||
2425 (iptr->sx.val.i == 0x00000020) ||
2426 (iptr->sx.val.i == 0x00000040) ||
2427 (iptr->sx.val.i == 0x00000080) ||
2428 (iptr->sx.val.i == 0x00000100) ||
2429 (iptr->sx.val.i == 0x00000200) ||
2430 (iptr->sx.val.i == 0x00000400) ||
2431 (iptr->sx.val.i == 0x00000800) ||
2432 (iptr->sx.val.i == 0x00001000) ||
2433 (iptr->sx.val.i == 0x00002000) ||
2434 (iptr->sx.val.i == 0x00004000) ||
2435 (iptr->sx.val.i == 0x00008000) ||
2436 (iptr->sx.val.i == 0x00010000) ||
2437 (iptr->sx.val.i == 0x00020000) ||
2438 (iptr->sx.val.i == 0x00040000) ||
2439 (iptr->sx.val.i == 0x00080000) ||
2440 (iptr->sx.val.i == 0x00100000) ||
2441 (iptr->sx.val.i == 0x00200000) ||
2442 (iptr->sx.val.i == 0x00400000) ||
2443 (iptr->sx.val.i == 0x00800000) ||
2444 (iptr->sx.val.i == 0x01000000) ||
2445 (iptr->sx.val.i == 0x02000000) ||
2446 (iptr->sx.val.i == 0x04000000) ||
2447 (iptr->sx.val.i == 0x08000000) ||
2448 (iptr->sx.val.i == 0x10000000) ||
2449 (iptr->sx.val.i == 0x20000000) ||
2450 (iptr->sx.val.i == 0x40000000) ||
2451 (iptr->sx.val.i == 0x80000000))
2453 iptr->opc = ICMD_IREMPOW2;
2454 iptr->sx.val.i -= 1;
2455 goto icmd_iconst_tail;
2458 #if SUPPORT_CONST_LOGICAL
2460 iptr->opc = ICMD_IANDCONST;
2461 goto icmd_iconst_tail;
2464 iptr->opc = ICMD_IORCONST;
2465 goto icmd_iconst_tail;
2468 iptr->opc = ICMD_IXORCONST;
2469 goto icmd_iconst_tail;
2471 #endif /* SUPPORT_CONST_LOGICAL */
2473 iptr->opc = ICMD_ISHLCONST;
2474 goto icmd_iconst_tail;
2477 iptr->opc = ICMD_ISHRCONST;
2478 goto icmd_iconst_tail;
2481 iptr->opc = ICMD_IUSHRCONST;
2482 goto icmd_iconst_tail;
2483 #if SUPPORT_LONG_SHIFT
2485 iptr->opc = ICMD_LSHLCONST;
2486 goto icmd_lconst_tail;
2489 iptr->opc = ICMD_LSHRCONST;
2490 goto icmd_lconst_tail;
2493 iptr->opc = ICMD_LUSHRCONST;
2494 goto icmd_lconst_tail;
2495 #endif /* SUPPORT_LONG_SHIFT */
2496 case ICMD_IF_ICMPEQ:
2497 iptr[1].opc = ICMD_IFEQ;
2501 /* set the constant for the following icmd */
2502 iptr[1].sx.val.i = iptr->sx.val.i;
2504 /* this instruction becomes a nop */
2505 iptr->opc = ICMD_NOP;
2508 case ICMD_IF_ICMPLT:
2509 iptr[1].opc = ICMD_IFLT;
2510 goto icmd_if_icmp_tail;
2512 case ICMD_IF_ICMPLE:
2513 iptr[1].opc = ICMD_IFLE;
2514 goto icmd_if_icmp_tail;
2516 case ICMD_IF_ICMPNE:
2517 iptr[1].opc = ICMD_IFNE;
2518 goto icmd_if_icmp_tail;
2520 case ICMD_IF_ICMPGT:
2521 iptr[1].opc = ICMD_IFGT;
2522 goto icmd_if_icmp_tail;
2524 case ICMD_IF_ICMPGE:
2525 iptr[1].opc = ICMD_IFGE;
2526 goto icmd_if_icmp_tail;
2528 #if SUPPORT_CONST_STORE
2533 # if SUPPORT_CONST_STORE_ZERO_ONLY
2534 if (iptr->sx.val.i != 0)
2537 switch (iptr[1].opc) {
2539 iptr->opc = ICMD_IASTORECONST;
2540 iptr->flags.bits |= INS_FLAG_CHECK;
2543 iptr->opc = ICMD_BASTORECONST;
2544 iptr->flags.bits |= INS_FLAG_CHECK;
2547 iptr->opc = ICMD_CASTORECONST;
2548 iptr->flags.bits |= INS_FLAG_CHECK;
2551 iptr->opc = ICMD_SASTORECONST;
2552 iptr->flags.bits |= INS_FLAG_CHECK;
2556 iptr[1].opc = ICMD_NOP;
2558 /* copy the constant to s3 */
2559 /* XXX constval -> astoreconstval? */
2560 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2561 OP2_0(TYPE_ADR, TYPE_INT);
2562 COUNT(count_pcmd_op);
2565 case ICMD_PUTSTATIC:
2567 # if SUPPORT_CONST_STORE_ZERO_ONLY
2568 if (iptr->sx.val.i != 0)
2571 /* XXX check field type? */
2573 /* copy the constant to s2 */
2574 /* XXX constval -> fieldconstval? */
2575 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2578 /* set the field reference (s3) */
2579 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2580 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2581 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2582 fmiref = iptr->sx.s23.s3.uf->fieldref;
2585 fmiref = iptr[1].sx.s23.s3.fmiref;
2586 iptr->sx.s23.s3.fmiref = fmiref;
2589 #if defined(ENABLE_VERIFIER)
2590 expectedtype = fmiref->parseddesc.fd->type;
2591 switch (iptr[0].opc) {
2593 if (expectedtype != TYPE_INT)
2594 goto throw_stack_type_error;
2597 if (expectedtype != TYPE_LNG)
2598 goto throw_stack_type_error;
2601 if (expectedtype != TYPE_ADR)
2602 goto throw_stack_type_error;
2607 #endif /* defined(ENABLE_VERIFIER) */
2609 switch (iptr[1].opc) {
2610 case ICMD_PUTSTATIC:
2611 iptr->opc = ICMD_PUTSTATICCONST;
2615 iptr->opc = ICMD_PUTFIELDCONST;
2620 iptr[1].opc = ICMD_NOP;
2621 COUNT(count_pcmd_op);
2623 #endif /* SUPPORT_CONST_STORE */
2629 /* if we get here, the ICONST has been optimized */
2633 /* normal case of an unoptimized ICONST */
2637 /************************** LCONST OPTIMIZATIONS **************************/
2640 COUNT(count_pcmd_load);
2644 /* switch depending on the following instruction */
2646 switch (iptr[1].opc) {
2647 #if SUPPORT_LONG_ADD
2649 iptr->opc = ICMD_LADDCONST;
2653 /* instruction of type LONG -> LONG */
2654 iptr[1].opc = ICMD_NOP;
2655 OP1_1(TYPE_LNG, TYPE_LNG);
2656 COUNT(count_pcmd_op);
2660 iptr->opc = ICMD_LSUBCONST;
2661 goto icmd_lconst_tail;
2663 #endif /* SUPPORT_LONG_ADD */
2664 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2666 iptr->opc = ICMD_LMULCONST;
2667 goto icmd_lconst_tail;
2668 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2669 # if SUPPORT_LONG_SHIFT
2671 if (iptr->sx.val.l == 0x00000002)
2673 else if (iptr->sx.val.l == 0x00000004)
2675 else if (iptr->sx.val.l == 0x00000008)
2677 else if (iptr->sx.val.l == 0x00000010)
2679 else if (iptr->sx.val.l == 0x00000020)
2681 else if (iptr->sx.val.l == 0x00000040)
2683 else if (iptr->sx.val.l == 0x00000080)
2685 else if (iptr->sx.val.l == 0x00000100)
2687 else if (iptr->sx.val.l == 0x00000200)
2689 else if (iptr->sx.val.l == 0x00000400)
2690 iptr->sx.val.i = 10;
2691 else if (iptr->sx.val.l == 0x00000800)
2692 iptr->sx.val.i = 11;
2693 else if (iptr->sx.val.l == 0x00001000)
2694 iptr->sx.val.i = 12;
2695 else if (iptr->sx.val.l == 0x00002000)
2696 iptr->sx.val.i = 13;
2697 else if (iptr->sx.val.l == 0x00004000)
2698 iptr->sx.val.i = 14;
2699 else if (iptr->sx.val.l == 0x00008000)
2700 iptr->sx.val.i = 15;
2701 else if (iptr->sx.val.l == 0x00010000)
2702 iptr->sx.val.i = 16;
2703 else if (iptr->sx.val.l == 0x00020000)
2704 iptr->sx.val.i = 17;
2705 else if (iptr->sx.val.l == 0x00040000)
2706 iptr->sx.val.i = 18;
2707 else if (iptr->sx.val.l == 0x00080000)
2708 iptr->sx.val.i = 19;
2709 else if (iptr->sx.val.l == 0x00100000)
2710 iptr->sx.val.i = 20;
2711 else if (iptr->sx.val.l == 0x00200000)
2712 iptr->sx.val.i = 21;
2713 else if (iptr->sx.val.l == 0x00400000)
2714 iptr->sx.val.i = 22;
2715 else if (iptr->sx.val.l == 0x00800000)
2716 iptr->sx.val.i = 23;
2717 else if (iptr->sx.val.l == 0x01000000)
2718 iptr->sx.val.i = 24;
2719 else if (iptr->sx.val.l == 0x02000000)
2720 iptr->sx.val.i = 25;
2721 else if (iptr->sx.val.l == 0x04000000)
2722 iptr->sx.val.i = 26;
2723 else if (iptr->sx.val.l == 0x08000000)
2724 iptr->sx.val.i = 27;
2725 else if (iptr->sx.val.l == 0x10000000)
2726 iptr->sx.val.i = 28;
2727 else if (iptr->sx.val.l == 0x20000000)
2728 iptr->sx.val.i = 29;
2729 else if (iptr->sx.val.l == 0x40000000)
2730 iptr->sx.val.i = 30;
2731 else if (iptr->sx.val.l == 0x80000000)
2732 iptr->sx.val.i = 31;
2736 iptr->opc = ICMD_LMULPOW2;
2737 goto icmd_lconst_tail;
2738 # endif /* SUPPORT_LONG_SHIFT */
2739 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2740 #if SUPPORT_LONG_DIV_POW2
2742 if (iptr->sx.val.l == 0x00000002)
2744 else if (iptr->sx.val.l == 0x00000004)
2746 else if (iptr->sx.val.l == 0x00000008)
2748 else if (iptr->sx.val.l == 0x00000010)
2750 else if (iptr->sx.val.l == 0x00000020)
2752 else if (iptr->sx.val.l == 0x00000040)
2754 else if (iptr->sx.val.l == 0x00000080)
2756 else if (iptr->sx.val.l == 0x00000100)
2758 else if (iptr->sx.val.l == 0x00000200)
2760 else if (iptr->sx.val.l == 0x00000400)
2761 iptr->sx.val.i = 10;
2762 else if (iptr->sx.val.l == 0x00000800)
2763 iptr->sx.val.i = 11;
2764 else if (iptr->sx.val.l == 0x00001000)
2765 iptr->sx.val.i = 12;
2766 else if (iptr->sx.val.l == 0x00002000)
2767 iptr->sx.val.i = 13;
2768 else if (iptr->sx.val.l == 0x00004000)
2769 iptr->sx.val.i = 14;
2770 else if (iptr->sx.val.l == 0x00008000)
2771 iptr->sx.val.i = 15;
2772 else if (iptr->sx.val.l == 0x00010000)
2773 iptr->sx.val.i = 16;
2774 else if (iptr->sx.val.l == 0x00020000)
2775 iptr->sx.val.i = 17;
2776 else if (iptr->sx.val.l == 0x00040000)
2777 iptr->sx.val.i = 18;
2778 else if (iptr->sx.val.l == 0x00080000)
2779 iptr->sx.val.i = 19;
2780 else if (iptr->sx.val.l == 0x00100000)
2781 iptr->sx.val.i = 20;
2782 else if (iptr->sx.val.l == 0x00200000)
2783 iptr->sx.val.i = 21;
2784 else if (iptr->sx.val.l == 0x00400000)
2785 iptr->sx.val.i = 22;
2786 else if (iptr->sx.val.l == 0x00800000)
2787 iptr->sx.val.i = 23;
2788 else if (iptr->sx.val.l == 0x01000000)
2789 iptr->sx.val.i = 24;
2790 else if (iptr->sx.val.l == 0x02000000)
2791 iptr->sx.val.i = 25;
2792 else if (iptr->sx.val.l == 0x04000000)
2793 iptr->sx.val.i = 26;
2794 else if (iptr->sx.val.l == 0x08000000)
2795 iptr->sx.val.i = 27;
2796 else if (iptr->sx.val.l == 0x10000000)
2797 iptr->sx.val.i = 28;
2798 else if (iptr->sx.val.l == 0x20000000)
2799 iptr->sx.val.i = 29;
2800 else if (iptr->sx.val.l == 0x40000000)
2801 iptr->sx.val.i = 30;
2802 else if (iptr->sx.val.l == 0x80000000)
2803 iptr->sx.val.i = 31;
2807 iptr->opc = ICMD_LDIVPOW2;
2808 goto icmd_lconst_tail;
2809 #endif /* SUPPORT_LONG_DIV_POW2 */
2811 #if SUPPORT_LONG_REM_POW2
2813 if ((iptr->sx.val.l == 0x00000002) ||
2814 (iptr->sx.val.l == 0x00000004) ||
2815 (iptr->sx.val.l == 0x00000008) ||
2816 (iptr->sx.val.l == 0x00000010) ||
2817 (iptr->sx.val.l == 0x00000020) ||
2818 (iptr->sx.val.l == 0x00000040) ||
2819 (iptr->sx.val.l == 0x00000080) ||
2820 (iptr->sx.val.l == 0x00000100) ||
2821 (iptr->sx.val.l == 0x00000200) ||
2822 (iptr->sx.val.l == 0x00000400) ||
2823 (iptr->sx.val.l == 0x00000800) ||
2824 (iptr->sx.val.l == 0x00001000) ||
2825 (iptr->sx.val.l == 0x00002000) ||
2826 (iptr->sx.val.l == 0x00004000) ||
2827 (iptr->sx.val.l == 0x00008000) ||
2828 (iptr->sx.val.l == 0x00010000) ||
2829 (iptr->sx.val.l == 0x00020000) ||
2830 (iptr->sx.val.l == 0x00040000) ||
2831 (iptr->sx.val.l == 0x00080000) ||
2832 (iptr->sx.val.l == 0x00100000) ||
2833 (iptr->sx.val.l == 0x00200000) ||
2834 (iptr->sx.val.l == 0x00400000) ||
2835 (iptr->sx.val.l == 0x00800000) ||
2836 (iptr->sx.val.l == 0x01000000) ||
2837 (iptr->sx.val.l == 0x02000000) ||
2838 (iptr->sx.val.l == 0x04000000) ||
2839 (iptr->sx.val.l == 0x08000000) ||
2840 (iptr->sx.val.l == 0x10000000) ||
2841 (iptr->sx.val.l == 0x20000000) ||
2842 (iptr->sx.val.l == 0x40000000) ||
2843 (iptr->sx.val.l == 0x80000000))
2845 iptr->opc = ICMD_LREMPOW2;
2846 iptr->sx.val.l -= 1;
2847 goto icmd_lconst_tail;
2850 #endif /* SUPPORT_LONG_REM_POW2 */
2852 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2855 iptr->opc = ICMD_LANDCONST;
2856 goto icmd_lconst_tail;
2859 iptr->opc = ICMD_LORCONST;
2860 goto icmd_lconst_tail;
2863 iptr->opc = ICMD_LXORCONST;
2864 goto icmd_lconst_tail;
2865 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2867 #if SUPPORT_LONG_CMP_CONST
2869 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2872 /* switch on the instruction after LCONST - LCMP */
2874 switch (iptr[2].opc) {
2876 iptr->opc = ICMD_IF_LEQ;
2879 icmd_lconst_lcmp_tail:
2880 /* convert LCONST, LCMP, IFXX to IF_LXX */
2881 iptr->dst.insindex = iptr[2].dst.insindex;
2882 iptr[1].opc = ICMD_NOP;
2883 iptr[2].opc = ICMD_NOP;
2885 OP1_BRANCH(TYPE_LNG);
2887 COUNT(count_pcmd_bra);
2888 COUNT(count_pcmd_op);
2892 iptr->opc = ICMD_IF_LNE;
2893 goto icmd_lconst_lcmp_tail;
2896 iptr->opc = ICMD_IF_LLT;
2897 goto icmd_lconst_lcmp_tail;
2900 iptr->opc = ICMD_IF_LGT;
2901 goto icmd_lconst_lcmp_tail;
2904 iptr->opc = ICMD_IF_LLE;
2905 goto icmd_lconst_lcmp_tail;
2908 iptr->opc = ICMD_IF_LGE;
2909 goto icmd_lconst_lcmp_tail;
2913 } /* end switch on opcode after LCONST - LCMP */
2915 #endif /* SUPPORT_LONG_CMP_CONST */
2917 #if SUPPORT_CONST_STORE
2919 # if SUPPORT_CONST_STORE_ZERO_ONLY
2920 if (iptr->sx.val.l != 0)
2923 #if SIZEOF_VOID_P == 4
2924 /* the constant must fit into a ptrint */
2925 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2928 /* move the constant to s3 */
2929 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2931 iptr->opc = ICMD_LASTORECONST;
2932 iptr->flags.bits |= INS_FLAG_CHECK;
2933 OP2_0(TYPE_ADR, TYPE_INT);
2935 iptr[1].opc = ICMD_NOP;
2936 COUNT(count_pcmd_op);
2939 case ICMD_PUTSTATIC:
2941 # if SUPPORT_CONST_STORE_ZERO_ONLY
2942 if (iptr->sx.val.l != 0)
2945 #if SIZEOF_VOID_P == 4
2946 /* the constant must fit into a ptrint */
2947 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2950 /* XXX check field type? */
2952 /* copy the constant to s2 */
2953 /* XXX constval -> fieldconstval? */
2954 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2958 #endif /* SUPPORT_CONST_STORE */
2962 } /* end switch opcode after LCONST */
2964 /* if we get here, the LCONST has been optimized */
2968 /* the normal case of an unoptimized LCONST */
2972 /************************ END OF LCONST OPTIMIZATIONS *********************/
2975 COUNT(count_pcmd_load);
2980 COUNT(count_pcmd_load);
2984 /************************** ACONST OPTIMIZATIONS **************************/
2987 coalescing_boundary = sd.new;
2988 COUNT(count_pcmd_load);
2989 #if SUPPORT_CONST_STORE
2990 /* We can only optimize if the ACONST is resolved
2991 * and there is an instruction after it. */
2993 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2996 switch (iptr[1].opc) {
2998 /* We can only optimize for NULL values
2999 * here because otherwise a checkcast is
3001 if (iptr->sx.val.anyptr != NULL)
3004 /* copy the constant (NULL) to s3 */
3005 iptr->sx.s23.s3.constval = 0;
3006 iptr->opc = ICMD_AASTORECONST;
3007 iptr->flags.bits |= INS_FLAG_CHECK;
3008 OP2_0(TYPE_ADR, TYPE_INT);
3010 iptr[1].opc = ICMD_NOP;
3011 COUNT(count_pcmd_op);
3014 case ICMD_PUTSTATIC:
3016 # if SUPPORT_CONST_STORE_ZERO_ONLY
3017 if (iptr->sx.val.anyptr != NULL)
3020 /* XXX check field type? */
3021 /* copy the constant to s2 */
3022 /* XXX constval -> fieldconstval? */
3023 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3031 /* if we get here the ACONST has been optimized */
3035 #endif /* SUPPORT_CONST_STORE */
3040 /* pop 0 push 1 load */
3047 COUNT(count_load_instruction);
3048 i = opcode - ICMD_ILOAD; /* type */
3050 j = iptr->s1.varindex =
3051 jd->local_map[iptr->s1.varindex * 5 + i];
3053 #if defined(ENABLE_VERIFIER)
3054 if (sd.var[j].type == TYPE_RET) {
3055 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3060 #if defined(ENABLE_SSA)
3062 GET_NEW_VAR(sd, new_index, i);
3079 coalescing_boundary = sd.new;
3080 iptr->flags.bits |= INS_FLAG_CHECK;
3081 COUNT(count_check_null);
3082 COUNT(count_check_bound);
3083 COUNT(count_pcmd_mem);
3084 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3091 coalescing_boundary = sd.new;
3092 iptr->flags.bits |= INS_FLAG_CHECK;
3093 COUNT(count_check_null);
3094 COUNT(count_check_bound);
3095 COUNT(count_pcmd_mem);
3096 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3099 /* pop 0 push 0 iinc */
3102 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3103 #if defined(ENABLE_SSA)
3106 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3110 last_store_boundary[iptr->s1.varindex] = sd.new;
3113 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3118 if ((copy->varkind == LOCALVAR) &&
3119 (copy->varnum == iptr->s1.varindex))
3121 assert(IS_LOCALVAR(copy));
3127 #if defined(ENABLE_SSA)
3131 iptr->dst.varindex = iptr->s1.varindex;
3134 /* pop 1 push 0 store */
3143 i = opcode - ICMD_ISTORE; /* type */
3144 javaindex = iptr->dst.varindex;
3145 j = iptr->dst.varindex =
3146 jd->local_map[javaindex * 5 + i];
3148 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3150 #if defined(ENABLE_STATISTICS)
3153 i = sd.new - curstack;
3155 count_store_length[20]++;
3157 count_store_length[i]++;
3160 count_store_depth[10]++;
3162 count_store_depth[i]++;
3166 #if defined(ENABLE_SSA)
3169 /* check for conflicts as described in Figure 5.2 */
3171 copy = curstack->prev;
3174 if ((copy->varkind == LOCALVAR) &&
3175 (copy->varnum == j))
3177 copy->varkind = TEMPVAR;
3178 assert(IS_LOCALVAR(copy));
3185 /* if the variable is already coalesced, don't bother */
3187 /* We do not need to check against INOUT, as invars */
3188 /* are always before the coalescing boundary. */
3190 if (curstack->varkind == LOCALVAR)
3193 /* there is no STORE Lj while curstack is live */
3195 if (curstack < last_store_boundary[javaindex])
3196 goto assume_conflict;
3198 /* curstack must be after the coalescing boundary */
3200 if (curstack < coalescing_boundary)
3201 goto assume_conflict;
3203 /* there is no DEF LOCALVAR(j) while curstack is live */
3205 copy = sd.new; /* most recent stackslot created + 1 */
3206 while (--copy > curstack) {
3207 if (copy->varkind == LOCALVAR && copy->varnum == j)
3208 goto assume_conflict;
3211 /* coalesce the temporary variable with Lj */
3212 assert((curstack->varkind == TEMPVAR)
3213 || (curstack->varkind == UNDEFVAR));
3214 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3215 assert(!IS_INOUT(curstack));
3216 assert(!IS_PREALLOC(curstack));
3218 assert(curstack->creator);
3219 assert(curstack->creator->dst.varindex == curstack->varnum);
3220 assert(!(curstack->flags & PASSTHROUGH));
3221 RELEASE_INDEX(sd, curstack);
3222 curstack->varkind = LOCALVAR;
3223 curstack->varnum = j;
3224 curstack->creator->dst.varindex = j;
3227 /* revert the coalescing, if it has been done earlier */
3229 if ((curstack->varkind == LOCALVAR)
3230 && (curstack->varnum == j))
3232 assert(IS_LOCALVAR(curstack));
3233 SET_TEMPVAR(curstack);
3236 /* remember the stack boundary at this store */
3238 last_store_boundary[javaindex] = sd.new;
3239 #if defined(ENABLE_SSA)
3240 } /* if (ls != NULL) */
3243 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3246 STORE(opcode - ICMD_ISTORE, j);
3252 coalescing_boundary = sd.new;
3253 iptr->flags.bits |= INS_FLAG_CHECK;
3254 COUNT(count_check_null);
3255 COUNT(count_check_bound);
3256 COUNT(count_pcmd_mem);
3258 bte = builtintable_get_internal(BUILTIN_canstore);
3261 if (md->memuse > rd->memuse)
3262 rd->memuse = md->memuse;
3263 if (md->argintreguse > rd->argintreguse)
3264 rd->argintreguse = md->argintreguse;
3265 /* XXX non-leaf method? */
3267 /* make all stack variables saved */
3271 sd.var[copy->varnum].flags |= SAVEDVAR;
3272 /* in case copy->varnum is/will be a LOCALVAR */
3273 /* once and set back to a non LOCALVAR */
3274 /* the correct SAVEDVAR flag has to be */
3275 /* remembered in copy->flags, too */
3276 copy->flags |= SAVEDVAR;
3280 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3287 coalescing_boundary = sd.new;
3288 iptr->flags.bits |= INS_FLAG_CHECK;
3289 COUNT(count_check_null);
3290 COUNT(count_check_bound);
3291 COUNT(count_pcmd_mem);
3292 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3299 coalescing_boundary = sd.new;
3300 iptr->flags.bits |= INS_FLAG_CHECK;
3301 COUNT(count_check_null);
3302 COUNT(count_check_bound);
3303 COUNT(count_pcmd_mem);
3304 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3310 #ifdef ENABLE_VERIFIER
3313 if (IS_2_WORD_TYPE(curstack->type))
3314 goto throw_stack_category_error;
3325 coalescing_boundary = sd.new;
3326 /* Assert here that no LOCAL or INOUTS get */
3327 /* preallocated, since tha macros are not */
3328 /* available in md-abi.c! */
3329 if (IS_TEMPVAR(curstack))
3330 md_return_alloc(jd, curstack);
3331 COUNT(count_pcmd_return);
3332 OP1_0(opcode - ICMD_IRETURN);
3333 superblockend = true;
3337 coalescing_boundary = sd.new;
3338 COUNT(count_check_null);
3340 curstack = NULL; stackdepth = 0;
3341 superblockend = true;
3344 case ICMD_PUTSTATIC:
3345 coalescing_boundary = sd.new;
3346 COUNT(count_pcmd_mem);
3347 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3348 OP1_0(fmiref->parseddesc.fd->type);
3351 /* pop 1 push 0 branch */
3354 case ICMD_IFNONNULL:
3355 COUNT(count_pcmd_bra);
3356 OP1_BRANCH(TYPE_ADR);
3366 COUNT(count_pcmd_bra);
3367 /* iptr->sx.val.i is set implicitly in parse by
3368 clearing the memory or from IF_ICMPxx
3371 OP1_BRANCH(TYPE_INT);
3372 /* iptr->sx.val.i = 0; */
3376 /* pop 0 push 0 branch */
3379 COUNT(count_pcmd_bra);
3382 superblockend = true;
3385 /* pop 1 push 0 table branch */
3387 case ICMD_TABLESWITCH:
3388 COUNT(count_pcmd_table);
3389 OP1_BRANCH(TYPE_INT);
3391 table = iptr->dst.table;
3392 BRANCH_TARGET(*table, tbptr);
3395 i = iptr->sx.s23.s3.tablehigh
3396 - iptr->sx.s23.s2.tablelow + 1;
3399 BRANCH_TARGET(*table, tbptr);
3402 superblockend = true;
3405 /* pop 1 push 0 table branch */
3407 case ICMD_LOOKUPSWITCH:
3408 COUNT(count_pcmd_table);
3409 OP1_BRANCH(TYPE_INT);
3411 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3413 lookup = iptr->dst.lookup;
3415 i = iptr->sx.s23.s2.lookupcount;
3418 BRANCH_TARGET(lookup->target, tbptr);
3421 superblockend = true;
3424 case ICMD_MONITORENTER:
3425 case ICMD_MONITOREXIT:
3426 coalescing_boundary = sd.new;
3427 COUNT(count_check_null);
3431 /* pop 2 push 0 branch */
3433 case ICMD_IF_ICMPEQ:
3434 case ICMD_IF_ICMPNE:
3435 case ICMD_IF_ICMPLT:
3436 case ICMD_IF_ICMPGE:
3437 case ICMD_IF_ICMPGT:
3438 case ICMD_IF_ICMPLE:
3439 COUNT(count_pcmd_bra);
3440 OP2_BRANCH(TYPE_INT, TYPE_INT);
3444 case ICMD_IF_ACMPEQ:
3445 case ICMD_IF_ACMPNE:
3446 COUNT(count_pcmd_bra);
3447 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3454 coalescing_boundary = sd.new;
3455 COUNT(count_check_null);
3456 COUNT(count_pcmd_mem);
3457 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3458 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3463 if (!IS_2_WORD_TYPE(curstack->type)) {
3465 #ifdef ENABLE_VERIFIER
3468 if (IS_2_WORD_TYPE(curstack->prev->type))
3469 goto throw_stack_category_error;
3472 OP2_0_ANY_ANY; /* pop two slots */
3475 iptr->opc = ICMD_POP;
3476 OP1_0_ANY; /* pop one (two-word) slot */
3480 /* pop 0 push 1 dup */
3483 #ifdef ENABLE_VERIFIER
3486 if (IS_2_WORD_TYPE(curstack->type))
3487 goto throw_stack_category_error;
3490 COUNT(count_dup_instruction);
3496 coalescing_boundary = sd.new - 1;
3501 if (IS_2_WORD_TYPE(curstack->type)) {
3503 iptr->opc = ICMD_DUP;
3508 /* ..., ????, cat1 */
3509 #ifdef ENABLE_VERIFIER
3511 if (IS_2_WORD_TYPE(curstack->prev->type))
3512 goto throw_stack_category_error;
3515 src1 = curstack->prev;
3518 COPY_UP(src1); iptr++; len--;
3521 coalescing_boundary = sd.new;
3525 /* pop 2 push 3 dup */
3528 #ifdef ENABLE_VERIFIER
3531 if (IS_2_WORD_TYPE(curstack->type) ||
3532 IS_2_WORD_TYPE(curstack->prev->type))
3533 goto throw_stack_category_error;
3538 src1 = curstack->prev;
3543 /* move non-temporary sources out of the way */
3544 if (!IS_TEMPVAR(src2)) {
3545 MOVE_TO_TEMP(src2); iptr++; len--;
3548 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3550 MOVE_UP(src1); iptr++; len--;
3551 MOVE_UP(src2); iptr++; len--;
3553 COPY_DOWN(curstack, dst1);
3555 coalescing_boundary = sd.new;
3560 if (IS_2_WORD_TYPE(curstack->type)) {
3561 /* ..., ????, cat2 */
3562 #ifdef ENABLE_VERIFIER
3564 if (IS_2_WORD_TYPE(curstack->prev->type))
3565 goto throw_stack_category_error;
3568 iptr->opc = ICMD_DUP_X1;
3572 /* ..., ????, cat1 */
3573 #ifdef ENABLE_VERIFIER
3576 if (IS_2_WORD_TYPE(curstack->prev->type)
3577 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3578 goto throw_stack_category_error;
3583 src1 = curstack->prev->prev;
3584 src2 = curstack->prev;
3586 POPANY; POPANY; POPANY;
3589 /* move non-temporary sources out of the way */
3590 if (!IS_TEMPVAR(src2)) {
3591 MOVE_TO_TEMP(src2); iptr++; len--;
3593 if (!IS_TEMPVAR(src3)) {
3594 MOVE_TO_TEMP(src3); iptr++; len--;
3597 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3598 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3600 MOVE_UP(src1); iptr++; len--;
3601 MOVE_UP(src2); iptr++; len--;
3602 MOVE_UP(src3); iptr++; len--;
3604 COPY_DOWN(curstack, dst2); iptr++; len--;
3605 COPY_DOWN(curstack->prev, dst1);
3607 coalescing_boundary = sd.new;
3611 /* pop 3 push 4 dup */
3615 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3616 /* ..., cat2, ???? */
3617 #ifdef ENABLE_VERIFIER
3619 if (IS_2_WORD_TYPE(curstack->type))
3620 goto throw_stack_category_error;
3623 iptr->opc = ICMD_DUP_X1;
3627 /* ..., cat1, ???? */
3628 #ifdef ENABLE_VERIFIER
3631 if (IS_2_WORD_TYPE(curstack->type)
3632 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3633 goto throw_stack_category_error;
3637 src1 = curstack->prev->prev;
3638 src2 = curstack->prev;
3640 POPANY; POPANY; POPANY;
3643 /* move non-temporary sources out of the way */
3644 if (!IS_TEMPVAR(src2)) {
3645 MOVE_TO_TEMP(src2); iptr++; len--;
3647 if (!IS_TEMPVAR(src3)) {
3648 MOVE_TO_TEMP(src3); iptr++; len--;
3651 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3653 MOVE_UP(src1); iptr++; len--;
3654 MOVE_UP(src2); iptr++; len--;
3655 MOVE_UP(src3); iptr++; len--;
3657 COPY_DOWN(curstack, dst1);
3659 coalescing_boundary = sd.new;
3665 if (IS_2_WORD_TYPE(curstack->type)) {
3666 /* ..., ????, cat2 */
3667 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3668 /* ..., cat2, cat2 */
3669 iptr->opc = ICMD_DUP_X1;
3673 /* ..., cat1, cat2 */
3674 #ifdef ENABLE_VERIFIER
3677 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3678 goto throw_stack_category_error;
3681 iptr->opc = ICMD_DUP_X2;
3687 /* ..., ????, ????, cat1 */
3689 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3690 /* ..., cat2, ????, cat1 */
3691 #ifdef ENABLE_VERIFIER
3693 if (IS_2_WORD_TYPE(curstack->prev->type))
3694 goto throw_stack_category_error;
3697 iptr->opc = ICMD_DUP2_X1;
3701 /* ..., cat1, ????, cat1 */
3702 #ifdef ENABLE_VERIFIER
3705 if (IS_2_WORD_TYPE(curstack->prev->type)
3706 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3707 goto throw_stack_category_error;
3711 src1 = curstack->prev->prev->prev;
3712 src2 = curstack->prev->prev;
3713 src3 = curstack->prev;
3715 POPANY; POPANY; POPANY; POPANY;
3718 /* move non-temporary sources out of the way */
3719 if (!IS_TEMPVAR(src2)) {
3720 MOVE_TO_TEMP(src2); iptr++; len--;
3722 if (!IS_TEMPVAR(src3)) {
3723 MOVE_TO_TEMP(src3); iptr++; len--;
3725 if (!IS_TEMPVAR(src4)) {
3726 MOVE_TO_TEMP(src4); iptr++; len--;
3729 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3730 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3732 MOVE_UP(src1); iptr++; len--;
3733 MOVE_UP(src2); iptr++; len--;
3734 MOVE_UP(src3); iptr++; len--;
3735 MOVE_UP(src4); iptr++; len--;
3737 COPY_DOWN(curstack, dst2); iptr++; len--;
3738 COPY_DOWN(curstack->prev, dst1);
3740 coalescing_boundary = sd.new;
3744 /* pop 2 push 2 swap */
3747 #ifdef ENABLE_VERIFIER
3750 if (IS_2_WORD_TYPE(curstack->type)
3751 || IS_2_WORD_TYPE(curstack->prev->type))
3752 goto throw_stack_category_error;
3756 src1 = curstack->prev;
3761 /* move non-temporary sources out of the way */
3762 if (!IS_TEMPVAR(src1)) {
3763 MOVE_TO_TEMP(src1); iptr++; len--;
3766 MOVE_UP(src2); iptr++; len--;
3769 coalescing_boundary = sd.new;
3776 coalescing_boundary = sd.new;
3777 #if !SUPPORT_DIVISION
3778 bte = iptr->sx.s23.s3.bte;
3781 if (md->memuse > rd->memuse)
3782 rd->memuse = md->memuse;
3783 if (md->argintreguse > rd->argintreguse)
3784 rd->argintreguse = md->argintreguse;
3786 /* make all stack variables saved */
3790 sd.var[copy->varnum].flags |= SAVEDVAR;
3791 copy->flags |= SAVEDVAR;
3796 #endif /* !SUPPORT_DIVISION */
3807 COUNT(count_pcmd_op);
3808 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3813 coalescing_boundary = sd.new;
3814 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3815 bte = iptr->sx.s23.s3.bte;
3818 if (md->memuse > rd->memuse)
3819 rd->memuse = md->memuse;
3820 if (md->argintreguse > rd->argintreguse)
3821 rd->argintreguse = md->argintreguse;
3822 /* XXX non-leaf method? */
3824 /* make all stack variables saved */
3828 sd.var[copy->varnum].flags |= SAVEDVAR;
3829 copy->flags |= SAVEDVAR;
3834 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3839 #if SUPPORT_LONG_LOGICAL
3843 #endif /* SUPPORT_LONG_LOGICAL */
3844 COUNT(count_pcmd_op);
3845 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3851 COUNT(count_pcmd_op);
3852 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3860 COUNT(count_pcmd_op);
3861 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3869 COUNT(count_pcmd_op);
3870 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3874 COUNT(count_pcmd_op);
3875 #if SUPPORT_LONG_CMP_CONST
3876 if ((len == 0) || (iptr[1].sx.val.i != 0))
3879 switch (iptr[1].opc) {
3881 iptr->opc = ICMD_IF_LCMPEQ;
3883 iptr->dst.insindex = iptr[1].dst.insindex;
3884 iptr[1].opc = ICMD_NOP;
3886 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3889 COUNT(count_pcmd_bra);
3892 iptr->opc = ICMD_IF_LCMPNE;
3893 goto icmd_lcmp_if_tail;
3895 iptr->opc = ICMD_IF_LCMPLT;
3896 goto icmd_lcmp_if_tail;
3898 iptr->opc = ICMD_IF_LCMPGT;
3899 goto icmd_lcmp_if_tail;
3901 iptr->opc = ICMD_IF_LCMPLE;
3902 goto icmd_lcmp_if_tail;
3904 iptr->opc = ICMD_IF_LCMPGE;
3905 goto icmd_lcmp_if_tail;
3911 #endif /* SUPPORT_LONG_CMP_CONST */
3912 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3915 /* XXX why is this deactivated? */
3918 COUNT(count_pcmd_op);
3919 if ((len == 0) || (iptr[1].sx.val.i != 0))
3922 switch (iptr[1].opc) {
3924 iptr->opc = ICMD_IF_FCMPEQ;
3926 iptr->dst.insindex = iptr[1].dst.insindex;
3927 iptr[1].opc = ICMD_NOP;
3929 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3932 COUNT(count_pcmd_bra);
3935 iptr->opc = ICMD_IF_FCMPNE;
3936 goto icmd_if_fcmpl_tail;
3938 iptr->opc = ICMD_IF_FCMPL_LT;
3939 goto icmd_if_fcmpl_tail;
3941 iptr->opc = ICMD_IF_FCMPL_GT;
3942 goto icmd_if_fcmpl_tail;
3944 iptr->opc = ICMD_IF_FCMPL_LE;
3945 goto icmd_if_fcmpl_tail;
3947 iptr->opc = ICMD_IF_FCMPL_GE;
3948 goto icmd_if_fcmpl_tail;
3955 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3959 COUNT(count_pcmd_op);
3960 if ((len == 0) || (iptr[1].sx.val.i != 0))
3963 switch (iptr[1].opc) {
3965 iptr->opc = ICMD_IF_FCMPEQ;
3967 iptr->dst.insindex = iptr[1].dst.insindex;
3968 iptr[1].opc = ICMD_NOP;
3970 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3973 COUNT(count_pcmd_bra);
3976 iptr->opc = ICMD_IF_FCMPNE;
3977 goto icmd_if_fcmpg_tail;
3979 iptr->opc = ICMD_IF_FCMPG_LT;
3980 goto icmd_if_fcmpg_tail;
3982 iptr->opc = ICMD_IF_FCMPG_GT;
3983 goto icmd_if_fcmpg_tail;
3985 iptr->opc = ICMD_IF_FCMPG_LE;
3986 goto icmd_if_fcmpg_tail;
3988 iptr->opc = ICMD_IF_FCMPG_GE;
3989 goto icmd_if_fcmpg_tail;
3996 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4000 COUNT(count_pcmd_op);
4001 if ((len == 0) || (iptr[1].sx.val.i != 0))
4004 switch (iptr[1].opc) {
4006 iptr->opc = ICMD_IF_DCMPEQ;
4008 iptr->dst.insindex = iptr[1].dst.insindex;
4009 iptr[1].opc = ICMD_NOP;
4011 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4014 COUNT(count_pcmd_bra);
4017 iptr->opc = ICMD_IF_DCMPNE;
4018 goto icmd_if_dcmpl_tail;
4020 iptr->opc = ICMD_IF_DCMPL_LT;
4021 goto icmd_if_dcmpl_tail;
4023 iptr->opc = ICMD_IF_DCMPL_GT;
4024 goto icmd_if_dcmpl_tail;
4026 iptr->opc = ICMD_IF_DCMPL_LE;
4027 goto icmd_if_dcmpl_tail;
4029 iptr->opc = ICMD_IF_DCMPL_GE;
4030 goto icmd_if_dcmpl_tail;
4037 OPTT2_1(TYPE_DBL, TYPE_INT);
4041 COUNT(count_pcmd_op);
4042 if ((len == 0) || (iptr[1].sx.val.i != 0))
4045 switch (iptr[1].opc) {
4047 iptr->opc = ICMD_IF_DCMPEQ;
4049 iptr->dst.insindex = iptr[1].dst.insindex;
4050 iptr[1].opc = ICMD_NOP;
4052 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4055 COUNT(count_pcmd_bra);
4058 iptr->opc = ICMD_IF_DCMPNE;
4059 goto icmd_if_dcmpg_tail;
4061 iptr->opc = ICMD_IF_DCMPG_LT;
4062 goto icmd_if_dcmpg_tail;
4064 iptr->opc = ICMD_IF_DCMPG_GT;
4065 goto icmd_if_dcmpg_tail;
4067 iptr->opc = ICMD_IF_DCMPG_LE;
4068 goto icmd_if_dcmpg_tail;
4070 iptr->opc = ICMD_IF_DCMPG_GE;
4071 goto icmd_if_dcmpg_tail;
4078 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4083 COUNT(count_pcmd_op);
4084 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4089 COUNT(count_pcmd_op);
4090 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4099 case ICMD_INT2SHORT:
4100 COUNT(count_pcmd_op);
4101 OP1_1(TYPE_INT, TYPE_INT);
4104 COUNT(count_pcmd_op);
4105 OP1_1(TYPE_LNG, TYPE_LNG);
4108 COUNT(count_pcmd_op);
4109 OP1_1(TYPE_FLT, TYPE_FLT);
4112 COUNT(count_pcmd_op);
4113 OP1_1(TYPE_DBL, TYPE_DBL);
4117 COUNT(count_pcmd_op);
4118 OP1_1(TYPE_INT, TYPE_LNG);
4121 COUNT(count_pcmd_op);
4122 OP1_1(TYPE_INT, TYPE_FLT);
4125 COUNT(count_pcmd_op);
4126 OP1_1(TYPE_INT, TYPE_DBL);
4129 COUNT(count_pcmd_op);
4130 OP1_1(TYPE_LNG, TYPE_INT);
4133 COUNT(count_pcmd_op);
4134 OP1_1(TYPE_LNG, TYPE_FLT);
4137 COUNT(count_pcmd_op);
4138 OP1_1(TYPE_LNG, TYPE_DBL);
4141 COUNT(count_pcmd_op);
4142 OP1_1(TYPE_FLT, TYPE_INT);
4145 COUNT(count_pcmd_op);
4146 OP1_1(TYPE_FLT, TYPE_LNG);
4149 COUNT(count_pcmd_op);
4150 OP1_1(TYPE_FLT, TYPE_DBL);
4153 COUNT(count_pcmd_op);
4154 OP1_1(TYPE_DBL, TYPE_INT);
4157 COUNT(count_pcmd_op);
4158 OP1_1(TYPE_DBL, TYPE_LNG);
4161 COUNT(count_pcmd_op);
4162 OP1_1(TYPE_DBL, TYPE_FLT);
4165 case ICMD_CHECKCAST:
4166 coalescing_boundary = sd.new;
4167 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4168 /* array type cast-check */
4170 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4173 if (md->memuse > rd->memuse)
4174 rd->memuse = md->memuse;
4175 if (md->argintreguse > rd->argintreguse)
4176 rd->argintreguse = md->argintreguse;
4178 /* make all stack variables saved */
4182 sd.var[copy->varnum].flags |= SAVEDVAR;
4183 copy->flags |= SAVEDVAR;
4187 OP1_1(TYPE_ADR, TYPE_ADR);
4190 case ICMD_INSTANCEOF:
4191 case ICMD_ARRAYLENGTH:
4192 coalescing_boundary = sd.new;
4193 OP1_1(TYPE_ADR, TYPE_INT);
4197 case ICMD_ANEWARRAY:
4198 coalescing_boundary = sd.new;
4199 OP1_1(TYPE_INT, TYPE_ADR);
4203 coalescing_boundary = sd.new;
4204 COUNT(count_check_null);
4205 COUNT(count_pcmd_mem);
4206 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4207 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4212 case ICMD_GETSTATIC:
4213 coalescing_boundary = sd.new;
4214 COUNT(count_pcmd_mem);
4215 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4216 OP0_1(fmiref->parseddesc.fd->type);
4220 coalescing_boundary = sd.new;
4227 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4228 tbptr->type = BBTYPE_SBR;
4230 assert(sd.bptr->next); /* XXX exception */
4231 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4232 #if defined(ENABLE_VERIFIER)
4233 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4236 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4240 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4242 /* We need to check for overflow right here because
4243 * the pushed value is poped afterwards */
4246 superblockend = true;
4247 /* XXX should not be marked as interface, as it does not need to be */
4248 /* allocated. Same for the invar of the target. */
4251 /* pop many push any */
4255 bte = iptr->sx.s23.s3.bte;
4259 case ICMD_INVOKESTATIC:
4260 case ICMD_INVOKESPECIAL:
4261 case ICMD_INVOKEVIRTUAL:
4262 case ICMD_INVOKEINTERFACE:
4263 COUNT(count_pcmd_met);
4265 /* Check for functions to replace with builtin
4268 if (builtintable_replace_function(iptr))
4271 INSTRUCTION_GET_METHODDESC(iptr, md);
4272 /* XXX resurrect this COUNT? */
4273 /* if (lm->flags & ACC_STATIC) */
4274 /* {COUNT(count_check_null);} */
4278 coalescing_boundary = sd.new;
4282 if (md->memuse > rd->memuse)
4283 rd->memuse = md->memuse;
4284 if (md->argintreguse > rd->argintreguse)
4285 rd->argintreguse = md->argintreguse;
4286 if (md->argfltreguse > rd->argfltreguse)
4287 rd->argfltreguse = md->argfltreguse;
4291 iptr->s1.argcount = stackdepth;
4292 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4295 for (i-- ; i >= 0; i--) {
4296 iptr->sx.s23.s2.args[i] = copy->varnum;
4298 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4299 /* -> won't help anyway */
4300 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4302 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4303 /* If we pass float arguments in integer argument registers, we
4304 * are not allowed to precolor them here. Floats have to be moved
4305 * to this regs explicitly in codegen().
4306 * Only arguments that are passed by stack anyway can be precolored
4307 * (michi 2005/07/24) */
4308 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4309 (!IS_FLT_DBL_TYPE(copy->type)
4310 || md->params[i].inmemory)) {
4312 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4317 if (md->params[i].inmemory) {
4318 sd.var[copy->varnum].vv.regoff =
4319 md->params[i].regoff;
4320 sd.var[copy->varnum].flags |=
4324 if (IS_FLT_DBL_TYPE(copy->type)) {
4325 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4326 assert(0); /* XXX is this assert ok? */
4328 sd.var[copy->varnum].vv.regoff =
4329 rd->argfltregs[md->params[i].regoff];
4330 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4333 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4334 if (IS_2_WORD_TYPE(copy->type))
4335 sd.var[copy->varnum].vv.regoff =
4336 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4337 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4340 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4341 sd.var[copy->varnum].vv.regoff =
4342 rd->argintregs[md->params[i].regoff];
4350 /* deal with live-through stack slots "under" the */
4356 iptr->sx.s23.s2.args[i++] = copy->varnum;
4357 sd.var[copy->varnum].flags |= SAVEDVAR;
4358 copy->flags |= SAVEDVAR | PASSTHROUGH;
4362 /* pop the arguments */
4371 /* push the return value */
4373 if (md->returntype.type != TYPE_VOID) {
4374 GET_NEW_VAR(sd, new_index, md->returntype.type);
4375 DST(md->returntype.type, new_index);
4380 case ICMD_INLINE_START:
4381 case ICMD_INLINE_END:
4386 case ICMD_MULTIANEWARRAY:
4387 coalescing_boundary = sd.new;
4388 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4389 rd->argintreguse = MIN(3, INT_ARG_CNT);
4391 i = iptr->s1.argcount;
4395 iptr->sx.s23.s2.args = DMNEW(s4, i);
4397 #if defined(SPECIALMEMUSE)
4398 # if defined(__DARWIN__)
4399 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4400 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4402 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4403 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4406 # if defined(__I386__)
4407 if (rd->memuse < i + 3)
4408 rd->memuse = i + 3; /* n integer args spilled on stack */
4409 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4410 if (rd->memuse < i + 2)
4411 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4414 rd->memuse = i; /* n integer args spilled on stack */
4415 # endif /* defined(__I386__) */
4419 /* check INT type here? Currently typecheck does this. */
4420 iptr->sx.s23.s2.args[i] = copy->varnum;
4421 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4422 && (!IS_INOUT(copy))
4423 && (!IS_LOCALVAR(copy)) ) {
4424 copy->varkind = ARGVAR;
4425 sd.var[copy->varnum].flags |=
4426 INMEMORY & PREALLOC;
4427 #if defined(SPECIALMEMUSE)
4428 # if defined(__DARWIN__)
4429 sd.var[copy->varnum].vv.regoff = i +
4430 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4432 sd.var[copy->varnum].vv.regoff = i +
4433 LA_SIZE_IN_POINTERS + 3;
4436 # if defined(__I386__)
4437 sd.var[copy->varnum].vv.regoff = i + 3;
4438 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4439 sd.var[copy->varnum].vv.regoff = i + 2;
4441 sd.var[copy->varnum].vv.regoff = i;
4442 # endif /* defined(__I386__) */
4443 #endif /* defined(SPECIALMEMUSE) */
4448 sd.var[copy->varnum].flags |= SAVEDVAR;
4449 copy->flags |= SAVEDVAR;
4453 i = iptr->s1.argcount;
4458 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4459 DST(TYPE_ADR, new_index);
4465 new_internalerror("Unknown ICMD %d", opcode);
4471 } /* while instructions */
4473 /* stack slots at basic block end become interfaces */
4475 sd.bptr->outdepth = stackdepth;
4476 sd.bptr->outvars = DMNEW(s4, stackdepth);
4479 for (copy = curstack; copy; i--, copy = copy->prev) {
4483 /* with the new vars rd->interfaces will be removed */
4484 /* and all in and outvars have to be STACKVARS! */
4485 /* in the moment i.e. SWAP with in and out vars can */
4486 /* create an unresolvable conflict */
4493 v = sd.var + copy->varnum;
4496 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4497 /* no interface var until now for this depth and */
4499 jd->interface_map[i*5 + t].flags = v->flags;
4502 jd->interface_map[i*5 + t].flags |= v->flags;
4505 sd.bptr->outvars[i] = copy->varnum;
4508 /* check if interface slots at basic block begin must be saved */
4510 for (i=0; i<sd.bptr->indepth; ++i) {
4511 varinfo *v = sd.var + sd.bptr->invars[i];
4518 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4519 /* no interface var until now for this depth and */
4521 jd->interface_map[i*5 + t].flags = v->flags;
4524 jd->interface_map[i*5 + t].flags |= v->flags;
4528 /* store the number of this block's variables */
4530 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4532 #if defined(STACK_VERBOSE)
4533 stack_verbose_block_exit(&sd, superblockend);
4536 /* reach the following block, if any */
4539 if (!stack_reach_next_block(&sd))
4544 } while (sd.repeat && !deadcode);
4546 /* XXX reset TYPE_RET to TYPE_ADR */
4548 for (i=0; i<sd.vartop; ++i) {
4549 if (sd.var[i].type == TYPE_RET)
4550 sd.var[i].type = TYPE_ADR;
4553 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4555 ex = jd->exceptiontable;
4556 for (; ex != NULL; ex = ex->down) {
4557 if (ex->start == ex->end) {
4558 assert(ex->end->next);
4559 ex->end = ex->end->next;
4563 /* store number of created variables */
4565 jd->vartop = sd.vartop;
4567 /* gather statistics *****************************************************/
4569 #if defined(ENABLE_STATISTICS)
4571 if (jd->basicblockcount > count_max_basic_blocks)
4572 count_max_basic_blocks = jd->basicblockcount;
4573 count_basic_blocks += jd->basicblockcount;
4574 if (jd->instructioncount > count_max_javainstr)
4575 count_max_javainstr = jd->instructioncount;
4576 count_javainstr += jd->instructioncount;
4577 if (jd->stackcount > count_upper_bound_new_stack)
4578 count_upper_bound_new_stack = jd->stackcount;
4579 if ((sd.new - jd->stack) > count_max_new_stack)
4580 count_max_new_stack = (sd.new - jd->stack);
4582 sd.bptr = jd->basicblocks;
4583 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4584 if (sd.bptr->flags > BBREACHED) {
4585 if (sd.bptr->indepth >= 10)
4586 count_block_stack[10]++;
4588 count_block_stack[sd.bptr->indepth]++;
4589 len = sd.bptr->icount;
4591 count_block_size_distribution[len]++;
4593 count_block_size_distribution[10]++;
4595 count_block_size_distribution[11]++;
4597 count_block_size_distribution[12]++;
4599 count_block_size_distribution[13]++;
4601 count_block_size_distribution[14]++;
4603 count_block_size_distribution[15]++;
4605 count_block_size_distribution[16]++;
4607 count_block_size_distribution[17]++;
4611 if (iteration_count == 1)
4612 count_analyse_iterations[0]++;
4613 else if (iteration_count == 2)
4614 count_analyse_iterations[1]++;
4615 else if (iteration_count == 3)
4616 count_analyse_iterations[2]++;
4617 else if (iteration_count == 4)
4618 count_analyse_iterations[3]++;
4620 count_analyse_iterations[4]++;
4622 if (jd->basicblockcount <= 5)
4623 count_method_bb_distribution[0]++;
4624 else if (jd->basicblockcount <= 10)
4625 count_method_bb_distribution[1]++;
4626 else if (jd->basicblockcount <= 15)
4627 count_method_bb_distribution[2]++;
4628 else if (jd->basicblockcount <= 20)
4629 count_method_bb_distribution[3]++;
4630 else if (jd->basicblockcount <= 30)
4631 count_method_bb_distribution[4]++;
4632 else if (jd->basicblockcount <= 40)
4633 count_method_bb_distribution[5]++;
4634 else if (jd->basicblockcount <= 50)
4635 count_method_bb_distribution[6]++;
4636 else if (jd->basicblockcount <= 75)
4637 count_method_bb_distribution[7]++;
4639 count_method_bb_distribution[8]++;
4641 #endif /* defined(ENABLE_STATISTICS) */
4643 /* everything's ok *******************************************************/
4647 /* goto labels for throwing verifier exceptions **************************/
4649 #if defined(ENABLE_VERIFIER)
4651 throw_stack_underflow:
4652 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4655 throw_stack_overflow:
4656 exceptions_throw_verifyerror(m, "Stack size too large");
4659 throw_stack_type_error:
4660 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4663 throw_stack_category_error:
4664 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4671 /* functions for verbose stack analysis output ********************************/
4673 #if defined(STACK_VERBOSE)
4674 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4676 printf("%c", show_jit_type_letters[v->type]);
4677 if (v->type == TYPE_RET)
4678 printf("{L%03d}", v->vv.retaddr->nr);
4682 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4684 assert(index >= 0 && index < sd->vartop);
4685 stack_verbose_show_varinfo(sd, sd->var + index);
4689 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4693 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4695 for (i=0; i<bptr->indepth; ++i) {
4698 stack_verbose_show_variable(sd, bptr->invars[i]);
4703 printf("] inlocals [");
4704 if (bptr->inlocals) {
4705 for (i=0; i<sd->localcount; ++i) {
4708 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4713 printf("] out:%d [", bptr->outdepth);
4714 if (bptr->outvars) {
4715 for (i=0; i<bptr->outdepth; ++i) {
4718 stack_verbose_show_variable(sd, bptr->outvars[i]);
4726 printf(" (clone of L%03d)", bptr->original->nr);
4728 basicblock *b = bptr->copied_to;
4730 printf(" (copied to ");
4731 for (; b; b = b->copied_to)
4732 printf("L%03d ", b->nr);
4739 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4743 printf("======================================== STACK %sANALYSE BLOCK ",
4744 (reanalyse) ? "RE-" : "");
4745 stack_verbose_show_block(sd, sd->bptr);
4748 if (sd->handlers[0]) {
4749 printf("HANDLERS: ");
4750 for (i=0; sd->handlers[i]; ++i) {
4751 printf("L%03d ", sd->handlers[i]->handler->nr);
4759 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4761 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4762 stack_verbose_show_block(sd, sd->bptr);
4769 * These are local overrides for various environment variables in Emacs.
4770 * Please do not remove this and leave it at the end of the file, where
4771 * Emacs will automagically detect them.
4772 * ---------------------------------------------------------------------
4775 * indent-tabs-mode: t
4779 * vim:noexpandtab:sw=4:ts=4: