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.hpp"
38 #include "native/native.hpp"
40 #include "toolbox/logging.hpp"
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.hpp"
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.hpp"
57 #include "vm/jit/parse.hpp"
58 #include "vm/jit/show.hpp"
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 /* For returnAddresses we use a field of the typeinfo to store from which */
97 /* subroutine the returnAddress will return, if used. */
98 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
99 /* to need it initialised to NULL. This should be investigated. */
101 #if defined(ENABLE_VERIFIER)
102 #define SBRSTART typeinfo.elementclass.any
106 /* stackdata_t *****************************************************************
108 This struct holds internal data during stack analysis.
110 *******************************************************************************/
112 typedef struct stackdata_t stackdata_t;
115 basicblock *bptr; /* the current basic block being analysed */
116 stackelement_t *new; /* next free stackelement */
117 s4 vartop; /* next free variable index */
118 s4 localcount; /* number of locals (at the start of var) */
119 s4 varcount; /* maximum number of variables expected */
120 s4 varsallocated; /* total number of variables allocated */
121 s4 maxlocals; /* max. number of Java locals */
122 varinfo *var; /* variable array (same as jd->var) */
123 s4 *javalocals; /* map from Java locals to jd->var indices */
124 methodinfo *m; /* the method being analysed */
125 jitdata *jd; /* current jitdata */
126 basicblock *last_real_block; /* the last block before the empty one */
127 bool repeat; /* if true, iterate the analysis again */
128 exception_entry **handlers; /* exception handlers for the current block */
129 exception_entry *extableend; /* points to the last exception entry */
130 stackelement_t exstack; /* instack for exception handlers */
134 /* macros for allocating/releasing variable indices *****************/
136 #define GET_NEW_INDEX(sd, new_varindex) \
138 assert((sd).vartop < (sd).varcount); \
139 (new_varindex) = ((sd).vartop)++; \
142 /* Not implemented now - could be used to reuse varindices. */
143 /* Pay attention to not release a localvar once implementing it! */
144 #define RELEASE_INDEX(sd, varindex)
146 #define GET_NEW_VAR(sd, newvarindex, newtype) \
148 GET_NEW_INDEX((sd), (newvarindex)); \
149 (sd).var[newvarindex].type = (newtype); \
153 /* macros for querying variable properties **************************/
155 #define IS_INOUT(sp) \
156 (sd.var[(sp)->varnum].flags & INOUT)
158 #define IS_PREALLOC(sp) \
159 (sd.var[(sp)->varnum].flags & PREALLOC)
161 #define IS_TEMPVAR(sp) \
162 ( ((sp)->varnum >= sd.localcount) \
163 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
166 #define IS_LOCALVAR_SD(sd, sp) \
167 ((sp)->varnum < (sd).localcount)
169 #define IS_LOCALVAR(sp) \
170 IS_LOCALVAR_SD(sd, (sp))
173 /* macros for setting variable properties ****************************/
175 #define SET_TEMPVAR(sp) \
177 if (IS_LOCALVAR((sp))) { \
178 stack_change_to_tempvar(&sd, (sp), iptr); \
180 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
183 #define SET_PREALLOC(sp) \
185 assert(!IS_LOCALVAR((sp))); \
186 sd.var[(sp)->varnum].flags |= PREALLOC; \
190 /* macros for source operands ***************************************/
193 (iptr->s1.varindex = -1)
195 #define USE_S1(type1) \
198 CHECK_BASIC_TYPE(type1, curstack->type); \
199 iptr->s1.varindex = curstack->varnum; \
205 iptr->s1.varindex = curstack->varnum; \
208 #define USE_S1_S2(type1, type2) \
211 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
212 CHECK_BASIC_TYPE(type2, curstack->type); \
213 iptr->sx.s23.s2.varindex = curstack->varnum; \
214 iptr->s1.varindex = curstack->prev->varnum; \
217 #define USE_S1_S2_ANY_ANY \
220 iptr->sx.s23.s2.varindex = curstack->varnum; \
221 iptr->s1.varindex = curstack->prev->varnum; \
224 #define USE_S1_S2_S3(type1, type2, type3) \
227 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
228 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
229 CHECK_BASIC_TYPE(type3, curstack->type); \
230 iptr->sx.s23.s3.varindex = curstack->varnum; \
231 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
232 iptr->s1.varindex = curstack->prev->prev->varnum; \
235 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
238 if (curstack->varkind == UNDEFVAR) \
239 curstack->varkind = TEMPVAR; \
240 curstack = curstack->prev; \
243 #define POP_S1(type1) \
246 if (curstack->varkind == UNDEFVAR) \
247 curstack->varkind = TEMPVAR; \
248 curstack = curstack->prev; \
254 if (curstack->varkind == UNDEFVAR) \
255 curstack->varkind = TEMPVAR; \
256 curstack = curstack->prev; \
259 #define POP_S1_S2(type1, type2) \
261 USE_S1_S2(type1, type2); \
262 if (curstack->varkind == UNDEFVAR) \
263 curstack->varkind = TEMPVAR; \
264 if (curstack->prev->varkind == UNDEFVAR) \
265 curstack->prev->varkind = TEMPVAR; \
266 curstack = curstack->prev->prev; \
269 #define POP_S1_S2_ANY_ANY \
272 if (curstack->varkind == UNDEFVAR) \
273 curstack->varkind = TEMPVAR; \
274 if (curstack->prev->varkind == UNDEFVAR) \
275 curstack->prev->varkind = TEMPVAR; \
276 curstack = curstack->prev->prev; \
279 #define POP_S1_S2_S3(type1, type2, type3) \
281 USE_S1_S2_S3(type1, type2, type3); \
282 if (curstack->varkind == UNDEFVAR) \
283 curstack->varkind = TEMPVAR; \
284 if (curstack->prev->varkind == UNDEFVAR) \
285 curstack->prev->varkind = TEMPVAR; \
286 if (curstack->prev->prev->varkind == UNDEFVAR) \
287 curstack->prev->prev->varkind = TEMPVAR; \
288 curstack = curstack->prev->prev->prev; \
295 /* macros for setting the destination operand ***********************/
298 (iptr->dst.varindex = -1)
300 #define DST(typed, index) \
302 NEWSTACKn((typed),(index)); \
303 curstack->creator = iptr; \
304 iptr->dst.varindex = (index); \
307 #define DST_LOCALVAR(typed, index) \
309 NEWSTACK((typed), LOCALVAR, (index)); \
310 curstack->creator = iptr; \
311 iptr->dst.varindex = (index); \
315 /* macro for propagating constant values ****************************/
317 #if defined(ENABLE_VERIFIER)
318 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
320 if (((dv)->type = (sv)->type) == TYPE_RET) { \
321 (dv)->vv = (sv)->vv; \
322 (dv)->SBRSTART = (sv)->SBRSTART; \
326 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
328 (dv)->type = (sv)->type; \
329 if (((dv)->type = (sv)->type) == TYPE_RET) { \
330 (dv)->vv = (sv)->vv; \
335 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
336 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
339 /* stack modelling macros *******************************************/
341 #define OP0_1(typed) \
344 GET_NEW_VAR(sd, new_index, (typed)); \
345 DST((typed), new_index); \
356 #define OP1_BRANCH(type1) \
362 #define OP1_1(type1, typed) \
365 GET_NEW_VAR(sd, new_index, (typed)); \
366 DST(typed, new_index); \
369 #define OP2_1(type1, type2, typed) \
371 POP_S1_S2(type1, type2); \
372 GET_NEW_VAR(sd, new_index, (typed)); \
373 DST(typed, new_index); \
388 #define OP1_0(type1) \
395 #define OP2_0(type1, type2) \
397 POP_S1_S2(type1, type2); \
402 #define OP2_BRANCH(type1, type2) \
404 POP_S1_S2(type1, type2); \
408 #define OP2_0_ANY_ANY \
415 #define OP3_0(type1, type2, type3) \
417 POP_S1_S2_S3(type1, type2, type3); \
422 #define LOAD(type1, index) \
424 DST_LOCALVAR(type1, index); \
428 #define STORE(type1, index) \
435 /* macros for DUP elimination ***************************************/
437 /* XXX replace NEW_VAR with NEW_INDEX */
438 #define DUP_SLOT(sp) \
440 GET_NEW_VAR(sd, new_index, (sp)->type); \
441 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
442 NEWSTACK((sp)->type, TEMPVAR, new_index); \
445 /* does not check input stackdepth */
446 #define MOVE_UP(sp) \
448 iptr->opc = ICMD_MOVE; \
449 iptr->s1.varindex = (sp)->varnum; \
451 curstack->creator = iptr; \
452 iptr->dst.varindex = curstack->varnum; \
456 /* does not check input stackdepth */
457 #define COPY_UP(sp) \
460 iptr->opc = ICMD_COPY; \
461 iptr->s1.varindex = (sp)->varnum; \
463 curstack->creator = iptr; \
464 iptr->dst.varindex = curstack->varnum; \
468 #define COPY_DOWN(s, d) \
471 iptr->opc = ICMD_COPY; \
472 iptr->s1.varindex = (s)->varnum; \
473 iptr->dst.varindex = (d)->varnum; \
474 (d)->creator = iptr; \
477 #define MOVE_TO_TEMP(sp) \
479 GET_NEW_INDEX(sd, new_index); \
480 iptr->opc = ICMD_MOVE; \
481 iptr->s1.varindex = (sp)->varnum; \
482 iptr->dst.varindex = new_index; \
483 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
484 (sp)->varnum = new_index; \
485 (sp)->varkind = TEMPVAR; \
488 /* macros for branching / reaching basic blocks *********************/
490 #define BRANCH_TARGET(bt, tempbptr) \
492 tempbptr = (bt).block; \
493 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
495 if (tempbptr == NULL) \
497 (bt).block = tempbptr; \
500 #define BRANCH(tempbptr) \
501 BRANCH_TARGET(iptr->dst, tempbptr)
504 /* forward declarations *******************************************************/
506 static void stack_create_invars(stackdata_t *sd, basicblock *b,
507 stackelement_t * curstack, int stackdepth);
508 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
510 #if defined(STACK_VERBOSE)
511 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
512 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
513 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
514 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
515 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
516 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
517 stackelement_t * curstack);
521 /* stack_init ******************************************************************
523 Initialized the stack analysis subsystem (called by jit_init).
525 *******************************************************************************/
527 bool stack_init(void)
533 /* stack_grow_variable_array ***************************************************
535 Grow the variable array so the given number of additional variables fits in.
536 The number is added to `varcount`, which is the maximum number of variables
537 we expect to need at this point. The actual number of variables
538 (`varsallocated`) may be larger than that, in order to avoid too many
542 sd...........stack analysis data
543 num..........number of additional variables
545 *******************************************************************************/
547 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
553 if (sd->varcount + num > sd->varsallocated) {
554 newsize = 2*sd->varsallocated + num;
556 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
557 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
558 sd->varsallocated = newsize;
559 sd->jd->var = sd->var;
563 sd->jd->varcount += num;
565 assert(sd->varcount <= sd->varsallocated);
569 /* stack_append_block **********************************************************
571 Append the given block after the last real block of the method (before
572 the pseudo-block at the end).
575 sd...........stack analysis data
576 b............the block to append
578 *******************************************************************************/
580 static void stack_append_block(stackdata_t *sd, basicblock *b)
582 #if defined(STACK_VERBOSE)
583 printf("APPENDING BLOCK L%0d\n", b->nr);
586 b->next = sd->last_real_block->next;
587 sd->last_real_block->next = b;
588 sd->last_real_block = b;
589 b->nr = sd->jd->basicblockcount++;
590 b->next->nr = b->nr + 1;
594 /* stack_clone_block ***********************************************************
596 Create a copy of the given block and insert it at the end of the method.
598 CAUTION: This function does not copy the any variables or the instruction
599 list. It _does_, however, reserve space for the block's invars in the
603 sd...........stack analysis data
604 b............the block to clone
607 a pointer to the copy
609 *******************************************************************************/
611 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
615 clone = DNEW(basicblock);
618 clone->iinstr = NULL;
619 clone->inlocals = NULL;
620 clone->javalocals = NULL;
621 clone->invars = NULL;
623 clone->original = (b->original) ? b->original : b;
624 clone->copied_to = clone->original->copied_to;
625 clone->original->copied_to = clone;
627 clone->flags = BBREACHED;
629 stack_append_block(sd, clone);
631 /* reserve space for the invars of the clone */
633 stack_grow_variable_array(sd, b->indepth);
635 #if defined(STACK_VERBOSE)
636 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
643 /* stack_create_locals *********************************************************
645 Create the local variables for the start of the given basic block.
648 sd...........stack analysis data
649 b............block to create the locals for
651 *******************************************************************************/
653 static void stack_create_locals(stackdata_t *sd, basicblock *b)
659 /* copy the current state of the local variables */
660 /* (one extra local is needed by the verifier) */
662 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
664 for (i=0; i<sd->localcount; ++i)
667 /* the current map from java locals to cacao variables */
669 jl = DMNEW(s4, sd->maxlocals);
671 MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
675 /* stack_merge_locals **********************************************************
677 Merge local variables at the beginning of the given basic block.
680 sd...........stack analysis data
681 b............the block that is reached
683 *******************************************************************************/
685 static void stack_merge_locals(stackdata_t *sd, basicblock *b)
691 /* If a javalocal is mapped to different cacao locals along the */
692 /* incoming control-flow edges, it becomes undefined. */
694 for (i=0; i<sd->maxlocals; ++i) {
695 if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
696 b->javalocals[i] = UNUSED;
697 if (b->flags >= BBFINISHED)
698 b->flags = BBTYPECHECK_REACHED;
699 if (b->nr <= sd->bptr->nr)
704 #if defined(ENABLE_VERIFIER)
706 for (i=0; i<sd->localcount; ++i) {
707 dv = b->inlocals + i;
709 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
710 && (sv->SBRSTART != dv->SBRSTART))
712 #if defined(STACK_VERBOSE)
713 printf("JSR MISMATCH: setting variable %d to VOID\n", i);
715 dv->type = TYPE_VOID;
716 if (b->flags >= BBFINISHED)
717 b->flags = BBTYPECHECK_REACHED;
718 sd->repeat = true; /* This is very rare, so just repeat */
722 #endif /* defined(ENABLE_VERIFIER) */
726 /* stack_create_invars *********************************************************
728 Create the invars for the given basic block. Also make a copy of the locals.
731 sd...........stack analysis data
732 b............block to create the invars for
733 curstack.....current stack top
734 stackdepth...current stack depth
736 This function creates STACKDEPTH invars and sets their types to the
737 types to the types of the corresponding slot in the current stack.
739 *******************************************************************************/
741 static void stack_create_invars(stackdata_t *sd, basicblock *b,
742 stackelement_t * curstack, int stackdepth)
750 assert(sd->vartop + stackdepth <= sd->varcount);
752 b->indepth = stackdepth;
753 b->invars = DMNEW(s4, stackdepth);
755 /* allocate the variable indices */
756 index = (sd->vartop += stackdepth);
759 for (sp = curstack; i--; sp = sp->prev) {
760 b->invars[i] = --index;
761 dv = sd->var + index;
762 sv = sd->var + sp->varnum;
764 COPY_VAL_AND_TYPE_VAR(sv, dv);
767 stack_create_locals(sd, b);
771 /* stack_create_invars_from_outvars ********************************************
773 Create the invars for the given basic block. Also make a copy of the locals.
774 Types are propagated from the outvars of the current block.
777 sd...........stack analysis data
778 b............block to create the invars for
780 *******************************************************************************/
782 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
788 n = sd->bptr->outdepth;
789 assert(sd->vartop + n <= sd->varcount);
792 b->invars = DMNEW(s4, n);
795 dv = sd->var + sd->vartop;
797 /* allocate the invars */
799 for (i=0; i<n; ++i, ++dv) {
800 sv = sd->var + sd->bptr->outvars[i];
801 b->invars[i] = sd->vartop++;
803 COPY_VAL_AND_TYPE_VAR(sv, dv);
807 stack_create_locals(sd, b);
811 /* stack_check_invars **********************************************************
813 Check the current stack against the invars of the given basic block.
814 Depth and types must match.
817 sd...........stack analysis data
818 b............block which invars to check against
819 curstack.....current stack top
820 stackdepth...current stack depth
824 NULL.........a VerifyError has been thrown
826 *******************************************************************************/
828 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
829 stackelement_t * curstack, int stackdepth)
838 #if defined(STACK_VERBOSE)
839 printf("stack_check_invars(L%03d)\n", b->nr);
842 /* find original of b */
847 #if defined(STACK_VERBOSE)
848 printf("original is L%03d\n", orig->nr);
853 #if defined(ENABLE_VERIFIER)
854 if (i != stackdepth) {
855 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
863 #if defined(STACK_VERBOSE)
864 printf("checking against ");
865 stack_verbose_show_block(sd, b); printf("\n");
869 for (i = orig->indepth; i--; sp = sp->prev) {
870 dv = sd->var + b->invars[i];
871 sv = sd->var + sp->varnum;
873 #if defined(ENABLE_VERIFIER)
874 if (dv->type != sp->type) {
875 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
880 if (sp->type == TYPE_RET) {
881 #if defined(ENABLE_VERIFIER)
882 if (dv->SBRSTART != sv->SBRSTART) {
883 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
887 if (dv->vv.retaddr != sv->vv.retaddr) {
889 /* don't break! have to check the remaining stackslots */
895 for (i=0; i<sd->localcount; ++i) {
896 dv = b->inlocals + i;
898 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
900 #if defined(ENABLE_VERIFIER)
901 (sv->SBRSTART == dv->SBRSTART) &&
903 (sv->vv.retaddr != dv->vv.retaddr))
913 /* XXX cascading collapse? */
915 stack_merge_locals(sd, b);
917 #if defined(STACK_VERBOSE)
918 printf("------> using L%03d\n", b->nr);
922 } while ((b = b->copied_to) != NULL);
924 b = stack_clone_block(sd, orig);
928 stack_create_invars(sd, b, curstack, stackdepth);
933 /* stack_check_invars_from_outvars *********************************************
935 Check the outvars of the current block against the invars of the given block.
936 Depth and types must match.
939 sd...........stack analysis data
940 b............block which invars to check against
944 NULL.........a VerifyError has been thrown
946 *******************************************************************************/
948 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
956 #if defined(STACK_VERBOSE)
957 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
960 /* find original of b */
965 #if defined(STACK_VERBOSE)
966 printf("original is L%03d\n", orig->nr);
970 n = sd->bptr->outdepth;
972 #if defined(ENABLE_VERIFIER)
974 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
982 #if defined(STACK_VERBOSE)
983 printf("checking against ");
984 stack_verbose_show_block(sd, b); printf("\n");
988 dv = sd->var + b->invars[0];
990 for (i=0; i<n; ++i, ++dv) {
991 sv = sd->var + sd->bptr->outvars[i];
993 #if defined(ENABLE_VERIFIER)
994 if (sv->type != dv->type) {
995 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1000 if (dv->type == TYPE_RET) {
1001 #if defined(ENABLE_VERIFIER)
1002 if (sv->SBRSTART != dv->SBRSTART) {
1003 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1007 if (sv->vv.retaddr != dv->vv.retaddr) {
1009 /* don't break! have to check the remaining stackslots */
1016 for (i=0; i<sd->localcount; ++i) {
1017 dv = b->inlocals + i;
1020 #if defined(ENABLE_VERIFIER)
1021 (sv->SBRSTART == dv->SBRSTART) &&
1023 (sv->type == TYPE_RET && dv->type == TYPE_RET))
1025 if (sv->vv.retaddr != dv->vv.retaddr) {
1034 /* XXX cascading collapse? */
1036 stack_merge_locals(sd, b);
1038 #if defined(STACK_VERBOSE)
1039 printf("------> using L%03d\n", b->nr);
1043 } while ((b = b->copied_to) != NULL);
1045 b = stack_clone_block(sd, orig);
1049 stack_create_invars_from_outvars(sd, b);
1054 /* stack_create_instack ********************************************************
1056 Create the instack of the current basic block.
1059 sd...........stack analysis data
1062 the current stack top at the start of the basic block.
1064 *******************************************************************************/
1066 static stackelement_t * stack_create_instack(stackdata_t *sd)
1068 stackelement_t * sp;
1072 if ((depth = sd->bptr->indepth) == 0)
1075 sp = (sd->new += depth);
1079 index = sd->bptr->invars[depth];
1081 sp->type = sd->var[index].type;
1085 sp->varkind = STACKVAR;
1089 /* return the top of the created stack */
1094 /* stack_mark_reached **********************************************************
1096 Mark the given block reached and propagate the current stack and locals to
1097 it. This function specializes the target block, if necessary, and returns
1098 a pointer to the specialized target.
1101 sd...........stack analysis data
1102 b............the block to reach
1103 curstack.....the current stack top
1104 stackdepth...the current stack depth
1107 a pointer to (a specialized version of) the target
1108 NULL.........a VerifyError has been thrown
1110 *******************************************************************************/
1112 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackelement_t * curstack, int stackdepth)
1116 #if defined(STACK_VERBOSE)
1117 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1120 /* mark targets of backward branches */
1122 if (b->nr <= sd->bptr->nr)
1123 b->bitflags |= BBFLAG_REPLACEMENT;
1125 if (b->flags < BBREACHED) {
1126 /* b is reached for the first time. Create its invars. */
1128 #if defined(STACK_VERBOSE)
1129 printf("reached L%03d for the first time\n", b->nr);
1132 stack_create_invars(sd, b, curstack, stackdepth);
1134 b->flags = BBREACHED;
1139 /* b has been reached before. Check that its invars match. */
1141 return stack_check_invars(sd, b, curstack, stackdepth);
1146 /* stack_mark_reached_from_outvars *********************************************
1148 Mark the given block reached and propagate the outvars of the current block
1149 and the current locals to it. This function specializes the target block,
1150 if necessary, and returns a pointer to the specialized target.
1153 sd...........stack analysis data
1154 b............the block to reach
1157 a pointer to (a specialized version of) the target
1158 NULL.........a VerifyError has been thrown
1160 *******************************************************************************/
1162 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1166 #if defined(STACK_VERBOSE)
1167 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1170 /* mark targets of backward branches */
1172 if (b->nr <= sd->bptr->nr)
1173 b->bitflags |= BBFLAG_REPLACEMENT;
1175 if (b->flags < BBREACHED) {
1176 /* b is reached for the first time. Create its invars. */
1178 #if defined(STACK_VERBOSE)
1179 printf("reached L%03d for the first time\n", b->nr);
1182 stack_create_invars_from_outvars(sd, b);
1184 b->flags = BBREACHED;
1189 /* b has been reached before. Check that its invars match. */
1191 return stack_check_invars_from_outvars(sd, b);
1196 /* stack_reach_next_block ******************************************************
1198 Mark the following block reached and propagate the outvars of the
1199 current block and the current locals to it. This function
1200 specializes the target block, if necessary, and returns a pointer
1201 to the specialized target.
1204 sd...........stack analysis data
1207 a pointer to (a specialized version of) the following block
1208 NULL.........a VerifyError has been thrown
1210 *******************************************************************************/
1212 static bool stack_reach_next_block(stackdata_t *sd)
1217 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1218 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1223 if (tbptr != sd->bptr->next) {
1224 #if defined(STACK_VERBOSE)
1225 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1227 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1228 assert(iptr->opc == ICMD_NOP);
1229 iptr->opc = ICMD_GOTO;
1230 iptr->dst.block = tbptr;
1231 #if defined(STACK_VERBOSE)
1232 if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
1235 if (tbptr->flags < BBFINISHED)
1236 sd->repeat = true; /* XXX check if we really need to repeat */
1243 /* stack_reach_handlers ********************************************************
1245 Reach the exception handlers for the current block.
1248 sd...........stack analysis data
1251 true.........everything ok
1252 false........a VerifyError has been thrown
1254 *******************************************************************************/
1256 static bool stack_reach_handlers(stackdata_t *sd)
1261 #if defined(STACK_VERBOSE)
1262 printf("reaching exception handlers...\n");
1265 for (i=0; sd->handlers[i]; ++i) {
1266 tbptr = sd->handlers[i]->handler;
1268 tbptr->type = BBTYPE_EXH;
1269 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1271 /* reach (and specialize) the handler block */
1273 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1278 sd->handlers[i]->handler = tbptr;
1285 /* stack_reanalyse_block ******************************************************
1287 Re-analyse the current block. This is called if either the block itself
1288 has already been analysed before, or the current block is a clone of an
1289 already analysed block, and this clone is reached for the first time.
1290 In the latter case, this function does all that is necessary for fully
1291 cloning the block (cloning the instruction list and variables, etc.).
1294 sd...........stack analysis data
1297 true.........everything ok
1298 false........a VerifyError has been thrown
1300 *******************************************************************************/
1302 #define RELOCATE(index) \
1304 if ((index) >= blockvarstart) \
1305 (index) += blockvarshift; \
1306 else if ((index) >= invarstart) \
1307 (index) += invarshift; \
1310 bool stack_reanalyse_block(stackdata_t *sd)
1322 branch_target_t *table;
1323 lookup_target_t *lookup;
1325 bool cloneinstructions;
1326 exception_entry *ex;
1328 #if defined(STACK_VERBOSE)
1329 stack_verbose_block_enter(sd, true);
1336 assert(orig != NULL);
1338 /* clone the instruction list */
1340 cloneinstructions = true;
1342 assert(orig->iinstr);
1344 iptr = DMNEW(instruction, len + 1);
1346 MCOPY(iptr, orig->iinstr, instruction, len);
1347 iptr[len].opc = ICMD_NOP;
1349 iptr[len].flags.bits = 0;
1353 /* reserve space for the clone's block variables */
1355 stack_grow_variable_array(sd, orig->varcount);
1357 /* we already have the invars set */
1359 assert(b->indepth == orig->indepth);
1361 /* calculate relocation shifts for invars and block variables */
1363 if (orig->indepth) {
1364 invarstart = orig->invars[0];
1365 invarshift = b->invars[0] - invarstart;
1368 invarstart = INT_MAX;
1371 blockvarstart = orig->varstart;
1372 blockvarshift = sd->vartop - blockvarstart;
1374 /* copy block variables */
1376 b->varstart = sd->vartop;
1377 b->varcount = orig->varcount;
1378 sd->vartop += b->varcount;
1379 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1383 b->outdepth = orig->outdepth;
1384 b->outvars = DMNEW(s4, orig->outdepth);
1385 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1387 /* clone exception handlers */
1389 for (i=0; sd->handlers[i]; ++i) {
1390 ex = DNEW(exception_entry);
1391 ex->handler = sd->handlers[i]->handler;
1393 ex->end = b; /* XXX hack, see end of stack_analyse */
1394 ex->catchtype = sd->handlers[i]->catchtype;
1397 assert(sd->extableend->down == NULL);
1398 sd->extableend->down = ex;
1399 sd->extableend = ex;
1400 sd->jd->exceptiontablelength++;
1402 sd->handlers[i] = ex;
1406 cloneinstructions = false;
1409 invarstart = sd->vartop;
1410 blockvarstart = sd->vartop;
1415 /* find exception handlers for the cloned block */
1417 ex = sd->jd->exceptiontable;
1418 for (; ex != NULL; ex = ex->down) {
1419 /* XXX the cloned exception handlers have identical */
1420 /* start end end blocks. */
1421 if ((ex->start == b) && (ex->end == b)) {
1422 sd->handlers[len++] = ex;
1425 sd->handlers[len] = NULL;
1428 #if defined(STACK_VERBOSE)
1429 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1430 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1433 /* mark block as finished */
1435 b->flags = BBFINISHED;
1437 /* initialize locals at the start of this block */
1440 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1442 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1444 /* reach exception handlers for this block */
1446 if (!stack_reach_handlers(sd))
1449 superblockend = false;
1451 for (len = b->icount; len--; iptr++) {
1452 #if defined(STACK_VERBOSE)
1453 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1457 switch (iptr->opc) {
1459 varindex = iptr->s1.varindex;
1461 #if defined(ENABLE_VERIFIER)
1462 if (sd->var[varindex].type != TYPE_RET) {
1463 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1468 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1469 superblockend = true;
1473 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1474 RELOCATE(iptr->dst.varindex);
1475 superblockend = true;
1479 superblockend = true;
1482 case ICMD_CHECKNULL:
1483 case ICMD_PUTSTATICCONST:
1491 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1492 superblockend = true;
1495 /* pop 0 push 1 const */
1503 /* pop 0 push 1 load */
1510 RELOCATE(iptr->dst.varindex);
1523 RELOCATE(iptr->sx.s23.s2.varindex);
1524 RELOCATE(iptr->s1.varindex);
1525 RELOCATE(iptr->dst.varindex);
1538 RELOCATE(iptr->sx.s23.s3.varindex);
1539 RELOCATE(iptr->sx.s23.s2.varindex);
1540 RELOCATE(iptr->s1.varindex);
1543 /* pop 1 push 0 store */
1550 RELOCATE(iptr->s1.varindex);
1552 varindex = iptr->dst.varindex;
1553 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1554 i = iptr->sx.s23.s3.javaindex;
1555 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1556 iptr->sx.s23.s2.retaddrnr =
1557 JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1558 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1561 sd->javalocals[i] = varindex;
1562 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1563 sd->javalocals[i-1] = UNUSED;
1564 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1565 sd->javalocals[i+1] = UNUSED;
1576 RELOCATE(iptr->s1.varindex);
1577 superblockend = true;
1580 case ICMD_PUTSTATIC:
1581 case ICMD_PUTFIELDCONST:
1583 RELOCATE(iptr->s1.varindex);
1586 /* pop 1 push 0 branch */
1589 case ICMD_IFNONNULL:
1604 RELOCATE(iptr->s1.varindex);
1605 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1608 /* pop 1 push 0 table branch */
1610 case ICMD_TABLESWITCH:
1611 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1613 if (cloneinstructions) {
1614 table = DMNEW(branch_target_t, i);
1615 MCOPY(table, iptr->dst.table, branch_target_t, i);
1616 iptr->dst.table = table;
1619 table = iptr->dst.table;
1622 RELOCATE(iptr->s1.varindex);
1624 table->block = stack_mark_reached_from_outvars(sd, table->block);
1627 superblockend = true;
1630 case ICMD_LOOKUPSWITCH:
1631 i = iptr->sx.s23.s2.lookupcount;
1632 if (cloneinstructions) {
1633 lookup = DMNEW(lookup_target_t, i);
1634 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1635 iptr->dst.lookup = lookup;
1638 lookup = iptr->dst.lookup;
1640 RELOCATE(iptr->s1.varindex);
1642 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1645 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1646 superblockend = true;
1649 case ICMD_MONITORENTER:
1650 case ICMD_MONITOREXIT:
1651 RELOCATE(iptr->s1.varindex);
1654 /* pop 2 push 0 branch */
1656 case ICMD_IF_ICMPEQ:
1657 case ICMD_IF_ICMPNE:
1658 case ICMD_IF_ICMPLT:
1659 case ICMD_IF_ICMPGE:
1660 case ICMD_IF_ICMPGT:
1661 case ICMD_IF_ICMPLE:
1663 case ICMD_IF_LCMPEQ:
1664 case ICMD_IF_LCMPNE:
1665 case ICMD_IF_LCMPLT:
1666 case ICMD_IF_LCMPGE:
1667 case ICMD_IF_LCMPGT:
1668 case ICMD_IF_LCMPLE:
1670 case ICMD_IF_ACMPEQ:
1671 case ICMD_IF_ACMPNE:
1672 RELOCATE(iptr->sx.s23.s2.varindex);
1673 RELOCATE(iptr->s1.varindex);
1674 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1680 case ICMD_IASTORECONST:
1681 case ICMD_LASTORECONST:
1682 case ICMD_AASTORECONST:
1683 case ICMD_BASTORECONST:
1684 case ICMD_CASTORECONST:
1685 case ICMD_SASTORECONST:
1687 RELOCATE(iptr->sx.s23.s2.varindex);
1688 RELOCATE(iptr->s1.varindex);
1691 /* pop 0 push 1 copy */
1695 RELOCATE(iptr->dst.varindex);
1696 RELOCATE(iptr->s1.varindex);
1697 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1739 RELOCATE(iptr->sx.s23.s2.varindex);
1740 RELOCATE(iptr->s1.varindex);
1741 RELOCATE(iptr->dst.varindex);
1746 case ICMD_CHECKCAST:
1747 case ICMD_ARRAYLENGTH:
1748 case ICMD_INSTANCEOF:
1750 case ICMD_ANEWARRAY:
1752 case ICMD_IADDCONST:
1753 case ICMD_ISUBCONST:
1754 case ICMD_IMULCONST:
1758 case ICMD_IANDCONST:
1760 case ICMD_IXORCONST:
1761 case ICMD_ISHLCONST:
1762 case ICMD_ISHRCONST:
1763 case ICMD_IUSHRCONST:
1764 case ICMD_LADDCONST:
1765 case ICMD_LSUBCONST:
1766 case ICMD_LMULCONST:
1770 case ICMD_LANDCONST:
1772 case ICMD_LXORCONST:
1773 case ICMD_LSHLCONST:
1774 case ICMD_LSHRCONST:
1775 case ICMD_LUSHRCONST:
1779 case ICMD_INT2SHORT:
1795 RELOCATE(iptr->s1.varindex);
1796 RELOCATE(iptr->dst.varindex);
1801 case ICMD_GETSTATIC:
1803 RELOCATE(iptr->dst.varindex);
1806 /* pop many push any */
1808 case ICMD_INVOKESTATIC:
1809 case ICMD_INVOKESPECIAL:
1810 case ICMD_INVOKEVIRTUAL:
1811 case ICMD_INVOKEINTERFACE:
1813 case ICMD_MULTIANEWARRAY:
1814 i = iptr->s1.argcount;
1815 if (cloneinstructions) {
1816 argp = DMNEW(s4, i);
1817 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1818 iptr->sx.s23.s2.args = argp;
1821 argp = iptr->sx.s23.s2.args;
1828 RELOCATE(iptr->dst.varindex);
1832 exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1837 #if defined(STACK_VERBOSE)
1838 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1843 /* relocate outvars */
1845 for (i=0; i<b->outdepth; ++i) {
1846 RELOCATE(b->outvars[i]);
1849 #if defined(STACK_VERBOSE)
1850 stack_verbose_block_exit(sd, superblockend);
1853 /* propagate to the next block */
1856 if (!stack_reach_next_block(sd))
1863 /* stack_change_to_tempvar *****************************************************
1865 Change the given stackslot to a TEMPVAR. This includes creating a new
1866 temporary variable and changing the dst.varindex of the creator of the
1867 stacklot to the new variable index. If this stackslot has been passed
1868 through ICMDs between the point of its creation and the current point,
1869 then the variable index is also changed in these ICMDs.
1872 sd...........stack analysis data
1873 sp...........stackslot to change
1874 ilimit.......instruction up to which to look for ICMDs passing-through
1875 the stackslot (exclusive). This may point exactly after the
1876 last instruction, in which case the search is done to the
1879 *******************************************************************************/
1881 static void stack_change_to_tempvar(stackdata_t *sd, stackelement_t * sp,
1882 instruction *ilimit)
1890 oldindex = sp->varnum;
1892 /* create a new temporary variable */
1894 GET_NEW_VAR(*sd, newindex, sp->type);
1896 sd->var[newindex].flags = sp->flags;
1898 /* change the stackslot */
1900 sp->varnum = newindex;
1901 sp->varkind = TEMPVAR;
1903 /* change the dst.varindex of the stackslot's creator */
1906 sp->creator->dst.varindex = newindex;
1908 /* handle ICMDs this stackslot passed through, if any */
1910 if (sp->flags & PASSTHROUGH) {
1911 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1913 /* assert that the limit points to an ICMD, or after the last one */
1915 assert(ilimit >= sd->bptr->iinstr);
1916 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1918 /* find the stackdepth under sp plus one */
1919 /* Note: This number is usually known when this function is called, */
1920 /* but calculating it here is less error-prone and should not be */
1921 /* a performance problem. */
1923 for (depth = 0; sp != NULL; sp = sp->prev)
1926 /* iterate over all instructions in the range and replace */
1928 for (; iptr < ilimit; ++iptr) {
1929 switch (iptr->opc) {
1930 case ICMD_INVOKESTATIC:
1931 case ICMD_INVOKESPECIAL:
1932 case ICMD_INVOKEVIRTUAL:
1933 case ICMD_INVOKEINTERFACE:
1935 i = iptr->s1.argcount - depth;
1936 if (iptr->sx.s23.s2.args[i] == oldindex) {
1937 iptr->sx.s23.s2.args[i] = newindex;
1940 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1941 /* stackslot, it must be added in this switch! */
1948 /* stack_init_javalocals *******************************************************
1950 Initialize the mapping from Java locals to cacao variables at method entry.
1953 sd...........stack analysis data
1955 *******************************************************************************/
1957 static void stack_init_javalocals(stackdata_t *sd)
1966 jl = DMNEW(s4, sd->maxlocals);
1967 jd->basicblocks[0].javalocals = jl;
1969 for (i=0; i<sd->maxlocals; ++i)
1972 md = jd->m->parseddesc;
1974 for (i=0; i<md->paramcount; ++i) {
1975 type = md->paramtypes[i].type;
1976 jl[j] = jd->local_map[5*j + type];
1978 if (IS_2_WORD_TYPE(type))
1984 /* stack_analyse ***************************************************************
1986 Analyse_stack uses the intermediate code created by parse.c to
1987 build a model of the JVM operand stack for the current method.
1989 The following checks are performed:
1990 - check for operand stack underflow (before each instruction)
1991 - check for operand stack overflow (after[1] each instruction)
1992 - check for matching stack depth at merging points
1993 - check for matching basic types[2] at merging points
1994 - check basic types for instruction input (except for BUILTIN*
1995 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1997 [1]) Checking this after the instruction should be ok. parse.c
1998 counts the number of required stack slots in such a way that it is
1999 only vital that we don't exceed `maxstack` at basic block
2002 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2003 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2004 types are not discerned.
2006 *******************************************************************************/
2008 bool stack_analyse(jitdata *jd)
2010 methodinfo *m; /* method being analyzed */
2015 stackelement_t *curstack; /* current stack top */
2016 stackelement_t *copy;
2017 int opcode; /* opcode of current instruction */
2020 int type; /* operand type */
2021 int len; /* # of instructions after the current one */
2022 bool superblockend; /* if true, no fallthrough to next block */
2023 bool deadcode; /* true if no live code has been reached */
2024 instruction *iptr; /* the current instruction */
2026 basicblock *original;
2027 exception_entry *ex;
2029 stackelement_t **last_store_boundary;
2030 stackelement_t *coalescing_boundary;
2032 stackelement_t *src1, *src2, *src3, *src4, *dst1, *dst2;
2034 branch_target_t *table;
2035 lookup_target_t *lookup;
2036 #if defined(ENABLE_VERIFIER)
2037 int expectedtype; /* used by CHECK_BASIC_TYPE */
2039 builtintable_entry *bte;
2041 constant_FMIref *fmiref;
2042 #if defined(ENABLE_STATISTICS)
2043 int iteration_count; /* number of iterations of analysis */
2045 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2047 #if defined(STACK_VERBOSE)
2048 show_method(jd, SHOW_PARSE);
2051 /* get required compiler data - initialization */
2057 /* initialize the stackdata_t struct */
2061 sd.varcount = jd->varcount;
2062 sd.vartop = jd->vartop;
2063 sd.localcount = jd->localcount;
2065 sd.varsallocated = sd.varcount;
2066 sd.maxlocals = m->maxlocals;
2067 sd.javalocals = DMNEW(s4, sd.maxlocals);
2068 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2070 /* prepare the variable for exception handler stacks */
2071 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2073 sd.exstack.type = TYPE_ADR;
2074 sd.exstack.prev = NULL;
2075 sd.exstack.varnum = sd.localcount;
2076 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2078 #if defined(ENABLE_STATISTICS)
2079 iteration_count = 0;
2082 /* find the last real basic block */
2084 sd.last_real_block = NULL;
2085 tbptr = jd->basicblocks;
2086 while (tbptr->next) {
2087 sd.last_real_block = tbptr;
2088 tbptr = tbptr->next;
2090 assert(sd.last_real_block);
2092 /* find the last exception handler */
2094 if (jd->exceptiontablelength)
2095 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2097 sd.extableend = NULL;
2099 /* init jd->interface_map */
2101 jd->maxinterfaces = m->maxstack;
2102 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2103 for (i = 0; i < m->maxstack * 5; i++)
2104 jd->interface_map[i].flags = UNUSED;
2106 last_store_boundary = DMNEW(stackelement_t *, m->maxlocals);
2108 /* initialize flags and invars (none) of first block */
2110 jd->basicblocks[0].flags = BBREACHED;
2111 jd->basicblocks[0].invars = NULL;
2112 jd->basicblocks[0].indepth = 0;
2113 jd->basicblocks[0].inlocals =
2114 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2115 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2116 jd->localcount + VERIFIER_EXTRA_LOCALS);
2118 /* initialize java local mapping of first block */
2120 stack_init_javalocals(&sd);
2122 /* stack analysis loop (until fixpoint reached) **************************/
2125 #if defined(ENABLE_STATISTICS)
2129 /* initialize loop over basic blocks */
2131 sd.bptr = jd->basicblocks;
2132 superblockend = true;
2138 /* iterate over basic blocks *****************************************/
2140 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2142 if (sd.bptr->flags == BBDELETED) {
2143 /* This block has been deleted - do nothing. */
2148 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2149 /* re-analyse a block because its input changed */
2153 if (!stack_reanalyse_block(&sd))
2156 superblockend = true; /* XXX */
2160 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2161 /* This block has not been reached so far, and we
2162 don't fall into it, so we'll have to iterate
2169 if (sd.bptr->flags > BBREACHED) {
2170 /* This block is already finished. */
2172 superblockend = true;
2176 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2177 /* This block is a clone and the original has not been
2178 analysed, yet. Analyse it on the next
2182 /* XXX superblockend? */
2186 /* This block has to be analysed now. */
2190 /* XXX The rest of this block is still indented one level too */
2191 /* much in order to avoid a giant diff by changing that. */
2193 /* We know that sd.bptr->flags == BBREACHED. */
2194 /* This block has been reached before. */
2196 assert(sd.bptr->flags == BBREACHED);
2197 stackdepth = sd.bptr->indepth;
2199 /* find exception handlers for this block */
2201 /* determine the active exception handlers for this block */
2202 /* XXX could use a faster algorithm with sorted lists or */
2205 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2208 ex = jd->exceptiontable;
2209 for (; ex != NULL; ex = ex->down) {
2210 if ((ex->start <= original) && (ex->end > original)) {
2211 sd.handlers[len++] = ex;
2214 sd.handlers[len] = NULL;
2217 /* reanalyse cloned block */
2219 if (sd.bptr->original) {
2220 if (!stack_reanalyse_block(&sd))
2225 /* reset the new pointer for allocating stackslots */
2229 /* create the instack of this block */
2231 curstack = stack_create_instack(&sd);
2233 /* initialize locals at the start of this block */
2235 if (sd.bptr->inlocals)
2236 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2238 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2240 /* set up local variables for analyzing this block */
2242 superblockend = false;
2243 len = sd.bptr->icount;
2244 iptr = sd.bptr->iinstr;
2246 /* mark the block as analysed */
2248 sd.bptr->flags = BBFINISHED;
2250 /* reset variables for dependency checking */
2252 coalescing_boundary = sd.new;
2253 for( i = 0; i < m->maxlocals; i++)
2254 last_store_boundary[i] = sd.new;
2256 /* remember the start of this block's variables */
2258 sd.bptr->varstart = sd.vartop;
2260 #if defined(STACK_VERBOSE)
2261 stack_verbose_block_enter(&sd, false);
2264 /* reach exception handlers for this block */
2266 if (!stack_reach_handlers(&sd))
2269 /* iterate over ICMDs ****************************************/
2271 while (--len >= 0) {
2273 #if defined(STACK_VERBOSE)
2274 stack_verbose_show_state(&sd, iptr, curstack);
2277 /* fetch the current opcode */
2281 /* automatically replace some ICMDs with builtins */
2283 bte = builtintable_get_automatic(opcode);
2285 if ((bte != NULL) && (bte->opcode == opcode)) {
2286 iptr->opc = ICMD_BUILTIN;
2287 iptr->flags.bits &= INS_FLAG_ID_MASK;
2288 iptr->sx.s23.s3.bte = bte;
2289 /* iptr->line is already set */
2290 code_unflag_leafmethod(code);
2294 /* main opcode switch *************************************/
2306 case ICMD_CHECKNULL:
2307 coalescing_boundary = sd.new;
2308 COUNT(count_check_null);
2311 iptr->dst.varindex = iptr->s1.varindex;
2315 varindex = iptr->s1.varindex =
2316 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2318 #if defined(ENABLE_VERIFIER)
2319 if (sd.var[varindex].type != TYPE_RET) {
2320 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2327 iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2328 superblockend = true;
2332 COUNT(count_pcmd_return);
2335 superblockend = true;
2336 sd.jd->returncount++;
2337 sd.jd->returnblock = sd.bptr;
2340 case ICMD_BREAKPOINT:
2345 /* pop 0 push 1 const */
2347 /************************** ICONST OPTIMIZATIONS **************************/
2350 COUNT(count_pcmd_load);
2354 switch (iptr[1].opc) {
2356 iptr->opc = ICMD_IADDCONST;
2360 iptr[1].opc = ICMD_NOP;
2361 OP1_1(TYPE_INT, TYPE_INT);
2362 COUNT(count_pcmd_op);
2366 iptr->opc = ICMD_ISUBCONST;
2367 goto icmd_iconst_tail;
2368 #if SUPPORT_CONST_MUL
2370 iptr->opc = ICMD_IMULCONST;
2371 goto icmd_iconst_tail;
2372 #else /* SUPPORT_CONST_MUL */
2374 if (iptr->sx.val.i == 0x00000002)
2376 else if (iptr->sx.val.i == 0x00000004)
2378 else if (iptr->sx.val.i == 0x00000008)
2380 else if (iptr->sx.val.i == 0x00000010)
2382 else if (iptr->sx.val.i == 0x00000020)
2384 else if (iptr->sx.val.i == 0x00000040)
2386 else if (iptr->sx.val.i == 0x00000080)
2388 else if (iptr->sx.val.i == 0x00000100)
2390 else if (iptr->sx.val.i == 0x00000200)
2392 else if (iptr->sx.val.i == 0x00000400)
2393 iptr->sx.val.i = 10;
2394 else if (iptr->sx.val.i == 0x00000800)
2395 iptr->sx.val.i = 11;
2396 else if (iptr->sx.val.i == 0x00001000)
2397 iptr->sx.val.i = 12;
2398 else if (iptr->sx.val.i == 0x00002000)
2399 iptr->sx.val.i = 13;
2400 else if (iptr->sx.val.i == 0x00004000)
2401 iptr->sx.val.i = 14;
2402 else if (iptr->sx.val.i == 0x00008000)
2403 iptr->sx.val.i = 15;
2404 else if (iptr->sx.val.i == 0x00010000)
2405 iptr->sx.val.i = 16;
2406 else if (iptr->sx.val.i == 0x00020000)
2407 iptr->sx.val.i = 17;
2408 else if (iptr->sx.val.i == 0x00040000)
2409 iptr->sx.val.i = 18;
2410 else if (iptr->sx.val.i == 0x00080000)
2411 iptr->sx.val.i = 19;
2412 else if (iptr->sx.val.i == 0x00100000)
2413 iptr->sx.val.i = 20;
2414 else if (iptr->sx.val.i == 0x00200000)
2415 iptr->sx.val.i = 21;
2416 else if (iptr->sx.val.i == 0x00400000)
2417 iptr->sx.val.i = 22;
2418 else if (iptr->sx.val.i == 0x00800000)
2419 iptr->sx.val.i = 23;
2420 else if (iptr->sx.val.i == 0x01000000)
2421 iptr->sx.val.i = 24;
2422 else if (iptr->sx.val.i == 0x02000000)
2423 iptr->sx.val.i = 25;
2424 else if (iptr->sx.val.i == 0x04000000)
2425 iptr->sx.val.i = 26;
2426 else if (iptr->sx.val.i == 0x08000000)
2427 iptr->sx.val.i = 27;
2428 else if (iptr->sx.val.i == 0x10000000)
2429 iptr->sx.val.i = 28;
2430 else if (iptr->sx.val.i == 0x20000000)
2431 iptr->sx.val.i = 29;
2432 else if (iptr->sx.val.i == 0x40000000)
2433 iptr->sx.val.i = 30;
2434 else if (iptr->sx.val.i == 0x80000000)
2435 iptr->sx.val.i = 31;
2439 iptr->opc = ICMD_IMULPOW2;
2440 goto icmd_iconst_tail;
2441 #endif /* SUPPORT_CONST_MUL */
2443 if (iptr->sx.val.i == 0x00000002)
2445 else if (iptr->sx.val.i == 0x00000004)
2447 else if (iptr->sx.val.i == 0x00000008)
2449 else if (iptr->sx.val.i == 0x00000010)
2451 else if (iptr->sx.val.i == 0x00000020)
2453 else if (iptr->sx.val.i == 0x00000040)
2455 else if (iptr->sx.val.i == 0x00000080)
2457 else if (iptr->sx.val.i == 0x00000100)
2459 else if (iptr->sx.val.i == 0x00000200)
2461 else if (iptr->sx.val.i == 0x00000400)
2462 iptr->sx.val.i = 10;
2463 else if (iptr->sx.val.i == 0x00000800)
2464 iptr->sx.val.i = 11;
2465 else if (iptr->sx.val.i == 0x00001000)
2466 iptr->sx.val.i = 12;
2467 else if (iptr->sx.val.i == 0x00002000)
2468 iptr->sx.val.i = 13;
2469 else if (iptr->sx.val.i == 0x00004000)
2470 iptr->sx.val.i = 14;
2471 else if (iptr->sx.val.i == 0x00008000)
2472 iptr->sx.val.i = 15;
2473 else if (iptr->sx.val.i == 0x00010000)
2474 iptr->sx.val.i = 16;
2475 else if (iptr->sx.val.i == 0x00020000)
2476 iptr->sx.val.i = 17;
2477 else if (iptr->sx.val.i == 0x00040000)
2478 iptr->sx.val.i = 18;
2479 else if (iptr->sx.val.i == 0x00080000)
2480 iptr->sx.val.i = 19;
2481 else if (iptr->sx.val.i == 0x00100000)
2482 iptr->sx.val.i = 20;
2483 else if (iptr->sx.val.i == 0x00200000)
2484 iptr->sx.val.i = 21;
2485 else if (iptr->sx.val.i == 0x00400000)
2486 iptr->sx.val.i = 22;
2487 else if (iptr->sx.val.i == 0x00800000)
2488 iptr->sx.val.i = 23;
2489 else if (iptr->sx.val.i == 0x01000000)
2490 iptr->sx.val.i = 24;
2491 else if (iptr->sx.val.i == 0x02000000)
2492 iptr->sx.val.i = 25;
2493 else if (iptr->sx.val.i == 0x04000000)
2494 iptr->sx.val.i = 26;
2495 else if (iptr->sx.val.i == 0x08000000)
2496 iptr->sx.val.i = 27;
2497 else if (iptr->sx.val.i == 0x10000000)
2498 iptr->sx.val.i = 28;
2499 else if (iptr->sx.val.i == 0x20000000)
2500 iptr->sx.val.i = 29;
2501 else if (iptr->sx.val.i == 0x40000000)
2502 iptr->sx.val.i = 30;
2503 else if (iptr->sx.val.i == 0x80000000)
2504 iptr->sx.val.i = 31;
2508 iptr->opc = ICMD_IDIVPOW2;
2509 goto icmd_iconst_tail;
2512 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2513 if ((iptr->sx.val.i == 0x00000002) ||
2514 (iptr->sx.val.i == 0x00000004) ||
2515 (iptr->sx.val.i == 0x00000008) ||
2516 (iptr->sx.val.i == 0x00000010) ||
2517 (iptr->sx.val.i == 0x00000020) ||
2518 (iptr->sx.val.i == 0x00000040) ||
2519 (iptr->sx.val.i == 0x00000080) ||
2520 (iptr->sx.val.i == 0x00000100) ||
2521 (iptr->sx.val.i == 0x00000200) ||
2522 (iptr->sx.val.i == 0x00000400) ||
2523 (iptr->sx.val.i == 0x00000800) ||
2524 (iptr->sx.val.i == 0x00001000) ||
2525 (iptr->sx.val.i == 0x00002000) ||
2526 (iptr->sx.val.i == 0x00004000) ||
2527 (iptr->sx.val.i == 0x00008000) ||
2528 (iptr->sx.val.i == 0x00010000) ||
2529 (iptr->sx.val.i == 0x00020000) ||
2530 (iptr->sx.val.i == 0x00040000) ||
2531 (iptr->sx.val.i == 0x00080000) ||
2532 (iptr->sx.val.i == 0x00100000) ||
2533 (iptr->sx.val.i == 0x00200000) ||
2534 (iptr->sx.val.i == 0x00400000) ||
2535 (iptr->sx.val.i == 0x00800000) ||
2536 (iptr->sx.val.i == 0x01000000) ||
2537 (iptr->sx.val.i == 0x02000000) ||
2538 (iptr->sx.val.i == 0x04000000) ||
2539 (iptr->sx.val.i == 0x08000000) ||
2540 (iptr->sx.val.i == 0x10000000) ||
2541 (iptr->sx.val.i == 0x20000000) ||
2542 (iptr->sx.val.i == 0x40000000) ||
2543 (iptr->sx.val.i == 0x80000000))
2545 iptr->opc = ICMD_IREMPOW2;
2546 iptr->sx.val.i -= 1;
2547 goto icmd_iconst_tail;
2550 #if SUPPORT_CONST_LOGICAL
2552 iptr->opc = ICMD_IANDCONST;
2553 goto icmd_iconst_tail;
2556 iptr->opc = ICMD_IORCONST;
2557 goto icmd_iconst_tail;
2560 iptr->opc = ICMD_IXORCONST;
2561 goto icmd_iconst_tail;
2563 #endif /* SUPPORT_CONST_LOGICAL */
2565 iptr->opc = ICMD_ISHLCONST;
2566 goto icmd_iconst_tail;
2569 iptr->opc = ICMD_ISHRCONST;
2570 goto icmd_iconst_tail;
2573 iptr->opc = ICMD_IUSHRCONST;
2574 goto icmd_iconst_tail;
2575 #if SUPPORT_LONG_SHIFT
2577 iptr->opc = ICMD_LSHLCONST;
2578 goto icmd_lconst_tail;
2581 iptr->opc = ICMD_LSHRCONST;
2582 goto icmd_lconst_tail;
2585 iptr->opc = ICMD_LUSHRCONST;
2586 goto icmd_lconst_tail;
2587 #endif /* SUPPORT_LONG_SHIFT */
2588 case ICMD_IF_ICMPEQ:
2589 iptr[1].opc = ICMD_IFEQ;
2593 /* set the constant for the following icmd */
2594 iptr[1].sx.val.i = iptr->sx.val.i;
2596 /* this instruction becomes a nop */
2597 iptr->opc = ICMD_NOP;
2600 case ICMD_IF_ICMPLT:
2601 iptr[1].opc = ICMD_IFLT;
2602 goto icmd_if_icmp_tail;
2604 case ICMD_IF_ICMPLE:
2605 iptr[1].opc = ICMD_IFLE;
2606 goto icmd_if_icmp_tail;
2608 case ICMD_IF_ICMPNE:
2609 iptr[1].opc = ICMD_IFNE;
2610 goto icmd_if_icmp_tail;
2612 case ICMD_IF_ICMPGT:
2613 iptr[1].opc = ICMD_IFGT;
2614 goto icmd_if_icmp_tail;
2616 case ICMD_IF_ICMPGE:
2617 iptr[1].opc = ICMD_IFGE;
2618 goto icmd_if_icmp_tail;
2620 #if SUPPORT_CONST_STORE
2625 # if SUPPORT_CONST_STORE_ZERO_ONLY
2626 if (iptr->sx.val.i != 0)
2629 switch (iptr[1].opc) {
2631 iptr->opc = ICMD_IASTORECONST;
2632 iptr->flags.bits |= INS_FLAG_CHECK;
2635 iptr->opc = ICMD_BASTORECONST;
2636 iptr->flags.bits |= INS_FLAG_CHECK;
2639 iptr->opc = ICMD_CASTORECONST;
2640 iptr->flags.bits |= INS_FLAG_CHECK;
2643 iptr->opc = ICMD_SASTORECONST;
2644 iptr->flags.bits |= INS_FLAG_CHECK;
2648 iptr[1].opc = ICMD_NOP;
2650 /* copy the constant to s3 */
2651 /* XXX constval -> astoreconstval? */
2652 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2653 OP2_0(TYPE_ADR, TYPE_INT);
2654 COUNT(count_pcmd_op);
2657 case ICMD_PUTSTATIC:
2659 # if SUPPORT_CONST_STORE_ZERO_ONLY
2660 if (iptr->sx.val.i != 0)
2663 /* XXX check field type? */
2665 /* copy the constant to s2 */
2666 /* XXX constval -> fieldconstval? */
2667 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2670 /* set the field reference (s3) */
2671 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2672 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2673 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2674 fmiref = iptr->sx.s23.s3.uf->fieldref;
2677 fmiref = iptr[1].sx.s23.s3.fmiref;
2678 iptr->sx.s23.s3.fmiref = fmiref;
2681 #if defined(ENABLE_VERIFIER)
2682 expectedtype = fmiref->parseddesc.fd->type;
2683 switch (iptr[0].opc) {
2685 if (expectedtype != TYPE_INT)
2686 goto throw_stack_type_error;
2689 if (expectedtype != TYPE_LNG)
2690 goto throw_stack_type_error;
2693 if (expectedtype != TYPE_ADR)
2694 goto throw_stack_type_error;
2699 #endif /* defined(ENABLE_VERIFIER) */
2701 switch (iptr[1].opc) {
2702 case ICMD_PUTSTATIC:
2703 iptr->opc = ICMD_PUTSTATICCONST;
2707 iptr->opc = ICMD_PUTFIELDCONST;
2712 iptr[1].opc = ICMD_NOP;
2713 COUNT(count_pcmd_op);
2715 #endif /* SUPPORT_CONST_STORE */
2721 /* if we get here, the ICONST has been optimized */
2725 /* normal case of an unoptimized ICONST */
2729 /************************** LCONST OPTIMIZATIONS **************************/
2732 COUNT(count_pcmd_load);
2736 /* switch depending on the following instruction */
2738 switch (iptr[1].opc) {
2739 #if SUPPORT_LONG_ADD
2741 iptr->opc = ICMD_LADDCONST;
2745 /* instruction of type LONG -> LONG */
2746 iptr[1].opc = ICMD_NOP;
2747 OP1_1(TYPE_LNG, TYPE_LNG);
2748 COUNT(count_pcmd_op);
2752 iptr->opc = ICMD_LSUBCONST;
2753 goto icmd_lconst_tail;
2755 #endif /* SUPPORT_LONG_ADD */
2756 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2758 iptr->opc = ICMD_LMULCONST;
2759 goto icmd_lconst_tail;
2760 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2761 # if SUPPORT_LONG_SHIFT
2763 if (iptr->sx.val.l == 0x00000002)
2765 else if (iptr->sx.val.l == 0x00000004)
2767 else if (iptr->sx.val.l == 0x00000008)
2769 else if (iptr->sx.val.l == 0x00000010)
2771 else if (iptr->sx.val.l == 0x00000020)
2773 else if (iptr->sx.val.l == 0x00000040)
2775 else if (iptr->sx.val.l == 0x00000080)
2777 else if (iptr->sx.val.l == 0x00000100)
2779 else if (iptr->sx.val.l == 0x00000200)
2781 else if (iptr->sx.val.l == 0x00000400)
2782 iptr->sx.val.i = 10;
2783 else if (iptr->sx.val.l == 0x00000800)
2784 iptr->sx.val.i = 11;
2785 else if (iptr->sx.val.l == 0x00001000)
2786 iptr->sx.val.i = 12;
2787 else if (iptr->sx.val.l == 0x00002000)
2788 iptr->sx.val.i = 13;
2789 else if (iptr->sx.val.l == 0x00004000)
2790 iptr->sx.val.i = 14;
2791 else if (iptr->sx.val.l == 0x00008000)
2792 iptr->sx.val.i = 15;
2793 else if (iptr->sx.val.l == 0x00010000)
2794 iptr->sx.val.i = 16;
2795 else if (iptr->sx.val.l == 0x00020000)
2796 iptr->sx.val.i = 17;
2797 else if (iptr->sx.val.l == 0x00040000)
2798 iptr->sx.val.i = 18;
2799 else if (iptr->sx.val.l == 0x00080000)
2800 iptr->sx.val.i = 19;
2801 else if (iptr->sx.val.l == 0x00100000)
2802 iptr->sx.val.i = 20;
2803 else if (iptr->sx.val.l == 0x00200000)
2804 iptr->sx.val.i = 21;
2805 else if (iptr->sx.val.l == 0x00400000)
2806 iptr->sx.val.i = 22;
2807 else if (iptr->sx.val.l == 0x00800000)
2808 iptr->sx.val.i = 23;
2809 else if (iptr->sx.val.l == 0x01000000)
2810 iptr->sx.val.i = 24;
2811 else if (iptr->sx.val.l == 0x02000000)
2812 iptr->sx.val.i = 25;
2813 else if (iptr->sx.val.l == 0x04000000)
2814 iptr->sx.val.i = 26;
2815 else if (iptr->sx.val.l == 0x08000000)
2816 iptr->sx.val.i = 27;
2817 else if (iptr->sx.val.l == 0x10000000)
2818 iptr->sx.val.i = 28;
2819 else if (iptr->sx.val.l == 0x20000000)
2820 iptr->sx.val.i = 29;
2821 else if (iptr->sx.val.l == 0x40000000)
2822 iptr->sx.val.i = 30;
2823 else if (iptr->sx.val.l == 0x80000000)
2824 iptr->sx.val.i = 31;
2828 iptr->opc = ICMD_LMULPOW2;
2829 goto icmd_lconst_tail;
2830 # endif /* SUPPORT_LONG_SHIFT */
2831 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2832 #if SUPPORT_LONG_DIV_POW2
2834 if (iptr->sx.val.l == 0x00000002)
2836 else if (iptr->sx.val.l == 0x00000004)
2838 else if (iptr->sx.val.l == 0x00000008)
2840 else if (iptr->sx.val.l == 0x00000010)
2842 else if (iptr->sx.val.l == 0x00000020)
2844 else if (iptr->sx.val.l == 0x00000040)
2846 else if (iptr->sx.val.l == 0x00000080)
2848 else if (iptr->sx.val.l == 0x00000100)
2850 else if (iptr->sx.val.l == 0x00000200)
2852 else if (iptr->sx.val.l == 0x00000400)
2853 iptr->sx.val.i = 10;
2854 else if (iptr->sx.val.l == 0x00000800)
2855 iptr->sx.val.i = 11;
2856 else if (iptr->sx.val.l == 0x00001000)
2857 iptr->sx.val.i = 12;
2858 else if (iptr->sx.val.l == 0x00002000)
2859 iptr->sx.val.i = 13;
2860 else if (iptr->sx.val.l == 0x00004000)
2861 iptr->sx.val.i = 14;
2862 else if (iptr->sx.val.l == 0x00008000)
2863 iptr->sx.val.i = 15;
2864 else if (iptr->sx.val.l == 0x00010000)
2865 iptr->sx.val.i = 16;
2866 else if (iptr->sx.val.l == 0x00020000)
2867 iptr->sx.val.i = 17;
2868 else if (iptr->sx.val.l == 0x00040000)
2869 iptr->sx.val.i = 18;
2870 else if (iptr->sx.val.l == 0x00080000)
2871 iptr->sx.val.i = 19;
2872 else if (iptr->sx.val.l == 0x00100000)
2873 iptr->sx.val.i = 20;
2874 else if (iptr->sx.val.l == 0x00200000)
2875 iptr->sx.val.i = 21;
2876 else if (iptr->sx.val.l == 0x00400000)
2877 iptr->sx.val.i = 22;
2878 else if (iptr->sx.val.l == 0x00800000)
2879 iptr->sx.val.i = 23;
2880 else if (iptr->sx.val.l == 0x01000000)
2881 iptr->sx.val.i = 24;
2882 else if (iptr->sx.val.l == 0x02000000)
2883 iptr->sx.val.i = 25;
2884 else if (iptr->sx.val.l == 0x04000000)
2885 iptr->sx.val.i = 26;
2886 else if (iptr->sx.val.l == 0x08000000)
2887 iptr->sx.val.i = 27;
2888 else if (iptr->sx.val.l == 0x10000000)
2889 iptr->sx.val.i = 28;
2890 else if (iptr->sx.val.l == 0x20000000)
2891 iptr->sx.val.i = 29;
2892 else if (iptr->sx.val.l == 0x40000000)
2893 iptr->sx.val.i = 30;
2894 else if (iptr->sx.val.l == 0x80000000)
2895 iptr->sx.val.i = 31;
2899 iptr->opc = ICMD_LDIVPOW2;
2900 goto icmd_lconst_tail;
2901 #endif /* SUPPORT_LONG_DIV_POW2 */
2903 #if SUPPORT_LONG_REM_POW2
2905 if ((iptr->sx.val.l == 0x00000002) ||
2906 (iptr->sx.val.l == 0x00000004) ||
2907 (iptr->sx.val.l == 0x00000008) ||
2908 (iptr->sx.val.l == 0x00000010) ||
2909 (iptr->sx.val.l == 0x00000020) ||
2910 (iptr->sx.val.l == 0x00000040) ||
2911 (iptr->sx.val.l == 0x00000080) ||
2912 (iptr->sx.val.l == 0x00000100) ||
2913 (iptr->sx.val.l == 0x00000200) ||
2914 (iptr->sx.val.l == 0x00000400) ||
2915 (iptr->sx.val.l == 0x00000800) ||
2916 (iptr->sx.val.l == 0x00001000) ||
2917 (iptr->sx.val.l == 0x00002000) ||
2918 (iptr->sx.val.l == 0x00004000) ||
2919 (iptr->sx.val.l == 0x00008000) ||
2920 (iptr->sx.val.l == 0x00010000) ||
2921 (iptr->sx.val.l == 0x00020000) ||
2922 (iptr->sx.val.l == 0x00040000) ||
2923 (iptr->sx.val.l == 0x00080000) ||
2924 (iptr->sx.val.l == 0x00100000) ||
2925 (iptr->sx.val.l == 0x00200000) ||
2926 (iptr->sx.val.l == 0x00400000) ||
2927 (iptr->sx.val.l == 0x00800000) ||
2928 (iptr->sx.val.l == 0x01000000) ||
2929 (iptr->sx.val.l == 0x02000000) ||
2930 (iptr->sx.val.l == 0x04000000) ||
2931 (iptr->sx.val.l == 0x08000000) ||
2932 (iptr->sx.val.l == 0x10000000) ||
2933 (iptr->sx.val.l == 0x20000000) ||
2934 (iptr->sx.val.l == 0x40000000) ||
2935 (iptr->sx.val.l == 0x80000000))
2937 iptr->opc = ICMD_LREMPOW2;
2938 iptr->sx.val.l -= 1;
2939 goto icmd_lconst_tail;
2942 #endif /* SUPPORT_LONG_REM_POW2 */
2944 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2947 iptr->opc = ICMD_LANDCONST;
2948 goto icmd_lconst_tail;
2951 iptr->opc = ICMD_LORCONST;
2952 goto icmd_lconst_tail;
2955 iptr->opc = ICMD_LXORCONST;
2956 goto icmd_lconst_tail;
2957 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2959 #if SUPPORT_LONG_CMP_CONST
2961 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2964 /* switch on the instruction after LCONST - LCMP */
2966 switch (iptr[2].opc) {
2968 iptr->opc = ICMD_IF_LEQ;
2971 icmd_lconst_lcmp_tail:
2972 /* convert LCONST, LCMP, IFXX to IF_LXX */
2973 iptr->dst.block = iptr[2].dst.block;
2974 iptr[1].opc = ICMD_NOP;
2975 iptr[2].opc = ICMD_NOP;
2977 OP1_BRANCH(TYPE_LNG);
2979 COUNT(count_pcmd_bra);
2980 COUNT(count_pcmd_op);
2984 iptr->opc = ICMD_IF_LNE;
2985 goto icmd_lconst_lcmp_tail;
2988 iptr->opc = ICMD_IF_LLT;
2989 goto icmd_lconst_lcmp_tail;
2992 iptr->opc = ICMD_IF_LGT;
2993 goto icmd_lconst_lcmp_tail;
2996 iptr->opc = ICMD_IF_LLE;
2997 goto icmd_lconst_lcmp_tail;
3000 iptr->opc = ICMD_IF_LGE;
3001 goto icmd_lconst_lcmp_tail;
3005 } /* end switch on opcode after LCONST - LCMP */
3007 #endif /* SUPPORT_LONG_CMP_CONST */
3009 #if SUPPORT_CONST_STORE
3011 # if SUPPORT_CONST_STORE_ZERO_ONLY
3012 if (iptr->sx.val.l != 0)
3015 #if SIZEOF_VOID_P == 4
3016 /* the constant must fit into a ptrint */
3017 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3020 /* move the constant to s3 */
3021 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3023 iptr->opc = ICMD_LASTORECONST;
3024 iptr->flags.bits |= INS_FLAG_CHECK;
3025 OP2_0(TYPE_ADR, TYPE_INT);
3027 iptr[1].opc = ICMD_NOP;
3028 COUNT(count_pcmd_op);
3031 case ICMD_PUTSTATIC:
3033 # if SUPPORT_CONST_STORE_ZERO_ONLY
3034 if (iptr->sx.val.l != 0)
3037 #if SIZEOF_VOID_P == 4
3038 /* the constant must fit into a ptrint */
3039 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3042 /* XXX check field type? */
3044 /* copy the constant to s2 */
3045 /* XXX constval -> fieldconstval? */
3046 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3050 #endif /* SUPPORT_CONST_STORE */
3054 } /* end switch opcode after LCONST */
3056 /* if we get here, the LCONST has been optimized */
3060 /* the normal case of an unoptimized LCONST */
3064 /************************ END OF LCONST OPTIMIZATIONS *********************/
3067 COUNT(count_pcmd_load);
3072 COUNT(count_pcmd_load);
3076 /************************** ACONST OPTIMIZATIONS **************************/
3079 coalescing_boundary = sd.new;
3080 COUNT(count_pcmd_load);
3081 #if SUPPORT_CONST_STORE
3082 /* We can only optimize if the ACONST is resolved
3083 * and there is an instruction after it. */
3085 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3088 switch (iptr[1].opc) {
3090 /* We can only optimize for NULL values
3091 * here because otherwise a checkcast is
3093 if (iptr->sx.val.anyptr != NULL)
3096 /* copy the constant (NULL) to s3 */
3097 iptr->sx.s23.s3.constval = 0;
3098 iptr->opc = ICMD_AASTORECONST;
3099 iptr->flags.bits |= INS_FLAG_CHECK;
3100 OP2_0(TYPE_ADR, TYPE_INT);
3102 iptr[1].opc = ICMD_NOP;
3103 COUNT(count_pcmd_op);
3106 case ICMD_PUTSTATIC:
3108 # if SUPPORT_CONST_STORE_ZERO_ONLY
3109 if (iptr->sx.val.anyptr != NULL)
3112 /* XXX check field type? */
3113 /* copy the constant to s2 */
3114 /* XXX constval -> fieldconstval? */
3115 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3123 /* if we get here the ACONST has been optimized */
3127 #endif /* SUPPORT_CONST_STORE */
3132 /* pop 0 push 1 load */
3139 COUNT(count_load_instruction);
3140 type = opcode - ICMD_ILOAD;
3142 varindex = iptr->s1.varindex =
3143 jd->local_map[iptr->s1.varindex * 5 + type];
3145 #if defined(ENABLE_VERIFIER)
3146 if (sd.var[varindex].type == TYPE_RET) {
3147 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3151 LOAD(type, varindex);
3160 coalescing_boundary = sd.new;
3161 iptr->flags.bits |= INS_FLAG_CHECK;
3162 COUNT(count_check_null);
3163 COUNT(count_check_bound);
3164 COUNT(count_pcmd_mem);
3165 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3172 coalescing_boundary = sd.new;
3173 iptr->flags.bits |= INS_FLAG_CHECK;
3174 COUNT(count_check_null);
3175 COUNT(count_check_bound);
3176 COUNT(count_pcmd_mem);
3177 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3180 /* pop 0 push 0 iinc */
3183 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3184 javaindex = iptr->s1.varindex;
3185 last_store_boundary[javaindex] = sd.new;
3188 jd->local_map[javaindex * 5 + TYPE_INT];
3193 if ((copy->varkind == LOCALVAR) &&
3194 (jd->reverselocalmap[copy->varnum] == javaindex))
3196 assert(IS_LOCALVAR(copy));
3203 iptr->dst.varindex = iptr->s1.varindex;
3206 /* pop 1 push 0 store */
3215 type = opcode - ICMD_ISTORE;
3216 javaindex = iptr->dst.varindex;
3217 varindex = iptr->dst.varindex =
3218 jd->local_map[javaindex * 5 + type];
3220 COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3222 iptr->sx.s23.s3.javaindex = javaindex;
3224 if (curstack->type == TYPE_RET) {
3225 iptr->flags.bits |= INS_FLAG_RETADDR;
3226 iptr->sx.s23.s2.retaddrnr =
3227 JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3228 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3231 sd.javalocals[javaindex] = varindex;
3233 /* invalidate the following javalocal for 2-word types */
3235 if (IS_2_WORD_TYPE(type)) {
3236 sd.javalocals[javaindex+1] = UNUSED;
3237 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3240 /* invalidate 2-word types if second half was overwritten */
3242 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
3243 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3244 sd.javalocals[javaindex-1] = UNUSED;
3245 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3249 #if defined(ENABLE_STATISTICS)
3252 i = sd.new - curstack;
3254 count_store_length[20]++;
3256 count_store_length[i]++;
3259 count_store_depth[10]++;
3261 count_store_depth[i]++;
3265 /* check for conflicts as described in Figure 5.2 */
3267 copy = curstack->prev;
3270 if ((copy->varkind == LOCALVAR) &&
3271 (jd->reverselocalmap[copy->varnum] == javaindex))
3273 assert(IS_LOCALVAR(copy));
3280 /* if the variable is already coalesced, don't bother */
3282 /* We do not need to check against INOUT, as invars */
3283 /* are always before the coalescing boundary. */
3285 if (curstack->varkind == LOCALVAR)
3288 /* there is no STORE Lj while curstack is live */
3290 if (curstack < last_store_boundary[javaindex])
3291 goto assume_conflict;
3293 /* curstack must be after the coalescing boundary */
3295 if (curstack < coalescing_boundary)
3296 goto assume_conflict;
3298 /* there is no DEF LOCALVAR(varindex) while curstack is live */
3300 copy = sd.new; /* most recent stackslot created + 1 */
3301 while (--copy > curstack) {
3302 if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
3303 goto assume_conflict;
3306 /* coalesce the temporary variable with Lj */
3307 assert((curstack->varkind == TEMPVAR)
3308 || (curstack->varkind == UNDEFVAR));
3309 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3310 assert(!IS_INOUT(curstack));
3311 assert(!IS_PREALLOC(curstack));
3313 assert(curstack->creator);
3314 assert(curstack->creator->dst.varindex == curstack->varnum);
3315 assert(!(curstack->flags & PASSTHROUGH));
3316 RELEASE_INDEX(sd, curstack);
3317 curstack->varkind = LOCALVAR;
3318 curstack->varnum = varindex;
3319 curstack->creator->dst.varindex = varindex;
3322 /* revert the coalescing, if it has been done earlier */
3324 if ((curstack->varkind == LOCALVAR)
3325 && (jd->reverselocalmap[curstack->varnum] == javaindex))
3327 assert(IS_LOCALVAR(curstack));
3328 SET_TEMPVAR(curstack);
3331 /* remember the stack boundary at this store */
3333 last_store_boundary[javaindex] = sd.new;
3335 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3336 STORE(TYPE_RET, varindex);
3338 STORE(opcode - ICMD_ISTORE, varindex);
3344 coalescing_boundary = sd.new;
3345 iptr->flags.bits |= INS_FLAG_CHECK;
3346 COUNT(count_check_null);
3347 COUNT(count_check_bound);
3348 COUNT(count_pcmd_mem);
3350 bte = builtintable_get_internal(BUILTIN_FAST_canstore);
3353 if (md->memuse > rd->memuse)
3354 rd->memuse = md->memuse;
3355 if (md->argintreguse > rd->argintreguse)
3356 rd->argintreguse = md->argintreguse;
3357 /* XXX non-leaf method? */
3359 /* make all stack variables saved */
3363 sd.var[copy->varnum].flags |= SAVEDVAR;
3364 /* in case copy->varnum is/will be a LOCALVAR */
3365 /* once and set back to a non LOCALVAR */
3366 /* the correct SAVEDVAR flag has to be */
3367 /* remembered in copy->flags, too */
3368 copy->flags |= SAVEDVAR;
3372 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3379 coalescing_boundary = sd.new;
3380 iptr->flags.bits |= INS_FLAG_CHECK;
3381 COUNT(count_check_null);
3382 COUNT(count_check_bound);
3383 COUNT(count_pcmd_mem);
3384 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3391 coalescing_boundary = sd.new;
3392 iptr->flags.bits |= INS_FLAG_CHECK;
3393 COUNT(count_check_null);
3394 COUNT(count_check_bound);
3395 COUNT(count_pcmd_mem);
3396 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3402 #ifdef ENABLE_VERIFIER
3405 if (IS_2_WORD_TYPE(curstack->type))
3406 goto throw_stack_category_error;
3417 coalescing_boundary = sd.new;
3418 /* Assert here that no LOCAL or INOUTS get */
3419 /* preallocated, since tha macros are not */
3420 /* available in md-abi.c! */
3421 if (IS_TEMPVAR(curstack))
3422 md_return_alloc(jd, curstack);
3423 COUNT(count_pcmd_return);
3424 OP1_0(opcode - ICMD_IRETURN);
3425 superblockend = true;
3426 sd.jd->returncount++;
3427 sd.jd->returnblock = sd.bptr;
3431 coalescing_boundary = sd.new;
3432 COUNT(count_check_null);
3434 curstack = NULL; stackdepth = 0;
3435 superblockend = true;
3438 case ICMD_PUTSTATIC:
3439 coalescing_boundary = sd.new;
3440 COUNT(count_pcmd_mem);
3441 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3442 OP1_0(fmiref->parseddesc.fd->type);
3445 /* pop 1 push 0 branch */
3448 case ICMD_IFNONNULL:
3449 COUNT(count_pcmd_bra);
3450 OP1_BRANCH(TYPE_ADR);
3460 COUNT(count_pcmd_bra);
3461 /* iptr->sx.val.i is set implicitly in parse by
3462 clearing the memory or from IF_ICMPxx
3465 OP1_BRANCH(TYPE_INT);
3466 /* iptr->sx.val.i = 0; */
3470 /* pop 0 push 0 branch */
3473 COUNT(count_pcmd_bra);
3476 superblockend = true;
3479 /* pop 1 push 0 table branch */
3481 case ICMD_TABLESWITCH:
3482 COUNT(count_pcmd_table);
3483 OP1_BRANCH(TYPE_INT);
3485 table = iptr->dst.table;
3486 BRANCH_TARGET(*table, tbptr);
3489 i = iptr->sx.s23.s3.tablehigh
3490 - iptr->sx.s23.s2.tablelow + 1;
3493 BRANCH_TARGET(*table, tbptr);
3496 superblockend = true;
3499 /* pop 1 push 0 table branch */
3501 case ICMD_LOOKUPSWITCH:
3502 COUNT(count_pcmd_table);
3503 OP1_BRANCH(TYPE_INT);
3505 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3507 lookup = iptr->dst.lookup;
3509 i = iptr->sx.s23.s2.lookupcount;
3512 BRANCH_TARGET(lookup->target, tbptr);
3515 superblockend = true;
3518 case ICMD_MONITORENTER:
3519 case ICMD_MONITOREXIT:
3520 coalescing_boundary = sd.new;
3521 COUNT(count_check_null);
3525 /* pop 2 push 0 branch */
3527 case ICMD_IF_ICMPEQ:
3528 case ICMD_IF_ICMPNE:
3529 case ICMD_IF_ICMPLT:
3530 case ICMD_IF_ICMPGE:
3531 case ICMD_IF_ICMPGT:
3532 case ICMD_IF_ICMPLE:
3533 COUNT(count_pcmd_bra);
3534 OP2_BRANCH(TYPE_INT, TYPE_INT);
3538 case ICMD_IF_ACMPEQ:
3539 case ICMD_IF_ACMPNE:
3540 COUNT(count_pcmd_bra);
3541 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3548 coalescing_boundary = sd.new;
3549 COUNT(count_check_null);
3550 COUNT(count_pcmd_mem);
3551 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3552 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3557 if (!IS_2_WORD_TYPE(curstack->type)) {
3559 #ifdef ENABLE_VERIFIER
3562 if (IS_2_WORD_TYPE(curstack->prev->type))
3563 goto throw_stack_category_error;
3566 OP2_0_ANY_ANY; /* pop two slots */
3569 iptr->opc = ICMD_POP;
3570 OP1_0_ANY; /* pop one (two-word) slot */
3574 /* pop 0 push 1 dup */
3577 #ifdef ENABLE_VERIFIER
3580 if (IS_2_WORD_TYPE(curstack->type))
3581 goto throw_stack_category_error;
3584 COUNT(count_dup_instruction);
3590 coalescing_boundary = sd.new - 1;
3595 if (IS_2_WORD_TYPE(curstack->type)) {
3597 iptr->opc = ICMD_DUP;
3602 /* ..., ????, cat1 */
3603 #ifdef ENABLE_VERIFIER
3605 if (IS_2_WORD_TYPE(curstack->prev->type))
3606 goto throw_stack_category_error;
3609 src1 = curstack->prev;
3612 COPY_UP(src1); iptr++; len--;
3615 coalescing_boundary = sd.new;
3619 /* pop 2 push 3 dup */
3622 #ifdef ENABLE_VERIFIER
3625 if (IS_2_WORD_TYPE(curstack->type) ||
3626 IS_2_WORD_TYPE(curstack->prev->type))
3627 goto throw_stack_category_error;
3632 src1 = curstack->prev;
3637 /* move non-temporary sources out of the way */
3638 if (!IS_TEMPVAR(src2)) {
3639 MOVE_TO_TEMP(src2); iptr++; len--;
3642 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3644 MOVE_UP(src1); iptr++; len--;
3645 MOVE_UP(src2); iptr++; len--;
3647 COPY_DOWN(curstack, dst1);
3649 coalescing_boundary = sd.new;
3654 if (IS_2_WORD_TYPE(curstack->type)) {
3655 /* ..., ????, cat2 */
3656 #ifdef ENABLE_VERIFIER
3658 if (IS_2_WORD_TYPE(curstack->prev->type))
3659 goto throw_stack_category_error;
3662 iptr->opc = ICMD_DUP_X1;
3666 /* ..., ????, cat1 */
3667 #ifdef ENABLE_VERIFIER
3670 if (IS_2_WORD_TYPE(curstack->prev->type)
3671 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3672 goto throw_stack_category_error;
3677 src1 = curstack->prev->prev;
3678 src2 = curstack->prev;
3680 POPANY; POPANY; POPANY;
3683 /* move non-temporary sources out of the way */
3684 if (!IS_TEMPVAR(src2)) {
3685 MOVE_TO_TEMP(src2); iptr++; len--;
3687 if (!IS_TEMPVAR(src3)) {
3688 MOVE_TO_TEMP(src3); iptr++; len--;
3691 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3692 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3694 MOVE_UP(src1); iptr++; len--;
3695 MOVE_UP(src2); iptr++; len--;
3696 MOVE_UP(src3); iptr++; len--;
3698 COPY_DOWN(curstack, dst2); iptr++; len--;
3699 COPY_DOWN(curstack->prev, dst1);
3701 coalescing_boundary = sd.new;
3705 /* pop 3 push 4 dup */
3709 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3710 /* ..., cat2, ???? */
3711 #ifdef ENABLE_VERIFIER
3713 if (IS_2_WORD_TYPE(curstack->type))
3714 goto throw_stack_category_error;
3717 iptr->opc = ICMD_DUP_X1;
3721 /* ..., cat1, ???? */
3722 #ifdef ENABLE_VERIFIER
3725 if (IS_2_WORD_TYPE(curstack->type)
3726 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3727 goto throw_stack_category_error;
3731 src1 = curstack->prev->prev;
3732 src2 = curstack->prev;
3734 POPANY; POPANY; POPANY;
3737 /* move non-temporary sources out of the way */
3738 if (!IS_TEMPVAR(src2)) {
3739 MOVE_TO_TEMP(src2); iptr++; len--;
3741 if (!IS_TEMPVAR(src3)) {
3742 MOVE_TO_TEMP(src3); iptr++; len--;
3745 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3747 MOVE_UP(src1); iptr++; len--;
3748 MOVE_UP(src2); iptr++; len--;
3749 MOVE_UP(src3); iptr++; len--;
3751 COPY_DOWN(curstack, dst1);
3753 coalescing_boundary = sd.new;
3759 if (IS_2_WORD_TYPE(curstack->type)) {
3760 /* ..., ????, cat2 */
3761 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3762 /* ..., cat2, cat2 */
3763 iptr->opc = ICMD_DUP_X1;
3767 /* ..., cat1, cat2 */
3768 #ifdef ENABLE_VERIFIER
3771 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3772 goto throw_stack_category_error;
3775 iptr->opc = ICMD_DUP_X2;
3781 /* ..., ????, ????, cat1 */
3783 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3784 /* ..., cat2, ????, cat1 */
3785 #ifdef ENABLE_VERIFIER
3787 if (IS_2_WORD_TYPE(curstack->prev->type))
3788 goto throw_stack_category_error;
3791 iptr->opc = ICMD_DUP2_X1;
3795 /* ..., cat1, ????, cat1 */
3796 #ifdef ENABLE_VERIFIER
3799 if (IS_2_WORD_TYPE(curstack->prev->type)
3800 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3801 goto throw_stack_category_error;
3805 src1 = curstack->prev->prev->prev;
3806 src2 = curstack->prev->prev;
3807 src3 = curstack->prev;
3809 POPANY; POPANY; POPANY; POPANY;
3812 /* move non-temporary sources out of the way */
3813 if (!IS_TEMPVAR(src2)) {
3814 MOVE_TO_TEMP(src2); iptr++; len--;
3816 if (!IS_TEMPVAR(src3)) {
3817 MOVE_TO_TEMP(src3); iptr++; len--;
3819 if (!IS_TEMPVAR(src4)) {
3820 MOVE_TO_TEMP(src4); iptr++; len--;
3823 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3824 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3826 MOVE_UP(src1); iptr++; len--;
3827 MOVE_UP(src2); iptr++; len--;
3828 MOVE_UP(src3); iptr++; len--;
3829 MOVE_UP(src4); iptr++; len--;
3831 COPY_DOWN(curstack, dst2); iptr++; len--;
3832 COPY_DOWN(curstack->prev, dst1);
3834 coalescing_boundary = sd.new;
3838 /* pop 2 push 2 swap */
3841 #ifdef ENABLE_VERIFIER
3844 if (IS_2_WORD_TYPE(curstack->type)
3845 || IS_2_WORD_TYPE(curstack->prev->type))
3846 goto throw_stack_category_error;
3850 src1 = curstack->prev;
3855 /* move non-temporary sources out of the way */
3856 if (!IS_TEMPVAR(src1)) {
3857 MOVE_TO_TEMP(src1); iptr++; len--;
3860 MOVE_UP(src2); iptr++; len--;
3863 coalescing_boundary = sd.new;
3870 coalescing_boundary = sd.new;
3871 #if !SUPPORT_DIVISION
3872 bte = iptr->sx.s23.s3.bte;
3875 if (md->memuse > rd->memuse)
3876 rd->memuse = md->memuse;
3877 if (md->argintreguse > rd->argintreguse)
3878 rd->argintreguse = md->argintreguse;
3880 /* make all stack variables saved */
3884 sd.var[copy->varnum].flags |= SAVEDVAR;
3885 copy->flags |= SAVEDVAR;
3890 #endif /* !SUPPORT_DIVISION */
3901 COUNT(count_pcmd_op);
3902 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3907 coalescing_boundary = sd.new;
3908 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3909 bte = iptr->sx.s23.s3.bte;
3912 if (md->memuse > rd->memuse)
3913 rd->memuse = md->memuse;
3914 if (md->argintreguse > rd->argintreguse)
3915 rd->argintreguse = md->argintreguse;
3916 /* XXX non-leaf method? */
3918 /* make all stack variables saved */
3922 sd.var[copy->varnum].flags |= SAVEDVAR;
3923 copy->flags |= SAVEDVAR;
3928 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3933 #if SUPPORT_LONG_LOGICAL
3937 #endif /* SUPPORT_LONG_LOGICAL */
3938 COUNT(count_pcmd_op);
3939 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3945 COUNT(count_pcmd_op);
3946 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3954 COUNT(count_pcmd_op);
3955 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3963 COUNT(count_pcmd_op);
3964 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3968 COUNT(count_pcmd_op);
3969 #if SUPPORT_LONG_CMP_CONST
3970 if ((len == 0) || (iptr[1].sx.val.i != 0))
3973 switch (iptr[1].opc) {
3975 iptr->opc = ICMD_IF_LCMPEQ;
3977 iptr->dst.block = iptr[1].dst.block;
3978 iptr[1].opc = ICMD_NOP;
3980 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3983 COUNT(count_pcmd_bra);
3986 iptr->opc = ICMD_IF_LCMPNE;
3987 goto icmd_lcmp_if_tail;
3989 iptr->opc = ICMD_IF_LCMPLT;
3990 goto icmd_lcmp_if_tail;
3992 iptr->opc = ICMD_IF_LCMPGT;
3993 goto icmd_lcmp_if_tail;
3995 iptr->opc = ICMD_IF_LCMPLE;
3996 goto icmd_lcmp_if_tail;
3998 iptr->opc = ICMD_IF_LCMPGE;
3999 goto icmd_lcmp_if_tail;
4005 #endif /* SUPPORT_LONG_CMP_CONST */
4006 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4011 COUNT(count_pcmd_op);
4012 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4017 COUNT(count_pcmd_op);
4018 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4026 case ICMD_INT2SHORT:
4027 COUNT(count_pcmd_op);
4028 OP1_1(TYPE_INT, TYPE_INT);
4031 COUNT(count_pcmd_op);
4032 OP1_1(TYPE_LNG, TYPE_LNG);
4035 COUNT(count_pcmd_op);
4036 OP1_1(TYPE_FLT, TYPE_FLT);
4039 COUNT(count_pcmd_op);
4040 OP1_1(TYPE_DBL, TYPE_DBL);
4044 COUNT(count_pcmd_op);
4045 OP1_1(TYPE_INT, TYPE_LNG);
4048 COUNT(count_pcmd_op);
4049 OP1_1(TYPE_INT, TYPE_FLT);
4052 COUNT(count_pcmd_op);
4053 OP1_1(TYPE_INT, TYPE_DBL);
4056 COUNT(count_pcmd_op);
4057 OP1_1(TYPE_LNG, TYPE_INT);
4060 COUNT(count_pcmd_op);
4061 OP1_1(TYPE_LNG, TYPE_FLT);
4064 COUNT(count_pcmd_op);
4065 OP1_1(TYPE_LNG, TYPE_DBL);
4068 COUNT(count_pcmd_op);
4069 OP1_1(TYPE_FLT, TYPE_INT);
4072 COUNT(count_pcmd_op);
4073 OP1_1(TYPE_FLT, TYPE_LNG);
4076 COUNT(count_pcmd_op);
4077 OP1_1(TYPE_FLT, TYPE_DBL);
4080 COUNT(count_pcmd_op);
4081 OP1_1(TYPE_DBL, TYPE_INT);
4084 COUNT(count_pcmd_op);
4085 OP1_1(TYPE_DBL, TYPE_LNG);
4088 COUNT(count_pcmd_op);
4089 OP1_1(TYPE_DBL, TYPE_FLT);
4092 case ICMD_CHECKCAST:
4093 coalescing_boundary = sd.new;
4094 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4095 /* array type cast-check */
4097 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4100 if (md->memuse > rd->memuse)
4101 rd->memuse = md->memuse;
4102 if (md->argintreguse > rd->argintreguse)
4103 rd->argintreguse = md->argintreguse;
4105 /* make all stack variables saved */
4109 sd.var[copy->varnum].flags |= SAVEDVAR;
4110 copy->flags |= SAVEDVAR;
4114 OP1_1(TYPE_ADR, TYPE_ADR);
4117 case ICMD_INSTANCEOF:
4118 case ICMD_ARRAYLENGTH:
4119 coalescing_boundary = sd.new;
4120 OP1_1(TYPE_ADR, TYPE_INT);
4124 case ICMD_ANEWARRAY:
4125 coalescing_boundary = sd.new;
4126 OP1_1(TYPE_INT, TYPE_ADR);
4130 coalescing_boundary = sd.new;
4131 COUNT(count_check_null);
4132 COUNT(count_pcmd_mem);
4133 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4134 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4139 case ICMD_GETSTATIC:
4140 coalescing_boundary = sd.new;
4141 COUNT(count_pcmd_mem);
4142 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4143 OP0_1(fmiref->parseddesc.fd->type);
4147 coalescing_boundary = sd.new;
4154 tbptr = iptr->sx.s23.s3.jsrtarget.block;
4155 tbptr->type = BBTYPE_SBR;
4157 assert(sd.bptr->next); /* XXX exception */
4158 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4159 #if defined(ENABLE_VERIFIER)
4160 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4163 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4167 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4169 /* We need to check for overflow right here because
4170 * the pushed value is poped afterwards */
4173 superblockend = true;
4174 /* XXX should not be marked as interface, as it does not need to be */
4175 /* allocated. Same for the invar of the target. */
4178 /* pop many push any */
4182 bte = iptr->sx.s23.s3.bte;
4186 case ICMD_INVOKESTATIC:
4187 case ICMD_INVOKESPECIAL:
4188 case ICMD_INVOKEVIRTUAL:
4189 case ICMD_INVOKEINTERFACE:
4190 COUNT(count_pcmd_met);
4192 /* Check for functions to replace with builtin
4195 if (builtintable_replace_function(iptr))
4198 INSTRUCTION_GET_METHODDESC(iptr, md);
4199 /* XXX resurrect this COUNT? */
4200 /* if (lm->flags & ACC_STATIC) */
4201 /* {COUNT(count_check_null);} */
4205 coalescing_boundary = sd.new;
4209 if (md->memuse > rd->memuse)
4210 rd->memuse = md->memuse;
4211 if (md->argintreguse > rd->argintreguse)
4212 rd->argintreguse = md->argintreguse;
4213 if (md->argfltreguse > rd->argfltreguse)
4214 rd->argfltreguse = md->argfltreguse;
4218 iptr->s1.argcount = stackdepth;
4219 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4222 for (i-- ; i >= 0; i--) {
4223 iptr->sx.s23.s2.args[i] = copy->varnum;
4225 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4226 /* -> won't help anyway */
4227 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4229 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4230 /* If we pass float arguments in integer argument registers, we
4231 * are not allowed to precolor them here. Floats have to be moved
4232 * to this regs explicitly in codegen().
4233 * Only arguments that are passed by stack anyway can be precolored
4234 * (michi 2005/07/24) */
4235 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4236 (!IS_FLT_DBL_TYPE(copy->type)
4237 || md->params[i].inmemory)) {
4239 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4244 if (md->params[i].inmemory) {
4245 sd.var[copy->varnum].vv.regoff =
4246 md->params[i].regoff;
4247 sd.var[copy->varnum].flags |=
4251 if (IS_FLT_DBL_TYPE(copy->type)) {
4252 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4253 assert(0); /* XXX is this assert ok? */
4255 sd.var[copy->varnum].vv.regoff =
4256 md->params[i].regoff;
4257 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4260 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4261 if (IS_2_WORD_TYPE(copy->type))
4262 sd.var[copy->varnum].vv.regoff =
4263 PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4264 GET_HIGH_REG(md->params[i].regoff));
4267 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4268 sd.var[copy->varnum].vv.regoff =
4269 md->params[i].regoff;
4277 /* deal with live-through stack slots "under" the */
4283 iptr->sx.s23.s2.args[i++] = copy->varnum;
4284 sd.var[copy->varnum].flags |= SAVEDVAR;
4285 copy->flags |= SAVEDVAR | PASSTHROUGH;
4289 /* pop the arguments */
4298 /* push the return value */
4300 if (md->returntype.type != TYPE_VOID) {
4301 GET_NEW_VAR(sd, new_index, md->returntype.type);
4302 DST(md->returntype.type, new_index);
4307 case ICMD_MULTIANEWARRAY:
4308 coalescing_boundary = sd.new;
4309 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4310 rd->argintreguse = MIN(3, INT_ARG_CNT);
4312 i = iptr->s1.argcount;
4316 iptr->sx.s23.s2.args = DMNEW(s4, i);
4318 #if defined(SPECIALMEMUSE)
4319 # if defined(__DARWIN__)
4320 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4321 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4323 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4324 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4327 # if defined(__I386__)
4328 if (rd->memuse < i + 3)
4329 rd->memuse = i + 3; /* n integer args spilled on stack */
4330 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4331 if (rd->memuse < i + 2)
4332 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4335 rd->memuse = i; /* n integer args spilled on stack */
4336 # endif /* defined(__I386__) */
4340 /* check INT type here? Currently typecheck does this. */
4341 iptr->sx.s23.s2.args[i] = copy->varnum;
4342 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4343 && (!IS_INOUT(copy))
4344 && (!IS_LOCALVAR(copy)) ) {
4345 copy->varkind = ARGVAR;
4346 sd.var[copy->varnum].flags |=
4347 INMEMORY & PREALLOC;
4348 #if defined(SPECIALMEMUSE)
4349 # if defined(__DARWIN__)
4350 sd.var[copy->varnum].vv.regoff = i +
4351 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4353 sd.var[copy->varnum].vv.regoff = i +
4354 LA_SIZE_IN_POINTERS + 3;
4357 # if defined(__I386__)
4358 sd.var[copy->varnum].vv.regoff = i + 3;
4359 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4360 sd.var[copy->varnum].vv.regoff = i + 2;
4362 sd.var[copy->varnum].vv.regoff = i;
4363 # endif /* defined(__I386__) */
4364 #endif /* defined(SPECIALMEMUSE) */
4369 sd.var[copy->varnum].flags |= SAVEDVAR;
4370 copy->flags |= SAVEDVAR;
4374 i = iptr->s1.argcount;
4379 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4380 DST(TYPE_ADR, new_index);
4385 exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4392 } /* while instructions */
4394 /* show state after last instruction */
4396 #if defined(STACK_VERBOSE)
4397 stack_verbose_show_state(&sd, NULL, curstack);
4400 /* stack slots at basic block end become interfaces */
4402 sd.bptr->outdepth = stackdepth;
4403 sd.bptr->outvars = DMNEW(s4, stackdepth);
4406 for (copy = curstack; copy; i--, copy = copy->prev) {
4409 /* with the new vars rd->interfaces will be removed */
4410 /* and all in and outvars have to be STACKVARS! */
4411 /* in the moment i.e. SWAP with in and out vars can */
4412 /* create an unresolvable conflict */
4417 v = sd.var + copy->varnum;
4420 /* do not allocate variables for returnAddresses */
4422 if (type != TYPE_RET) {
4423 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4424 /* no interface var until now for this depth and */
4426 jd->interface_map[i*5 + type].flags = v->flags;
4429 jd->interface_map[i*5 + type].flags |= v->flags;
4433 sd.bptr->outvars[i] = copy->varnum;
4436 /* check if interface slots at basic block begin must be saved */
4438 for (i=0; i<sd.bptr->indepth; ++i) {
4439 varinfo *v = sd.var + sd.bptr->invars[i];
4443 if (type != TYPE_RET) {
4444 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4445 /* no interface var until now for this depth and */
4447 jd->interface_map[i*5 + type].flags = v->flags;
4450 jd->interface_map[i*5 + type].flags |= v->flags;
4455 /* store the number of this block's variables */
4457 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4459 #if defined(STACK_VERBOSE)
4460 stack_verbose_block_exit(&sd, superblockend);
4463 /* reach the following block, if any */
4466 if (!stack_reach_next_block(&sd))
4471 } while (sd.repeat && !deadcode);
4473 /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4475 /* A local variable may be used as both a returnAddress and a reference */
4476 /* type variable, as we do not split variables between these types when */
4477 /* renaming locals. While returnAddresses have been eliminated now, we */
4478 /* must assume that the variable is still used as TYPE_ADR. */
4479 /* The only way that a local can be TYPE_VOID at this point, is that it */
4480 /* was a TYPE_RET variable for which incompatible returnAddresses were */
4481 /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4483 /* XXX: It would be nice to remove otherwise unused returnAddress */
4484 /* variables from the local variable array, so they are not */
4485 /* allocated by simplereg. (For LSRA this is not needed). */
4487 for (i=0; i<sd.localcount; ++i) {
4488 if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4489 sd.var[i].type = TYPE_ADR;
4492 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4494 for (i=sd.localcount; i<sd.vartop; ++i) {
4495 if (sd.var[i].type == TYPE_RET)
4496 sd.var[i].flags |= PREALLOC;
4499 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4501 ex = jd->exceptiontable;
4502 for (; ex != NULL; ex = ex->down) {
4503 if (ex->start == ex->end) {
4504 assert(ex->end->next);
4505 ex->end = ex->end->next;
4509 /* store number of created variables */
4511 jd->vartop = sd.vartop;
4513 /* gather statistics *****************************************************/
4515 #if defined(ENABLE_STATISTICS)
4517 if (jd->basicblockcount > count_max_basic_blocks)
4518 count_max_basic_blocks = jd->basicblockcount;
4519 count_basic_blocks += jd->basicblockcount;
4520 if (jd->instructioncount > count_max_javainstr)
4521 count_max_javainstr = jd->instructioncount;
4522 count_javainstr += jd->instructioncount;
4523 if (jd->stackcount > count_upper_bound_new_stack)
4524 count_upper_bound_new_stack = jd->stackcount;
4525 if ((sd.new - jd->stack) > count_max_new_stack)
4526 count_max_new_stack = (sd.new - jd->stack);
4528 sd.bptr = jd->basicblocks;
4529 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4530 if (sd.bptr->flags > BBREACHED) {
4531 if (sd.bptr->indepth >= 10)
4532 count_block_stack[10]++;
4534 count_block_stack[sd.bptr->indepth]++;
4535 len = sd.bptr->icount;
4537 count_block_size_distribution[len]++;
4539 count_block_size_distribution[10]++;
4541 count_block_size_distribution[11]++;
4543 count_block_size_distribution[12]++;
4545 count_block_size_distribution[13]++;
4547 count_block_size_distribution[14]++;
4549 count_block_size_distribution[15]++;
4551 count_block_size_distribution[16]++;
4553 count_block_size_distribution[17]++;
4557 if (iteration_count == 1)
4558 count_analyse_iterations[0]++;
4559 else if (iteration_count == 2)
4560 count_analyse_iterations[1]++;
4561 else if (iteration_count == 3)
4562 count_analyse_iterations[2]++;
4563 else if (iteration_count == 4)
4564 count_analyse_iterations[3]++;
4566 count_analyse_iterations[4]++;
4568 if (jd->basicblockcount <= 5)
4569 count_method_bb_distribution[0]++;
4570 else if (jd->basicblockcount <= 10)
4571 count_method_bb_distribution[1]++;
4572 else if (jd->basicblockcount <= 15)
4573 count_method_bb_distribution[2]++;
4574 else if (jd->basicblockcount <= 20)
4575 count_method_bb_distribution[3]++;
4576 else if (jd->basicblockcount <= 30)
4577 count_method_bb_distribution[4]++;
4578 else if (jd->basicblockcount <= 40)
4579 count_method_bb_distribution[5]++;
4580 else if (jd->basicblockcount <= 50)
4581 count_method_bb_distribution[6]++;
4582 else if (jd->basicblockcount <= 75)
4583 count_method_bb_distribution[7]++;
4585 count_method_bb_distribution[8]++;
4587 #endif /* defined(ENABLE_STATISTICS) */
4589 /* everything's ok *******************************************************/
4593 /* goto labels for throwing verifier exceptions **************************/
4595 #if defined(ENABLE_VERIFIER)
4597 throw_stack_underflow:
4598 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4601 throw_stack_overflow:
4602 exceptions_throw_verifyerror(m, "Stack size too large");
4605 throw_stack_type_error:
4606 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4609 throw_stack_category_error:
4610 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4617 /* stack_javalocals_store ******************************************************
4619 Model the effect of a ?STORE instruction upon the given javalocals array.
4622 iptr.............the ?STORE instruction
4623 javalocals.......the javalocals array to modify
4625 *******************************************************************************/
4627 void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4629 s4 varindex; /* index into the jd->var array */
4630 s4 javaindex; /* java local index */
4632 varindex = iptr->dst.varindex;
4633 javaindex = iptr->sx.s23.s3.javaindex;
4635 if (javaindex != UNUSED) {
4636 assert(javaindex >= 0);
4637 if (iptr->flags.bits & INS_FLAG_RETADDR)
4638 javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4640 javalocals[javaindex] = varindex;
4642 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4643 javalocals[javaindex-1] = UNUSED;
4645 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4646 javalocals[javaindex+1] = UNUSED;
4651 /* functions for verbose stack analysis output ********************************/
4653 #if defined(STACK_VERBOSE)
4654 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4656 printf("%c", show_jit_type_letters[v->type]);
4657 if (v->type == TYPE_RET) {
4658 printf("{L%03d}", v->vv.retaddr->nr);
4659 #if defined(ENABLE_VERIFIER)
4660 printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4666 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4668 assert(index >= 0 && index < sd->vartop);
4669 stack_verbose_show_varinfo(sd, sd->var + index);
4673 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4677 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4679 for (i=0; i<bptr->indepth; ++i) {
4682 stack_verbose_show_variable(sd, bptr->invars[i]);
4687 printf("] javalocals ");
4688 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4689 printf(" inlocals [");
4690 if (bptr->inlocals) {
4691 for (i=0; i<sd->localcount; ++i) {
4694 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4699 printf("] out:%d [", bptr->outdepth);
4700 if (bptr->outvars) {
4701 for (i=0; i<bptr->outdepth; ++i) {
4704 stack_verbose_show_variable(sd, bptr->outvars[i]);
4712 printf(" (clone of L%03d)", bptr->original->nr);
4714 basicblock *b = bptr->copied_to;
4716 printf(" (copied to ");
4717 for (; b; b = b->copied_to)
4718 printf("L%03d ", b->nr);
4725 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4729 printf("======================================== STACK %sANALYSE BLOCK ",
4730 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4731 stack_verbose_show_block(sd, sd->bptr);
4734 if (sd->handlers[0]) {
4735 printf("HANDLERS: ");
4736 for (i=0; sd->handlers[i]; ++i) {
4737 printf("L%03d ", sd->handlers[i]->handler->nr);
4745 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4747 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4748 stack_verbose_show_block(sd, sd->bptr);
4752 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackelement_t *curstack)
4758 stackelement_t **stack;
4760 printf(" javalocals ");
4761 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4764 for(i = 0, sp = curstack; sp; sp = sp->prev)
4768 stack = MNEW(stackelement_t *, depth);
4769 for(sp = curstack; sp; sp = sp->prev)
4772 for(i=0; i<depth; ++i) {
4776 v = &(sd->var[sp->varnum]);
4778 if (v->flags & INOUT)
4780 if (v->flags & PREALLOC)
4782 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4783 if (v->type == TYPE_RET) {
4784 printf("(L%03d)", v->vv.retaddr->nr);
4789 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4796 * These are local overrides for various environment variables in Emacs.
4797 * Please do not remove this and leave it at the end of the file, where
4798 * Emacs will automagically detect them.
4799 * ---------------------------------------------------------------------
4802 * indent-tabs-mode: t
4806 * vim:noexpandtab:sw=4:ts=4: