1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "mm/memory.h"
40 #include "native/native.h"
42 #include "toolbox/logging.h"
44 #include "vm/global.h"
45 #include "vm/builtin.h"
46 #include "vm/stringlocal.h"
49 #include "vm/jit/abi.h"
50 #include "vm/jit/cfg.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/parse.h"
53 #include "vm/jit/show.h"
55 #if defined(ENABLE_DISASSEMBLER)
56 # include "vm/jit/disass.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/stack.h"
63 #if defined(ENABLE_SSA)
64 # include "vm/jit/optimizing/lsra.h"
65 # include "vm/jit/optimizing/ssa.h"
66 #elif defined(ENABLE_LSRA)
67 # include "vm/jit/allocator/lsra.h"
71 #include "vmcore/options.h"
72 #include "vm/resolve.h"
74 #if defined(ENABLE_STATISTICS)
75 # include "vmcore/statistics.h"
78 /*#define STACK_VERBOSE*/
81 /* macro for saving #ifdefs ***************************************************/
83 #if defined(ENABLE_STATISTICS)
84 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
87 if (stackdepth >= 10) \
88 count_store_depth[10]++; \
90 count_store_depth[stackdepth]++; \
93 #else /* !defined(ENABLE_STATISTICS) */
94 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
98 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
101 /* For returnAddresses we use a field of the typeinfo to store from which */
102 /* subroutine the returnAddress will return, if used. */
103 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
104 /* to need it initialised to NULL. This should be investigated. */
106 #if defined(ENABLE_VERIFIER)
107 #define SBRSTART typeinfo.elementclass.any
111 /* stackdata_t *****************************************************************
113 This struct holds internal data during stack analysis.
115 *******************************************************************************/
117 typedef struct stackdata_t stackdata_t;
120 basicblock *bptr; /* the current basic block being analysed */
121 stackptr new; /* next free stackelement */
122 s4 vartop; /* next free variable index */
123 s4 localcount; /* number of locals (at the start of var) */
124 s4 varcount; /* maximum number of variables expected */
125 s4 varsallocated; /* total number of variables allocated */
126 s4 maxlocals; /* max. number of Java locals */
127 varinfo *var; /* variable array (same as jd->var) */
128 s4 *javalocals; /* map from Java locals to jd->var indices */
129 methodinfo *m; /* the method being analysed */
130 jitdata *jd; /* current jitdata */
131 basicblock *last_real_block; /* the last block before the empty one */
132 bool repeat; /* if true, iterate the analysis again */
133 exception_entry **handlers; /* exception handlers for the current block */
134 exception_entry *extableend; /* points to the last exception entry */
135 stackelement exstack; /* instack for exception handlers */
139 /* macros for allocating/releasing variable indices *****************/
141 #define GET_NEW_INDEX(sd, new_varindex) \
143 assert((sd).vartop < (sd).varcount); \
144 (new_varindex) = ((sd).vartop)++; \
147 /* Not implemented now - could be used to reuse varindices. */
148 /* Pay attention to not release a localvar once implementing it! */
149 #define RELEASE_INDEX(sd, varindex)
151 #define GET_NEW_VAR(sd, newvarindex, newtype) \
153 GET_NEW_INDEX((sd), (newvarindex)); \
154 (sd).var[newvarindex].type = (newtype); \
158 /* macros for querying variable properties **************************/
160 #define IS_INOUT(sp) \
161 (sd.var[(sp)->varnum].flags & INOUT)
163 #define IS_PREALLOC(sp) \
164 (sd.var[(sp)->varnum].flags & PREALLOC)
166 #define IS_TEMPVAR(sp) \
167 ( ((sp)->varnum >= sd.localcount) \
168 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
171 #define IS_LOCALVAR_SD(sd, sp) \
172 ((sp)->varnum < (sd).localcount)
174 #define IS_LOCALVAR(sp) \
175 IS_LOCALVAR_SD(sd, (sp))
178 /* macros for setting variable properties ****************************/
180 #define SET_TEMPVAR(sp) \
182 if (IS_LOCALVAR((sp))) { \
183 stack_change_to_tempvar(&sd, (sp), iptr); \
185 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
188 #define SET_PREALLOC(sp) \
190 assert(!IS_LOCALVAR((sp))); \
191 sd.var[(sp)->varnum].flags |= PREALLOC; \
195 /* macros for source operands ***************************************/
198 (iptr->s1.varindex = -1)
200 #define USE_S1(type1) \
203 CHECK_BASIC_TYPE(type1, curstack->type); \
204 iptr->s1.varindex = curstack->varnum; \
210 iptr->s1.varindex = curstack->varnum; \
213 #define USE_S1_S2(type1, type2) \
216 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
217 CHECK_BASIC_TYPE(type2, curstack->type); \
218 iptr->sx.s23.s2.varindex = curstack->varnum; \
219 iptr->s1.varindex = curstack->prev->varnum; \
222 #define USE_S1_S2_ANY_ANY \
225 iptr->sx.s23.s2.varindex = curstack->varnum; \
226 iptr->s1.varindex = curstack->prev->varnum; \
229 #define USE_S1_S2_S3(type1, type2, type3) \
232 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
233 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
234 CHECK_BASIC_TYPE(type3, curstack->type); \
235 iptr->sx.s23.s3.varindex = curstack->varnum; \
236 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
237 iptr->s1.varindex = curstack->prev->prev->varnum; \
240 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
243 if (curstack->varkind == UNDEFVAR) \
244 curstack->varkind = TEMPVAR; \
245 curstack = curstack->prev; \
248 #define POP_S1(type1) \
251 if (curstack->varkind == UNDEFVAR) \
252 curstack->varkind = TEMPVAR; \
253 curstack = curstack->prev; \
259 if (curstack->varkind == UNDEFVAR) \
260 curstack->varkind = TEMPVAR; \
261 curstack = curstack->prev; \
264 #define POP_S1_S2(type1, type2) \
266 USE_S1_S2(type1, type2); \
267 if (curstack->varkind == UNDEFVAR) \
268 curstack->varkind = TEMPVAR; \
269 if (curstack->prev->varkind == UNDEFVAR) \
270 curstack->prev->varkind = TEMPVAR; \
271 curstack = curstack->prev->prev; \
274 #define POP_S1_S2_ANY_ANY \
277 if (curstack->varkind == UNDEFVAR) \
278 curstack->varkind = TEMPVAR; \
279 if (curstack->prev->varkind == UNDEFVAR) \
280 curstack->prev->varkind = TEMPVAR; \
281 curstack = curstack->prev->prev; \
284 #define POP_S1_S2_S3(type1, type2, type3) \
286 USE_S1_S2_S3(type1, type2, type3); \
287 if (curstack->varkind == UNDEFVAR) \
288 curstack->varkind = TEMPVAR; \
289 if (curstack->prev->varkind == UNDEFVAR) \
290 curstack->prev->varkind = TEMPVAR; \
291 if (curstack->prev->prev->varkind == UNDEFVAR) \
292 curstack->prev->prev->varkind = TEMPVAR; \
293 curstack = curstack->prev->prev->prev; \
300 /* macros for setting the destination operand ***********************/
303 (iptr->dst.varindex = -1)
305 #define DST(typed, index) \
307 NEWSTACKn((typed),(index)); \
308 curstack->creator = iptr; \
309 iptr->dst.varindex = (index); \
312 #define DST_LOCALVAR(typed, index) \
314 NEWSTACK((typed), LOCALVAR, (index)); \
315 curstack->creator = iptr; \
316 iptr->dst.varindex = (index); \
320 /* macro for propagating constant values ****************************/
322 #if defined(ENABLE_VERIFIER)
323 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
325 if (((dv)->type = (sv)->type) == TYPE_RET) { \
326 (dv)->vv = (sv)->vv; \
327 (dv)->SBRSTART = (sv)->SBRSTART; \
331 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
333 (dv)->type = (sv)->type; \
334 if (((dv)->type = (sv)->type) == TYPE_RET) { \
335 (dv)->vv = (sv)->vv; \
340 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
341 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
344 /* stack modelling macros *******************************************/
346 #define OP0_1(typed) \
349 GET_NEW_VAR(sd, new_index, (typed)); \
350 DST((typed), new_index); \
361 #define OP1_BRANCH(type1) \
367 #define OP1_1(type1, typed) \
370 GET_NEW_VAR(sd, new_index, (typed)); \
371 DST(typed, new_index); \
374 #define OP2_1(type1, type2, typed) \
376 POP_S1_S2(type1, type2); \
377 GET_NEW_VAR(sd, new_index, (typed)); \
378 DST(typed, new_index); \
393 #define OP1_0(type1) \
400 #define OP2_0(type1, type2) \
402 POP_S1_S2(type1, type2); \
407 #define OP2_BRANCH(type1, type2) \
409 POP_S1_S2(type1, type2); \
413 #define OP2_0_ANY_ANY \
420 #define OP3_0(type1, type2, type3) \
422 POP_S1_S2_S3(type1, type2, type3); \
427 #define LOAD(type1, index) \
429 DST_LOCALVAR(type1, index); \
433 #define STORE(type1, index) \
440 /* macros for DUP elimination ***************************************/
442 /* XXX replace NEW_VAR with NEW_INDEX */
443 #define DUP_SLOT(sp) \
445 GET_NEW_VAR(sd, new_index, (sp)->type); \
446 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
447 NEWSTACK((sp)->type, TEMPVAR, new_index); \
450 /* does not check input stackdepth */
451 #define MOVE_UP(sp) \
453 iptr->opc = ICMD_MOVE; \
454 iptr->s1.varindex = (sp)->varnum; \
456 curstack->creator = iptr; \
457 iptr->dst.varindex = curstack->varnum; \
461 /* does not check input stackdepth */
462 #define COPY_UP(sp) \
465 iptr->opc = ICMD_COPY; \
466 iptr->s1.varindex = (sp)->varnum; \
468 curstack->creator = iptr; \
469 iptr->dst.varindex = curstack->varnum; \
473 #define COPY_DOWN(s, d) \
476 iptr->opc = ICMD_COPY; \
477 iptr->s1.varindex = (s)->varnum; \
478 iptr->dst.varindex = (d)->varnum; \
479 (d)->creator = iptr; \
482 #define MOVE_TO_TEMP(sp) \
484 GET_NEW_INDEX(sd, new_index); \
485 iptr->opc = ICMD_MOVE; \
486 iptr->s1.varindex = (sp)->varnum; \
487 iptr->dst.varindex = new_index; \
488 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
489 (sp)->varnum = new_index; \
490 (sp)->varkind = TEMPVAR; \
493 /* macros for branching / reaching basic blocks *********************/
495 #define BRANCH_TARGET(bt, tempbptr) \
497 tempbptr = (bt).block; \
498 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
500 if (tempbptr == NULL) \
502 (bt).block = tempbptr; \
505 #define BRANCH(tempbptr) \
506 BRANCH_TARGET(iptr->dst, tempbptr)
509 /* forward declarations *******************************************************/
511 static void stack_create_invars(stackdata_t *sd, basicblock *b,
512 stackptr curstack, int stackdepth);
513 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
515 #if defined(STACK_VERBOSE)
516 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
517 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
518 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
519 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
520 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
521 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
526 /* stack_init ******************************************************************
528 Initialized the stack analysis subsystem (called by jit_init).
530 *******************************************************************************/
532 bool stack_init(void)
538 /* stack_grow_variable_array ***************************************************
540 Grow the variable array so the given number of additional variables fits in.
541 The number is added to `varcount`, which is the maximum number of variables
542 we expect to need at this point. The actual number of variables
543 (`varsallocated`) may be larger than that, in order to avoid too many
547 sd...........stack analysis data
548 num..........number of additional variables
550 *******************************************************************************/
552 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
558 if (sd->varcount + num > sd->varsallocated) {
559 newsize = 2*sd->varsallocated + num;
561 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
562 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
563 sd->varsallocated = newsize;
564 sd->jd->var = sd->var;
568 sd->jd->varcount += num;
570 assert(sd->varcount <= sd->varsallocated);
574 /* stack_append_block **********************************************************
576 Append the given block after the last real block of the method (before
577 the pseudo-block at the end).
580 sd...........stack analysis data
581 b............the block to append
583 *******************************************************************************/
585 static void stack_append_block(stackdata_t *sd, basicblock *b)
587 #if defined(STACK_VERBOSE)
588 printf("APPENDING BLOCK L%0d\n", b->nr);
591 b->next = sd->last_real_block->next;
592 sd->last_real_block->next = b;
593 sd->last_real_block = b;
594 b->nr = sd->jd->basicblockcount++;
595 b->next->nr = b->nr + 1;
599 /* stack_clone_block ***********************************************************
601 Create a copy of the given block and insert it at the end of the method.
603 CAUTION: This function does not copy the any variables or the instruction
604 list. It _does_, however, reserve space for the block's invars in the
608 sd...........stack analysis data
609 b............the block to clone
612 a pointer to the copy
614 *******************************************************************************/
616 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
620 clone = DNEW(basicblock);
623 clone->iinstr = NULL;
624 clone->inlocals = NULL;
625 clone->javalocals = NULL;
626 clone->invars = NULL;
628 clone->original = (b->original) ? b->original : b;
629 clone->copied_to = clone->original->copied_to;
630 clone->original->copied_to = clone;
632 clone->flags = BBREACHED;
634 stack_append_block(sd, clone);
636 /* reserve space for the invars of the clone */
638 stack_grow_variable_array(sd, b->indepth);
640 #if defined(STACK_VERBOSE)
641 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
648 /* stack_create_locals *********************************************************
650 Create the local variables for the start of the given basic block.
653 sd...........stack analysis data
654 b............block to create the locals for
656 *******************************************************************************/
658 static void stack_create_locals(stackdata_t *sd, basicblock *b)
664 /* copy the current state of the local variables */
665 /* (one extra local is needed by the verifier) */
667 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
669 for (i=0; i<sd->localcount; ++i)
672 /* the current map from java locals to cacao variables */
674 jl = DMNEW(s4, sd->maxlocals);
676 MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
680 /* stack_merge_locals **********************************************************
682 Merge local variables at the beginning of the given basic block.
685 sd...........stack analysis data
686 b............the block that is reached
688 *******************************************************************************/
690 static void stack_merge_locals(stackdata_t *sd, basicblock *b)
696 /* If a javalocal is mapped to different cacao locals along the */
697 /* incoming control-flow edges, it becomes undefined. */
699 for (i=0; i<sd->maxlocals; ++i) {
700 if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
701 b->javalocals[i] = UNUSED;
702 if (b->flags >= BBFINISHED)
703 b->flags = BBTYPECHECK_REACHED;
704 if (b->nr <= sd->bptr->nr)
709 #if defined(ENABLE_VERIFIER)
711 for (i=0; i<sd->localcount; ++i) {
712 dv = b->inlocals + i;
714 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
715 && (sv->SBRSTART != dv->SBRSTART))
717 #if defined(STACK_VERBOSE)
718 printf("JSR MISMATCH: setting variable %d to VOID\n", i);
720 dv->type = TYPE_VOID;
721 if (b->flags >= BBFINISHED)
722 b->flags = BBTYPECHECK_REACHED;
723 sd->repeat = true; /* This is very rare, so just repeat */
727 #endif /* defined(ENABLE_VERIFIER) */
731 /* stack_create_invars *********************************************************
733 Create the invars for the given basic block. Also make a copy of the locals.
736 sd...........stack analysis data
737 b............block to create the invars for
738 curstack.....current stack top
739 stackdepth...current stack depth
741 This function creates STACKDEPTH invars and sets their types to the
742 types to the types of the corresponding slot in the current stack.
744 *******************************************************************************/
746 static void stack_create_invars(stackdata_t *sd, basicblock *b,
747 stackptr curstack, int stackdepth)
755 assert(sd->vartop + stackdepth <= sd->varcount);
757 b->indepth = stackdepth;
758 b->invars = DMNEW(s4, stackdepth);
760 /* allocate the variable indices */
761 index = (sd->vartop += stackdepth);
764 for (sp = curstack; i--; sp = sp->prev) {
765 b->invars[i] = --index;
766 dv = sd->var + index;
767 sv = sd->var + sp->varnum;
769 COPY_VAL_AND_TYPE_VAR(sv, dv);
772 stack_create_locals(sd, b);
776 /* stack_create_invars_from_outvars ********************************************
778 Create the invars for the given basic block. Also make a copy of the locals.
779 Types are propagated from the outvars of the current block.
782 sd...........stack analysis data
783 b............block to create the invars for
785 *******************************************************************************/
787 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
793 n = sd->bptr->outdepth;
794 assert(sd->vartop + n <= sd->varcount);
797 b->invars = DMNEW(s4, n);
800 dv = sd->var + sd->vartop;
802 /* allocate the invars */
804 for (i=0; i<n; ++i, ++dv) {
805 sv = sd->var + sd->bptr->outvars[i];
806 b->invars[i] = sd->vartop++;
808 COPY_VAL_AND_TYPE_VAR(sv, dv);
812 stack_create_locals(sd, b);
816 /* stack_check_invars **********************************************************
818 Check the current stack against the invars of the given basic block.
819 Depth and types must match.
822 sd...........stack analysis data
823 b............block which invars to check against
824 curstack.....current stack top
825 stackdepth...current stack depth
829 NULL.........a VerifyError has been thrown
831 *******************************************************************************/
833 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
834 stackptr curstack, int stackdepth)
843 #if defined(STACK_VERBOSE)
844 printf("stack_check_invars(L%03d)\n", b->nr);
847 /* find original of b */
852 #if defined(STACK_VERBOSE)
853 printf("original is L%03d\n", orig->nr);
858 #if defined(ENABLE_VERIFIER)
859 if (i != stackdepth) {
860 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
868 #if defined(STACK_VERBOSE)
869 printf("checking against ");
870 stack_verbose_show_block(sd, b); printf("\n");
874 for (i = orig->indepth; i--; sp = sp->prev) {
875 dv = sd->var + b->invars[i];
876 sv = sd->var + sp->varnum;
878 #if defined(ENABLE_VERIFIER)
879 if (dv->type != sp->type) {
880 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
885 if (sp->type == TYPE_RET) {
886 #if defined(ENABLE_VERIFIER)
887 if (dv->SBRSTART != sv->SBRSTART) {
888 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
892 if (dv->vv.retaddr != sv->vv.retaddr) {
894 /* don't break! have to check the remaining stackslots */
900 for (i=0; i<sd->localcount; ++i) {
901 dv = b->inlocals + i;
903 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
905 #if defined(ENABLE_VERIFIER)
906 (sv->SBRSTART == dv->SBRSTART) &&
908 (sv->vv.retaddr != dv->vv.retaddr))
918 /* XXX cascading collapse? */
920 stack_merge_locals(sd, b);
922 #if defined(STACK_VERBOSE)
923 printf("------> using L%03d\n", b->nr);
927 } while ((b = b->copied_to) != NULL);
929 b = stack_clone_block(sd, orig);
933 stack_create_invars(sd, b, curstack, stackdepth);
938 /* stack_check_invars_from_outvars *********************************************
940 Check the outvars of the current block against the invars of the given block.
941 Depth and types must match.
944 sd...........stack analysis data
945 b............block which invars to check against
949 NULL.........a VerifyError has been thrown
951 *******************************************************************************/
953 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
961 #if defined(STACK_VERBOSE)
962 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
965 /* find original of b */
970 #if defined(STACK_VERBOSE)
971 printf("original is L%03d\n", orig->nr);
975 n = sd->bptr->outdepth;
977 #if defined(ENABLE_VERIFIER)
979 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
987 #if defined(STACK_VERBOSE)
988 printf("checking against ");
989 stack_verbose_show_block(sd, b); printf("\n");
993 dv = sd->var + b->invars[0];
995 for (i=0; i<n; ++i, ++dv) {
996 sv = sd->var + sd->bptr->outvars[i];
998 #if defined(ENABLE_VERIFIER)
999 if (sv->type != dv->type) {
1000 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1005 if (dv->type == TYPE_RET) {
1006 #if defined(ENABLE_VERIFIER)
1007 if (sv->SBRSTART != dv->SBRSTART) {
1008 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1012 if (sv->vv.retaddr != dv->vv.retaddr) {
1014 /* don't break! have to check the remaining stackslots */
1021 for (i=0; i<sd->localcount; ++i) {
1022 dv = b->inlocals + i;
1025 #if defined(ENABLE_VERIFIER)
1026 (sv->SBRSTART == dv->SBRSTART) &&
1028 (sv->type == TYPE_RET && dv->type == TYPE_RET))
1030 if (sv->vv.retaddr != dv->vv.retaddr) {
1039 /* XXX cascading collapse? */
1041 stack_merge_locals(sd, b);
1043 #if defined(STACK_VERBOSE)
1044 printf("------> using L%03d\n", b->nr);
1048 } while ((b = b->copied_to) != NULL);
1050 b = stack_clone_block(sd, orig);
1054 stack_create_invars_from_outvars(sd, b);
1059 /* stack_create_instack ********************************************************
1061 Create the instack of the current basic block.
1064 sd...........stack analysis data
1067 the current stack top at the start of the basic block.
1069 *******************************************************************************/
1071 static stackptr stack_create_instack(stackdata_t *sd)
1077 if ((depth = sd->bptr->indepth) == 0)
1080 sp = (sd->new += depth);
1084 index = sd->bptr->invars[depth];
1086 sp->type = sd->var[index].type;
1090 sp->varkind = STACKVAR;
1094 /* return the top of the created stack */
1099 /* stack_mark_reached **********************************************************
1101 Mark the given block reached and propagate the current stack and locals to
1102 it. This function specializes the target block, if necessary, and returns
1103 a pointer to the specialized target.
1106 sd...........stack analysis data
1107 b............the block to reach
1108 curstack.....the current stack top
1109 stackdepth...the current stack depth
1112 a pointer to (a specialized version of) the target
1113 NULL.........a VerifyError has been thrown
1115 *******************************************************************************/
1117 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1121 #if defined(STACK_VERBOSE)
1122 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1125 /* mark targets of backward branches */
1127 if (b->nr <= sd->bptr->nr)
1128 b->bitflags |= BBFLAG_REPLACEMENT;
1130 if (b->flags < BBREACHED) {
1131 /* b is reached for the first time. Create its invars. */
1133 #if defined(STACK_VERBOSE)
1134 printf("reached L%03d for the first time\n", b->nr);
1137 stack_create_invars(sd, b, curstack, stackdepth);
1139 b->flags = BBREACHED;
1144 /* b has been reached before. Check that its invars match. */
1146 return stack_check_invars(sd, b, curstack, stackdepth);
1151 /* stack_mark_reached_from_outvars *********************************************
1153 Mark the given block reached and propagate the outvars of the current block
1154 and the current locals to it. This function specializes the target block,
1155 if necessary, and returns a pointer to the specialized target.
1158 sd...........stack analysis data
1159 b............the block to reach
1162 a pointer to (a specialized version of) the target
1163 NULL.........a VerifyError has been thrown
1165 *******************************************************************************/
1167 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1171 #if defined(STACK_VERBOSE)
1172 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1175 /* mark targets of backward branches */
1177 if (b->nr <= sd->bptr->nr)
1178 b->bitflags |= BBFLAG_REPLACEMENT;
1180 if (b->flags < BBREACHED) {
1181 /* b is reached for the first time. Create its invars. */
1183 #if defined(STACK_VERBOSE)
1184 printf("reached L%03d for the first time\n", b->nr);
1187 stack_create_invars_from_outvars(sd, b);
1189 b->flags = BBREACHED;
1194 /* b has been reached before. Check that its invars match. */
1196 return stack_check_invars_from_outvars(sd, b);
1201 /* stack_reach_next_block ******************************************************
1203 Mark the following block reached and propagate the outvars of the
1204 current block and the current locals to it. This function
1205 specializes the target block, if necessary, and returns a pointer
1206 to the specialized target.
1209 sd...........stack analysis data
1212 a pointer to (a specialized version of) the following block
1213 NULL.........a VerifyError has been thrown
1215 *******************************************************************************/
1217 static bool stack_reach_next_block(stackdata_t *sd)
1222 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1223 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1228 if (tbptr != sd->bptr->next) {
1229 #if defined(STACK_VERBOSE)
1230 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1232 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1233 assert(iptr->opc == ICMD_NOP);
1234 iptr->opc = ICMD_GOTO;
1235 iptr->dst.block = tbptr;
1236 #if defined(STACK_VERBOSE)
1237 if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
1240 if (tbptr->flags < BBFINISHED)
1241 sd->repeat = true; /* XXX check if we really need to repeat */
1248 /* stack_reach_handlers ********************************************************
1250 Reach the exception handlers for the current block.
1253 sd...........stack analysis data
1256 true.........everything ok
1257 false........a VerifyError has been thrown
1259 *******************************************************************************/
1261 static bool stack_reach_handlers(stackdata_t *sd)
1266 #if defined(STACK_VERBOSE)
1267 printf("reaching exception handlers...\n");
1270 for (i=0; sd->handlers[i]; ++i) {
1271 tbptr = sd->handlers[i]->handler;
1273 tbptr->type = BBTYPE_EXH;
1274 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1276 /* reach (and specialize) the handler block */
1278 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1283 sd->handlers[i]->handler = tbptr;
1290 /* stack_reanalyse_block ******************************************************
1292 Re-analyse the current block. This is called if either the block itself
1293 has already been analysed before, or the current block is a clone of an
1294 already analysed block, and this clone is reached for the first time.
1295 In the latter case, this function does all that is necessary for fully
1296 cloning the block (cloning the instruction list and variables, etc.).
1299 sd...........stack analysis data
1302 true.........everything ok
1303 false........a VerifyError has been thrown
1305 *******************************************************************************/
1307 #define RELOCATE(index) \
1309 if ((index) >= blockvarstart) \
1310 (index) += blockvarshift; \
1311 else if ((index) >= invarstart) \
1312 (index) += invarshift; \
1315 bool stack_reanalyse_block(stackdata_t *sd)
1327 branch_target_t *table;
1328 lookup_target_t *lookup;
1330 bool cloneinstructions;
1331 exception_entry *ex;
1333 #if defined(STACK_VERBOSE)
1334 stack_verbose_block_enter(sd, true);
1341 assert(orig != NULL);
1343 /* clone the instruction list */
1345 cloneinstructions = true;
1347 assert(orig->iinstr);
1349 iptr = DMNEW(instruction, len + 1);
1351 MCOPY(iptr, orig->iinstr, instruction, len);
1352 iptr[len].opc = ICMD_NOP;
1354 iptr[len].flags.bits = 0;
1358 /* reserve space for the clone's block variables */
1360 stack_grow_variable_array(sd, orig->varcount);
1362 /* we already have the invars set */
1364 assert(b->indepth == orig->indepth);
1366 /* calculate relocation shifts for invars and block variables */
1368 if (orig->indepth) {
1369 invarstart = orig->invars[0];
1370 invarshift = b->invars[0] - invarstart;
1373 invarstart = INT_MAX;
1376 blockvarstart = orig->varstart;
1377 blockvarshift = sd->vartop - blockvarstart;
1379 /* copy block variables */
1381 b->varstart = sd->vartop;
1382 b->varcount = orig->varcount;
1383 sd->vartop += b->varcount;
1384 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1388 b->outdepth = orig->outdepth;
1389 b->outvars = DMNEW(s4, orig->outdepth);
1390 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1392 /* clone exception handlers */
1394 for (i=0; sd->handlers[i]; ++i) {
1395 ex = DNEW(exception_entry);
1396 ex->handler = sd->handlers[i]->handler;
1398 ex->end = b; /* XXX hack, see end of stack_analyse */
1399 ex->catchtype = sd->handlers[i]->catchtype;
1402 assert(sd->extableend->down == NULL);
1403 sd->extableend->down = ex;
1404 sd->extableend = ex;
1405 sd->jd->exceptiontablelength++;
1407 sd->handlers[i] = ex;
1411 cloneinstructions = false;
1414 invarstart = sd->vartop;
1415 blockvarstart = sd->vartop;
1420 /* find exception handlers for the cloned block */
1422 ex = sd->jd->exceptiontable;
1423 for (; ex != NULL; ex = ex->down) {
1424 /* XXX the cloned exception handlers have identical */
1425 /* start end end blocks. */
1426 if ((ex->start == b) && (ex->end == b)) {
1427 sd->handlers[len++] = ex;
1430 sd->handlers[len] = NULL;
1433 #if defined(STACK_VERBOSE)
1434 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1435 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1438 /* mark block as finished */
1440 b->flags = BBFINISHED;
1442 /* initialize locals at the start of this block */
1445 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1447 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1449 /* reach exception handlers for this block */
1451 if (!stack_reach_handlers(sd))
1454 superblockend = false;
1456 for (len = b->icount; len--; iptr++) {
1457 #if defined(STACK_VERBOSE)
1458 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1462 switch (iptr->opc) {
1464 varindex = iptr->s1.varindex;
1466 #if defined(ENABLE_VERIFIER)
1467 if (sd->var[varindex].type != TYPE_RET) {
1468 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1473 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1474 superblockend = true;
1478 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1479 RELOCATE(iptr->dst.varindex);
1480 superblockend = true;
1484 superblockend = true;
1487 case ICMD_CHECKNULL:
1488 case ICMD_PUTSTATICCONST:
1496 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1497 superblockend = true;
1500 /* pop 0 push 1 const */
1508 /* pop 0 push 1 load */
1515 RELOCATE(iptr->dst.varindex);
1528 RELOCATE(iptr->sx.s23.s2.varindex);
1529 RELOCATE(iptr->s1.varindex);
1530 RELOCATE(iptr->dst.varindex);
1543 RELOCATE(iptr->sx.s23.s3.varindex);
1544 RELOCATE(iptr->sx.s23.s2.varindex);
1545 RELOCATE(iptr->s1.varindex);
1548 /* pop 1 push 0 store */
1555 RELOCATE(iptr->s1.varindex);
1557 varindex = iptr->dst.varindex;
1558 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1559 i = iptr->sx.s23.s3.javaindex;
1560 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1561 iptr->sx.s23.s2.retaddrnr =
1562 JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1563 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1566 sd->javalocals[i] = varindex;
1567 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1568 sd->javalocals[i-1] = UNUSED;
1569 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1570 sd->javalocals[i+1] = UNUSED;
1581 RELOCATE(iptr->s1.varindex);
1582 superblockend = true;
1585 case ICMD_PUTSTATIC:
1586 case ICMD_PUTFIELDCONST:
1588 RELOCATE(iptr->s1.varindex);
1591 /* pop 1 push 0 branch */
1594 case ICMD_IFNONNULL:
1609 RELOCATE(iptr->s1.varindex);
1610 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1613 /* pop 1 push 0 table branch */
1615 case ICMD_TABLESWITCH:
1616 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1618 if (cloneinstructions) {
1619 table = DMNEW(branch_target_t, i);
1620 MCOPY(table, iptr->dst.table, branch_target_t, i);
1621 iptr->dst.table = table;
1624 table = iptr->dst.table;
1627 RELOCATE(iptr->s1.varindex);
1629 table->block = stack_mark_reached_from_outvars(sd, table->block);
1632 superblockend = true;
1635 case ICMD_LOOKUPSWITCH:
1636 i = iptr->sx.s23.s2.lookupcount;
1637 if (cloneinstructions) {
1638 lookup = DMNEW(lookup_target_t, i);
1639 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1640 iptr->dst.lookup = lookup;
1643 lookup = iptr->dst.lookup;
1645 RELOCATE(iptr->s1.varindex);
1647 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1650 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1651 superblockend = true;
1654 case ICMD_MONITORENTER:
1655 case ICMD_MONITOREXIT:
1656 RELOCATE(iptr->s1.varindex);
1659 /* pop 2 push 0 branch */
1661 case ICMD_IF_ICMPEQ:
1662 case ICMD_IF_ICMPNE:
1663 case ICMD_IF_ICMPLT:
1664 case ICMD_IF_ICMPGE:
1665 case ICMD_IF_ICMPGT:
1666 case ICMD_IF_ICMPLE:
1668 case ICMD_IF_LCMPEQ:
1669 case ICMD_IF_LCMPNE:
1670 case ICMD_IF_LCMPLT:
1671 case ICMD_IF_LCMPGE:
1672 case ICMD_IF_LCMPGT:
1673 case ICMD_IF_LCMPLE:
1675 case ICMD_IF_ACMPEQ:
1676 case ICMD_IF_ACMPNE:
1677 RELOCATE(iptr->sx.s23.s2.varindex);
1678 RELOCATE(iptr->s1.varindex);
1679 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1685 case ICMD_IASTORECONST:
1686 case ICMD_LASTORECONST:
1687 case ICMD_AASTORECONST:
1688 case ICMD_BASTORECONST:
1689 case ICMD_CASTORECONST:
1690 case ICMD_SASTORECONST:
1692 RELOCATE(iptr->sx.s23.s2.varindex);
1693 RELOCATE(iptr->s1.varindex);
1696 /* pop 0 push 1 copy */
1700 RELOCATE(iptr->dst.varindex);
1701 RELOCATE(iptr->s1.varindex);
1702 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1744 RELOCATE(iptr->sx.s23.s2.varindex);
1745 RELOCATE(iptr->s1.varindex);
1746 RELOCATE(iptr->dst.varindex);
1751 case ICMD_CHECKCAST:
1752 case ICMD_ARRAYLENGTH:
1753 case ICMD_INSTANCEOF:
1755 case ICMD_ANEWARRAY:
1757 case ICMD_IADDCONST:
1758 case ICMD_ISUBCONST:
1759 case ICMD_IMULCONST:
1763 case ICMD_IANDCONST:
1765 case ICMD_IXORCONST:
1766 case ICMD_ISHLCONST:
1767 case ICMD_ISHRCONST:
1768 case ICMD_IUSHRCONST:
1769 case ICMD_LADDCONST:
1770 case ICMD_LSUBCONST:
1771 case ICMD_LMULCONST:
1775 case ICMD_LANDCONST:
1777 case ICMD_LXORCONST:
1778 case ICMD_LSHLCONST:
1779 case ICMD_LSHRCONST:
1780 case ICMD_LUSHRCONST:
1784 case ICMD_INT2SHORT:
1800 RELOCATE(iptr->s1.varindex);
1801 RELOCATE(iptr->dst.varindex);
1806 case ICMD_GETSTATIC:
1808 RELOCATE(iptr->dst.varindex);
1811 /* pop many push any */
1813 case ICMD_INVOKESTATIC:
1814 case ICMD_INVOKESPECIAL:
1815 case ICMD_INVOKEVIRTUAL:
1816 case ICMD_INVOKEINTERFACE:
1818 case ICMD_MULTIANEWARRAY:
1819 i = iptr->s1.argcount;
1820 if (cloneinstructions) {
1821 argp = DMNEW(s4, i);
1822 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1823 iptr->sx.s23.s2.args = argp;
1826 argp = iptr->sx.s23.s2.args;
1833 RELOCATE(iptr->dst.varindex);
1837 exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1842 #if defined(STACK_VERBOSE)
1843 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1848 /* relocate outvars */
1850 for (i=0; i<b->outdepth; ++i) {
1851 RELOCATE(b->outvars[i]);
1854 #if defined(STACK_VERBOSE)
1855 stack_verbose_block_exit(sd, superblockend);
1858 /* propagate to the next block */
1861 if (!stack_reach_next_block(sd))
1868 /* stack_change_to_tempvar *****************************************************
1870 Change the given stackslot to a TEMPVAR. This includes creating a new
1871 temporary variable and changing the dst.varindex of the creator of the
1872 stacklot to the new variable index. If this stackslot has been passed
1873 through ICMDs between the point of its creation and the current point,
1874 then the variable index is also changed in these ICMDs.
1877 sd...........stack analysis data
1878 sp...........stackslot to change
1879 ilimit.......instruction up to which to look for ICMDs passing-through
1880 the stackslot (exclusive). This may point exactly after the
1881 last instruction, in which case the search is done to the
1884 *******************************************************************************/
1886 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1887 instruction *ilimit)
1895 oldindex = sp->varnum;
1897 /* create a new temporary variable */
1899 GET_NEW_VAR(*sd, newindex, sp->type);
1901 sd->var[newindex].flags = sp->flags;
1903 /* change the stackslot */
1905 sp->varnum = newindex;
1906 sp->varkind = TEMPVAR;
1908 /* change the dst.varindex of the stackslot's creator */
1911 sp->creator->dst.varindex = newindex;
1913 /* handle ICMDs this stackslot passed through, if any */
1915 if (sp->flags & PASSTHROUGH) {
1916 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1918 /* assert that the limit points to an ICMD, or after the last one */
1920 assert(ilimit >= sd->bptr->iinstr);
1921 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1923 /* find the stackdepth under sp plus one */
1924 /* Note: This number is usually known when this function is called, */
1925 /* but calculating it here is less error-prone and should not be */
1926 /* a performance problem. */
1928 for (depth = 0; sp != NULL; sp = sp->prev)
1931 /* iterate over all instructions in the range and replace */
1933 for (; iptr < ilimit; ++iptr) {
1934 switch (iptr->opc) {
1935 case ICMD_INVOKESTATIC:
1936 case ICMD_INVOKESPECIAL:
1937 case ICMD_INVOKEVIRTUAL:
1938 case ICMD_INVOKEINTERFACE:
1940 i = iptr->s1.argcount - depth;
1941 if (iptr->sx.s23.s2.args[i] == oldindex) {
1942 iptr->sx.s23.s2.args[i] = newindex;
1945 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1946 /* stackslot, it must be added in this switch! */
1953 /* stack_init_javalocals *******************************************************
1955 Initialize the mapping from Java locals to cacao variables at method entry.
1958 sd...........stack analysis data
1960 *******************************************************************************/
1962 static void stack_init_javalocals(stackdata_t *sd)
1971 jl = DMNEW(s4, sd->maxlocals);
1972 jd->basicblocks[0].javalocals = jl;
1974 for (i=0; i<sd->maxlocals; ++i)
1977 md = jd->m->parseddesc;
1979 for (i=0; i<md->paramcount; ++i) {
1980 type = md->paramtypes[i].type;
1981 jl[j] = jd->local_map[5*j + type];
1983 if (IS_2_WORD_TYPE(type))
1989 /* stack_analyse ***************************************************************
1991 Analyse_stack uses the intermediate code created by parse.c to
1992 build a model of the JVM operand stack for the current method.
1994 The following checks are performed:
1995 - check for operand stack underflow (before each instruction)
1996 - check for operand stack overflow (after[1] each instruction)
1997 - check for matching stack depth at merging points
1998 - check for matching basic types[2] at merging points
1999 - check basic types for instruction input (except for BUILTIN*
2000 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
2002 [1]) Checking this after the instruction should be ok. parse.c
2003 counts the number of required stack slots in such a way that it is
2004 only vital that we don't exceed `maxstack` at basic block
2007 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2008 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2009 types are not discerned.
2011 *******************************************************************************/
2013 bool stack_analyse(jitdata *jd)
2015 methodinfo *m; /* method being analyzed */
2020 stackptr curstack; /* current stack top */
2022 int opcode; /* opcode of current instruction */
2025 int type; /* operand type */
2026 int len; /* # of instructions after the current one */
2027 bool superblockend; /* if true, no fallthrough to next block */
2028 bool deadcode; /* true if no live code has been reached */
2029 instruction *iptr; /* the current instruction */
2031 basicblock *original;
2032 exception_entry *ex;
2034 stackptr *last_store_boundary;
2035 stackptr coalescing_boundary;
2037 stackptr src1, src2, src3, src4, dst1, dst2;
2039 branch_target_t *table;
2040 lookup_target_t *lookup;
2041 #if defined(ENABLE_VERIFIER)
2042 int expectedtype; /* used by CHECK_BASIC_TYPE */
2044 builtintable_entry *bte;
2046 constant_FMIref *fmiref;
2047 #if defined(ENABLE_STATISTICS)
2048 int iteration_count; /* number of iterations of analysis */
2050 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2052 #if defined(STACK_VERBOSE)
2053 show_method(jd, SHOW_PARSE);
2056 /* get required compiler data - initialization */
2062 /* initialize the stackdata_t struct */
2066 sd.varcount = jd->varcount;
2067 sd.vartop = jd->vartop;
2068 sd.localcount = jd->localcount;
2070 sd.varsallocated = sd.varcount;
2071 sd.maxlocals = m->maxlocals;
2072 sd.javalocals = DMNEW(s4, sd.maxlocals);
2073 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2075 /* prepare the variable for exception handler stacks */
2076 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2078 sd.exstack.type = TYPE_ADR;
2079 sd.exstack.prev = NULL;
2080 sd.exstack.varnum = sd.localcount;
2081 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2083 #if defined(ENABLE_STATISTICS)
2084 iteration_count = 0;
2087 /* find the last real basic block */
2089 sd.last_real_block = NULL;
2090 tbptr = jd->basicblocks;
2091 while (tbptr->next) {
2092 sd.last_real_block = tbptr;
2093 tbptr = tbptr->next;
2095 assert(sd.last_real_block);
2097 /* find the last exception handler */
2099 if (jd->exceptiontablelength)
2100 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2102 sd.extableend = NULL;
2104 /* init jd->interface_map */
2106 jd->maxinterfaces = m->maxstack;
2107 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2108 for (i = 0; i < m->maxstack * 5; i++)
2109 jd->interface_map[i].flags = UNUSED;
2111 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2113 /* initialize flags and invars (none) of first block */
2115 jd->basicblocks[0].flags = BBREACHED;
2116 jd->basicblocks[0].invars = NULL;
2117 jd->basicblocks[0].indepth = 0;
2118 jd->basicblocks[0].inlocals =
2119 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2120 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2121 jd->localcount + VERIFIER_EXTRA_LOCALS);
2123 /* initialize java local mapping of first block */
2125 stack_init_javalocals(&sd);
2127 /* stack analysis loop (until fixpoint reached) **************************/
2130 #if defined(ENABLE_STATISTICS)
2134 /* initialize loop over basic blocks */
2136 sd.bptr = jd->basicblocks;
2137 superblockend = true;
2143 /* iterate over basic blocks *****************************************/
2145 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2147 if (sd.bptr->flags == BBDELETED) {
2148 /* This block has been deleted - do nothing. */
2153 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2154 /* re-analyse a block because its input changed */
2158 if (!stack_reanalyse_block(&sd))
2161 superblockend = true; /* XXX */
2165 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2166 /* This block has not been reached so far, and we
2167 don't fall into it, so we'll have to iterate
2174 if (sd.bptr->flags > BBREACHED) {
2175 /* This block is already finished. */
2177 superblockend = true;
2181 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2182 /* This block is a clone and the original has not been
2183 analysed, yet. Analyse it on the next
2187 /* XXX superblockend? */
2191 /* This block has to be analysed now. */
2195 /* XXX The rest of this block is still indented one level too */
2196 /* much in order to avoid a giant diff by changing that. */
2198 /* We know that sd.bptr->flags == BBREACHED. */
2199 /* This block has been reached before. */
2201 assert(sd.bptr->flags == BBREACHED);
2202 stackdepth = sd.bptr->indepth;
2204 /* find exception handlers for this block */
2206 /* determine the active exception handlers for this block */
2207 /* XXX could use a faster algorithm with sorted lists or */
2210 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2213 ex = jd->exceptiontable;
2214 for (; ex != NULL; ex = ex->down) {
2215 if ((ex->start <= original) && (ex->end > original)) {
2216 sd.handlers[len++] = ex;
2219 sd.handlers[len] = NULL;
2222 /* reanalyse cloned block */
2224 if (sd.bptr->original) {
2225 if (!stack_reanalyse_block(&sd))
2230 /* reset the new pointer for allocating stackslots */
2234 /* create the instack of this block */
2236 curstack = stack_create_instack(&sd);
2238 /* initialize locals at the start of this block */
2240 if (sd.bptr->inlocals)
2241 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2243 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2245 /* set up local variables for analyzing this block */
2247 superblockend = false;
2248 len = sd.bptr->icount;
2249 iptr = sd.bptr->iinstr;
2251 /* mark the block as analysed */
2253 sd.bptr->flags = BBFINISHED;
2255 /* reset variables for dependency checking */
2257 coalescing_boundary = sd.new;
2258 for( i = 0; i < m->maxlocals; i++)
2259 last_store_boundary[i] = sd.new;
2261 /* remember the start of this block's variables */
2263 sd.bptr->varstart = sd.vartop;
2265 #if defined(STACK_VERBOSE)
2266 stack_verbose_block_enter(&sd, false);
2269 /* reach exception handlers for this block */
2271 if (!stack_reach_handlers(&sd))
2274 /* iterate over ICMDs ****************************************/
2276 while (--len >= 0) {
2278 #if defined(STACK_VERBOSE)
2279 stack_verbose_show_state(&sd, iptr, curstack);
2282 /* fetch the current opcode */
2286 /* automatically replace some ICMDs with builtins */
2288 bte = builtintable_get_automatic(opcode);
2290 if ((bte != NULL) && (bte->opcode == opcode)) {
2291 iptr->opc = ICMD_BUILTIN;
2292 iptr->flags.bits &= INS_FLAG_ID_MASK;
2293 iptr->sx.s23.s3.bte = bte;
2294 /* iptr->line is already set */
2295 code_unflag_leafmethod(code);
2299 /* main opcode switch *************************************/
2311 case ICMD_CHECKNULL:
2312 coalescing_boundary = sd.new;
2313 COUNT(count_check_null);
2316 iptr->dst.varindex = iptr->s1.varindex;
2320 varindex = iptr->s1.varindex =
2321 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2323 #if defined(ENABLE_VERIFIER)
2324 if (sd.var[varindex].type != TYPE_RET) {
2325 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2332 iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2333 superblockend = true;
2337 COUNT(count_pcmd_return);
2340 superblockend = true;
2341 sd.jd->returncount++;
2342 sd.jd->returnblock = sd.bptr;
2346 /* pop 0 push 1 const */
2348 /************************** ICONST OPTIMIZATIONS **************************/
2351 COUNT(count_pcmd_load);
2355 switch (iptr[1].opc) {
2357 iptr->opc = ICMD_IADDCONST;
2361 iptr[1].opc = ICMD_NOP;
2362 OP1_1(TYPE_INT, TYPE_INT);
2363 COUNT(count_pcmd_op);
2367 iptr->opc = ICMD_ISUBCONST;
2368 goto icmd_iconst_tail;
2369 #if SUPPORT_CONST_MUL
2371 iptr->opc = ICMD_IMULCONST;
2372 goto icmd_iconst_tail;
2373 #else /* SUPPORT_CONST_MUL */
2375 if (iptr->sx.val.i == 0x00000002)
2377 else if (iptr->sx.val.i == 0x00000004)
2379 else if (iptr->sx.val.i == 0x00000008)
2381 else if (iptr->sx.val.i == 0x00000010)
2383 else if (iptr->sx.val.i == 0x00000020)
2385 else if (iptr->sx.val.i == 0x00000040)
2387 else if (iptr->sx.val.i == 0x00000080)
2389 else if (iptr->sx.val.i == 0x00000100)
2391 else if (iptr->sx.val.i == 0x00000200)
2393 else if (iptr->sx.val.i == 0x00000400)
2394 iptr->sx.val.i = 10;
2395 else if (iptr->sx.val.i == 0x00000800)
2396 iptr->sx.val.i = 11;
2397 else if (iptr->sx.val.i == 0x00001000)
2398 iptr->sx.val.i = 12;
2399 else if (iptr->sx.val.i == 0x00002000)
2400 iptr->sx.val.i = 13;
2401 else if (iptr->sx.val.i == 0x00004000)
2402 iptr->sx.val.i = 14;
2403 else if (iptr->sx.val.i == 0x00008000)
2404 iptr->sx.val.i = 15;
2405 else if (iptr->sx.val.i == 0x00010000)
2406 iptr->sx.val.i = 16;
2407 else if (iptr->sx.val.i == 0x00020000)
2408 iptr->sx.val.i = 17;
2409 else if (iptr->sx.val.i == 0x00040000)
2410 iptr->sx.val.i = 18;
2411 else if (iptr->sx.val.i == 0x00080000)
2412 iptr->sx.val.i = 19;
2413 else if (iptr->sx.val.i == 0x00100000)
2414 iptr->sx.val.i = 20;
2415 else if (iptr->sx.val.i == 0x00200000)
2416 iptr->sx.val.i = 21;
2417 else if (iptr->sx.val.i == 0x00400000)
2418 iptr->sx.val.i = 22;
2419 else if (iptr->sx.val.i == 0x00800000)
2420 iptr->sx.val.i = 23;
2421 else if (iptr->sx.val.i == 0x01000000)
2422 iptr->sx.val.i = 24;
2423 else if (iptr->sx.val.i == 0x02000000)
2424 iptr->sx.val.i = 25;
2425 else if (iptr->sx.val.i == 0x04000000)
2426 iptr->sx.val.i = 26;
2427 else if (iptr->sx.val.i == 0x08000000)
2428 iptr->sx.val.i = 27;
2429 else if (iptr->sx.val.i == 0x10000000)
2430 iptr->sx.val.i = 28;
2431 else if (iptr->sx.val.i == 0x20000000)
2432 iptr->sx.val.i = 29;
2433 else if (iptr->sx.val.i == 0x40000000)
2434 iptr->sx.val.i = 30;
2435 else if (iptr->sx.val.i == 0x80000000)
2436 iptr->sx.val.i = 31;
2440 iptr->opc = ICMD_IMULPOW2;
2441 goto icmd_iconst_tail;
2442 #endif /* SUPPORT_CONST_MUL */
2444 if (iptr->sx.val.i == 0x00000002)
2446 else if (iptr->sx.val.i == 0x00000004)
2448 else if (iptr->sx.val.i == 0x00000008)
2450 else if (iptr->sx.val.i == 0x00000010)
2452 else if (iptr->sx.val.i == 0x00000020)
2454 else if (iptr->sx.val.i == 0x00000040)
2456 else if (iptr->sx.val.i == 0x00000080)
2458 else if (iptr->sx.val.i == 0x00000100)
2460 else if (iptr->sx.val.i == 0x00000200)
2462 else if (iptr->sx.val.i == 0x00000400)
2463 iptr->sx.val.i = 10;
2464 else if (iptr->sx.val.i == 0x00000800)
2465 iptr->sx.val.i = 11;
2466 else if (iptr->sx.val.i == 0x00001000)
2467 iptr->sx.val.i = 12;
2468 else if (iptr->sx.val.i == 0x00002000)
2469 iptr->sx.val.i = 13;
2470 else if (iptr->sx.val.i == 0x00004000)
2471 iptr->sx.val.i = 14;
2472 else if (iptr->sx.val.i == 0x00008000)
2473 iptr->sx.val.i = 15;
2474 else if (iptr->sx.val.i == 0x00010000)
2475 iptr->sx.val.i = 16;
2476 else if (iptr->sx.val.i == 0x00020000)
2477 iptr->sx.val.i = 17;
2478 else if (iptr->sx.val.i == 0x00040000)
2479 iptr->sx.val.i = 18;
2480 else if (iptr->sx.val.i == 0x00080000)
2481 iptr->sx.val.i = 19;
2482 else if (iptr->sx.val.i == 0x00100000)
2483 iptr->sx.val.i = 20;
2484 else if (iptr->sx.val.i == 0x00200000)
2485 iptr->sx.val.i = 21;
2486 else if (iptr->sx.val.i == 0x00400000)
2487 iptr->sx.val.i = 22;
2488 else if (iptr->sx.val.i == 0x00800000)
2489 iptr->sx.val.i = 23;
2490 else if (iptr->sx.val.i == 0x01000000)
2491 iptr->sx.val.i = 24;
2492 else if (iptr->sx.val.i == 0x02000000)
2493 iptr->sx.val.i = 25;
2494 else if (iptr->sx.val.i == 0x04000000)
2495 iptr->sx.val.i = 26;
2496 else if (iptr->sx.val.i == 0x08000000)
2497 iptr->sx.val.i = 27;
2498 else if (iptr->sx.val.i == 0x10000000)
2499 iptr->sx.val.i = 28;
2500 else if (iptr->sx.val.i == 0x20000000)
2501 iptr->sx.val.i = 29;
2502 else if (iptr->sx.val.i == 0x40000000)
2503 iptr->sx.val.i = 30;
2504 else if (iptr->sx.val.i == 0x80000000)
2505 iptr->sx.val.i = 31;
2509 iptr->opc = ICMD_IDIVPOW2;
2510 goto icmd_iconst_tail;
2513 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2514 if ((iptr->sx.val.i == 0x00000002) ||
2515 (iptr->sx.val.i == 0x00000004) ||
2516 (iptr->sx.val.i == 0x00000008) ||
2517 (iptr->sx.val.i == 0x00000010) ||
2518 (iptr->sx.val.i == 0x00000020) ||
2519 (iptr->sx.val.i == 0x00000040) ||
2520 (iptr->sx.val.i == 0x00000080) ||
2521 (iptr->sx.val.i == 0x00000100) ||
2522 (iptr->sx.val.i == 0x00000200) ||
2523 (iptr->sx.val.i == 0x00000400) ||
2524 (iptr->sx.val.i == 0x00000800) ||
2525 (iptr->sx.val.i == 0x00001000) ||
2526 (iptr->sx.val.i == 0x00002000) ||
2527 (iptr->sx.val.i == 0x00004000) ||
2528 (iptr->sx.val.i == 0x00008000) ||
2529 (iptr->sx.val.i == 0x00010000) ||
2530 (iptr->sx.val.i == 0x00020000) ||
2531 (iptr->sx.val.i == 0x00040000) ||
2532 (iptr->sx.val.i == 0x00080000) ||
2533 (iptr->sx.val.i == 0x00100000) ||
2534 (iptr->sx.val.i == 0x00200000) ||
2535 (iptr->sx.val.i == 0x00400000) ||
2536 (iptr->sx.val.i == 0x00800000) ||
2537 (iptr->sx.val.i == 0x01000000) ||
2538 (iptr->sx.val.i == 0x02000000) ||
2539 (iptr->sx.val.i == 0x04000000) ||
2540 (iptr->sx.val.i == 0x08000000) ||
2541 (iptr->sx.val.i == 0x10000000) ||
2542 (iptr->sx.val.i == 0x20000000) ||
2543 (iptr->sx.val.i == 0x40000000) ||
2544 (iptr->sx.val.i == 0x80000000))
2546 iptr->opc = ICMD_IREMPOW2;
2547 iptr->sx.val.i -= 1;
2548 goto icmd_iconst_tail;
2551 #if SUPPORT_CONST_LOGICAL
2553 iptr->opc = ICMD_IANDCONST;
2554 goto icmd_iconst_tail;
2557 iptr->opc = ICMD_IORCONST;
2558 goto icmd_iconst_tail;
2561 iptr->opc = ICMD_IXORCONST;
2562 goto icmd_iconst_tail;
2564 #endif /* SUPPORT_CONST_LOGICAL */
2566 iptr->opc = ICMD_ISHLCONST;
2567 goto icmd_iconst_tail;
2570 iptr->opc = ICMD_ISHRCONST;
2571 goto icmd_iconst_tail;
2574 iptr->opc = ICMD_IUSHRCONST;
2575 goto icmd_iconst_tail;
2576 #if SUPPORT_LONG_SHIFT
2578 iptr->opc = ICMD_LSHLCONST;
2579 goto icmd_lconst_tail;
2582 iptr->opc = ICMD_LSHRCONST;
2583 goto icmd_lconst_tail;
2586 iptr->opc = ICMD_LUSHRCONST;
2587 goto icmd_lconst_tail;
2588 #endif /* SUPPORT_LONG_SHIFT */
2589 case ICMD_IF_ICMPEQ:
2590 iptr[1].opc = ICMD_IFEQ;
2594 /* set the constant for the following icmd */
2595 iptr[1].sx.val.i = iptr->sx.val.i;
2597 /* this instruction becomes a nop */
2598 iptr->opc = ICMD_NOP;
2601 case ICMD_IF_ICMPLT:
2602 iptr[1].opc = ICMD_IFLT;
2603 goto icmd_if_icmp_tail;
2605 case ICMD_IF_ICMPLE:
2606 iptr[1].opc = ICMD_IFLE;
2607 goto icmd_if_icmp_tail;
2609 case ICMD_IF_ICMPNE:
2610 iptr[1].opc = ICMD_IFNE;
2611 goto icmd_if_icmp_tail;
2613 case ICMD_IF_ICMPGT:
2614 iptr[1].opc = ICMD_IFGT;
2615 goto icmd_if_icmp_tail;
2617 case ICMD_IF_ICMPGE:
2618 iptr[1].opc = ICMD_IFGE;
2619 goto icmd_if_icmp_tail;
2621 #if SUPPORT_CONST_STORE
2626 # if SUPPORT_CONST_STORE_ZERO_ONLY
2627 if (iptr->sx.val.i != 0)
2630 switch (iptr[1].opc) {
2632 iptr->opc = ICMD_IASTORECONST;
2633 iptr->flags.bits |= INS_FLAG_CHECK;
2636 iptr->opc = ICMD_BASTORECONST;
2637 iptr->flags.bits |= INS_FLAG_CHECK;
2640 iptr->opc = ICMD_CASTORECONST;
2641 iptr->flags.bits |= INS_FLAG_CHECK;
2644 iptr->opc = ICMD_SASTORECONST;
2645 iptr->flags.bits |= INS_FLAG_CHECK;
2649 iptr[1].opc = ICMD_NOP;
2651 /* copy the constant to s3 */
2652 /* XXX constval -> astoreconstval? */
2653 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2654 OP2_0(TYPE_ADR, TYPE_INT);
2655 COUNT(count_pcmd_op);
2658 case ICMD_PUTSTATIC:
2660 # if SUPPORT_CONST_STORE_ZERO_ONLY
2661 if (iptr->sx.val.i != 0)
2664 /* XXX check field type? */
2666 /* copy the constant to s2 */
2667 /* XXX constval -> fieldconstval? */
2668 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2671 /* set the field reference (s3) */
2672 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2673 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2674 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2675 fmiref = iptr->sx.s23.s3.uf->fieldref;
2678 fmiref = iptr[1].sx.s23.s3.fmiref;
2679 iptr->sx.s23.s3.fmiref = fmiref;
2682 #if defined(ENABLE_VERIFIER)
2683 expectedtype = fmiref->parseddesc.fd->type;
2684 switch (iptr[0].opc) {
2686 if (expectedtype != TYPE_INT)
2687 goto throw_stack_type_error;
2690 if (expectedtype != TYPE_LNG)
2691 goto throw_stack_type_error;
2694 if (expectedtype != TYPE_ADR)
2695 goto throw_stack_type_error;
2700 #endif /* defined(ENABLE_VERIFIER) */
2702 switch (iptr[1].opc) {
2703 case ICMD_PUTSTATIC:
2704 iptr->opc = ICMD_PUTSTATICCONST;
2708 iptr->opc = ICMD_PUTFIELDCONST;
2713 iptr[1].opc = ICMD_NOP;
2714 COUNT(count_pcmd_op);
2716 #endif /* SUPPORT_CONST_STORE */
2722 /* if we get here, the ICONST has been optimized */
2726 /* normal case of an unoptimized ICONST */
2730 /************************** LCONST OPTIMIZATIONS **************************/
2733 COUNT(count_pcmd_load);
2737 /* switch depending on the following instruction */
2739 switch (iptr[1].opc) {
2740 #if SUPPORT_LONG_ADD
2742 iptr->opc = ICMD_LADDCONST;
2746 /* instruction of type LONG -> LONG */
2747 iptr[1].opc = ICMD_NOP;
2748 OP1_1(TYPE_LNG, TYPE_LNG);
2749 COUNT(count_pcmd_op);
2753 iptr->opc = ICMD_LSUBCONST;
2754 goto icmd_lconst_tail;
2756 #endif /* SUPPORT_LONG_ADD */
2757 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2759 iptr->opc = ICMD_LMULCONST;
2760 goto icmd_lconst_tail;
2761 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2762 # if SUPPORT_LONG_SHIFT
2764 if (iptr->sx.val.l == 0x00000002)
2766 else if (iptr->sx.val.l == 0x00000004)
2768 else if (iptr->sx.val.l == 0x00000008)
2770 else if (iptr->sx.val.l == 0x00000010)
2772 else if (iptr->sx.val.l == 0x00000020)
2774 else if (iptr->sx.val.l == 0x00000040)
2776 else if (iptr->sx.val.l == 0x00000080)
2778 else if (iptr->sx.val.l == 0x00000100)
2780 else if (iptr->sx.val.l == 0x00000200)
2782 else if (iptr->sx.val.l == 0x00000400)
2783 iptr->sx.val.i = 10;
2784 else if (iptr->sx.val.l == 0x00000800)
2785 iptr->sx.val.i = 11;
2786 else if (iptr->sx.val.l == 0x00001000)
2787 iptr->sx.val.i = 12;
2788 else if (iptr->sx.val.l == 0x00002000)
2789 iptr->sx.val.i = 13;
2790 else if (iptr->sx.val.l == 0x00004000)
2791 iptr->sx.val.i = 14;
2792 else if (iptr->sx.val.l == 0x00008000)
2793 iptr->sx.val.i = 15;
2794 else if (iptr->sx.val.l == 0x00010000)
2795 iptr->sx.val.i = 16;
2796 else if (iptr->sx.val.l == 0x00020000)
2797 iptr->sx.val.i = 17;
2798 else if (iptr->sx.val.l == 0x00040000)
2799 iptr->sx.val.i = 18;
2800 else if (iptr->sx.val.l == 0x00080000)
2801 iptr->sx.val.i = 19;
2802 else if (iptr->sx.val.l == 0x00100000)
2803 iptr->sx.val.i = 20;
2804 else if (iptr->sx.val.l == 0x00200000)
2805 iptr->sx.val.i = 21;
2806 else if (iptr->sx.val.l == 0x00400000)
2807 iptr->sx.val.i = 22;
2808 else if (iptr->sx.val.l == 0x00800000)
2809 iptr->sx.val.i = 23;
2810 else if (iptr->sx.val.l == 0x01000000)
2811 iptr->sx.val.i = 24;
2812 else if (iptr->sx.val.l == 0x02000000)
2813 iptr->sx.val.i = 25;
2814 else if (iptr->sx.val.l == 0x04000000)
2815 iptr->sx.val.i = 26;
2816 else if (iptr->sx.val.l == 0x08000000)
2817 iptr->sx.val.i = 27;
2818 else if (iptr->sx.val.l == 0x10000000)
2819 iptr->sx.val.i = 28;
2820 else if (iptr->sx.val.l == 0x20000000)
2821 iptr->sx.val.i = 29;
2822 else if (iptr->sx.val.l == 0x40000000)
2823 iptr->sx.val.i = 30;
2824 else if (iptr->sx.val.l == 0x80000000)
2825 iptr->sx.val.i = 31;
2829 iptr->opc = ICMD_LMULPOW2;
2830 goto icmd_lconst_tail;
2831 # endif /* SUPPORT_LONG_SHIFT */
2832 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2833 #if SUPPORT_LONG_DIV_POW2
2835 if (iptr->sx.val.l == 0x00000002)
2837 else if (iptr->sx.val.l == 0x00000004)
2839 else if (iptr->sx.val.l == 0x00000008)
2841 else if (iptr->sx.val.l == 0x00000010)
2843 else if (iptr->sx.val.l == 0x00000020)
2845 else if (iptr->sx.val.l == 0x00000040)
2847 else if (iptr->sx.val.l == 0x00000080)
2849 else if (iptr->sx.val.l == 0x00000100)
2851 else if (iptr->sx.val.l == 0x00000200)
2853 else if (iptr->sx.val.l == 0x00000400)
2854 iptr->sx.val.i = 10;
2855 else if (iptr->sx.val.l == 0x00000800)
2856 iptr->sx.val.i = 11;
2857 else if (iptr->sx.val.l == 0x00001000)
2858 iptr->sx.val.i = 12;
2859 else if (iptr->sx.val.l == 0x00002000)
2860 iptr->sx.val.i = 13;
2861 else if (iptr->sx.val.l == 0x00004000)
2862 iptr->sx.val.i = 14;
2863 else if (iptr->sx.val.l == 0x00008000)
2864 iptr->sx.val.i = 15;
2865 else if (iptr->sx.val.l == 0x00010000)
2866 iptr->sx.val.i = 16;
2867 else if (iptr->sx.val.l == 0x00020000)
2868 iptr->sx.val.i = 17;
2869 else if (iptr->sx.val.l == 0x00040000)
2870 iptr->sx.val.i = 18;
2871 else if (iptr->sx.val.l == 0x00080000)
2872 iptr->sx.val.i = 19;
2873 else if (iptr->sx.val.l == 0x00100000)
2874 iptr->sx.val.i = 20;
2875 else if (iptr->sx.val.l == 0x00200000)
2876 iptr->sx.val.i = 21;
2877 else if (iptr->sx.val.l == 0x00400000)
2878 iptr->sx.val.i = 22;
2879 else if (iptr->sx.val.l == 0x00800000)
2880 iptr->sx.val.i = 23;
2881 else if (iptr->sx.val.l == 0x01000000)
2882 iptr->sx.val.i = 24;
2883 else if (iptr->sx.val.l == 0x02000000)
2884 iptr->sx.val.i = 25;
2885 else if (iptr->sx.val.l == 0x04000000)
2886 iptr->sx.val.i = 26;
2887 else if (iptr->sx.val.l == 0x08000000)
2888 iptr->sx.val.i = 27;
2889 else if (iptr->sx.val.l == 0x10000000)
2890 iptr->sx.val.i = 28;
2891 else if (iptr->sx.val.l == 0x20000000)
2892 iptr->sx.val.i = 29;
2893 else if (iptr->sx.val.l == 0x40000000)
2894 iptr->sx.val.i = 30;
2895 else if (iptr->sx.val.l == 0x80000000)
2896 iptr->sx.val.i = 31;
2900 iptr->opc = ICMD_LDIVPOW2;
2901 goto icmd_lconst_tail;
2902 #endif /* SUPPORT_LONG_DIV_POW2 */
2904 #if SUPPORT_LONG_REM_POW2
2906 if ((iptr->sx.val.l == 0x00000002) ||
2907 (iptr->sx.val.l == 0x00000004) ||
2908 (iptr->sx.val.l == 0x00000008) ||
2909 (iptr->sx.val.l == 0x00000010) ||
2910 (iptr->sx.val.l == 0x00000020) ||
2911 (iptr->sx.val.l == 0x00000040) ||
2912 (iptr->sx.val.l == 0x00000080) ||
2913 (iptr->sx.val.l == 0x00000100) ||
2914 (iptr->sx.val.l == 0x00000200) ||
2915 (iptr->sx.val.l == 0x00000400) ||
2916 (iptr->sx.val.l == 0x00000800) ||
2917 (iptr->sx.val.l == 0x00001000) ||
2918 (iptr->sx.val.l == 0x00002000) ||
2919 (iptr->sx.val.l == 0x00004000) ||
2920 (iptr->sx.val.l == 0x00008000) ||
2921 (iptr->sx.val.l == 0x00010000) ||
2922 (iptr->sx.val.l == 0x00020000) ||
2923 (iptr->sx.val.l == 0x00040000) ||
2924 (iptr->sx.val.l == 0x00080000) ||
2925 (iptr->sx.val.l == 0x00100000) ||
2926 (iptr->sx.val.l == 0x00200000) ||
2927 (iptr->sx.val.l == 0x00400000) ||
2928 (iptr->sx.val.l == 0x00800000) ||
2929 (iptr->sx.val.l == 0x01000000) ||
2930 (iptr->sx.val.l == 0x02000000) ||
2931 (iptr->sx.val.l == 0x04000000) ||
2932 (iptr->sx.val.l == 0x08000000) ||
2933 (iptr->sx.val.l == 0x10000000) ||
2934 (iptr->sx.val.l == 0x20000000) ||
2935 (iptr->sx.val.l == 0x40000000) ||
2936 (iptr->sx.val.l == 0x80000000))
2938 iptr->opc = ICMD_LREMPOW2;
2939 iptr->sx.val.l -= 1;
2940 goto icmd_lconst_tail;
2943 #endif /* SUPPORT_LONG_REM_POW2 */
2945 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2948 iptr->opc = ICMD_LANDCONST;
2949 goto icmd_lconst_tail;
2952 iptr->opc = ICMD_LORCONST;
2953 goto icmd_lconst_tail;
2956 iptr->opc = ICMD_LXORCONST;
2957 goto icmd_lconst_tail;
2958 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2960 #if SUPPORT_LONG_CMP_CONST
2962 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2965 /* switch on the instruction after LCONST - LCMP */
2967 switch (iptr[2].opc) {
2969 iptr->opc = ICMD_IF_LEQ;
2972 icmd_lconst_lcmp_tail:
2973 /* convert LCONST, LCMP, IFXX to IF_LXX */
2974 iptr->dst.block = iptr[2].dst.block;
2975 iptr[1].opc = ICMD_NOP;
2976 iptr[2].opc = ICMD_NOP;
2978 OP1_BRANCH(TYPE_LNG);
2980 COUNT(count_pcmd_bra);
2981 COUNT(count_pcmd_op);
2985 iptr->opc = ICMD_IF_LNE;
2986 goto icmd_lconst_lcmp_tail;
2989 iptr->opc = ICMD_IF_LLT;
2990 goto icmd_lconst_lcmp_tail;
2993 iptr->opc = ICMD_IF_LGT;
2994 goto icmd_lconst_lcmp_tail;
2997 iptr->opc = ICMD_IF_LLE;
2998 goto icmd_lconst_lcmp_tail;
3001 iptr->opc = ICMD_IF_LGE;
3002 goto icmd_lconst_lcmp_tail;
3006 } /* end switch on opcode after LCONST - LCMP */
3008 #endif /* SUPPORT_LONG_CMP_CONST */
3010 #if SUPPORT_CONST_STORE
3012 # if SUPPORT_CONST_STORE_ZERO_ONLY
3013 if (iptr->sx.val.l != 0)
3016 #if SIZEOF_VOID_P == 4
3017 /* the constant must fit into a ptrint */
3018 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3021 /* move the constant to s3 */
3022 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3024 iptr->opc = ICMD_LASTORECONST;
3025 iptr->flags.bits |= INS_FLAG_CHECK;
3026 OP2_0(TYPE_ADR, TYPE_INT);
3028 iptr[1].opc = ICMD_NOP;
3029 COUNT(count_pcmd_op);
3032 case ICMD_PUTSTATIC:
3034 # if SUPPORT_CONST_STORE_ZERO_ONLY
3035 if (iptr->sx.val.l != 0)
3038 #if SIZEOF_VOID_P == 4
3039 /* the constant must fit into a ptrint */
3040 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3043 /* XXX check field type? */
3045 /* copy the constant to s2 */
3046 /* XXX constval -> fieldconstval? */
3047 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3051 #endif /* SUPPORT_CONST_STORE */
3055 } /* end switch opcode after LCONST */
3057 /* if we get here, the LCONST has been optimized */
3061 /* the normal case of an unoptimized LCONST */
3065 /************************ END OF LCONST OPTIMIZATIONS *********************/
3068 COUNT(count_pcmd_load);
3073 COUNT(count_pcmd_load);
3077 /************************** ACONST OPTIMIZATIONS **************************/
3080 coalescing_boundary = sd.new;
3081 COUNT(count_pcmd_load);
3082 #if SUPPORT_CONST_STORE
3083 /* We can only optimize if the ACONST is resolved
3084 * and there is an instruction after it. */
3086 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3089 switch (iptr[1].opc) {
3091 /* We can only optimize for NULL values
3092 * here because otherwise a checkcast is
3094 if (iptr->sx.val.anyptr != NULL)
3097 /* copy the constant (NULL) to s3 */
3098 iptr->sx.s23.s3.constval = 0;
3099 iptr->opc = ICMD_AASTORECONST;
3100 iptr->flags.bits |= INS_FLAG_CHECK;
3101 OP2_0(TYPE_ADR, TYPE_INT);
3103 iptr[1].opc = ICMD_NOP;
3104 COUNT(count_pcmd_op);
3107 case ICMD_PUTSTATIC:
3109 # if SUPPORT_CONST_STORE_ZERO_ONLY
3110 if (iptr->sx.val.anyptr != NULL)
3113 /* XXX check field type? */
3114 /* copy the constant to s2 */
3115 /* XXX constval -> fieldconstval? */
3116 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3124 /* if we get here the ACONST has been optimized */
3128 #endif /* SUPPORT_CONST_STORE */
3133 /* pop 0 push 1 load */
3140 COUNT(count_load_instruction);
3141 type = opcode - ICMD_ILOAD;
3143 varindex = iptr->s1.varindex =
3144 jd->local_map[iptr->s1.varindex * 5 + type];
3146 #if defined(ENABLE_VERIFIER)
3147 if (sd.var[varindex].type == TYPE_RET) {
3148 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3152 LOAD(type, varindex);
3161 coalescing_boundary = sd.new;
3162 iptr->flags.bits |= INS_FLAG_CHECK;
3163 COUNT(count_check_null);
3164 COUNT(count_check_bound);
3165 COUNT(count_pcmd_mem);
3166 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3173 coalescing_boundary = sd.new;
3174 iptr->flags.bits |= INS_FLAG_CHECK;
3175 COUNT(count_check_null);
3176 COUNT(count_check_bound);
3177 COUNT(count_pcmd_mem);
3178 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3181 /* pop 0 push 0 iinc */
3184 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3185 javaindex = iptr->s1.varindex;
3186 last_store_boundary[javaindex] = sd.new;
3189 jd->local_map[javaindex * 5 + TYPE_INT];
3194 if ((copy->varkind == LOCALVAR) &&
3195 (jd->reverselocalmap[copy->varnum] == javaindex))
3197 assert(IS_LOCALVAR(copy));
3204 iptr->dst.varindex = iptr->s1.varindex;
3207 /* pop 1 push 0 store */
3216 type = opcode - ICMD_ISTORE;
3217 javaindex = iptr->dst.varindex;
3218 varindex = iptr->dst.varindex =
3219 jd->local_map[javaindex * 5 + type];
3221 COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3223 iptr->sx.s23.s3.javaindex = javaindex;
3225 if (curstack->type == TYPE_RET) {
3226 iptr->flags.bits |= INS_FLAG_RETADDR;
3227 iptr->sx.s23.s2.retaddrnr =
3228 JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3229 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3232 sd.javalocals[javaindex] = varindex;
3234 /* invalidate the following javalocal for 2-word types */
3236 if (IS_2_WORD_TYPE(type)) {
3237 sd.javalocals[javaindex+1] = UNUSED;
3238 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3241 /* invalidate 2-word types if second half was overwritten */
3243 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
3244 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3245 sd.javalocals[javaindex-1] = UNUSED;
3246 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3250 #if defined(ENABLE_STATISTICS)
3253 i = sd.new - curstack;
3255 count_store_length[20]++;
3257 count_store_length[i]++;
3260 count_store_depth[10]++;
3262 count_store_depth[i]++;
3266 /* check for conflicts as described in Figure 5.2 */
3268 copy = curstack->prev;
3271 if ((copy->varkind == LOCALVAR) &&
3272 (jd->reverselocalmap[copy->varnum] == javaindex))
3274 copy->varkind = TEMPVAR;
3275 assert(IS_LOCALVAR(copy));
3282 /* if the variable is already coalesced, don't bother */
3284 /* We do not need to check against INOUT, as invars */
3285 /* are always before the coalescing boundary. */
3287 if (curstack->varkind == LOCALVAR)
3290 /* there is no STORE Lj while curstack is live */
3292 if (curstack < last_store_boundary[javaindex])
3293 goto assume_conflict;
3295 /* curstack must be after the coalescing boundary */
3297 if (curstack < coalescing_boundary)
3298 goto assume_conflict;
3300 /* there is no DEF LOCALVAR(varindex) while curstack is live */
3302 copy = sd.new; /* most recent stackslot created + 1 */
3303 while (--copy > curstack) {
3304 if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
3305 goto assume_conflict;
3308 /* coalesce the temporary variable with Lj */
3309 assert((curstack->varkind == TEMPVAR)
3310 || (curstack->varkind == UNDEFVAR));
3311 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3312 assert(!IS_INOUT(curstack));
3313 assert(!IS_PREALLOC(curstack));
3315 assert(curstack->creator);
3316 assert(curstack->creator->dst.varindex == curstack->varnum);
3317 assert(!(curstack->flags & PASSTHROUGH));
3318 RELEASE_INDEX(sd, curstack);
3319 curstack->varkind = LOCALVAR;
3320 curstack->varnum = varindex;
3321 curstack->creator->dst.varindex = varindex;
3324 /* revert the coalescing, if it has been done earlier */
3326 if ((curstack->varkind == LOCALVAR)
3327 && (jd->reverselocalmap[curstack->varnum] == javaindex))
3329 assert(IS_LOCALVAR(curstack));
3330 SET_TEMPVAR(curstack);
3333 /* remember the stack boundary at this store */
3335 last_store_boundary[javaindex] = sd.new;
3337 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3338 STORE(TYPE_RET, varindex);
3340 STORE(opcode - ICMD_ISTORE, varindex);
3346 coalescing_boundary = sd.new;
3347 iptr->flags.bits |= INS_FLAG_CHECK;
3348 COUNT(count_check_null);
3349 COUNT(count_check_bound);
3350 COUNT(count_pcmd_mem);
3352 bte = builtintable_get_internal(BUILTIN_FAST_canstore);
3355 if (md->memuse > rd->memuse)
3356 rd->memuse = md->memuse;
3357 if (md->argintreguse > rd->argintreguse)
3358 rd->argintreguse = md->argintreguse;
3359 /* XXX non-leaf method? */
3361 /* make all stack variables saved */
3365 sd.var[copy->varnum].flags |= SAVEDVAR;
3366 /* in case copy->varnum is/will be a LOCALVAR */
3367 /* once and set back to a non LOCALVAR */
3368 /* the correct SAVEDVAR flag has to be */
3369 /* remembered in copy->flags, too */
3370 copy->flags |= SAVEDVAR;
3374 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3381 coalescing_boundary = sd.new;
3382 iptr->flags.bits |= INS_FLAG_CHECK;
3383 COUNT(count_check_null);
3384 COUNT(count_check_bound);
3385 COUNT(count_pcmd_mem);
3386 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3393 coalescing_boundary = sd.new;
3394 iptr->flags.bits |= INS_FLAG_CHECK;
3395 COUNT(count_check_null);
3396 COUNT(count_check_bound);
3397 COUNT(count_pcmd_mem);
3398 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3404 #ifdef ENABLE_VERIFIER
3407 if (IS_2_WORD_TYPE(curstack->type))
3408 goto throw_stack_category_error;
3419 coalescing_boundary = sd.new;
3420 /* Assert here that no LOCAL or INOUTS get */
3421 /* preallocated, since tha macros are not */
3422 /* available in md-abi.c! */
3423 if (IS_TEMPVAR(curstack))
3424 md_return_alloc(jd, curstack);
3425 COUNT(count_pcmd_return);
3426 OP1_0(opcode - ICMD_IRETURN);
3427 superblockend = true;
3428 sd.jd->returncount++;
3429 sd.jd->returnblock = sd.bptr;
3433 coalescing_boundary = sd.new;
3434 COUNT(count_check_null);
3436 curstack = NULL; stackdepth = 0;
3437 superblockend = true;
3440 case ICMD_PUTSTATIC:
3441 coalescing_boundary = sd.new;
3442 COUNT(count_pcmd_mem);
3443 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3444 OP1_0(fmiref->parseddesc.fd->type);
3447 /* pop 1 push 0 branch */
3450 case ICMD_IFNONNULL:
3451 COUNT(count_pcmd_bra);
3452 OP1_BRANCH(TYPE_ADR);
3462 COUNT(count_pcmd_bra);
3463 /* iptr->sx.val.i is set implicitly in parse by
3464 clearing the memory or from IF_ICMPxx
3467 OP1_BRANCH(TYPE_INT);
3468 /* iptr->sx.val.i = 0; */
3472 /* pop 0 push 0 branch */
3475 COUNT(count_pcmd_bra);
3478 superblockend = true;
3481 /* pop 1 push 0 table branch */
3483 case ICMD_TABLESWITCH:
3484 COUNT(count_pcmd_table);
3485 OP1_BRANCH(TYPE_INT);
3487 table = iptr->dst.table;
3488 BRANCH_TARGET(*table, tbptr);
3491 i = iptr->sx.s23.s3.tablehigh
3492 - iptr->sx.s23.s2.tablelow + 1;
3495 BRANCH_TARGET(*table, tbptr);
3498 superblockend = true;
3501 /* pop 1 push 0 table branch */
3503 case ICMD_LOOKUPSWITCH:
3504 COUNT(count_pcmd_table);
3505 OP1_BRANCH(TYPE_INT);
3507 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3509 lookup = iptr->dst.lookup;
3511 i = iptr->sx.s23.s2.lookupcount;
3514 BRANCH_TARGET(lookup->target, tbptr);
3517 superblockend = true;
3520 case ICMD_MONITORENTER:
3521 case ICMD_MONITOREXIT:
3522 coalescing_boundary = sd.new;
3523 COUNT(count_check_null);
3527 /* pop 2 push 0 branch */
3529 case ICMD_IF_ICMPEQ:
3530 case ICMD_IF_ICMPNE:
3531 case ICMD_IF_ICMPLT:
3532 case ICMD_IF_ICMPGE:
3533 case ICMD_IF_ICMPGT:
3534 case ICMD_IF_ICMPLE:
3535 COUNT(count_pcmd_bra);
3536 OP2_BRANCH(TYPE_INT, TYPE_INT);
3540 case ICMD_IF_ACMPEQ:
3541 case ICMD_IF_ACMPNE:
3542 COUNT(count_pcmd_bra);
3543 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3550 coalescing_boundary = sd.new;
3551 COUNT(count_check_null);
3552 COUNT(count_pcmd_mem);
3553 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3554 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3559 if (!IS_2_WORD_TYPE(curstack->type)) {
3561 #ifdef ENABLE_VERIFIER
3564 if (IS_2_WORD_TYPE(curstack->prev->type))
3565 goto throw_stack_category_error;
3568 OP2_0_ANY_ANY; /* pop two slots */
3571 iptr->opc = ICMD_POP;
3572 OP1_0_ANY; /* pop one (two-word) slot */
3576 /* pop 0 push 1 dup */
3579 #ifdef ENABLE_VERIFIER
3582 if (IS_2_WORD_TYPE(curstack->type))
3583 goto throw_stack_category_error;
3586 COUNT(count_dup_instruction);
3592 coalescing_boundary = sd.new - 1;
3597 if (IS_2_WORD_TYPE(curstack->type)) {
3599 iptr->opc = ICMD_DUP;
3604 /* ..., ????, cat1 */
3605 #ifdef ENABLE_VERIFIER
3607 if (IS_2_WORD_TYPE(curstack->prev->type))
3608 goto throw_stack_category_error;
3611 src1 = curstack->prev;
3614 COPY_UP(src1); iptr++; len--;
3617 coalescing_boundary = sd.new;
3621 /* pop 2 push 3 dup */
3624 #ifdef ENABLE_VERIFIER
3627 if (IS_2_WORD_TYPE(curstack->type) ||
3628 IS_2_WORD_TYPE(curstack->prev->type))
3629 goto throw_stack_category_error;
3634 src1 = curstack->prev;
3639 /* move non-temporary sources out of the way */
3640 if (!IS_TEMPVAR(src2)) {
3641 MOVE_TO_TEMP(src2); iptr++; len--;
3644 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3646 MOVE_UP(src1); iptr++; len--;
3647 MOVE_UP(src2); iptr++; len--;
3649 COPY_DOWN(curstack, dst1);
3651 coalescing_boundary = sd.new;
3656 if (IS_2_WORD_TYPE(curstack->type)) {
3657 /* ..., ????, cat2 */
3658 #ifdef ENABLE_VERIFIER
3660 if (IS_2_WORD_TYPE(curstack->prev->type))
3661 goto throw_stack_category_error;
3664 iptr->opc = ICMD_DUP_X1;
3668 /* ..., ????, cat1 */
3669 #ifdef ENABLE_VERIFIER
3672 if (IS_2_WORD_TYPE(curstack->prev->type)
3673 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3674 goto throw_stack_category_error;
3679 src1 = curstack->prev->prev;
3680 src2 = curstack->prev;
3682 POPANY; POPANY; POPANY;
3685 /* move non-temporary sources out of the way */
3686 if (!IS_TEMPVAR(src2)) {
3687 MOVE_TO_TEMP(src2); iptr++; len--;
3689 if (!IS_TEMPVAR(src3)) {
3690 MOVE_TO_TEMP(src3); iptr++; len--;
3693 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3694 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3696 MOVE_UP(src1); iptr++; len--;
3697 MOVE_UP(src2); iptr++; len--;
3698 MOVE_UP(src3); iptr++; len--;
3700 COPY_DOWN(curstack, dst2); iptr++; len--;
3701 COPY_DOWN(curstack->prev, dst1);
3703 coalescing_boundary = sd.new;
3707 /* pop 3 push 4 dup */
3711 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3712 /* ..., cat2, ???? */
3713 #ifdef ENABLE_VERIFIER
3715 if (IS_2_WORD_TYPE(curstack->type))
3716 goto throw_stack_category_error;
3719 iptr->opc = ICMD_DUP_X1;
3723 /* ..., cat1, ???? */
3724 #ifdef ENABLE_VERIFIER
3727 if (IS_2_WORD_TYPE(curstack->type)
3728 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3729 goto throw_stack_category_error;
3733 src1 = curstack->prev->prev;
3734 src2 = curstack->prev;
3736 POPANY; POPANY; POPANY;
3739 /* move non-temporary sources out of the way */
3740 if (!IS_TEMPVAR(src2)) {
3741 MOVE_TO_TEMP(src2); iptr++; len--;
3743 if (!IS_TEMPVAR(src3)) {
3744 MOVE_TO_TEMP(src3); iptr++; len--;
3747 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3749 MOVE_UP(src1); iptr++; len--;
3750 MOVE_UP(src2); iptr++; len--;
3751 MOVE_UP(src3); iptr++; len--;
3753 COPY_DOWN(curstack, dst1);
3755 coalescing_boundary = sd.new;
3761 if (IS_2_WORD_TYPE(curstack->type)) {
3762 /* ..., ????, cat2 */
3763 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3764 /* ..., cat2, cat2 */
3765 iptr->opc = ICMD_DUP_X1;
3769 /* ..., cat1, cat2 */
3770 #ifdef ENABLE_VERIFIER
3773 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3774 goto throw_stack_category_error;
3777 iptr->opc = ICMD_DUP_X2;
3783 /* ..., ????, ????, cat1 */
3785 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3786 /* ..., cat2, ????, cat1 */
3787 #ifdef ENABLE_VERIFIER
3789 if (IS_2_WORD_TYPE(curstack->prev->type))
3790 goto throw_stack_category_error;
3793 iptr->opc = ICMD_DUP2_X1;
3797 /* ..., cat1, ????, cat1 */
3798 #ifdef ENABLE_VERIFIER
3801 if (IS_2_WORD_TYPE(curstack->prev->type)
3802 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3803 goto throw_stack_category_error;
3807 src1 = curstack->prev->prev->prev;
3808 src2 = curstack->prev->prev;
3809 src3 = curstack->prev;
3811 POPANY; POPANY; POPANY; POPANY;
3814 /* move non-temporary sources out of the way */
3815 if (!IS_TEMPVAR(src2)) {
3816 MOVE_TO_TEMP(src2); iptr++; len--;
3818 if (!IS_TEMPVAR(src3)) {
3819 MOVE_TO_TEMP(src3); iptr++; len--;
3821 if (!IS_TEMPVAR(src4)) {
3822 MOVE_TO_TEMP(src4); iptr++; len--;
3825 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3826 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3828 MOVE_UP(src1); iptr++; len--;
3829 MOVE_UP(src2); iptr++; len--;
3830 MOVE_UP(src3); iptr++; len--;
3831 MOVE_UP(src4); iptr++; len--;
3833 COPY_DOWN(curstack, dst2); iptr++; len--;
3834 COPY_DOWN(curstack->prev, dst1);
3836 coalescing_boundary = sd.new;
3840 /* pop 2 push 2 swap */
3843 #ifdef ENABLE_VERIFIER
3846 if (IS_2_WORD_TYPE(curstack->type)
3847 || IS_2_WORD_TYPE(curstack->prev->type))
3848 goto throw_stack_category_error;
3852 src1 = curstack->prev;
3857 /* move non-temporary sources out of the way */
3858 if (!IS_TEMPVAR(src1)) {
3859 MOVE_TO_TEMP(src1); iptr++; len--;
3862 MOVE_UP(src2); iptr++; len--;
3865 coalescing_boundary = sd.new;
3872 coalescing_boundary = sd.new;
3873 #if !SUPPORT_DIVISION
3874 bte = iptr->sx.s23.s3.bte;
3877 if (md->memuse > rd->memuse)
3878 rd->memuse = md->memuse;
3879 if (md->argintreguse > rd->argintreguse)
3880 rd->argintreguse = md->argintreguse;
3882 /* make all stack variables saved */
3886 sd.var[copy->varnum].flags |= SAVEDVAR;
3887 copy->flags |= SAVEDVAR;
3892 #endif /* !SUPPORT_DIVISION */
3903 COUNT(count_pcmd_op);
3904 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3909 coalescing_boundary = sd.new;
3910 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3911 bte = iptr->sx.s23.s3.bte;
3914 if (md->memuse > rd->memuse)
3915 rd->memuse = md->memuse;
3916 if (md->argintreguse > rd->argintreguse)
3917 rd->argintreguse = md->argintreguse;
3918 /* XXX non-leaf method? */
3920 /* make all stack variables saved */
3924 sd.var[copy->varnum].flags |= SAVEDVAR;
3925 copy->flags |= SAVEDVAR;
3930 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3935 #if SUPPORT_LONG_LOGICAL
3939 #endif /* SUPPORT_LONG_LOGICAL */
3940 COUNT(count_pcmd_op);
3941 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3947 COUNT(count_pcmd_op);
3948 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3956 COUNT(count_pcmd_op);
3957 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3965 COUNT(count_pcmd_op);
3966 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3970 COUNT(count_pcmd_op);
3971 #if SUPPORT_LONG_CMP_CONST
3972 if ((len == 0) || (iptr[1].sx.val.i != 0))
3975 switch (iptr[1].opc) {
3977 iptr->opc = ICMD_IF_LCMPEQ;
3979 iptr->dst.block = iptr[1].dst.block;
3980 iptr[1].opc = ICMD_NOP;
3982 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3985 COUNT(count_pcmd_bra);
3988 iptr->opc = ICMD_IF_LCMPNE;
3989 goto icmd_lcmp_if_tail;
3991 iptr->opc = ICMD_IF_LCMPLT;
3992 goto icmd_lcmp_if_tail;
3994 iptr->opc = ICMD_IF_LCMPGT;
3995 goto icmd_lcmp_if_tail;
3997 iptr->opc = ICMD_IF_LCMPLE;
3998 goto icmd_lcmp_if_tail;
4000 iptr->opc = ICMD_IF_LCMPGE;
4001 goto icmd_lcmp_if_tail;
4007 #endif /* SUPPORT_LONG_CMP_CONST */
4008 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4013 COUNT(count_pcmd_op);
4014 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4019 COUNT(count_pcmd_op);
4020 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4028 case ICMD_INT2SHORT:
4029 COUNT(count_pcmd_op);
4030 OP1_1(TYPE_INT, TYPE_INT);
4033 COUNT(count_pcmd_op);
4034 OP1_1(TYPE_LNG, TYPE_LNG);
4037 COUNT(count_pcmd_op);
4038 OP1_1(TYPE_FLT, TYPE_FLT);
4041 COUNT(count_pcmd_op);
4042 OP1_1(TYPE_DBL, TYPE_DBL);
4046 COUNT(count_pcmd_op);
4047 OP1_1(TYPE_INT, TYPE_LNG);
4050 COUNT(count_pcmd_op);
4051 OP1_1(TYPE_INT, TYPE_FLT);
4054 COUNT(count_pcmd_op);
4055 OP1_1(TYPE_INT, TYPE_DBL);
4058 COUNT(count_pcmd_op);
4059 OP1_1(TYPE_LNG, TYPE_INT);
4062 COUNT(count_pcmd_op);
4063 OP1_1(TYPE_LNG, TYPE_FLT);
4066 COUNT(count_pcmd_op);
4067 OP1_1(TYPE_LNG, TYPE_DBL);
4070 COUNT(count_pcmd_op);
4071 OP1_1(TYPE_FLT, TYPE_INT);
4074 COUNT(count_pcmd_op);
4075 OP1_1(TYPE_FLT, TYPE_LNG);
4078 COUNT(count_pcmd_op);
4079 OP1_1(TYPE_FLT, TYPE_DBL);
4082 COUNT(count_pcmd_op);
4083 OP1_1(TYPE_DBL, TYPE_INT);
4086 COUNT(count_pcmd_op);
4087 OP1_1(TYPE_DBL, TYPE_LNG);
4090 COUNT(count_pcmd_op);
4091 OP1_1(TYPE_DBL, TYPE_FLT);
4094 case ICMD_CHECKCAST:
4095 coalescing_boundary = sd.new;
4096 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4097 /* array type cast-check */
4099 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4102 if (md->memuse > rd->memuse)
4103 rd->memuse = md->memuse;
4104 if (md->argintreguse > rd->argintreguse)
4105 rd->argintreguse = md->argintreguse;
4107 /* make all stack variables saved */
4111 sd.var[copy->varnum].flags |= SAVEDVAR;
4112 copy->flags |= SAVEDVAR;
4116 OP1_1(TYPE_ADR, TYPE_ADR);
4119 case ICMD_INSTANCEOF:
4120 case ICMD_ARRAYLENGTH:
4121 coalescing_boundary = sd.new;
4122 OP1_1(TYPE_ADR, TYPE_INT);
4126 case ICMD_ANEWARRAY:
4127 coalescing_boundary = sd.new;
4128 OP1_1(TYPE_INT, TYPE_ADR);
4132 coalescing_boundary = sd.new;
4133 COUNT(count_check_null);
4134 COUNT(count_pcmd_mem);
4135 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4136 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4141 case ICMD_GETSTATIC:
4142 coalescing_boundary = sd.new;
4143 COUNT(count_pcmd_mem);
4144 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4145 OP0_1(fmiref->parseddesc.fd->type);
4149 coalescing_boundary = sd.new;
4156 tbptr = iptr->sx.s23.s3.jsrtarget.block;
4157 tbptr->type = BBTYPE_SBR;
4159 assert(sd.bptr->next); /* XXX exception */
4160 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4161 #if defined(ENABLE_VERIFIER)
4162 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4165 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4169 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4171 /* We need to check for overflow right here because
4172 * the pushed value is poped afterwards */
4175 superblockend = true;
4176 /* XXX should not be marked as interface, as it does not need to be */
4177 /* allocated. Same for the invar of the target. */
4180 /* pop many push any */
4184 bte = iptr->sx.s23.s3.bte;
4188 case ICMD_INVOKESTATIC:
4189 case ICMD_INVOKESPECIAL:
4190 case ICMD_INVOKEVIRTUAL:
4191 case ICMD_INVOKEINTERFACE:
4192 COUNT(count_pcmd_met);
4194 /* Check for functions to replace with builtin
4197 if (builtintable_replace_function(iptr))
4200 INSTRUCTION_GET_METHODDESC(iptr, md);
4201 /* XXX resurrect this COUNT? */
4202 /* if (lm->flags & ACC_STATIC) */
4203 /* {COUNT(count_check_null);} */
4207 coalescing_boundary = sd.new;
4211 if (md->memuse > rd->memuse)
4212 rd->memuse = md->memuse;
4213 if (md->argintreguse > rd->argintreguse)
4214 rd->argintreguse = md->argintreguse;
4215 if (md->argfltreguse > rd->argfltreguse)
4216 rd->argfltreguse = md->argfltreguse;
4220 iptr->s1.argcount = stackdepth;
4221 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4224 for (i-- ; i >= 0; i--) {
4225 iptr->sx.s23.s2.args[i] = copy->varnum;
4227 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4228 /* -> won't help anyway */
4229 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4231 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4232 /* If we pass float arguments in integer argument registers, we
4233 * are not allowed to precolor them here. Floats have to be moved
4234 * to this regs explicitly in codegen().
4235 * Only arguments that are passed by stack anyway can be precolored
4236 * (michi 2005/07/24) */
4237 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4238 (!IS_FLT_DBL_TYPE(copy->type)
4239 || md->params[i].inmemory)) {
4241 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4246 if (md->params[i].inmemory) {
4247 sd.var[copy->varnum].vv.regoff =
4248 md->params[i].regoff;
4249 sd.var[copy->varnum].flags |=
4253 if (IS_FLT_DBL_TYPE(copy->type)) {
4254 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4255 assert(0); /* XXX is this assert ok? */
4257 sd.var[copy->varnum].vv.regoff =
4258 md->params[i].regoff;
4259 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4262 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4263 if (IS_2_WORD_TYPE(copy->type))
4264 sd.var[copy->varnum].vv.regoff =
4265 PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4266 GET_HIGH_REG(md->params[i].regoff));
4269 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4270 sd.var[copy->varnum].vv.regoff =
4271 md->params[i].regoff;
4279 /* deal with live-through stack slots "under" the */
4285 iptr->sx.s23.s2.args[i++] = copy->varnum;
4286 sd.var[copy->varnum].flags |= SAVEDVAR;
4287 copy->flags |= SAVEDVAR | PASSTHROUGH;
4291 /* pop the arguments */
4300 /* push the return value */
4302 if (md->returntype.type != TYPE_VOID) {
4303 GET_NEW_VAR(sd, new_index, md->returntype.type);
4304 DST(md->returntype.type, new_index);
4309 case ICMD_MULTIANEWARRAY:
4310 coalescing_boundary = sd.new;
4311 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4312 rd->argintreguse = MIN(3, INT_ARG_CNT);
4314 i = iptr->s1.argcount;
4318 iptr->sx.s23.s2.args = DMNEW(s4, i);
4320 #if defined(SPECIALMEMUSE)
4321 # if defined(__DARWIN__)
4322 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4323 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4325 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4326 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4329 # if defined(__I386__)
4330 if (rd->memuse < i + 3)
4331 rd->memuse = i + 3; /* n integer args spilled on stack */
4332 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4333 if (rd->memuse < i + 2)
4334 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4337 rd->memuse = i; /* n integer args spilled on stack */
4338 # endif /* defined(__I386__) */
4342 /* check INT type here? Currently typecheck does this. */
4343 iptr->sx.s23.s2.args[i] = copy->varnum;
4344 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4345 && (!IS_INOUT(copy))
4346 && (!IS_LOCALVAR(copy)) ) {
4347 copy->varkind = ARGVAR;
4348 sd.var[copy->varnum].flags |=
4349 INMEMORY & PREALLOC;
4350 #if defined(SPECIALMEMUSE)
4351 # if defined(__DARWIN__)
4352 sd.var[copy->varnum].vv.regoff = i +
4353 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4355 sd.var[copy->varnum].vv.regoff = i +
4356 LA_SIZE_IN_POINTERS + 3;
4359 # if defined(__I386__)
4360 sd.var[copy->varnum].vv.regoff = i + 3;
4361 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4362 sd.var[copy->varnum].vv.regoff = i + 2;
4364 sd.var[copy->varnum].vv.regoff = i;
4365 # endif /* defined(__I386__) */
4366 #endif /* defined(SPECIALMEMUSE) */
4371 sd.var[copy->varnum].flags |= SAVEDVAR;
4372 copy->flags |= SAVEDVAR;
4376 i = iptr->s1.argcount;
4381 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4382 DST(TYPE_ADR, new_index);
4387 exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4394 } /* while instructions */
4396 /* show state after last instruction */
4398 #if defined(STACK_VERBOSE)
4399 stack_verbose_show_state(&sd, NULL, curstack);
4402 /* stack slots at basic block end become interfaces */
4404 sd.bptr->outdepth = stackdepth;
4405 sd.bptr->outvars = DMNEW(s4, stackdepth);
4408 for (copy = curstack; copy; i--, copy = copy->prev) {
4411 /* with the new vars rd->interfaces will be removed */
4412 /* and all in and outvars have to be STACKVARS! */
4413 /* in the moment i.e. SWAP with in and out vars can */
4414 /* create an unresolvable conflict */
4419 v = sd.var + copy->varnum;
4422 /* do not allocate variables for returnAddresses */
4424 if (type != TYPE_RET) {
4425 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4426 /* no interface var until now for this depth and */
4428 jd->interface_map[i*5 + type].flags = v->flags;
4431 jd->interface_map[i*5 + type].flags |= v->flags;
4435 sd.bptr->outvars[i] = copy->varnum;
4438 /* check if interface slots at basic block begin must be saved */
4440 for (i=0; i<sd.bptr->indepth; ++i) {
4441 varinfo *v = sd.var + sd.bptr->invars[i];
4445 if (type != TYPE_RET) {
4446 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4447 /* no interface var until now for this depth and */
4449 jd->interface_map[i*5 + type].flags = v->flags;
4452 jd->interface_map[i*5 + type].flags |= v->flags;
4457 /* store the number of this block's variables */
4459 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4461 #if defined(STACK_VERBOSE)
4462 stack_verbose_block_exit(&sd, superblockend);
4465 /* reach the following block, if any */
4468 if (!stack_reach_next_block(&sd))
4473 } while (sd.repeat && !deadcode);
4475 /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4477 /* A local variable may be used as both a returnAddress and a reference */
4478 /* type variable, as we do not split variables between these types when */
4479 /* renaming locals. While returnAddresses have been eliminated now, we */
4480 /* must assume that the variable is still used as TYPE_ADR. */
4481 /* The only way that a local can be TYPE_VOID at this point, is that it */
4482 /* was a TYPE_RET variable for which incompatible returnAddresses were */
4483 /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4485 /* XXX: It would be nice to remove otherwise unused returnAddress */
4486 /* variables from the local variable array, so they are not */
4487 /* allocated by simplereg. (For LSRA this is not needed). */
4489 for (i=0; i<sd.localcount; ++i) {
4490 if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4491 sd.var[i].type = TYPE_ADR;
4494 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4496 for (i=sd.localcount; i<sd.vartop; ++i) {
4497 if (sd.var[i].type == TYPE_RET)
4498 sd.var[i].flags |= PREALLOC;
4501 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4503 ex = jd->exceptiontable;
4504 for (; ex != NULL; ex = ex->down) {
4505 if (ex->start == ex->end) {
4506 assert(ex->end->next);
4507 ex->end = ex->end->next;
4511 /* store number of created variables */
4513 jd->vartop = sd.vartop;
4515 /* gather statistics *****************************************************/
4517 #if defined(ENABLE_STATISTICS)
4519 if (jd->basicblockcount > count_max_basic_blocks)
4520 count_max_basic_blocks = jd->basicblockcount;
4521 count_basic_blocks += jd->basicblockcount;
4522 if (jd->instructioncount > count_max_javainstr)
4523 count_max_javainstr = jd->instructioncount;
4524 count_javainstr += jd->instructioncount;
4525 if (jd->stackcount > count_upper_bound_new_stack)
4526 count_upper_bound_new_stack = jd->stackcount;
4527 if ((sd.new - jd->stack) > count_max_new_stack)
4528 count_max_new_stack = (sd.new - jd->stack);
4530 sd.bptr = jd->basicblocks;
4531 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4532 if (sd.bptr->flags > BBREACHED) {
4533 if (sd.bptr->indepth >= 10)
4534 count_block_stack[10]++;
4536 count_block_stack[sd.bptr->indepth]++;
4537 len = sd.bptr->icount;
4539 count_block_size_distribution[len]++;
4541 count_block_size_distribution[10]++;
4543 count_block_size_distribution[11]++;
4545 count_block_size_distribution[12]++;
4547 count_block_size_distribution[13]++;
4549 count_block_size_distribution[14]++;
4551 count_block_size_distribution[15]++;
4553 count_block_size_distribution[16]++;
4555 count_block_size_distribution[17]++;
4559 if (iteration_count == 1)
4560 count_analyse_iterations[0]++;
4561 else if (iteration_count == 2)
4562 count_analyse_iterations[1]++;
4563 else if (iteration_count == 3)
4564 count_analyse_iterations[2]++;
4565 else if (iteration_count == 4)
4566 count_analyse_iterations[3]++;
4568 count_analyse_iterations[4]++;
4570 if (jd->basicblockcount <= 5)
4571 count_method_bb_distribution[0]++;
4572 else if (jd->basicblockcount <= 10)
4573 count_method_bb_distribution[1]++;
4574 else if (jd->basicblockcount <= 15)
4575 count_method_bb_distribution[2]++;
4576 else if (jd->basicblockcount <= 20)
4577 count_method_bb_distribution[3]++;
4578 else if (jd->basicblockcount <= 30)
4579 count_method_bb_distribution[4]++;
4580 else if (jd->basicblockcount <= 40)
4581 count_method_bb_distribution[5]++;
4582 else if (jd->basicblockcount <= 50)
4583 count_method_bb_distribution[6]++;
4584 else if (jd->basicblockcount <= 75)
4585 count_method_bb_distribution[7]++;
4587 count_method_bb_distribution[8]++;
4589 #endif /* defined(ENABLE_STATISTICS) */
4591 /* everything's ok *******************************************************/
4595 /* goto labels for throwing verifier exceptions **************************/
4597 #if defined(ENABLE_VERIFIER)
4599 throw_stack_underflow:
4600 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4603 throw_stack_overflow:
4604 exceptions_throw_verifyerror(m, "Stack size too large");
4607 throw_stack_type_error:
4608 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4611 throw_stack_category_error:
4612 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4619 /* stack_javalocals_store ******************************************************
4621 Model the effect of a ?STORE instruction upon the given javalocals array.
4624 iptr.............the ?STORE instruction
4625 javalocals.......the javalocals array to modify
4627 *******************************************************************************/
4629 void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4631 s4 varindex; /* index into the jd->var array */
4632 s4 javaindex; /* java local index */
4634 varindex = iptr->dst.varindex;
4635 javaindex = iptr->sx.s23.s3.javaindex;
4637 if (javaindex != UNUSED) {
4638 assert(javaindex >= 0);
4639 if (iptr->flags.bits & INS_FLAG_RETADDR)
4640 javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4642 javalocals[javaindex] = varindex;
4644 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4645 javalocals[javaindex-1] = UNUSED;
4647 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4648 javalocals[javaindex+1] = UNUSED;
4653 /* functions for verbose stack analysis output ********************************/
4655 #if defined(STACK_VERBOSE)
4656 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4658 printf("%c", show_jit_type_letters[v->type]);
4659 if (v->type == TYPE_RET) {
4660 printf("{L%03d}", v->vv.retaddr->nr);
4661 #if defined(ENABLE_VERIFIER)
4662 printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4668 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4670 assert(index >= 0 && index < sd->vartop);
4671 stack_verbose_show_varinfo(sd, sd->var + index);
4675 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4679 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4681 for (i=0; i<bptr->indepth; ++i) {
4684 stack_verbose_show_variable(sd, bptr->invars[i]);
4689 printf("] javalocals ");
4690 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4691 printf(" inlocals [");
4692 if (bptr->inlocals) {
4693 for (i=0; i<sd->localcount; ++i) {
4696 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4701 printf("] out:%d [", bptr->outdepth);
4702 if (bptr->outvars) {
4703 for (i=0; i<bptr->outdepth; ++i) {
4706 stack_verbose_show_variable(sd, bptr->outvars[i]);
4714 printf(" (clone of L%03d)", bptr->original->nr);
4716 basicblock *b = bptr->copied_to;
4718 printf(" (copied to ");
4719 for (; b; b = b->copied_to)
4720 printf("L%03d ", b->nr);
4727 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4731 printf("======================================== STACK %sANALYSE BLOCK ",
4732 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4733 stack_verbose_show_block(sd, sd->bptr);
4736 if (sd->handlers[0]) {
4737 printf("HANDLERS: ");
4738 for (i=0; sd->handlers[i]; ++i) {
4739 printf("L%03d ", sd->handlers[i]->handler->nr);
4747 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4749 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4750 stack_verbose_show_block(sd, sd->bptr);
4754 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
4762 printf(" javalocals ");
4763 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4766 for(i = 0, sp = curstack; sp; sp = sp->prev)
4770 stack = MNEW(stackptr, depth);
4771 for(sp = curstack; sp; sp = sp->prev)
4774 for(i=0; i<depth; ++i) {
4778 v = &(sd->var[sp->varnum]);
4780 if (v->flags & INOUT)
4782 if (v->flags & PREALLOC)
4784 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4785 if (v->type == TYPE_RET) {
4786 printf("(L%03d)", v->vv.retaddr->nr);
4791 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4798 * These are local overrides for various environment variables in Emacs.
4799 * Please do not remove this and leave it at the end of the file, where
4800 * Emacs will automagically detect them.
4801 * ---------------------------------------------------------------------
4804 * indent-tabs-mode: t
4808 * vim:noexpandtab:sw=4:ts=4: