1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/memory.h"
38 #include "native/native.h"
40 #include "toolbox/logging.h"
42 #include "vm/jit/builtin.hpp"
43 #include "vm/exceptions.hpp"
44 #include "vm/global.h"
45 #include "vm/options.h"
46 #include "vm/resolve.h"
47 #include "vm/string.hpp"
50 #if defined(ENABLE_STATISTICS)
51 # include "vm/statistics.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/cfg.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/show.h"
60 #if defined(ENABLE_DISASSEMBLER)
61 # include "vm/jit/disass.h"
64 #include "vm/jit/jit.hpp"
65 #include "vm/jit/stack.h"
68 #if defined(ENABLE_SSA)
69 # include "vm/jit/optimizing/lsra.h"
70 # include "vm/jit/optimizing/ssa.h"
71 #elif defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
76 /*#define STACK_VERBOSE*/
79 /* macro for saving #ifdefs ***************************************************/
81 #if defined(ENABLE_STATISTICS)
82 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
85 if (stackdepth >= 10) \
86 count_store_depth[10]++; \
88 count_store_depth[stackdepth]++; \
91 #else /* !defined(ENABLE_STATISTICS) */
92 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
96 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
99 /* For returnAddresses we use a field of the typeinfo to store from which */
100 /* subroutine the returnAddress will return, if used. */
101 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
102 /* to need it initialised to NULL. This should be investigated. */
104 #if defined(ENABLE_VERIFIER)
105 #define SBRSTART typeinfo.elementclass.any
109 /* stackdata_t *****************************************************************
111 This struct holds internal data during stack analysis.
113 *******************************************************************************/
115 typedef struct stackdata_t stackdata_t;
118 basicblock *bptr; /* the current basic block being analysed */
119 stackelement_t *new; /* next free stackelement */
120 s4 vartop; /* next free variable index */
121 s4 localcount; /* number of locals (at the start of var) */
122 s4 varcount; /* maximum number of variables expected */
123 s4 varsallocated; /* total number of variables allocated */
124 s4 maxlocals; /* max. number of Java locals */
125 varinfo *var; /* variable array (same as jd->var) */
126 s4 *javalocals; /* map from Java locals to jd->var indices */
127 methodinfo *m; /* the method being analysed */
128 jitdata *jd; /* current jitdata */
129 basicblock *last_real_block; /* the last block before the empty one */
130 bool repeat; /* if true, iterate the analysis again */
131 exception_entry **handlers; /* exception handlers for the current block */
132 exception_entry *extableend; /* points to the last exception entry */
133 stackelement_t exstack; /* instack for exception handlers */
137 /* macros for allocating/releasing variable indices *****************/
139 #define GET_NEW_INDEX(sd, new_varindex) \
141 assert((sd).vartop < (sd).varcount); \
142 (new_varindex) = ((sd).vartop)++; \
145 /* Not implemented now - could be used to reuse varindices. */
146 /* Pay attention to not release a localvar once implementing it! */
147 #define RELEASE_INDEX(sd, varindex)
149 #define GET_NEW_VAR(sd, newvarindex, newtype) \
151 GET_NEW_INDEX((sd), (newvarindex)); \
152 (sd).var[newvarindex].type = (newtype); \
156 /* macros for querying variable properties **************************/
158 #define IS_INOUT(sp) \
159 (sd.var[(sp)->varnum].flags & INOUT)
161 #define IS_PREALLOC(sp) \
162 (sd.var[(sp)->varnum].flags & PREALLOC)
164 #define IS_TEMPVAR(sp) \
165 ( ((sp)->varnum >= sd.localcount) \
166 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
169 #define IS_LOCALVAR_SD(sd, sp) \
170 ((sp)->varnum < (sd).localcount)
172 #define IS_LOCALVAR(sp) \
173 IS_LOCALVAR_SD(sd, (sp))
176 /* macros for setting variable properties ****************************/
178 #define SET_TEMPVAR(sp) \
180 if (IS_LOCALVAR((sp))) { \
181 stack_change_to_tempvar(&sd, (sp), iptr); \
183 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
186 #define SET_PREALLOC(sp) \
188 assert(!IS_LOCALVAR((sp))); \
189 sd.var[(sp)->varnum].flags |= PREALLOC; \
193 /* macros for source operands ***************************************/
196 (iptr->s1.varindex = -1)
198 #define USE_S1(type1) \
201 CHECK_BASIC_TYPE(type1, curstack->type); \
202 iptr->s1.varindex = curstack->varnum; \
208 iptr->s1.varindex = curstack->varnum; \
211 #define USE_S1_S2(type1, type2) \
214 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
215 CHECK_BASIC_TYPE(type2, curstack->type); \
216 iptr->sx.s23.s2.varindex = curstack->varnum; \
217 iptr->s1.varindex = curstack->prev->varnum; \
220 #define USE_S1_S2_ANY_ANY \
223 iptr->sx.s23.s2.varindex = curstack->varnum; \
224 iptr->s1.varindex = curstack->prev->varnum; \
227 #define USE_S1_S2_S3(type1, type2, type3) \
230 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
231 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
232 CHECK_BASIC_TYPE(type3, curstack->type); \
233 iptr->sx.s23.s3.varindex = curstack->varnum; \
234 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
235 iptr->s1.varindex = curstack->prev->prev->varnum; \
238 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
241 if (curstack->varkind == UNDEFVAR) \
242 curstack->varkind = TEMPVAR; \
243 curstack = curstack->prev; \
246 #define POP_S1(type1) \
249 if (curstack->varkind == UNDEFVAR) \
250 curstack->varkind = TEMPVAR; \
251 curstack = curstack->prev; \
257 if (curstack->varkind == UNDEFVAR) \
258 curstack->varkind = TEMPVAR; \
259 curstack = curstack->prev; \
262 #define POP_S1_S2(type1, type2) \
264 USE_S1_S2(type1, type2); \
265 if (curstack->varkind == UNDEFVAR) \
266 curstack->varkind = TEMPVAR; \
267 if (curstack->prev->varkind == UNDEFVAR) \
268 curstack->prev->varkind = TEMPVAR; \
269 curstack = curstack->prev->prev; \
272 #define POP_S1_S2_ANY_ANY \
275 if (curstack->varkind == UNDEFVAR) \
276 curstack->varkind = TEMPVAR; \
277 if (curstack->prev->varkind == UNDEFVAR) \
278 curstack->prev->varkind = TEMPVAR; \
279 curstack = curstack->prev->prev; \
282 #define POP_S1_S2_S3(type1, type2, type3) \
284 USE_S1_S2_S3(type1, type2, type3); \
285 if (curstack->varkind == UNDEFVAR) \
286 curstack->varkind = TEMPVAR; \
287 if (curstack->prev->varkind == UNDEFVAR) \
288 curstack->prev->varkind = TEMPVAR; \
289 if (curstack->prev->prev->varkind == UNDEFVAR) \
290 curstack->prev->prev->varkind = TEMPVAR; \
291 curstack = curstack->prev->prev->prev; \
298 /* macros for setting the destination operand ***********************/
301 (iptr->dst.varindex = -1)
303 #define DST(typed, index) \
305 NEWSTACKn((typed),(index)); \
306 curstack->creator = iptr; \
307 iptr->dst.varindex = (index); \
310 #define DST_LOCALVAR(typed, index) \
312 NEWSTACK((typed), LOCALVAR, (index)); \
313 curstack->creator = iptr; \
314 iptr->dst.varindex = (index); \
318 /* macro for propagating constant values ****************************/
320 #if defined(ENABLE_VERIFIER)
321 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
323 if (((dv)->type = (sv)->type) == TYPE_RET) { \
324 (dv)->vv = (sv)->vv; \
325 (dv)->SBRSTART = (sv)->SBRSTART; \
329 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
331 (dv)->type = (sv)->type; \
332 if (((dv)->type = (sv)->type) == TYPE_RET) { \
333 (dv)->vv = (sv)->vv; \
338 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
339 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
342 /* stack modelling macros *******************************************/
344 #define OP0_1(typed) \
347 GET_NEW_VAR(sd, new_index, (typed)); \
348 DST((typed), new_index); \
359 #define OP1_BRANCH(type1) \
365 #define OP1_1(type1, typed) \
368 GET_NEW_VAR(sd, new_index, (typed)); \
369 DST(typed, new_index); \
372 #define OP2_1(type1, type2, typed) \
374 POP_S1_S2(type1, type2); \
375 GET_NEW_VAR(sd, new_index, (typed)); \
376 DST(typed, new_index); \
391 #define OP1_0(type1) \
398 #define OP2_0(type1, type2) \
400 POP_S1_S2(type1, type2); \
405 #define OP2_BRANCH(type1, type2) \
407 POP_S1_S2(type1, type2); \
411 #define OP2_0_ANY_ANY \
418 #define OP3_0(type1, type2, type3) \
420 POP_S1_S2_S3(type1, type2, type3); \
425 #define LOAD(type1, index) \
427 DST_LOCALVAR(type1, index); \
431 #define STORE(type1, index) \
438 /* macros for DUP elimination ***************************************/
440 /* XXX replace NEW_VAR with NEW_INDEX */
441 #define DUP_SLOT(sp) \
443 GET_NEW_VAR(sd, new_index, (sp)->type); \
444 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
445 NEWSTACK((sp)->type, TEMPVAR, new_index); \
448 /* does not check input stackdepth */
449 #define MOVE_UP(sp) \
451 iptr->opc = ICMD_MOVE; \
452 iptr->s1.varindex = (sp)->varnum; \
454 curstack->creator = iptr; \
455 iptr->dst.varindex = curstack->varnum; \
459 /* does not check input stackdepth */
460 #define COPY_UP(sp) \
463 iptr->opc = ICMD_COPY; \
464 iptr->s1.varindex = (sp)->varnum; \
466 curstack->creator = iptr; \
467 iptr->dst.varindex = curstack->varnum; \
471 #define COPY_DOWN(s, d) \
474 iptr->opc = ICMD_COPY; \
475 iptr->s1.varindex = (s)->varnum; \
476 iptr->dst.varindex = (d)->varnum; \
477 (d)->creator = iptr; \
480 #define MOVE_TO_TEMP(sp) \
482 GET_NEW_INDEX(sd, new_index); \
483 iptr->opc = ICMD_MOVE; \
484 iptr->s1.varindex = (sp)->varnum; \
485 iptr->dst.varindex = new_index; \
486 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
487 (sp)->varnum = new_index; \
488 (sp)->varkind = TEMPVAR; \
491 /* macros for branching / reaching basic blocks *********************/
493 #define BRANCH_TARGET(bt, tempbptr) \
495 tempbptr = (bt).block; \
496 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
498 if (tempbptr == NULL) \
500 (bt).block = tempbptr; \
503 #define BRANCH(tempbptr) \
504 BRANCH_TARGET(iptr->dst, tempbptr)
507 /* forward declarations *******************************************************/
509 static void stack_create_invars(stackdata_t *sd, basicblock *b,
510 stackelement_t * curstack, int stackdepth);
511 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
513 #if defined(STACK_VERBOSE)
514 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
515 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
516 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
517 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
518 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
519 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
520 stackelement_t * curstack);
524 /* stack_init ******************************************************************
526 Initialized the stack analysis subsystem (called by jit_init).
528 *******************************************************************************/
530 bool stack_init(void)
536 /* stack_grow_variable_array ***************************************************
538 Grow the variable array so the given number of additional variables fits in.
539 The number is added to `varcount`, which is the maximum number of variables
540 we expect to need at this point. The actual number of variables
541 (`varsallocated`) may be larger than that, in order to avoid too many
545 sd...........stack analysis data
546 num..........number of additional variables
548 *******************************************************************************/
550 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
556 if (sd->varcount + num > sd->varsallocated) {
557 newsize = 2*sd->varsallocated + num;
559 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
560 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
561 sd->varsallocated = newsize;
562 sd->jd->var = sd->var;
566 sd->jd->varcount += num;
568 assert(sd->varcount <= sd->varsallocated);
572 /* stack_append_block **********************************************************
574 Append the given block after the last real block of the method (before
575 the pseudo-block at the end).
578 sd...........stack analysis data
579 b............the block to append
581 *******************************************************************************/
583 static void stack_append_block(stackdata_t *sd, basicblock *b)
585 #if defined(STACK_VERBOSE)
586 printf("APPENDING BLOCK L%0d\n", b->nr);
589 b->next = sd->last_real_block->next;
590 sd->last_real_block->next = b;
591 sd->last_real_block = b;
592 b->nr = sd->jd->basicblockcount++;
593 b->next->nr = b->nr + 1;
597 /* stack_clone_block ***********************************************************
599 Create a copy of the given block and insert it at the end of the method.
601 CAUTION: This function does not copy the any variables or the instruction
602 list. It _does_, however, reserve space for the block's invars in the
606 sd...........stack analysis data
607 b............the block to clone
610 a pointer to the copy
612 *******************************************************************************/
614 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
618 clone = DNEW(basicblock);
621 clone->iinstr = NULL;
622 clone->inlocals = NULL;
623 clone->javalocals = NULL;
624 clone->invars = NULL;
626 clone->original = (b->original) ? b->original : b;
627 clone->copied_to = clone->original->copied_to;
628 clone->original->copied_to = clone;
630 clone->flags = BBREACHED;
632 stack_append_block(sd, clone);
634 /* reserve space for the invars of the clone */
636 stack_grow_variable_array(sd, b->indepth);
638 #if defined(STACK_VERBOSE)
639 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
646 /* stack_create_locals *********************************************************
648 Create the local variables for the start of the given basic block.
651 sd...........stack analysis data
652 b............block to create the locals for
654 *******************************************************************************/
656 static void stack_create_locals(stackdata_t *sd, basicblock *b)
662 /* copy the current state of the local variables */
663 /* (one extra local is needed by the verifier) */
665 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
667 for (i=0; i<sd->localcount; ++i)
670 /* the current map from java locals to cacao variables */
672 jl = DMNEW(s4, sd->maxlocals);
674 MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
678 /* stack_merge_locals **********************************************************
680 Merge local variables at the beginning of the given basic block.
683 sd...........stack analysis data
684 b............the block that is reached
686 *******************************************************************************/
688 static void stack_merge_locals(stackdata_t *sd, basicblock *b)
694 /* If a javalocal is mapped to different cacao locals along the */
695 /* incoming control-flow edges, it becomes undefined. */
697 for (i=0; i<sd->maxlocals; ++i) {
698 if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
699 b->javalocals[i] = UNUSED;
700 if (b->flags >= BBFINISHED)
701 b->flags = BBTYPECHECK_REACHED;
702 if (b->nr <= sd->bptr->nr)
707 #if defined(ENABLE_VERIFIER)
709 for (i=0; i<sd->localcount; ++i) {
710 dv = b->inlocals + i;
712 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
713 && (sv->SBRSTART != dv->SBRSTART))
715 #if defined(STACK_VERBOSE)
716 printf("JSR MISMATCH: setting variable %d to VOID\n", i);
718 dv->type = TYPE_VOID;
719 if (b->flags >= BBFINISHED)
720 b->flags = BBTYPECHECK_REACHED;
721 sd->repeat = true; /* This is very rare, so just repeat */
725 #endif /* defined(ENABLE_VERIFIER) */
729 /* stack_create_invars *********************************************************
731 Create the invars for the given basic block. Also make a copy of the locals.
734 sd...........stack analysis data
735 b............block to create the invars for
736 curstack.....current stack top
737 stackdepth...current stack depth
739 This function creates STACKDEPTH invars and sets their types to the
740 types to the types of the corresponding slot in the current stack.
742 *******************************************************************************/
744 static void stack_create_invars(stackdata_t *sd, basicblock *b,
745 stackelement_t * curstack, int stackdepth)
753 assert(sd->vartop + stackdepth <= sd->varcount);
755 b->indepth = stackdepth;
756 b->invars = DMNEW(s4, stackdepth);
758 /* allocate the variable indices */
759 index = (sd->vartop += stackdepth);
762 for (sp = curstack; i--; sp = sp->prev) {
763 b->invars[i] = --index;
764 dv = sd->var + index;
765 sv = sd->var + sp->varnum;
767 COPY_VAL_AND_TYPE_VAR(sv, dv);
770 stack_create_locals(sd, b);
774 /* stack_create_invars_from_outvars ********************************************
776 Create the invars for the given basic block. Also make a copy of the locals.
777 Types are propagated from the outvars of the current block.
780 sd...........stack analysis data
781 b............block to create the invars for
783 *******************************************************************************/
785 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
791 n = sd->bptr->outdepth;
792 assert(sd->vartop + n <= sd->varcount);
795 b->invars = DMNEW(s4, n);
798 dv = sd->var + sd->vartop;
800 /* allocate the invars */
802 for (i=0; i<n; ++i, ++dv) {
803 sv = sd->var + sd->bptr->outvars[i];
804 b->invars[i] = sd->vartop++;
806 COPY_VAL_AND_TYPE_VAR(sv, dv);
810 stack_create_locals(sd, b);
814 /* stack_check_invars **********************************************************
816 Check the current stack against the invars of the given basic block.
817 Depth and types must match.
820 sd...........stack analysis data
821 b............block which invars to check against
822 curstack.....current stack top
823 stackdepth...current stack depth
827 NULL.........a VerifyError has been thrown
829 *******************************************************************************/
831 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
832 stackelement_t * curstack, int stackdepth)
841 #if defined(STACK_VERBOSE)
842 printf("stack_check_invars(L%03d)\n", b->nr);
845 /* find original of b */
850 #if defined(STACK_VERBOSE)
851 printf("original is L%03d\n", orig->nr);
856 #if defined(ENABLE_VERIFIER)
857 if (i != stackdepth) {
858 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
866 #if defined(STACK_VERBOSE)
867 printf("checking against ");
868 stack_verbose_show_block(sd, b); printf("\n");
872 for (i = orig->indepth; i--; sp = sp->prev) {
873 dv = sd->var + b->invars[i];
874 sv = sd->var + sp->varnum;
876 #if defined(ENABLE_VERIFIER)
877 if (dv->type != sp->type) {
878 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
883 if (sp->type == TYPE_RET) {
884 #if defined(ENABLE_VERIFIER)
885 if (dv->SBRSTART != sv->SBRSTART) {
886 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
890 if (dv->vv.retaddr != sv->vv.retaddr) {
892 /* don't break! have to check the remaining stackslots */
898 for (i=0; i<sd->localcount; ++i) {
899 dv = b->inlocals + i;
901 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
903 #if defined(ENABLE_VERIFIER)
904 (sv->SBRSTART == dv->SBRSTART) &&
906 (sv->vv.retaddr != dv->vv.retaddr))
916 /* XXX cascading collapse? */
918 stack_merge_locals(sd, b);
920 #if defined(STACK_VERBOSE)
921 printf("------> using L%03d\n", b->nr);
925 } while ((b = b->copied_to) != NULL);
927 b = stack_clone_block(sd, orig);
931 stack_create_invars(sd, b, curstack, stackdepth);
936 /* stack_check_invars_from_outvars *********************************************
938 Check the outvars of the current block against the invars of the given block.
939 Depth and types must match.
942 sd...........stack analysis data
943 b............block which invars to check against
947 NULL.........a VerifyError has been thrown
949 *******************************************************************************/
951 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
959 #if defined(STACK_VERBOSE)
960 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
963 /* find original of b */
968 #if defined(STACK_VERBOSE)
969 printf("original is L%03d\n", orig->nr);
973 n = sd->bptr->outdepth;
975 #if defined(ENABLE_VERIFIER)
977 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
985 #if defined(STACK_VERBOSE)
986 printf("checking against ");
987 stack_verbose_show_block(sd, b); printf("\n");
991 dv = sd->var + b->invars[0];
993 for (i=0; i<n; ++i, ++dv) {
994 sv = sd->var + sd->bptr->outvars[i];
996 #if defined(ENABLE_VERIFIER)
997 if (sv->type != dv->type) {
998 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1003 if (dv->type == TYPE_RET) {
1004 #if defined(ENABLE_VERIFIER)
1005 if (sv->SBRSTART != dv->SBRSTART) {
1006 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1010 if (sv->vv.retaddr != dv->vv.retaddr) {
1012 /* don't break! have to check the remaining stackslots */
1019 for (i=0; i<sd->localcount; ++i) {
1020 dv = b->inlocals + i;
1023 #if defined(ENABLE_VERIFIER)
1024 (sv->SBRSTART == dv->SBRSTART) &&
1026 (sv->type == TYPE_RET && dv->type == TYPE_RET))
1028 if (sv->vv.retaddr != dv->vv.retaddr) {
1037 /* XXX cascading collapse? */
1039 stack_merge_locals(sd, b);
1041 #if defined(STACK_VERBOSE)
1042 printf("------> using L%03d\n", b->nr);
1046 } while ((b = b->copied_to) != NULL);
1048 b = stack_clone_block(sd, orig);
1052 stack_create_invars_from_outvars(sd, b);
1057 /* stack_create_instack ********************************************************
1059 Create the instack of the current basic block.
1062 sd...........stack analysis data
1065 the current stack top at the start of the basic block.
1067 *******************************************************************************/
1069 static stackelement_t * stack_create_instack(stackdata_t *sd)
1071 stackelement_t * sp;
1075 if ((depth = sd->bptr->indepth) == 0)
1078 sp = (sd->new += depth);
1082 index = sd->bptr->invars[depth];
1084 sp->type = sd->var[index].type;
1088 sp->varkind = STACKVAR;
1092 /* return the top of the created stack */
1097 /* stack_mark_reached **********************************************************
1099 Mark the given block reached and propagate the current stack and locals to
1100 it. This function specializes the target block, if necessary, and returns
1101 a pointer to the specialized target.
1104 sd...........stack analysis data
1105 b............the block to reach
1106 curstack.....the current stack top
1107 stackdepth...the current stack depth
1110 a pointer to (a specialized version of) the target
1111 NULL.........a VerifyError has been thrown
1113 *******************************************************************************/
1115 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackelement_t * curstack, int stackdepth)
1119 #if defined(STACK_VERBOSE)
1120 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1123 /* mark targets of backward branches */
1125 if (b->nr <= sd->bptr->nr)
1126 b->bitflags |= BBFLAG_REPLACEMENT;
1128 if (b->flags < BBREACHED) {
1129 /* b is reached for the first time. Create its invars. */
1131 #if defined(STACK_VERBOSE)
1132 printf("reached L%03d for the first time\n", b->nr);
1135 stack_create_invars(sd, b, curstack, stackdepth);
1137 b->flags = BBREACHED;
1142 /* b has been reached before. Check that its invars match. */
1144 return stack_check_invars(sd, b, curstack, stackdepth);
1149 /* stack_mark_reached_from_outvars *********************************************
1151 Mark the given block reached and propagate the outvars of the current block
1152 and the current locals to it. This function specializes the target block,
1153 if necessary, and returns a pointer to the specialized target.
1156 sd...........stack analysis data
1157 b............the block to reach
1160 a pointer to (a specialized version of) the target
1161 NULL.........a VerifyError has been thrown
1163 *******************************************************************************/
1165 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1169 #if defined(STACK_VERBOSE)
1170 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1173 /* mark targets of backward branches */
1175 if (b->nr <= sd->bptr->nr)
1176 b->bitflags |= BBFLAG_REPLACEMENT;
1178 if (b->flags < BBREACHED) {
1179 /* b is reached for the first time. Create its invars. */
1181 #if defined(STACK_VERBOSE)
1182 printf("reached L%03d for the first time\n", b->nr);
1185 stack_create_invars_from_outvars(sd, b);
1187 b->flags = BBREACHED;
1192 /* b has been reached before. Check that its invars match. */
1194 return stack_check_invars_from_outvars(sd, b);
1199 /* stack_reach_next_block ******************************************************
1201 Mark the following block reached and propagate the outvars of the
1202 current block and the current locals to it. This function
1203 specializes the target block, if necessary, and returns a pointer
1204 to the specialized target.
1207 sd...........stack analysis data
1210 a pointer to (a specialized version of) the following block
1211 NULL.........a VerifyError has been thrown
1213 *******************************************************************************/
1215 static bool stack_reach_next_block(stackdata_t *sd)
1220 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1221 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1226 if (tbptr != sd->bptr->next) {
1227 #if defined(STACK_VERBOSE)
1228 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1230 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1231 assert(iptr->opc == ICMD_NOP);
1232 iptr->opc = ICMD_GOTO;
1233 iptr->dst.block = tbptr;
1234 #if defined(STACK_VERBOSE)
1235 if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
1238 if (tbptr->flags < BBFINISHED)
1239 sd->repeat = true; /* XXX check if we really need to repeat */
1246 /* stack_reach_handlers ********************************************************
1248 Reach the exception handlers for the current block.
1251 sd...........stack analysis data
1254 true.........everything ok
1255 false........a VerifyError has been thrown
1257 *******************************************************************************/
1259 static bool stack_reach_handlers(stackdata_t *sd)
1264 #if defined(STACK_VERBOSE)
1265 printf("reaching exception handlers...\n");
1268 for (i=0; sd->handlers[i]; ++i) {
1269 tbptr = sd->handlers[i]->handler;
1271 tbptr->type = BBTYPE_EXH;
1272 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1274 /* reach (and specialize) the handler block */
1276 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1281 sd->handlers[i]->handler = tbptr;
1288 /* stack_reanalyse_block ******************************************************
1290 Re-analyse the current block. This is called if either the block itself
1291 has already been analysed before, or the current block is a clone of an
1292 already analysed block, and this clone is reached for the first time.
1293 In the latter case, this function does all that is necessary for fully
1294 cloning the block (cloning the instruction list and variables, etc.).
1297 sd...........stack analysis data
1300 true.........everything ok
1301 false........a VerifyError has been thrown
1303 *******************************************************************************/
1305 #define RELOCATE(index) \
1307 if ((index) >= blockvarstart) \
1308 (index) += blockvarshift; \
1309 else if ((index) >= invarstart) \
1310 (index) += invarshift; \
1313 bool stack_reanalyse_block(stackdata_t *sd)
1325 branch_target_t *table;
1326 lookup_target_t *lookup;
1328 bool cloneinstructions;
1329 exception_entry *ex;
1331 #if defined(STACK_VERBOSE)
1332 stack_verbose_block_enter(sd, true);
1339 assert(orig != NULL);
1341 /* clone the instruction list */
1343 cloneinstructions = true;
1345 assert(orig->iinstr);
1347 iptr = DMNEW(instruction, len + 1);
1349 MCOPY(iptr, orig->iinstr, instruction, len);
1350 iptr[len].opc = ICMD_NOP;
1352 iptr[len].flags.bits = 0;
1356 /* reserve space for the clone's block variables */
1358 stack_grow_variable_array(sd, orig->varcount);
1360 /* we already have the invars set */
1362 assert(b->indepth == orig->indepth);
1364 /* calculate relocation shifts for invars and block variables */
1366 if (orig->indepth) {
1367 invarstart = orig->invars[0];
1368 invarshift = b->invars[0] - invarstart;
1371 invarstart = INT_MAX;
1374 blockvarstart = orig->varstart;
1375 blockvarshift = sd->vartop - blockvarstart;
1377 /* copy block variables */
1379 b->varstart = sd->vartop;
1380 b->varcount = orig->varcount;
1381 sd->vartop += b->varcount;
1382 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1386 b->outdepth = orig->outdepth;
1387 b->outvars = DMNEW(s4, orig->outdepth);
1388 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1390 /* clone exception handlers */
1392 for (i=0; sd->handlers[i]; ++i) {
1393 ex = DNEW(exception_entry);
1394 ex->handler = sd->handlers[i]->handler;
1396 ex->end = b; /* XXX hack, see end of stack_analyse */
1397 ex->catchtype = sd->handlers[i]->catchtype;
1400 assert(sd->extableend->down == NULL);
1401 sd->extableend->down = ex;
1402 sd->extableend = ex;
1403 sd->jd->exceptiontablelength++;
1405 sd->handlers[i] = ex;
1409 cloneinstructions = false;
1412 invarstart = sd->vartop;
1413 blockvarstart = sd->vartop;
1418 /* find exception handlers for the cloned block */
1420 ex = sd->jd->exceptiontable;
1421 for (; ex != NULL; ex = ex->down) {
1422 /* XXX the cloned exception handlers have identical */
1423 /* start end end blocks. */
1424 if ((ex->start == b) && (ex->end == b)) {
1425 sd->handlers[len++] = ex;
1428 sd->handlers[len] = NULL;
1431 #if defined(STACK_VERBOSE)
1432 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1433 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1436 /* mark block as finished */
1438 b->flags = BBFINISHED;
1440 /* initialize locals at the start of this block */
1443 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1445 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1447 /* reach exception handlers for this block */
1449 if (!stack_reach_handlers(sd))
1452 superblockend = false;
1454 for (len = b->icount; len--; iptr++) {
1455 #if defined(STACK_VERBOSE)
1456 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1460 switch (iptr->opc) {
1462 varindex = iptr->s1.varindex;
1464 #if defined(ENABLE_VERIFIER)
1465 if (sd->var[varindex].type != TYPE_RET) {
1466 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1471 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1472 superblockend = true;
1476 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1477 RELOCATE(iptr->dst.varindex);
1478 superblockend = true;
1482 superblockend = true;
1485 case ICMD_CHECKNULL:
1486 case ICMD_PUTSTATICCONST:
1494 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1495 superblockend = true;
1498 /* pop 0 push 1 const */
1506 /* pop 0 push 1 load */
1513 RELOCATE(iptr->dst.varindex);
1526 RELOCATE(iptr->sx.s23.s2.varindex);
1527 RELOCATE(iptr->s1.varindex);
1528 RELOCATE(iptr->dst.varindex);
1541 RELOCATE(iptr->sx.s23.s3.varindex);
1542 RELOCATE(iptr->sx.s23.s2.varindex);
1543 RELOCATE(iptr->s1.varindex);
1546 /* pop 1 push 0 store */
1553 RELOCATE(iptr->s1.varindex);
1555 varindex = iptr->dst.varindex;
1556 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1557 i = iptr->sx.s23.s3.javaindex;
1558 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1559 iptr->sx.s23.s2.retaddrnr =
1560 JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1561 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1564 sd->javalocals[i] = varindex;
1565 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1566 sd->javalocals[i-1] = UNUSED;
1567 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1568 sd->javalocals[i+1] = UNUSED;
1579 RELOCATE(iptr->s1.varindex);
1580 superblockend = true;
1583 case ICMD_PUTSTATIC:
1584 case ICMD_PUTFIELDCONST:
1586 RELOCATE(iptr->s1.varindex);
1589 /* pop 1 push 0 branch */
1592 case ICMD_IFNONNULL:
1607 RELOCATE(iptr->s1.varindex);
1608 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1611 /* pop 1 push 0 table branch */
1613 case ICMD_TABLESWITCH:
1614 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1616 if (cloneinstructions) {
1617 table = DMNEW(branch_target_t, i);
1618 MCOPY(table, iptr->dst.table, branch_target_t, i);
1619 iptr->dst.table = table;
1622 table = iptr->dst.table;
1625 RELOCATE(iptr->s1.varindex);
1627 table->block = stack_mark_reached_from_outvars(sd, table->block);
1630 superblockend = true;
1633 case ICMD_LOOKUPSWITCH:
1634 i = iptr->sx.s23.s2.lookupcount;
1635 if (cloneinstructions) {
1636 lookup = DMNEW(lookup_target_t, i);
1637 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1638 iptr->dst.lookup = lookup;
1641 lookup = iptr->dst.lookup;
1643 RELOCATE(iptr->s1.varindex);
1645 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1648 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1649 superblockend = true;
1652 case ICMD_MONITORENTER:
1653 case ICMD_MONITOREXIT:
1654 RELOCATE(iptr->s1.varindex);
1657 /* pop 2 push 0 branch */
1659 case ICMD_IF_ICMPEQ:
1660 case ICMD_IF_ICMPNE:
1661 case ICMD_IF_ICMPLT:
1662 case ICMD_IF_ICMPGE:
1663 case ICMD_IF_ICMPGT:
1664 case ICMD_IF_ICMPLE:
1666 case ICMD_IF_LCMPEQ:
1667 case ICMD_IF_LCMPNE:
1668 case ICMD_IF_LCMPLT:
1669 case ICMD_IF_LCMPGE:
1670 case ICMD_IF_LCMPGT:
1671 case ICMD_IF_LCMPLE:
1673 case ICMD_IF_ACMPEQ:
1674 case ICMD_IF_ACMPNE:
1675 RELOCATE(iptr->sx.s23.s2.varindex);
1676 RELOCATE(iptr->s1.varindex);
1677 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1683 case ICMD_IASTORECONST:
1684 case ICMD_LASTORECONST:
1685 case ICMD_AASTORECONST:
1686 case ICMD_BASTORECONST:
1687 case ICMD_CASTORECONST:
1688 case ICMD_SASTORECONST:
1690 RELOCATE(iptr->sx.s23.s2.varindex);
1691 RELOCATE(iptr->s1.varindex);
1694 /* pop 0 push 1 copy */
1698 RELOCATE(iptr->dst.varindex);
1699 RELOCATE(iptr->s1.varindex);
1700 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1742 RELOCATE(iptr->sx.s23.s2.varindex);
1743 RELOCATE(iptr->s1.varindex);
1744 RELOCATE(iptr->dst.varindex);
1749 case ICMD_CHECKCAST:
1750 case ICMD_ARRAYLENGTH:
1751 case ICMD_INSTANCEOF:
1753 case ICMD_ANEWARRAY:
1755 case ICMD_IADDCONST:
1756 case ICMD_ISUBCONST:
1757 case ICMD_IMULCONST:
1761 case ICMD_IANDCONST:
1763 case ICMD_IXORCONST:
1764 case ICMD_ISHLCONST:
1765 case ICMD_ISHRCONST:
1766 case ICMD_IUSHRCONST:
1767 case ICMD_LADDCONST:
1768 case ICMD_LSUBCONST:
1769 case ICMD_LMULCONST:
1773 case ICMD_LANDCONST:
1775 case ICMD_LXORCONST:
1776 case ICMD_LSHLCONST:
1777 case ICMD_LSHRCONST:
1778 case ICMD_LUSHRCONST:
1782 case ICMD_INT2SHORT:
1798 RELOCATE(iptr->s1.varindex);
1799 RELOCATE(iptr->dst.varindex);
1804 case ICMD_GETSTATIC:
1806 RELOCATE(iptr->dst.varindex);
1809 /* pop many push any */
1811 case ICMD_INVOKESTATIC:
1812 case ICMD_INVOKESPECIAL:
1813 case ICMD_INVOKEVIRTUAL:
1814 case ICMD_INVOKEINTERFACE:
1816 case ICMD_MULTIANEWARRAY:
1817 i = iptr->s1.argcount;
1818 if (cloneinstructions) {
1819 argp = DMNEW(s4, i);
1820 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1821 iptr->sx.s23.s2.args = argp;
1824 argp = iptr->sx.s23.s2.args;
1831 RELOCATE(iptr->dst.varindex);
1835 exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1840 #if defined(STACK_VERBOSE)
1841 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1846 /* relocate outvars */
1848 for (i=0; i<b->outdepth; ++i) {
1849 RELOCATE(b->outvars[i]);
1852 #if defined(STACK_VERBOSE)
1853 stack_verbose_block_exit(sd, superblockend);
1856 /* propagate to the next block */
1859 if (!stack_reach_next_block(sd))
1866 /* stack_change_to_tempvar *****************************************************
1868 Change the given stackslot to a TEMPVAR. This includes creating a new
1869 temporary variable and changing the dst.varindex of the creator of the
1870 stacklot to the new variable index. If this stackslot has been passed
1871 through ICMDs between the point of its creation and the current point,
1872 then the variable index is also changed in these ICMDs.
1875 sd...........stack analysis data
1876 sp...........stackslot to change
1877 ilimit.......instruction up to which to look for ICMDs passing-through
1878 the stackslot (exclusive). This may point exactly after the
1879 last instruction, in which case the search is done to the
1882 *******************************************************************************/
1884 static void stack_change_to_tempvar(stackdata_t *sd, stackelement_t * sp,
1885 instruction *ilimit)
1893 oldindex = sp->varnum;
1895 /* create a new temporary variable */
1897 GET_NEW_VAR(*sd, newindex, sp->type);
1899 sd->var[newindex].flags = sp->flags;
1901 /* change the stackslot */
1903 sp->varnum = newindex;
1904 sp->varkind = TEMPVAR;
1906 /* change the dst.varindex of the stackslot's creator */
1909 sp->creator->dst.varindex = newindex;
1911 /* handle ICMDs this stackslot passed through, if any */
1913 if (sp->flags & PASSTHROUGH) {
1914 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1916 /* assert that the limit points to an ICMD, or after the last one */
1918 assert(ilimit >= sd->bptr->iinstr);
1919 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1921 /* find the stackdepth under sp plus one */
1922 /* Note: This number is usually known when this function is called, */
1923 /* but calculating it here is less error-prone and should not be */
1924 /* a performance problem. */
1926 for (depth = 0; sp != NULL; sp = sp->prev)
1929 /* iterate over all instructions in the range and replace */
1931 for (; iptr < ilimit; ++iptr) {
1932 switch (iptr->opc) {
1933 case ICMD_INVOKESTATIC:
1934 case ICMD_INVOKESPECIAL:
1935 case ICMD_INVOKEVIRTUAL:
1936 case ICMD_INVOKEINTERFACE:
1938 i = iptr->s1.argcount - depth;
1939 if (iptr->sx.s23.s2.args[i] == oldindex) {
1940 iptr->sx.s23.s2.args[i] = newindex;
1943 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1944 /* stackslot, it must be added in this switch! */
1951 /* stack_init_javalocals *******************************************************
1953 Initialize the mapping from Java locals to cacao variables at method entry.
1956 sd...........stack analysis data
1958 *******************************************************************************/
1960 static void stack_init_javalocals(stackdata_t *sd)
1969 jl = DMNEW(s4, sd->maxlocals);
1970 jd->basicblocks[0].javalocals = jl;
1972 for (i=0; i<sd->maxlocals; ++i)
1975 md = jd->m->parseddesc;
1977 for (i=0; i<md->paramcount; ++i) {
1978 type = md->paramtypes[i].type;
1979 jl[j] = jd->local_map[5*j + type];
1981 if (IS_2_WORD_TYPE(type))
1987 /* stack_analyse ***************************************************************
1989 Analyse_stack uses the intermediate code created by parse.c to
1990 build a model of the JVM operand stack for the current method.
1992 The following checks are performed:
1993 - check for operand stack underflow (before each instruction)
1994 - check for operand stack overflow (after[1] each instruction)
1995 - check for matching stack depth at merging points
1996 - check for matching basic types[2] at merging points
1997 - check basic types for instruction input (except for BUILTIN*
1998 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
2000 [1]) Checking this after the instruction should be ok. parse.c
2001 counts the number of required stack slots in such a way that it is
2002 only vital that we don't exceed `maxstack` at basic block
2005 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2006 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2007 types are not discerned.
2009 *******************************************************************************/
2011 bool stack_analyse(jitdata *jd)
2013 methodinfo *m; /* method being analyzed */
2018 stackelement_t *curstack; /* current stack top */
2019 stackelement_t *copy;
2020 int opcode; /* opcode of current instruction */
2023 int type; /* operand type */
2024 int len; /* # of instructions after the current one */
2025 bool superblockend; /* if true, no fallthrough to next block */
2026 bool deadcode; /* true if no live code has been reached */
2027 instruction *iptr; /* the current instruction */
2029 basicblock *original;
2030 exception_entry *ex;
2032 stackelement_t **last_store_boundary;
2033 stackelement_t *coalescing_boundary;
2035 stackelement_t *src1, *src2, *src3, *src4, *dst1, *dst2;
2037 branch_target_t *table;
2038 lookup_target_t *lookup;
2039 #if defined(ENABLE_VERIFIER)
2040 int expectedtype; /* used by CHECK_BASIC_TYPE */
2042 builtintable_entry *bte;
2044 constant_FMIref *fmiref;
2045 #if defined(ENABLE_STATISTICS)
2046 int iteration_count; /* number of iterations of analysis */
2048 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2050 #if defined(STACK_VERBOSE)
2051 show_method(jd, SHOW_PARSE);
2054 /* get required compiler data - initialization */
2060 /* initialize the stackdata_t struct */
2064 sd.varcount = jd->varcount;
2065 sd.vartop = jd->vartop;
2066 sd.localcount = jd->localcount;
2068 sd.varsallocated = sd.varcount;
2069 sd.maxlocals = m->maxlocals;
2070 sd.javalocals = DMNEW(s4, sd.maxlocals);
2071 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2073 /* prepare the variable for exception handler stacks */
2074 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2076 sd.exstack.type = TYPE_ADR;
2077 sd.exstack.prev = NULL;
2078 sd.exstack.varnum = sd.localcount;
2079 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2081 #if defined(ENABLE_STATISTICS)
2082 iteration_count = 0;
2085 /* find the last real basic block */
2087 sd.last_real_block = NULL;
2088 tbptr = jd->basicblocks;
2089 while (tbptr->next) {
2090 sd.last_real_block = tbptr;
2091 tbptr = tbptr->next;
2093 assert(sd.last_real_block);
2095 /* find the last exception handler */
2097 if (jd->exceptiontablelength)
2098 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2100 sd.extableend = NULL;
2102 /* init jd->interface_map */
2104 jd->maxinterfaces = m->maxstack;
2105 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2106 for (i = 0; i < m->maxstack * 5; i++)
2107 jd->interface_map[i].flags = UNUSED;
2109 last_store_boundary = DMNEW(stackelement_t *, m->maxlocals);
2111 /* initialize flags and invars (none) of first block */
2113 jd->basicblocks[0].flags = BBREACHED;
2114 jd->basicblocks[0].invars = NULL;
2115 jd->basicblocks[0].indepth = 0;
2116 jd->basicblocks[0].inlocals =
2117 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2118 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2119 jd->localcount + VERIFIER_EXTRA_LOCALS);
2121 /* initialize java local mapping of first block */
2123 stack_init_javalocals(&sd);
2125 /* stack analysis loop (until fixpoint reached) **************************/
2128 #if defined(ENABLE_STATISTICS)
2132 /* initialize loop over basic blocks */
2134 sd.bptr = jd->basicblocks;
2135 superblockend = true;
2141 /* iterate over basic blocks *****************************************/
2143 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2145 if (sd.bptr->flags == BBDELETED) {
2146 /* This block has been deleted - do nothing. */
2151 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2152 /* re-analyse a block because its input changed */
2156 if (!stack_reanalyse_block(&sd))
2159 superblockend = true; /* XXX */
2163 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2164 /* This block has not been reached so far, and we
2165 don't fall into it, so we'll have to iterate
2172 if (sd.bptr->flags > BBREACHED) {
2173 /* This block is already finished. */
2175 superblockend = true;
2179 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2180 /* This block is a clone and the original has not been
2181 analysed, yet. Analyse it on the next
2185 /* XXX superblockend? */
2189 /* This block has to be analysed now. */
2193 /* XXX The rest of this block is still indented one level too */
2194 /* much in order to avoid a giant diff by changing that. */
2196 /* We know that sd.bptr->flags == BBREACHED. */
2197 /* This block has been reached before. */
2199 assert(sd.bptr->flags == BBREACHED);
2200 stackdepth = sd.bptr->indepth;
2202 /* find exception handlers for this block */
2204 /* determine the active exception handlers for this block */
2205 /* XXX could use a faster algorithm with sorted lists or */
2208 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2211 ex = jd->exceptiontable;
2212 for (; ex != NULL; ex = ex->down) {
2213 if ((ex->start <= original) && (ex->end > original)) {
2214 sd.handlers[len++] = ex;
2217 sd.handlers[len] = NULL;
2220 /* reanalyse cloned block */
2222 if (sd.bptr->original) {
2223 if (!stack_reanalyse_block(&sd))
2228 /* reset the new pointer for allocating stackslots */
2232 /* create the instack of this block */
2234 curstack = stack_create_instack(&sd);
2236 /* initialize locals at the start of this block */
2238 if (sd.bptr->inlocals)
2239 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2241 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2243 /* set up local variables for analyzing this block */
2245 superblockend = false;
2246 len = sd.bptr->icount;
2247 iptr = sd.bptr->iinstr;
2249 /* mark the block as analysed */
2251 sd.bptr->flags = BBFINISHED;
2253 /* reset variables for dependency checking */
2255 coalescing_boundary = sd.new;
2256 for( i = 0; i < m->maxlocals; i++)
2257 last_store_boundary[i] = sd.new;
2259 /* remember the start of this block's variables */
2261 sd.bptr->varstart = sd.vartop;
2263 #if defined(STACK_VERBOSE)
2264 stack_verbose_block_enter(&sd, false);
2267 /* reach exception handlers for this block */
2269 if (!stack_reach_handlers(&sd))
2272 /* iterate over ICMDs ****************************************/
2274 while (--len >= 0) {
2276 #if defined(STACK_VERBOSE)
2277 stack_verbose_show_state(&sd, iptr, curstack);
2280 /* fetch the current opcode */
2284 /* automatically replace some ICMDs with builtins */
2286 bte = builtintable_get_automatic(opcode);
2288 if ((bte != NULL) && (bte->opcode == opcode)) {
2289 iptr->opc = ICMD_BUILTIN;
2290 iptr->flags.bits &= INS_FLAG_ID_MASK;
2291 iptr->sx.s23.s3.bte = bte;
2292 /* iptr->line is already set */
2293 code_unflag_leafmethod(code);
2297 /* main opcode switch *************************************/
2309 case ICMD_CHECKNULL:
2310 coalescing_boundary = sd.new;
2311 COUNT(count_check_null);
2314 iptr->dst.varindex = iptr->s1.varindex;
2318 varindex = iptr->s1.varindex =
2319 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2321 #if defined(ENABLE_VERIFIER)
2322 if (sd.var[varindex].type != TYPE_RET) {
2323 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2330 iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2331 superblockend = true;
2335 COUNT(count_pcmd_return);
2338 superblockend = true;
2339 sd.jd->returncount++;
2340 sd.jd->returnblock = sd.bptr;
2344 /* pop 0 push 1 const */
2346 /************************** ICONST OPTIMIZATIONS **************************/
2349 COUNT(count_pcmd_load);
2353 switch (iptr[1].opc) {
2355 iptr->opc = ICMD_IADDCONST;
2359 iptr[1].opc = ICMD_NOP;
2360 OP1_1(TYPE_INT, TYPE_INT);
2361 COUNT(count_pcmd_op);
2365 iptr->opc = ICMD_ISUBCONST;
2366 goto icmd_iconst_tail;
2367 #if SUPPORT_CONST_MUL
2369 iptr->opc = ICMD_IMULCONST;
2370 goto icmd_iconst_tail;
2371 #else /* SUPPORT_CONST_MUL */
2373 if (iptr->sx.val.i == 0x00000002)
2375 else if (iptr->sx.val.i == 0x00000004)
2377 else if (iptr->sx.val.i == 0x00000008)
2379 else if (iptr->sx.val.i == 0x00000010)
2381 else if (iptr->sx.val.i == 0x00000020)
2383 else if (iptr->sx.val.i == 0x00000040)
2385 else if (iptr->sx.val.i == 0x00000080)
2387 else if (iptr->sx.val.i == 0x00000100)
2389 else if (iptr->sx.val.i == 0x00000200)
2391 else if (iptr->sx.val.i == 0x00000400)
2392 iptr->sx.val.i = 10;
2393 else if (iptr->sx.val.i == 0x00000800)
2394 iptr->sx.val.i = 11;
2395 else if (iptr->sx.val.i == 0x00001000)
2396 iptr->sx.val.i = 12;
2397 else if (iptr->sx.val.i == 0x00002000)
2398 iptr->sx.val.i = 13;
2399 else if (iptr->sx.val.i == 0x00004000)
2400 iptr->sx.val.i = 14;
2401 else if (iptr->sx.val.i == 0x00008000)
2402 iptr->sx.val.i = 15;
2403 else if (iptr->sx.val.i == 0x00010000)
2404 iptr->sx.val.i = 16;
2405 else if (iptr->sx.val.i == 0x00020000)
2406 iptr->sx.val.i = 17;
2407 else if (iptr->sx.val.i == 0x00040000)
2408 iptr->sx.val.i = 18;
2409 else if (iptr->sx.val.i == 0x00080000)
2410 iptr->sx.val.i = 19;
2411 else if (iptr->sx.val.i == 0x00100000)
2412 iptr->sx.val.i = 20;
2413 else if (iptr->sx.val.i == 0x00200000)
2414 iptr->sx.val.i = 21;
2415 else if (iptr->sx.val.i == 0x00400000)
2416 iptr->sx.val.i = 22;
2417 else if (iptr->sx.val.i == 0x00800000)
2418 iptr->sx.val.i = 23;
2419 else if (iptr->sx.val.i == 0x01000000)
2420 iptr->sx.val.i = 24;
2421 else if (iptr->sx.val.i == 0x02000000)
2422 iptr->sx.val.i = 25;
2423 else if (iptr->sx.val.i == 0x04000000)
2424 iptr->sx.val.i = 26;
2425 else if (iptr->sx.val.i == 0x08000000)
2426 iptr->sx.val.i = 27;
2427 else if (iptr->sx.val.i == 0x10000000)
2428 iptr->sx.val.i = 28;
2429 else if (iptr->sx.val.i == 0x20000000)
2430 iptr->sx.val.i = 29;
2431 else if (iptr->sx.val.i == 0x40000000)
2432 iptr->sx.val.i = 30;
2433 else if (iptr->sx.val.i == 0x80000000)
2434 iptr->sx.val.i = 31;
2438 iptr->opc = ICMD_IMULPOW2;
2439 goto icmd_iconst_tail;
2440 #endif /* SUPPORT_CONST_MUL */
2442 if (iptr->sx.val.i == 0x00000002)
2444 else if (iptr->sx.val.i == 0x00000004)
2446 else if (iptr->sx.val.i == 0x00000008)
2448 else if (iptr->sx.val.i == 0x00000010)
2450 else if (iptr->sx.val.i == 0x00000020)
2452 else if (iptr->sx.val.i == 0x00000040)
2454 else if (iptr->sx.val.i == 0x00000080)
2456 else if (iptr->sx.val.i == 0x00000100)
2458 else if (iptr->sx.val.i == 0x00000200)
2460 else if (iptr->sx.val.i == 0x00000400)
2461 iptr->sx.val.i = 10;
2462 else if (iptr->sx.val.i == 0x00000800)
2463 iptr->sx.val.i = 11;
2464 else if (iptr->sx.val.i == 0x00001000)
2465 iptr->sx.val.i = 12;
2466 else if (iptr->sx.val.i == 0x00002000)
2467 iptr->sx.val.i = 13;
2468 else if (iptr->sx.val.i == 0x00004000)
2469 iptr->sx.val.i = 14;
2470 else if (iptr->sx.val.i == 0x00008000)
2471 iptr->sx.val.i = 15;
2472 else if (iptr->sx.val.i == 0x00010000)
2473 iptr->sx.val.i = 16;
2474 else if (iptr->sx.val.i == 0x00020000)
2475 iptr->sx.val.i = 17;
2476 else if (iptr->sx.val.i == 0x00040000)
2477 iptr->sx.val.i = 18;
2478 else if (iptr->sx.val.i == 0x00080000)
2479 iptr->sx.val.i = 19;
2480 else if (iptr->sx.val.i == 0x00100000)
2481 iptr->sx.val.i = 20;
2482 else if (iptr->sx.val.i == 0x00200000)
2483 iptr->sx.val.i = 21;
2484 else if (iptr->sx.val.i == 0x00400000)
2485 iptr->sx.val.i = 22;
2486 else if (iptr->sx.val.i == 0x00800000)
2487 iptr->sx.val.i = 23;
2488 else if (iptr->sx.val.i == 0x01000000)
2489 iptr->sx.val.i = 24;
2490 else if (iptr->sx.val.i == 0x02000000)
2491 iptr->sx.val.i = 25;
2492 else if (iptr->sx.val.i == 0x04000000)
2493 iptr->sx.val.i = 26;
2494 else if (iptr->sx.val.i == 0x08000000)
2495 iptr->sx.val.i = 27;
2496 else if (iptr->sx.val.i == 0x10000000)
2497 iptr->sx.val.i = 28;
2498 else if (iptr->sx.val.i == 0x20000000)
2499 iptr->sx.val.i = 29;
2500 else if (iptr->sx.val.i == 0x40000000)
2501 iptr->sx.val.i = 30;
2502 else if (iptr->sx.val.i == 0x80000000)
2503 iptr->sx.val.i = 31;
2507 iptr->opc = ICMD_IDIVPOW2;
2508 goto icmd_iconst_tail;
2511 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2512 if ((iptr->sx.val.i == 0x00000002) ||
2513 (iptr->sx.val.i == 0x00000004) ||
2514 (iptr->sx.val.i == 0x00000008) ||
2515 (iptr->sx.val.i == 0x00000010) ||
2516 (iptr->sx.val.i == 0x00000020) ||
2517 (iptr->sx.val.i == 0x00000040) ||
2518 (iptr->sx.val.i == 0x00000080) ||
2519 (iptr->sx.val.i == 0x00000100) ||
2520 (iptr->sx.val.i == 0x00000200) ||
2521 (iptr->sx.val.i == 0x00000400) ||
2522 (iptr->sx.val.i == 0x00000800) ||
2523 (iptr->sx.val.i == 0x00001000) ||
2524 (iptr->sx.val.i == 0x00002000) ||
2525 (iptr->sx.val.i == 0x00004000) ||
2526 (iptr->sx.val.i == 0x00008000) ||
2527 (iptr->sx.val.i == 0x00010000) ||
2528 (iptr->sx.val.i == 0x00020000) ||
2529 (iptr->sx.val.i == 0x00040000) ||
2530 (iptr->sx.val.i == 0x00080000) ||
2531 (iptr->sx.val.i == 0x00100000) ||
2532 (iptr->sx.val.i == 0x00200000) ||
2533 (iptr->sx.val.i == 0x00400000) ||
2534 (iptr->sx.val.i == 0x00800000) ||
2535 (iptr->sx.val.i == 0x01000000) ||
2536 (iptr->sx.val.i == 0x02000000) ||
2537 (iptr->sx.val.i == 0x04000000) ||
2538 (iptr->sx.val.i == 0x08000000) ||
2539 (iptr->sx.val.i == 0x10000000) ||
2540 (iptr->sx.val.i == 0x20000000) ||
2541 (iptr->sx.val.i == 0x40000000) ||
2542 (iptr->sx.val.i == 0x80000000))
2544 iptr->opc = ICMD_IREMPOW2;
2545 iptr->sx.val.i -= 1;
2546 goto icmd_iconst_tail;
2549 #if SUPPORT_CONST_LOGICAL
2551 iptr->opc = ICMD_IANDCONST;
2552 goto icmd_iconst_tail;
2555 iptr->opc = ICMD_IORCONST;
2556 goto icmd_iconst_tail;
2559 iptr->opc = ICMD_IXORCONST;
2560 goto icmd_iconst_tail;
2562 #endif /* SUPPORT_CONST_LOGICAL */
2564 iptr->opc = ICMD_ISHLCONST;
2565 goto icmd_iconst_tail;
2568 iptr->opc = ICMD_ISHRCONST;
2569 goto icmd_iconst_tail;
2572 iptr->opc = ICMD_IUSHRCONST;
2573 goto icmd_iconst_tail;
2574 #if SUPPORT_LONG_SHIFT
2576 iptr->opc = ICMD_LSHLCONST;
2577 goto icmd_lconst_tail;
2580 iptr->opc = ICMD_LSHRCONST;
2581 goto icmd_lconst_tail;
2584 iptr->opc = ICMD_LUSHRCONST;
2585 goto icmd_lconst_tail;
2586 #endif /* SUPPORT_LONG_SHIFT */
2587 case ICMD_IF_ICMPEQ:
2588 iptr[1].opc = ICMD_IFEQ;
2592 /* set the constant for the following icmd */
2593 iptr[1].sx.val.i = iptr->sx.val.i;
2595 /* this instruction becomes a nop */
2596 iptr->opc = ICMD_NOP;
2599 case ICMD_IF_ICMPLT:
2600 iptr[1].opc = ICMD_IFLT;
2601 goto icmd_if_icmp_tail;
2603 case ICMD_IF_ICMPLE:
2604 iptr[1].opc = ICMD_IFLE;
2605 goto icmd_if_icmp_tail;
2607 case ICMD_IF_ICMPNE:
2608 iptr[1].opc = ICMD_IFNE;
2609 goto icmd_if_icmp_tail;
2611 case ICMD_IF_ICMPGT:
2612 iptr[1].opc = ICMD_IFGT;
2613 goto icmd_if_icmp_tail;
2615 case ICMD_IF_ICMPGE:
2616 iptr[1].opc = ICMD_IFGE;
2617 goto icmd_if_icmp_tail;
2619 #if SUPPORT_CONST_STORE
2624 # if SUPPORT_CONST_STORE_ZERO_ONLY
2625 if (iptr->sx.val.i != 0)
2628 switch (iptr[1].opc) {
2630 iptr->opc = ICMD_IASTORECONST;
2631 iptr->flags.bits |= INS_FLAG_CHECK;
2634 iptr->opc = ICMD_BASTORECONST;
2635 iptr->flags.bits |= INS_FLAG_CHECK;
2638 iptr->opc = ICMD_CASTORECONST;
2639 iptr->flags.bits |= INS_FLAG_CHECK;
2642 iptr->opc = ICMD_SASTORECONST;
2643 iptr->flags.bits |= INS_FLAG_CHECK;
2647 iptr[1].opc = ICMD_NOP;
2649 /* copy the constant to s3 */
2650 /* XXX constval -> astoreconstval? */
2651 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2652 OP2_0(TYPE_ADR, TYPE_INT);
2653 COUNT(count_pcmd_op);
2656 case ICMD_PUTSTATIC:
2658 # if SUPPORT_CONST_STORE_ZERO_ONLY
2659 if (iptr->sx.val.i != 0)
2662 /* XXX check field type? */
2664 /* copy the constant to s2 */
2665 /* XXX constval -> fieldconstval? */
2666 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2669 /* set the field reference (s3) */
2670 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2671 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2672 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2673 fmiref = iptr->sx.s23.s3.uf->fieldref;
2676 fmiref = iptr[1].sx.s23.s3.fmiref;
2677 iptr->sx.s23.s3.fmiref = fmiref;
2680 #if defined(ENABLE_VERIFIER)
2681 expectedtype = fmiref->parseddesc.fd->type;
2682 switch (iptr[0].opc) {
2684 if (expectedtype != TYPE_INT)
2685 goto throw_stack_type_error;
2688 if (expectedtype != TYPE_LNG)
2689 goto throw_stack_type_error;
2692 if (expectedtype != TYPE_ADR)
2693 goto throw_stack_type_error;
2698 #endif /* defined(ENABLE_VERIFIER) */
2700 switch (iptr[1].opc) {
2701 case ICMD_PUTSTATIC:
2702 iptr->opc = ICMD_PUTSTATICCONST;
2706 iptr->opc = ICMD_PUTFIELDCONST;
2711 iptr[1].opc = ICMD_NOP;
2712 COUNT(count_pcmd_op);
2714 #endif /* SUPPORT_CONST_STORE */
2720 /* if we get here, the ICONST has been optimized */
2724 /* normal case of an unoptimized ICONST */
2728 /************************** LCONST OPTIMIZATIONS **************************/
2731 COUNT(count_pcmd_load);
2735 /* switch depending on the following instruction */
2737 switch (iptr[1].opc) {
2738 #if SUPPORT_LONG_ADD
2740 iptr->opc = ICMD_LADDCONST;
2744 /* instruction of type LONG -> LONG */
2745 iptr[1].opc = ICMD_NOP;
2746 OP1_1(TYPE_LNG, TYPE_LNG);
2747 COUNT(count_pcmd_op);
2751 iptr->opc = ICMD_LSUBCONST;
2752 goto icmd_lconst_tail;
2754 #endif /* SUPPORT_LONG_ADD */
2755 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2757 iptr->opc = ICMD_LMULCONST;
2758 goto icmd_lconst_tail;
2759 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2760 # if SUPPORT_LONG_SHIFT
2762 if (iptr->sx.val.l == 0x00000002)
2764 else if (iptr->sx.val.l == 0x00000004)
2766 else if (iptr->sx.val.l == 0x00000008)
2768 else if (iptr->sx.val.l == 0x00000010)
2770 else if (iptr->sx.val.l == 0x00000020)
2772 else if (iptr->sx.val.l == 0x00000040)
2774 else if (iptr->sx.val.l == 0x00000080)
2776 else if (iptr->sx.val.l == 0x00000100)
2778 else if (iptr->sx.val.l == 0x00000200)
2780 else if (iptr->sx.val.l == 0x00000400)
2781 iptr->sx.val.i = 10;
2782 else if (iptr->sx.val.l == 0x00000800)
2783 iptr->sx.val.i = 11;
2784 else if (iptr->sx.val.l == 0x00001000)
2785 iptr->sx.val.i = 12;
2786 else if (iptr->sx.val.l == 0x00002000)
2787 iptr->sx.val.i = 13;
2788 else if (iptr->sx.val.l == 0x00004000)
2789 iptr->sx.val.i = 14;
2790 else if (iptr->sx.val.l == 0x00008000)
2791 iptr->sx.val.i = 15;
2792 else if (iptr->sx.val.l == 0x00010000)
2793 iptr->sx.val.i = 16;
2794 else if (iptr->sx.val.l == 0x00020000)
2795 iptr->sx.val.i = 17;
2796 else if (iptr->sx.val.l == 0x00040000)
2797 iptr->sx.val.i = 18;
2798 else if (iptr->sx.val.l == 0x00080000)
2799 iptr->sx.val.i = 19;
2800 else if (iptr->sx.val.l == 0x00100000)
2801 iptr->sx.val.i = 20;
2802 else if (iptr->sx.val.l == 0x00200000)
2803 iptr->sx.val.i = 21;
2804 else if (iptr->sx.val.l == 0x00400000)
2805 iptr->sx.val.i = 22;
2806 else if (iptr->sx.val.l == 0x00800000)
2807 iptr->sx.val.i = 23;
2808 else if (iptr->sx.val.l == 0x01000000)
2809 iptr->sx.val.i = 24;
2810 else if (iptr->sx.val.l == 0x02000000)
2811 iptr->sx.val.i = 25;
2812 else if (iptr->sx.val.l == 0x04000000)
2813 iptr->sx.val.i = 26;
2814 else if (iptr->sx.val.l == 0x08000000)
2815 iptr->sx.val.i = 27;
2816 else if (iptr->sx.val.l == 0x10000000)
2817 iptr->sx.val.i = 28;
2818 else if (iptr->sx.val.l == 0x20000000)
2819 iptr->sx.val.i = 29;
2820 else if (iptr->sx.val.l == 0x40000000)
2821 iptr->sx.val.i = 30;
2822 else if (iptr->sx.val.l == 0x80000000)
2823 iptr->sx.val.i = 31;
2827 iptr->opc = ICMD_LMULPOW2;
2828 goto icmd_lconst_tail;
2829 # endif /* SUPPORT_LONG_SHIFT */
2830 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2831 #if SUPPORT_LONG_DIV_POW2
2833 if (iptr->sx.val.l == 0x00000002)
2835 else if (iptr->sx.val.l == 0x00000004)
2837 else if (iptr->sx.val.l == 0x00000008)
2839 else if (iptr->sx.val.l == 0x00000010)
2841 else if (iptr->sx.val.l == 0x00000020)
2843 else if (iptr->sx.val.l == 0x00000040)
2845 else if (iptr->sx.val.l == 0x00000080)
2847 else if (iptr->sx.val.l == 0x00000100)
2849 else if (iptr->sx.val.l == 0x00000200)
2851 else if (iptr->sx.val.l == 0x00000400)
2852 iptr->sx.val.i = 10;
2853 else if (iptr->sx.val.l == 0x00000800)
2854 iptr->sx.val.i = 11;
2855 else if (iptr->sx.val.l == 0x00001000)
2856 iptr->sx.val.i = 12;
2857 else if (iptr->sx.val.l == 0x00002000)
2858 iptr->sx.val.i = 13;
2859 else if (iptr->sx.val.l == 0x00004000)
2860 iptr->sx.val.i = 14;
2861 else if (iptr->sx.val.l == 0x00008000)
2862 iptr->sx.val.i = 15;
2863 else if (iptr->sx.val.l == 0x00010000)
2864 iptr->sx.val.i = 16;
2865 else if (iptr->sx.val.l == 0x00020000)
2866 iptr->sx.val.i = 17;
2867 else if (iptr->sx.val.l == 0x00040000)
2868 iptr->sx.val.i = 18;
2869 else if (iptr->sx.val.l == 0x00080000)
2870 iptr->sx.val.i = 19;
2871 else if (iptr->sx.val.l == 0x00100000)
2872 iptr->sx.val.i = 20;
2873 else if (iptr->sx.val.l == 0x00200000)
2874 iptr->sx.val.i = 21;
2875 else if (iptr->sx.val.l == 0x00400000)
2876 iptr->sx.val.i = 22;
2877 else if (iptr->sx.val.l == 0x00800000)
2878 iptr->sx.val.i = 23;
2879 else if (iptr->sx.val.l == 0x01000000)
2880 iptr->sx.val.i = 24;
2881 else if (iptr->sx.val.l == 0x02000000)
2882 iptr->sx.val.i = 25;
2883 else if (iptr->sx.val.l == 0x04000000)
2884 iptr->sx.val.i = 26;
2885 else if (iptr->sx.val.l == 0x08000000)
2886 iptr->sx.val.i = 27;
2887 else if (iptr->sx.val.l == 0x10000000)
2888 iptr->sx.val.i = 28;
2889 else if (iptr->sx.val.l == 0x20000000)
2890 iptr->sx.val.i = 29;
2891 else if (iptr->sx.val.l == 0x40000000)
2892 iptr->sx.val.i = 30;
2893 else if (iptr->sx.val.l == 0x80000000)
2894 iptr->sx.val.i = 31;
2898 iptr->opc = ICMD_LDIVPOW2;
2899 goto icmd_lconst_tail;
2900 #endif /* SUPPORT_LONG_DIV_POW2 */
2902 #if SUPPORT_LONG_REM_POW2
2904 if ((iptr->sx.val.l == 0x00000002) ||
2905 (iptr->sx.val.l == 0x00000004) ||
2906 (iptr->sx.val.l == 0x00000008) ||
2907 (iptr->sx.val.l == 0x00000010) ||
2908 (iptr->sx.val.l == 0x00000020) ||
2909 (iptr->sx.val.l == 0x00000040) ||
2910 (iptr->sx.val.l == 0x00000080) ||
2911 (iptr->sx.val.l == 0x00000100) ||
2912 (iptr->sx.val.l == 0x00000200) ||
2913 (iptr->sx.val.l == 0x00000400) ||
2914 (iptr->sx.val.l == 0x00000800) ||
2915 (iptr->sx.val.l == 0x00001000) ||
2916 (iptr->sx.val.l == 0x00002000) ||
2917 (iptr->sx.val.l == 0x00004000) ||
2918 (iptr->sx.val.l == 0x00008000) ||
2919 (iptr->sx.val.l == 0x00010000) ||
2920 (iptr->sx.val.l == 0x00020000) ||
2921 (iptr->sx.val.l == 0x00040000) ||
2922 (iptr->sx.val.l == 0x00080000) ||
2923 (iptr->sx.val.l == 0x00100000) ||
2924 (iptr->sx.val.l == 0x00200000) ||
2925 (iptr->sx.val.l == 0x00400000) ||
2926 (iptr->sx.val.l == 0x00800000) ||
2927 (iptr->sx.val.l == 0x01000000) ||
2928 (iptr->sx.val.l == 0x02000000) ||
2929 (iptr->sx.val.l == 0x04000000) ||
2930 (iptr->sx.val.l == 0x08000000) ||
2931 (iptr->sx.val.l == 0x10000000) ||
2932 (iptr->sx.val.l == 0x20000000) ||
2933 (iptr->sx.val.l == 0x40000000) ||
2934 (iptr->sx.val.l == 0x80000000))
2936 iptr->opc = ICMD_LREMPOW2;
2937 iptr->sx.val.l -= 1;
2938 goto icmd_lconst_tail;
2941 #endif /* SUPPORT_LONG_REM_POW2 */
2943 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2946 iptr->opc = ICMD_LANDCONST;
2947 goto icmd_lconst_tail;
2950 iptr->opc = ICMD_LORCONST;
2951 goto icmd_lconst_tail;
2954 iptr->opc = ICMD_LXORCONST;
2955 goto icmd_lconst_tail;
2956 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2958 #if SUPPORT_LONG_CMP_CONST
2960 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2963 /* switch on the instruction after LCONST - LCMP */
2965 switch (iptr[2].opc) {
2967 iptr->opc = ICMD_IF_LEQ;
2970 icmd_lconst_lcmp_tail:
2971 /* convert LCONST, LCMP, IFXX to IF_LXX */
2972 iptr->dst.block = iptr[2].dst.block;
2973 iptr[1].opc = ICMD_NOP;
2974 iptr[2].opc = ICMD_NOP;
2976 OP1_BRANCH(TYPE_LNG);
2978 COUNT(count_pcmd_bra);
2979 COUNT(count_pcmd_op);
2983 iptr->opc = ICMD_IF_LNE;
2984 goto icmd_lconst_lcmp_tail;
2987 iptr->opc = ICMD_IF_LLT;
2988 goto icmd_lconst_lcmp_tail;
2991 iptr->opc = ICMD_IF_LGT;
2992 goto icmd_lconst_lcmp_tail;
2995 iptr->opc = ICMD_IF_LLE;
2996 goto icmd_lconst_lcmp_tail;
2999 iptr->opc = ICMD_IF_LGE;
3000 goto icmd_lconst_lcmp_tail;
3004 } /* end switch on opcode after LCONST - LCMP */
3006 #endif /* SUPPORT_LONG_CMP_CONST */
3008 #if SUPPORT_CONST_STORE
3010 # if SUPPORT_CONST_STORE_ZERO_ONLY
3011 if (iptr->sx.val.l != 0)
3014 #if SIZEOF_VOID_P == 4
3015 /* the constant must fit into a ptrint */
3016 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3019 /* move the constant to s3 */
3020 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3022 iptr->opc = ICMD_LASTORECONST;
3023 iptr->flags.bits |= INS_FLAG_CHECK;
3024 OP2_0(TYPE_ADR, TYPE_INT);
3026 iptr[1].opc = ICMD_NOP;
3027 COUNT(count_pcmd_op);
3030 case ICMD_PUTSTATIC:
3032 # if SUPPORT_CONST_STORE_ZERO_ONLY
3033 if (iptr->sx.val.l != 0)
3036 #if SIZEOF_VOID_P == 4
3037 /* the constant must fit into a ptrint */
3038 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3041 /* XXX check field type? */
3043 /* copy the constant to s2 */
3044 /* XXX constval -> fieldconstval? */
3045 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3049 #endif /* SUPPORT_CONST_STORE */
3053 } /* end switch opcode after LCONST */
3055 /* if we get here, the LCONST has been optimized */
3059 /* the normal case of an unoptimized LCONST */
3063 /************************ END OF LCONST OPTIMIZATIONS *********************/
3066 COUNT(count_pcmd_load);
3071 COUNT(count_pcmd_load);
3075 /************************** ACONST OPTIMIZATIONS **************************/
3078 coalescing_boundary = sd.new;
3079 COUNT(count_pcmd_load);
3080 #if SUPPORT_CONST_STORE
3081 /* We can only optimize if the ACONST is resolved
3082 * and there is an instruction after it. */
3084 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3087 switch (iptr[1].opc) {
3089 /* We can only optimize for NULL values
3090 * here because otherwise a checkcast is
3092 if (iptr->sx.val.anyptr != NULL)
3095 /* copy the constant (NULL) to s3 */
3096 iptr->sx.s23.s3.constval = 0;
3097 iptr->opc = ICMD_AASTORECONST;
3098 iptr->flags.bits |= INS_FLAG_CHECK;
3099 OP2_0(TYPE_ADR, TYPE_INT);
3101 iptr[1].opc = ICMD_NOP;
3102 COUNT(count_pcmd_op);
3105 case ICMD_PUTSTATIC:
3107 # if SUPPORT_CONST_STORE_ZERO_ONLY
3108 if (iptr->sx.val.anyptr != NULL)
3111 /* XXX check field type? */
3112 /* copy the constant to s2 */
3113 /* XXX constval -> fieldconstval? */
3114 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3122 /* if we get here the ACONST has been optimized */
3126 #endif /* SUPPORT_CONST_STORE */
3131 /* pop 0 push 1 load */
3138 COUNT(count_load_instruction);
3139 type = opcode - ICMD_ILOAD;
3141 varindex = iptr->s1.varindex =
3142 jd->local_map[iptr->s1.varindex * 5 + type];
3144 #if defined(ENABLE_VERIFIER)
3145 if (sd.var[varindex].type == TYPE_RET) {
3146 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3150 LOAD(type, varindex);
3159 coalescing_boundary = sd.new;
3160 iptr->flags.bits |= INS_FLAG_CHECK;
3161 COUNT(count_check_null);
3162 COUNT(count_check_bound);
3163 COUNT(count_pcmd_mem);
3164 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3171 coalescing_boundary = sd.new;
3172 iptr->flags.bits |= INS_FLAG_CHECK;
3173 COUNT(count_check_null);
3174 COUNT(count_check_bound);
3175 COUNT(count_pcmd_mem);
3176 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3179 /* pop 0 push 0 iinc */
3182 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3183 javaindex = iptr->s1.varindex;
3184 last_store_boundary[javaindex] = sd.new;
3187 jd->local_map[javaindex * 5 + TYPE_INT];
3192 if ((copy->varkind == LOCALVAR) &&
3193 (jd->reverselocalmap[copy->varnum] == javaindex))
3195 assert(IS_LOCALVAR(copy));
3202 iptr->dst.varindex = iptr->s1.varindex;
3205 /* pop 1 push 0 store */
3214 type = opcode - ICMD_ISTORE;
3215 javaindex = iptr->dst.varindex;
3216 varindex = iptr->dst.varindex =
3217 jd->local_map[javaindex * 5 + type];
3219 COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3221 iptr->sx.s23.s3.javaindex = javaindex;
3223 if (curstack->type == TYPE_RET) {
3224 iptr->flags.bits |= INS_FLAG_RETADDR;
3225 iptr->sx.s23.s2.retaddrnr =
3226 JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3227 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3230 sd.javalocals[javaindex] = varindex;
3232 /* invalidate the following javalocal for 2-word types */
3234 if (IS_2_WORD_TYPE(type)) {
3235 sd.javalocals[javaindex+1] = UNUSED;
3236 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3239 /* invalidate 2-word types if second half was overwritten */
3241 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
3242 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3243 sd.javalocals[javaindex-1] = UNUSED;
3244 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3248 #if defined(ENABLE_STATISTICS)
3251 i = sd.new - curstack;
3253 count_store_length[20]++;
3255 count_store_length[i]++;
3258 count_store_depth[10]++;
3260 count_store_depth[i]++;
3264 /* check for conflicts as described in Figure 5.2 */
3266 copy = curstack->prev;
3269 if ((copy->varkind == LOCALVAR) &&
3270 (jd->reverselocalmap[copy->varnum] == javaindex))
3272 assert(IS_LOCALVAR(copy));
3279 /* if the variable is already coalesced, don't bother */
3281 /* We do not need to check against INOUT, as invars */
3282 /* are always before the coalescing boundary. */
3284 if (curstack->varkind == LOCALVAR)
3287 /* there is no STORE Lj while curstack is live */
3289 if (curstack < last_store_boundary[javaindex])
3290 goto assume_conflict;
3292 /* curstack must be after the coalescing boundary */
3294 if (curstack < coalescing_boundary)
3295 goto assume_conflict;
3297 /* there is no DEF LOCALVAR(varindex) while curstack is live */
3299 copy = sd.new; /* most recent stackslot created + 1 */
3300 while (--copy > curstack) {
3301 if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
3302 goto assume_conflict;
3305 /* coalesce the temporary variable with Lj */
3306 assert((curstack->varkind == TEMPVAR)
3307 || (curstack->varkind == UNDEFVAR));
3308 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3309 assert(!IS_INOUT(curstack));
3310 assert(!IS_PREALLOC(curstack));
3312 assert(curstack->creator);
3313 assert(curstack->creator->dst.varindex == curstack->varnum);
3314 assert(!(curstack->flags & PASSTHROUGH));
3315 RELEASE_INDEX(sd, curstack);
3316 curstack->varkind = LOCALVAR;
3317 curstack->varnum = varindex;
3318 curstack->creator->dst.varindex = varindex;
3321 /* revert the coalescing, if it has been done earlier */
3323 if ((curstack->varkind == LOCALVAR)
3324 && (jd->reverselocalmap[curstack->varnum] == javaindex))
3326 assert(IS_LOCALVAR(curstack));
3327 SET_TEMPVAR(curstack);
3330 /* remember the stack boundary at this store */
3332 last_store_boundary[javaindex] = sd.new;
3334 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3335 STORE(TYPE_RET, varindex);
3337 STORE(opcode - ICMD_ISTORE, varindex);
3343 coalescing_boundary = sd.new;
3344 iptr->flags.bits |= INS_FLAG_CHECK;
3345 COUNT(count_check_null);
3346 COUNT(count_check_bound);
3347 COUNT(count_pcmd_mem);
3349 bte = builtintable_get_internal(BUILTIN_FAST_canstore);
3352 if (md->memuse > rd->memuse)
3353 rd->memuse = md->memuse;
3354 if (md->argintreguse > rd->argintreguse)
3355 rd->argintreguse = md->argintreguse;
3356 /* XXX non-leaf method? */
3358 /* make all stack variables saved */
3362 sd.var[copy->varnum].flags |= SAVEDVAR;
3363 /* in case copy->varnum is/will be a LOCALVAR */
3364 /* once and set back to a non LOCALVAR */
3365 /* the correct SAVEDVAR flag has to be */
3366 /* remembered in copy->flags, too */
3367 copy->flags |= SAVEDVAR;
3371 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3378 coalescing_boundary = sd.new;
3379 iptr->flags.bits |= INS_FLAG_CHECK;
3380 COUNT(count_check_null);
3381 COUNT(count_check_bound);
3382 COUNT(count_pcmd_mem);
3383 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3390 coalescing_boundary = sd.new;
3391 iptr->flags.bits |= INS_FLAG_CHECK;
3392 COUNT(count_check_null);
3393 COUNT(count_check_bound);
3394 COUNT(count_pcmd_mem);
3395 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3401 #ifdef ENABLE_VERIFIER
3404 if (IS_2_WORD_TYPE(curstack->type))
3405 goto throw_stack_category_error;
3416 coalescing_boundary = sd.new;
3417 /* Assert here that no LOCAL or INOUTS get */
3418 /* preallocated, since tha macros are not */
3419 /* available in md-abi.c! */
3420 if (IS_TEMPVAR(curstack))
3421 md_return_alloc(jd, curstack);
3422 COUNT(count_pcmd_return);
3423 OP1_0(opcode - ICMD_IRETURN);
3424 superblockend = true;
3425 sd.jd->returncount++;
3426 sd.jd->returnblock = sd.bptr;
3430 coalescing_boundary = sd.new;
3431 COUNT(count_check_null);
3433 curstack = NULL; stackdepth = 0;
3434 superblockend = true;
3437 case ICMD_PUTSTATIC:
3438 coalescing_boundary = sd.new;
3439 COUNT(count_pcmd_mem);
3440 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3441 OP1_0(fmiref->parseddesc.fd->type);
3444 /* pop 1 push 0 branch */
3447 case ICMD_IFNONNULL:
3448 COUNT(count_pcmd_bra);
3449 OP1_BRANCH(TYPE_ADR);
3459 COUNT(count_pcmd_bra);
3460 /* iptr->sx.val.i is set implicitly in parse by
3461 clearing the memory or from IF_ICMPxx
3464 OP1_BRANCH(TYPE_INT);
3465 /* iptr->sx.val.i = 0; */
3469 /* pop 0 push 0 branch */
3472 COUNT(count_pcmd_bra);
3475 superblockend = true;
3478 /* pop 1 push 0 table branch */
3480 case ICMD_TABLESWITCH:
3481 COUNT(count_pcmd_table);
3482 OP1_BRANCH(TYPE_INT);
3484 table = iptr->dst.table;
3485 BRANCH_TARGET(*table, tbptr);
3488 i = iptr->sx.s23.s3.tablehigh
3489 - iptr->sx.s23.s2.tablelow + 1;
3492 BRANCH_TARGET(*table, tbptr);
3495 superblockend = true;
3498 /* pop 1 push 0 table branch */
3500 case ICMD_LOOKUPSWITCH:
3501 COUNT(count_pcmd_table);
3502 OP1_BRANCH(TYPE_INT);
3504 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3506 lookup = iptr->dst.lookup;
3508 i = iptr->sx.s23.s2.lookupcount;
3511 BRANCH_TARGET(lookup->target, tbptr);
3514 superblockend = true;
3517 case ICMD_MONITORENTER:
3518 case ICMD_MONITOREXIT:
3519 coalescing_boundary = sd.new;
3520 COUNT(count_check_null);
3524 /* pop 2 push 0 branch */
3526 case ICMD_IF_ICMPEQ:
3527 case ICMD_IF_ICMPNE:
3528 case ICMD_IF_ICMPLT:
3529 case ICMD_IF_ICMPGE:
3530 case ICMD_IF_ICMPGT:
3531 case ICMD_IF_ICMPLE:
3532 COUNT(count_pcmd_bra);
3533 OP2_BRANCH(TYPE_INT, TYPE_INT);
3537 case ICMD_IF_ACMPEQ:
3538 case ICMD_IF_ACMPNE:
3539 COUNT(count_pcmd_bra);
3540 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3547 coalescing_boundary = sd.new;
3548 COUNT(count_check_null);
3549 COUNT(count_pcmd_mem);
3550 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3551 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3556 if (!IS_2_WORD_TYPE(curstack->type)) {
3558 #ifdef ENABLE_VERIFIER
3561 if (IS_2_WORD_TYPE(curstack->prev->type))
3562 goto throw_stack_category_error;
3565 OP2_0_ANY_ANY; /* pop two slots */
3568 iptr->opc = ICMD_POP;
3569 OP1_0_ANY; /* pop one (two-word) slot */
3573 /* pop 0 push 1 dup */
3576 #ifdef ENABLE_VERIFIER
3579 if (IS_2_WORD_TYPE(curstack->type))
3580 goto throw_stack_category_error;
3583 COUNT(count_dup_instruction);
3589 coalescing_boundary = sd.new - 1;
3594 if (IS_2_WORD_TYPE(curstack->type)) {
3596 iptr->opc = ICMD_DUP;
3601 /* ..., ????, cat1 */
3602 #ifdef ENABLE_VERIFIER
3604 if (IS_2_WORD_TYPE(curstack->prev->type))
3605 goto throw_stack_category_error;
3608 src1 = curstack->prev;
3611 COPY_UP(src1); iptr++; len--;
3614 coalescing_boundary = sd.new;
3618 /* pop 2 push 3 dup */
3621 #ifdef ENABLE_VERIFIER
3624 if (IS_2_WORD_TYPE(curstack->type) ||
3625 IS_2_WORD_TYPE(curstack->prev->type))
3626 goto throw_stack_category_error;
3631 src1 = curstack->prev;
3636 /* move non-temporary sources out of the way */
3637 if (!IS_TEMPVAR(src2)) {
3638 MOVE_TO_TEMP(src2); iptr++; len--;
3641 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3643 MOVE_UP(src1); iptr++; len--;
3644 MOVE_UP(src2); iptr++; len--;
3646 COPY_DOWN(curstack, dst1);
3648 coalescing_boundary = sd.new;
3653 if (IS_2_WORD_TYPE(curstack->type)) {
3654 /* ..., ????, cat2 */
3655 #ifdef ENABLE_VERIFIER
3657 if (IS_2_WORD_TYPE(curstack->prev->type))
3658 goto throw_stack_category_error;
3661 iptr->opc = ICMD_DUP_X1;
3665 /* ..., ????, cat1 */
3666 #ifdef ENABLE_VERIFIER
3669 if (IS_2_WORD_TYPE(curstack->prev->type)
3670 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3671 goto throw_stack_category_error;
3676 src1 = curstack->prev->prev;
3677 src2 = curstack->prev;
3679 POPANY; POPANY; POPANY;
3682 /* move non-temporary sources out of the way */
3683 if (!IS_TEMPVAR(src2)) {
3684 MOVE_TO_TEMP(src2); iptr++; len--;
3686 if (!IS_TEMPVAR(src3)) {
3687 MOVE_TO_TEMP(src3); iptr++; len--;
3690 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3691 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3693 MOVE_UP(src1); iptr++; len--;
3694 MOVE_UP(src2); iptr++; len--;
3695 MOVE_UP(src3); iptr++; len--;
3697 COPY_DOWN(curstack, dst2); iptr++; len--;
3698 COPY_DOWN(curstack->prev, dst1);
3700 coalescing_boundary = sd.new;
3704 /* pop 3 push 4 dup */
3708 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3709 /* ..., cat2, ???? */
3710 #ifdef ENABLE_VERIFIER
3712 if (IS_2_WORD_TYPE(curstack->type))
3713 goto throw_stack_category_error;
3716 iptr->opc = ICMD_DUP_X1;
3720 /* ..., cat1, ???? */
3721 #ifdef ENABLE_VERIFIER
3724 if (IS_2_WORD_TYPE(curstack->type)
3725 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3726 goto throw_stack_category_error;
3730 src1 = curstack->prev->prev;
3731 src2 = curstack->prev;
3733 POPANY; POPANY; POPANY;
3736 /* move non-temporary sources out of the way */
3737 if (!IS_TEMPVAR(src2)) {
3738 MOVE_TO_TEMP(src2); iptr++; len--;
3740 if (!IS_TEMPVAR(src3)) {
3741 MOVE_TO_TEMP(src3); iptr++; len--;
3744 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3746 MOVE_UP(src1); iptr++; len--;
3747 MOVE_UP(src2); iptr++; len--;
3748 MOVE_UP(src3); iptr++; len--;
3750 COPY_DOWN(curstack, dst1);
3752 coalescing_boundary = sd.new;
3758 if (IS_2_WORD_TYPE(curstack->type)) {
3759 /* ..., ????, cat2 */
3760 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3761 /* ..., cat2, cat2 */
3762 iptr->opc = ICMD_DUP_X1;
3766 /* ..., cat1, cat2 */
3767 #ifdef ENABLE_VERIFIER
3770 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3771 goto throw_stack_category_error;
3774 iptr->opc = ICMD_DUP_X2;
3780 /* ..., ????, ????, cat1 */
3782 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3783 /* ..., cat2, ????, cat1 */
3784 #ifdef ENABLE_VERIFIER
3786 if (IS_2_WORD_TYPE(curstack->prev->type))
3787 goto throw_stack_category_error;
3790 iptr->opc = ICMD_DUP2_X1;
3794 /* ..., cat1, ????, cat1 */
3795 #ifdef ENABLE_VERIFIER
3798 if (IS_2_WORD_TYPE(curstack->prev->type)
3799 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3800 goto throw_stack_category_error;
3804 src1 = curstack->prev->prev->prev;
3805 src2 = curstack->prev->prev;
3806 src3 = curstack->prev;
3808 POPANY; POPANY; POPANY; POPANY;
3811 /* move non-temporary sources out of the way */
3812 if (!IS_TEMPVAR(src2)) {
3813 MOVE_TO_TEMP(src2); iptr++; len--;
3815 if (!IS_TEMPVAR(src3)) {
3816 MOVE_TO_TEMP(src3); iptr++; len--;
3818 if (!IS_TEMPVAR(src4)) {
3819 MOVE_TO_TEMP(src4); iptr++; len--;
3822 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3823 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3825 MOVE_UP(src1); iptr++; len--;
3826 MOVE_UP(src2); iptr++; len--;
3827 MOVE_UP(src3); iptr++; len--;
3828 MOVE_UP(src4); iptr++; len--;
3830 COPY_DOWN(curstack, dst2); iptr++; len--;
3831 COPY_DOWN(curstack->prev, dst1);
3833 coalescing_boundary = sd.new;
3837 /* pop 2 push 2 swap */
3840 #ifdef ENABLE_VERIFIER
3843 if (IS_2_WORD_TYPE(curstack->type)
3844 || IS_2_WORD_TYPE(curstack->prev->type))
3845 goto throw_stack_category_error;
3849 src1 = curstack->prev;
3854 /* move non-temporary sources out of the way */
3855 if (!IS_TEMPVAR(src1)) {
3856 MOVE_TO_TEMP(src1); iptr++; len--;
3859 MOVE_UP(src2); iptr++; len--;
3862 coalescing_boundary = sd.new;
3869 coalescing_boundary = sd.new;
3870 #if !SUPPORT_DIVISION
3871 bte = iptr->sx.s23.s3.bte;
3874 if (md->memuse > rd->memuse)
3875 rd->memuse = md->memuse;
3876 if (md->argintreguse > rd->argintreguse)
3877 rd->argintreguse = md->argintreguse;
3879 /* make all stack variables saved */
3883 sd.var[copy->varnum].flags |= SAVEDVAR;
3884 copy->flags |= SAVEDVAR;
3889 #endif /* !SUPPORT_DIVISION */
3900 COUNT(count_pcmd_op);
3901 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3906 coalescing_boundary = sd.new;
3907 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3908 bte = iptr->sx.s23.s3.bte;
3911 if (md->memuse > rd->memuse)
3912 rd->memuse = md->memuse;
3913 if (md->argintreguse > rd->argintreguse)
3914 rd->argintreguse = md->argintreguse;
3915 /* XXX non-leaf method? */
3917 /* make all stack variables saved */
3921 sd.var[copy->varnum].flags |= SAVEDVAR;
3922 copy->flags |= SAVEDVAR;
3927 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3932 #if SUPPORT_LONG_LOGICAL
3936 #endif /* SUPPORT_LONG_LOGICAL */
3937 COUNT(count_pcmd_op);
3938 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3944 COUNT(count_pcmd_op);
3945 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3953 COUNT(count_pcmd_op);
3954 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3962 COUNT(count_pcmd_op);
3963 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3967 COUNT(count_pcmd_op);
3968 #if SUPPORT_LONG_CMP_CONST
3969 if ((len == 0) || (iptr[1].sx.val.i != 0))
3972 switch (iptr[1].opc) {
3974 iptr->opc = ICMD_IF_LCMPEQ;
3976 iptr->dst.block = iptr[1].dst.block;
3977 iptr[1].opc = ICMD_NOP;
3979 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3982 COUNT(count_pcmd_bra);
3985 iptr->opc = ICMD_IF_LCMPNE;
3986 goto icmd_lcmp_if_tail;
3988 iptr->opc = ICMD_IF_LCMPLT;
3989 goto icmd_lcmp_if_tail;
3991 iptr->opc = ICMD_IF_LCMPGT;
3992 goto icmd_lcmp_if_tail;
3994 iptr->opc = ICMD_IF_LCMPLE;
3995 goto icmd_lcmp_if_tail;
3997 iptr->opc = ICMD_IF_LCMPGE;
3998 goto icmd_lcmp_if_tail;
4004 #endif /* SUPPORT_LONG_CMP_CONST */
4005 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4010 COUNT(count_pcmd_op);
4011 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4016 COUNT(count_pcmd_op);
4017 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4025 case ICMD_INT2SHORT:
4026 COUNT(count_pcmd_op);
4027 OP1_1(TYPE_INT, TYPE_INT);
4030 COUNT(count_pcmd_op);
4031 OP1_1(TYPE_LNG, TYPE_LNG);
4034 COUNT(count_pcmd_op);
4035 OP1_1(TYPE_FLT, TYPE_FLT);
4038 COUNT(count_pcmd_op);
4039 OP1_1(TYPE_DBL, TYPE_DBL);
4043 COUNT(count_pcmd_op);
4044 OP1_1(TYPE_INT, TYPE_LNG);
4047 COUNT(count_pcmd_op);
4048 OP1_1(TYPE_INT, TYPE_FLT);
4051 COUNT(count_pcmd_op);
4052 OP1_1(TYPE_INT, TYPE_DBL);
4055 COUNT(count_pcmd_op);
4056 OP1_1(TYPE_LNG, TYPE_INT);
4059 COUNT(count_pcmd_op);
4060 OP1_1(TYPE_LNG, TYPE_FLT);
4063 COUNT(count_pcmd_op);
4064 OP1_1(TYPE_LNG, TYPE_DBL);
4067 COUNT(count_pcmd_op);
4068 OP1_1(TYPE_FLT, TYPE_INT);
4071 COUNT(count_pcmd_op);
4072 OP1_1(TYPE_FLT, TYPE_LNG);
4075 COUNT(count_pcmd_op);
4076 OP1_1(TYPE_FLT, TYPE_DBL);
4079 COUNT(count_pcmd_op);
4080 OP1_1(TYPE_DBL, TYPE_INT);
4083 COUNT(count_pcmd_op);
4084 OP1_1(TYPE_DBL, TYPE_LNG);
4087 COUNT(count_pcmd_op);
4088 OP1_1(TYPE_DBL, TYPE_FLT);
4091 case ICMD_CHECKCAST:
4092 coalescing_boundary = sd.new;
4093 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4094 /* array type cast-check */
4096 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4099 if (md->memuse > rd->memuse)
4100 rd->memuse = md->memuse;
4101 if (md->argintreguse > rd->argintreguse)
4102 rd->argintreguse = md->argintreguse;
4104 /* make all stack variables saved */
4108 sd.var[copy->varnum].flags |= SAVEDVAR;
4109 copy->flags |= SAVEDVAR;
4113 OP1_1(TYPE_ADR, TYPE_ADR);
4116 case ICMD_INSTANCEOF:
4117 case ICMD_ARRAYLENGTH:
4118 coalescing_boundary = sd.new;
4119 OP1_1(TYPE_ADR, TYPE_INT);
4123 case ICMD_ANEWARRAY:
4124 coalescing_boundary = sd.new;
4125 OP1_1(TYPE_INT, TYPE_ADR);
4129 coalescing_boundary = sd.new;
4130 COUNT(count_check_null);
4131 COUNT(count_pcmd_mem);
4132 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4133 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4138 case ICMD_GETSTATIC:
4139 coalescing_boundary = sd.new;
4140 COUNT(count_pcmd_mem);
4141 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4142 OP0_1(fmiref->parseddesc.fd->type);
4146 coalescing_boundary = sd.new;
4153 tbptr = iptr->sx.s23.s3.jsrtarget.block;
4154 tbptr->type = BBTYPE_SBR;
4156 assert(sd.bptr->next); /* XXX exception */
4157 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4158 #if defined(ENABLE_VERIFIER)
4159 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4162 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4166 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4168 /* We need to check for overflow right here because
4169 * the pushed value is poped afterwards */
4172 superblockend = true;
4173 /* XXX should not be marked as interface, as it does not need to be */
4174 /* allocated. Same for the invar of the target. */
4177 /* pop many push any */
4181 bte = iptr->sx.s23.s3.bte;
4185 case ICMD_INVOKESTATIC:
4186 case ICMD_INVOKESPECIAL:
4187 case ICMD_INVOKEVIRTUAL:
4188 case ICMD_INVOKEINTERFACE:
4189 COUNT(count_pcmd_met);
4191 /* Check for functions to replace with builtin
4194 if (builtintable_replace_function(iptr))
4197 INSTRUCTION_GET_METHODDESC(iptr, md);
4198 /* XXX resurrect this COUNT? */
4199 /* if (lm->flags & ACC_STATIC) */
4200 /* {COUNT(count_check_null);} */
4204 coalescing_boundary = sd.new;
4208 if (md->memuse > rd->memuse)
4209 rd->memuse = md->memuse;
4210 if (md->argintreguse > rd->argintreguse)
4211 rd->argintreguse = md->argintreguse;
4212 if (md->argfltreguse > rd->argfltreguse)
4213 rd->argfltreguse = md->argfltreguse;
4217 iptr->s1.argcount = stackdepth;
4218 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4221 for (i-- ; i >= 0; i--) {
4222 iptr->sx.s23.s2.args[i] = copy->varnum;
4224 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4225 /* -> won't help anyway */
4226 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4228 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4229 /* If we pass float arguments in integer argument registers, we
4230 * are not allowed to precolor them here. Floats have to be moved
4231 * to this regs explicitly in codegen().
4232 * Only arguments that are passed by stack anyway can be precolored
4233 * (michi 2005/07/24) */
4234 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4235 (!IS_FLT_DBL_TYPE(copy->type)
4236 || md->params[i].inmemory)) {
4238 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4243 if (md->params[i].inmemory) {
4244 sd.var[copy->varnum].vv.regoff =
4245 md->params[i].regoff;
4246 sd.var[copy->varnum].flags |=
4250 if (IS_FLT_DBL_TYPE(copy->type)) {
4251 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4252 assert(0); /* XXX is this assert ok? */
4254 sd.var[copy->varnum].vv.regoff =
4255 md->params[i].regoff;
4256 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4259 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4260 if (IS_2_WORD_TYPE(copy->type))
4261 sd.var[copy->varnum].vv.regoff =
4262 PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4263 GET_HIGH_REG(md->params[i].regoff));
4266 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4267 sd.var[copy->varnum].vv.regoff =
4268 md->params[i].regoff;
4276 /* deal with live-through stack slots "under" the */
4282 iptr->sx.s23.s2.args[i++] = copy->varnum;
4283 sd.var[copy->varnum].flags |= SAVEDVAR;
4284 copy->flags |= SAVEDVAR | PASSTHROUGH;
4288 /* pop the arguments */
4297 /* push the return value */
4299 if (md->returntype.type != TYPE_VOID) {
4300 GET_NEW_VAR(sd, new_index, md->returntype.type);
4301 DST(md->returntype.type, new_index);
4306 case ICMD_MULTIANEWARRAY:
4307 coalescing_boundary = sd.new;
4308 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4309 rd->argintreguse = MIN(3, INT_ARG_CNT);
4311 i = iptr->s1.argcount;
4315 iptr->sx.s23.s2.args = DMNEW(s4, i);
4317 #if defined(SPECIALMEMUSE)
4318 # if defined(__DARWIN__)
4319 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4320 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4322 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4323 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4326 # if defined(__I386__)
4327 if (rd->memuse < i + 3)
4328 rd->memuse = i + 3; /* n integer args spilled on stack */
4329 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4330 if (rd->memuse < i + 2)
4331 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4334 rd->memuse = i; /* n integer args spilled on stack */
4335 # endif /* defined(__I386__) */
4339 /* check INT type here? Currently typecheck does this. */
4340 iptr->sx.s23.s2.args[i] = copy->varnum;
4341 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4342 && (!IS_INOUT(copy))
4343 && (!IS_LOCALVAR(copy)) ) {
4344 copy->varkind = ARGVAR;
4345 sd.var[copy->varnum].flags |=
4346 INMEMORY & PREALLOC;
4347 #if defined(SPECIALMEMUSE)
4348 # if defined(__DARWIN__)
4349 sd.var[copy->varnum].vv.regoff = i +
4350 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4352 sd.var[copy->varnum].vv.regoff = i +
4353 LA_SIZE_IN_POINTERS + 3;
4356 # if defined(__I386__)
4357 sd.var[copy->varnum].vv.regoff = i + 3;
4358 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4359 sd.var[copy->varnum].vv.regoff = i + 2;
4361 sd.var[copy->varnum].vv.regoff = i;
4362 # endif /* defined(__I386__) */
4363 #endif /* defined(SPECIALMEMUSE) */
4368 sd.var[copy->varnum].flags |= SAVEDVAR;
4369 copy->flags |= SAVEDVAR;
4373 i = iptr->s1.argcount;
4378 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4379 DST(TYPE_ADR, new_index);
4384 exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4391 } /* while instructions */
4393 /* show state after last instruction */
4395 #if defined(STACK_VERBOSE)
4396 stack_verbose_show_state(&sd, NULL, curstack);
4399 /* stack slots at basic block end become interfaces */
4401 sd.bptr->outdepth = stackdepth;
4402 sd.bptr->outvars = DMNEW(s4, stackdepth);
4405 for (copy = curstack; copy; i--, copy = copy->prev) {
4408 /* with the new vars rd->interfaces will be removed */
4409 /* and all in and outvars have to be STACKVARS! */
4410 /* in the moment i.e. SWAP with in and out vars can */
4411 /* create an unresolvable conflict */
4416 v = sd.var + copy->varnum;
4419 /* do not allocate variables for returnAddresses */
4421 if (type != TYPE_RET) {
4422 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4423 /* no interface var until now for this depth and */
4425 jd->interface_map[i*5 + type].flags = v->flags;
4428 jd->interface_map[i*5 + type].flags |= v->flags;
4432 sd.bptr->outvars[i] = copy->varnum;
4435 /* check if interface slots at basic block begin must be saved */
4437 for (i=0; i<sd.bptr->indepth; ++i) {
4438 varinfo *v = sd.var + sd.bptr->invars[i];
4442 if (type != TYPE_RET) {
4443 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4444 /* no interface var until now for this depth and */
4446 jd->interface_map[i*5 + type].flags = v->flags;
4449 jd->interface_map[i*5 + type].flags |= v->flags;
4454 /* store the number of this block's variables */
4456 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4458 #if defined(STACK_VERBOSE)
4459 stack_verbose_block_exit(&sd, superblockend);
4462 /* reach the following block, if any */
4465 if (!stack_reach_next_block(&sd))
4470 } while (sd.repeat && !deadcode);
4472 /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4474 /* A local variable may be used as both a returnAddress and a reference */
4475 /* type variable, as we do not split variables between these types when */
4476 /* renaming locals. While returnAddresses have been eliminated now, we */
4477 /* must assume that the variable is still used as TYPE_ADR. */
4478 /* The only way that a local can be TYPE_VOID at this point, is that it */
4479 /* was a TYPE_RET variable for which incompatible returnAddresses were */
4480 /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4482 /* XXX: It would be nice to remove otherwise unused returnAddress */
4483 /* variables from the local variable array, so they are not */
4484 /* allocated by simplereg. (For LSRA this is not needed). */
4486 for (i=0; i<sd.localcount; ++i) {
4487 if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4488 sd.var[i].type = TYPE_ADR;
4491 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4493 for (i=sd.localcount; i<sd.vartop; ++i) {
4494 if (sd.var[i].type == TYPE_RET)
4495 sd.var[i].flags |= PREALLOC;
4498 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4500 ex = jd->exceptiontable;
4501 for (; ex != NULL; ex = ex->down) {
4502 if (ex->start == ex->end) {
4503 assert(ex->end->next);
4504 ex->end = ex->end->next;
4508 /* store number of created variables */
4510 jd->vartop = sd.vartop;
4512 /* gather statistics *****************************************************/
4514 #if defined(ENABLE_STATISTICS)
4516 if (jd->basicblockcount > count_max_basic_blocks)
4517 count_max_basic_blocks = jd->basicblockcount;
4518 count_basic_blocks += jd->basicblockcount;
4519 if (jd->instructioncount > count_max_javainstr)
4520 count_max_javainstr = jd->instructioncount;
4521 count_javainstr += jd->instructioncount;
4522 if (jd->stackcount > count_upper_bound_new_stack)
4523 count_upper_bound_new_stack = jd->stackcount;
4524 if ((sd.new - jd->stack) > count_max_new_stack)
4525 count_max_new_stack = (sd.new - jd->stack);
4527 sd.bptr = jd->basicblocks;
4528 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4529 if (sd.bptr->flags > BBREACHED) {
4530 if (sd.bptr->indepth >= 10)
4531 count_block_stack[10]++;
4533 count_block_stack[sd.bptr->indepth]++;
4534 len = sd.bptr->icount;
4536 count_block_size_distribution[len]++;
4538 count_block_size_distribution[10]++;
4540 count_block_size_distribution[11]++;
4542 count_block_size_distribution[12]++;
4544 count_block_size_distribution[13]++;
4546 count_block_size_distribution[14]++;
4548 count_block_size_distribution[15]++;
4550 count_block_size_distribution[16]++;
4552 count_block_size_distribution[17]++;
4556 if (iteration_count == 1)
4557 count_analyse_iterations[0]++;
4558 else if (iteration_count == 2)
4559 count_analyse_iterations[1]++;
4560 else if (iteration_count == 3)
4561 count_analyse_iterations[2]++;
4562 else if (iteration_count == 4)
4563 count_analyse_iterations[3]++;
4565 count_analyse_iterations[4]++;
4567 if (jd->basicblockcount <= 5)
4568 count_method_bb_distribution[0]++;
4569 else if (jd->basicblockcount <= 10)
4570 count_method_bb_distribution[1]++;
4571 else if (jd->basicblockcount <= 15)
4572 count_method_bb_distribution[2]++;
4573 else if (jd->basicblockcount <= 20)
4574 count_method_bb_distribution[3]++;
4575 else if (jd->basicblockcount <= 30)
4576 count_method_bb_distribution[4]++;
4577 else if (jd->basicblockcount <= 40)
4578 count_method_bb_distribution[5]++;
4579 else if (jd->basicblockcount <= 50)
4580 count_method_bb_distribution[6]++;
4581 else if (jd->basicblockcount <= 75)
4582 count_method_bb_distribution[7]++;
4584 count_method_bb_distribution[8]++;
4586 #endif /* defined(ENABLE_STATISTICS) */
4588 /* everything's ok *******************************************************/
4592 /* goto labels for throwing verifier exceptions **************************/
4594 #if defined(ENABLE_VERIFIER)
4596 throw_stack_underflow:
4597 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4600 throw_stack_overflow:
4601 exceptions_throw_verifyerror(m, "Stack size too large");
4604 throw_stack_type_error:
4605 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4608 throw_stack_category_error:
4609 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4616 /* stack_javalocals_store ******************************************************
4618 Model the effect of a ?STORE instruction upon the given javalocals array.
4621 iptr.............the ?STORE instruction
4622 javalocals.......the javalocals array to modify
4624 *******************************************************************************/
4626 void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4628 s4 varindex; /* index into the jd->var array */
4629 s4 javaindex; /* java local index */
4631 varindex = iptr->dst.varindex;
4632 javaindex = iptr->sx.s23.s3.javaindex;
4634 if (javaindex != UNUSED) {
4635 assert(javaindex >= 0);
4636 if (iptr->flags.bits & INS_FLAG_RETADDR)
4637 javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4639 javalocals[javaindex] = varindex;
4641 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4642 javalocals[javaindex-1] = UNUSED;
4644 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4645 javalocals[javaindex+1] = UNUSED;
4650 /* functions for verbose stack analysis output ********************************/
4652 #if defined(STACK_VERBOSE)
4653 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4655 printf("%c", show_jit_type_letters[v->type]);
4656 if (v->type == TYPE_RET) {
4657 printf("{L%03d}", v->vv.retaddr->nr);
4658 #if defined(ENABLE_VERIFIER)
4659 printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4665 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4667 assert(index >= 0 && index < sd->vartop);
4668 stack_verbose_show_varinfo(sd, sd->var + index);
4672 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4676 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4678 for (i=0; i<bptr->indepth; ++i) {
4681 stack_verbose_show_variable(sd, bptr->invars[i]);
4686 printf("] javalocals ");
4687 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4688 printf(" inlocals [");
4689 if (bptr->inlocals) {
4690 for (i=0; i<sd->localcount; ++i) {
4693 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4698 printf("] out:%d [", bptr->outdepth);
4699 if (bptr->outvars) {
4700 for (i=0; i<bptr->outdepth; ++i) {
4703 stack_verbose_show_variable(sd, bptr->outvars[i]);
4711 printf(" (clone of L%03d)", bptr->original->nr);
4713 basicblock *b = bptr->copied_to;
4715 printf(" (copied to ");
4716 for (; b; b = b->copied_to)
4717 printf("L%03d ", b->nr);
4724 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4728 printf("======================================== STACK %sANALYSE BLOCK ",
4729 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4730 stack_verbose_show_block(sd, sd->bptr);
4733 if (sd->handlers[0]) {
4734 printf("HANDLERS: ");
4735 for (i=0; sd->handlers[i]; ++i) {
4736 printf("L%03d ", sd->handlers[i]->handler->nr);
4744 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4746 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4747 stack_verbose_show_block(sd, sd->bptr);
4751 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackelement_t *curstack)
4757 stackelement_t **stack;
4759 printf(" javalocals ");
4760 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4763 for(i = 0, sp = curstack; sp; sp = sp->prev)
4767 stack = MNEW(stackelement_t *, depth);
4768 for(sp = curstack; sp; sp = sp->prev)
4771 for(i=0; i<depth; ++i) {
4775 v = &(sd->var[sp->varnum]);
4777 if (v->flags & INOUT)
4779 if (v->flags & PREALLOC)
4781 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4782 if (v->type == TYPE_RET) {
4783 printf("(L%03d)", v->vv.retaddr->nr);
4788 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4795 * These are local overrides for various environment variables in Emacs.
4796 * Please do not remove this and leave it at the end of the file, where
4797 * Emacs will automagically detect them.
4798 * ---------------------------------------------------------------------
4801 * indent-tabs-mode: t
4805 * vim:noexpandtab:sw=4:ts=4: