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;
1237 if (tbptr->flags < BBFINISHED)
1238 sd->repeat = true; /* XXX check if we really need to repeat */
1245 /* stack_reach_handlers ********************************************************
1247 Reach the exception handlers for the current block.
1250 sd...........stack analysis data
1253 true.........everything ok
1254 false........a VerifyError has been thrown
1256 *******************************************************************************/
1258 static bool stack_reach_handlers(stackdata_t *sd)
1263 #if defined(STACK_VERBOSE)
1264 printf("reaching exception handlers...\n");
1267 for (i=0; sd->handlers[i]; ++i) {
1268 tbptr = sd->handlers[i]->handler;
1270 tbptr->type = BBTYPE_EXH;
1271 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1273 /* reach (and specialize) the handler block */
1275 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1280 sd->handlers[i]->handler = tbptr;
1287 /* stack_reanalyse_block ******************************************************
1289 Re-analyse the current block. This is called if either the block itself
1290 has already been analysed before, or the current block is a clone of an
1291 already analysed block, and this clone is reached for the first time.
1292 In the latter case, this function does all that is necessary for fully
1293 cloning the block (cloning the instruction list and variables, etc.).
1296 sd...........stack analysis data
1299 true.........everything ok
1300 false........a VerifyError has been thrown
1302 *******************************************************************************/
1304 #define RELOCATE(index) \
1306 if ((index) >= blockvarstart) \
1307 (index) += blockvarshift; \
1308 else if ((index) >= invarstart) \
1309 (index) += invarshift; \
1312 bool stack_reanalyse_block(stackdata_t *sd)
1324 branch_target_t *table;
1325 lookup_target_t *lookup;
1327 bool cloneinstructions;
1328 exception_entry *ex;
1330 #if defined(STACK_VERBOSE)
1331 stack_verbose_block_enter(sd, true);
1338 assert(orig != NULL);
1340 /* clone the instruction list */
1342 cloneinstructions = true;
1344 assert(orig->iinstr);
1346 iptr = DMNEW(instruction, len + 1);
1348 MCOPY(iptr, orig->iinstr, instruction, len);
1349 iptr[len].opc = ICMD_NOP;
1351 iptr[len].flags.bits = 0;
1355 /* reserve space for the clone's block variables */
1357 stack_grow_variable_array(sd, orig->varcount);
1359 /* we already have the invars set */
1361 assert(b->indepth == orig->indepth);
1363 /* calculate relocation shifts for invars and block variables */
1365 if (orig->indepth) {
1366 invarstart = orig->invars[0];
1367 invarshift = b->invars[0] - invarstart;
1370 invarstart = INT_MAX;
1373 blockvarstart = orig->varstart;
1374 blockvarshift = sd->vartop - blockvarstart;
1376 /* copy block variables */
1378 b->varstart = sd->vartop;
1379 b->varcount = orig->varcount;
1380 sd->vartop += b->varcount;
1381 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1385 b->outdepth = orig->outdepth;
1386 b->outvars = DMNEW(s4, orig->outdepth);
1387 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1389 /* clone exception handlers */
1391 for (i=0; sd->handlers[i]; ++i) {
1392 ex = DNEW(exception_entry);
1393 ex->handler = sd->handlers[i]->handler;
1395 ex->end = b; /* XXX hack, see end of stack_analyse */
1396 ex->catchtype = sd->handlers[i]->catchtype;
1399 assert(sd->extableend->down == NULL);
1400 sd->extableend->down = ex;
1401 sd->extableend = ex;
1402 sd->jd->exceptiontablelength++;
1404 sd->handlers[i] = ex;
1408 cloneinstructions = false;
1411 invarstart = sd->vartop;
1412 blockvarstart = sd->vartop;
1417 /* find exception handlers for the cloned block */
1419 ex = sd->jd->exceptiontable;
1420 for (; ex != NULL; ex = ex->down) {
1421 /* XXX the cloned exception handlers have identical */
1422 /* start end end blocks. */
1423 if ((ex->start == b) && (ex->end == b)) {
1424 sd->handlers[len++] = ex;
1427 sd->handlers[len] = NULL;
1430 #if defined(STACK_VERBOSE)
1431 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1432 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1435 /* mark block as finished */
1437 b->flags = BBFINISHED;
1439 /* initialize locals at the start of this block */
1442 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1444 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1446 /* reach exception handlers for this block */
1448 if (!stack_reach_handlers(sd))
1451 superblockend = false;
1453 for (len = b->icount; len--; iptr++) {
1454 #if defined(STACK_VERBOSE)
1455 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1459 switch (iptr->opc) {
1461 varindex = iptr->s1.varindex;
1463 #if defined(ENABLE_VERIFIER)
1464 if (sd->var[varindex].type != TYPE_RET) {
1465 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1470 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
1471 superblockend = true;
1475 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1476 RELOCATE(iptr->dst.varindex);
1477 superblockend = true;
1481 superblockend = true;
1484 case ICMD_CHECKNULL:
1485 case ICMD_PUTSTATICCONST:
1493 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1494 superblockend = true;
1497 /* pop 0 push 1 const */
1505 /* pop 0 push 1 load */
1512 RELOCATE(iptr->dst.varindex);
1525 RELOCATE(iptr->sx.s23.s2.varindex);
1526 RELOCATE(iptr->s1.varindex);
1527 RELOCATE(iptr->dst.varindex);
1540 RELOCATE(iptr->sx.s23.s3.varindex);
1541 RELOCATE(iptr->sx.s23.s2.varindex);
1542 RELOCATE(iptr->s1.varindex);
1545 /* pop 1 push 0 store */
1552 RELOCATE(iptr->s1.varindex);
1554 varindex = iptr->dst.varindex;
1555 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
1556 i = iptr->sx.s23.s3.javaindex;
1557 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1558 iptr->sx.s23.s2.retaddrnr =
1559 JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
1560 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1563 sd->javalocals[i] = varindex;
1564 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1565 sd->javalocals[i-1] = UNUSED;
1566 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1567 sd->javalocals[i+1] = UNUSED;
1578 RELOCATE(iptr->s1.varindex);
1579 superblockend = true;
1582 case ICMD_PUTSTATIC:
1583 case ICMD_PUTFIELDCONST:
1585 RELOCATE(iptr->s1.varindex);
1588 /* pop 1 push 0 branch */
1591 case ICMD_IFNONNULL:
1606 RELOCATE(iptr->s1.varindex);
1607 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1610 /* pop 1 push 0 table branch */
1612 case ICMD_TABLESWITCH:
1613 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1615 if (cloneinstructions) {
1616 table = DMNEW(branch_target_t, i);
1617 MCOPY(table, iptr->dst.table, branch_target_t, i);
1618 iptr->dst.table = table;
1621 table = iptr->dst.table;
1624 RELOCATE(iptr->s1.varindex);
1626 table->block = stack_mark_reached_from_outvars(sd, table->block);
1629 superblockend = true;
1632 case ICMD_LOOKUPSWITCH:
1633 i = iptr->sx.s23.s2.lookupcount;
1634 if (cloneinstructions) {
1635 lookup = DMNEW(lookup_target_t, i);
1636 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1637 iptr->dst.lookup = lookup;
1640 lookup = iptr->dst.lookup;
1642 RELOCATE(iptr->s1.varindex);
1644 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1647 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1648 superblockend = true;
1651 case ICMD_MONITORENTER:
1652 case ICMD_MONITOREXIT:
1653 RELOCATE(iptr->s1.varindex);
1656 /* pop 2 push 0 branch */
1658 case ICMD_IF_ICMPEQ:
1659 case ICMD_IF_ICMPNE:
1660 case ICMD_IF_ICMPLT:
1661 case ICMD_IF_ICMPGE:
1662 case ICMD_IF_ICMPGT:
1663 case ICMD_IF_ICMPLE:
1665 case ICMD_IF_LCMPEQ:
1666 case ICMD_IF_LCMPNE:
1667 case ICMD_IF_LCMPLT:
1668 case ICMD_IF_LCMPGE:
1669 case ICMD_IF_LCMPGT:
1670 case ICMD_IF_LCMPLE:
1672 case ICMD_IF_ACMPEQ:
1673 case ICMD_IF_ACMPNE:
1674 RELOCATE(iptr->sx.s23.s2.varindex);
1675 RELOCATE(iptr->s1.varindex);
1676 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1682 case ICMD_IASTORECONST:
1683 case ICMD_LASTORECONST:
1684 case ICMD_AASTORECONST:
1685 case ICMD_BASTORECONST:
1686 case ICMD_CASTORECONST:
1687 case ICMD_SASTORECONST:
1689 RELOCATE(iptr->sx.s23.s2.varindex);
1690 RELOCATE(iptr->s1.varindex);
1693 /* pop 0 push 1 copy */
1697 RELOCATE(iptr->dst.varindex);
1698 RELOCATE(iptr->s1.varindex);
1699 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1741 RELOCATE(iptr->sx.s23.s2.varindex);
1742 RELOCATE(iptr->s1.varindex);
1743 RELOCATE(iptr->dst.varindex);
1748 case ICMD_CHECKCAST:
1749 case ICMD_ARRAYLENGTH:
1750 case ICMD_INSTANCEOF:
1752 case ICMD_ANEWARRAY:
1754 case ICMD_IADDCONST:
1755 case ICMD_ISUBCONST:
1756 case ICMD_IMULCONST:
1760 case ICMD_IANDCONST:
1762 case ICMD_IXORCONST:
1763 case ICMD_ISHLCONST:
1764 case ICMD_ISHRCONST:
1765 case ICMD_IUSHRCONST:
1766 case ICMD_LADDCONST:
1767 case ICMD_LSUBCONST:
1768 case ICMD_LMULCONST:
1772 case ICMD_LANDCONST:
1774 case ICMD_LXORCONST:
1775 case ICMD_LSHLCONST:
1776 case ICMD_LSHRCONST:
1777 case ICMD_LUSHRCONST:
1781 case ICMD_INT2SHORT:
1797 RELOCATE(iptr->s1.varindex);
1798 RELOCATE(iptr->dst.varindex);
1803 case ICMD_GETSTATIC:
1805 RELOCATE(iptr->dst.varindex);
1808 /* pop many push any */
1810 case ICMD_INVOKESTATIC:
1811 case ICMD_INVOKESPECIAL:
1812 case ICMD_INVOKEVIRTUAL:
1813 case ICMD_INVOKEINTERFACE:
1815 case ICMD_MULTIANEWARRAY:
1816 i = iptr->s1.argcount;
1817 if (cloneinstructions) {
1818 argp = DMNEW(s4, i);
1819 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1820 iptr->sx.s23.s2.args = argp;
1823 argp = iptr->sx.s23.s2.args;
1830 RELOCATE(iptr->dst.varindex);
1834 exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
1839 #if defined(STACK_VERBOSE)
1840 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1845 /* relocate outvars */
1847 for (i=0; i<b->outdepth; ++i) {
1848 RELOCATE(b->outvars[i]);
1851 #if defined(STACK_VERBOSE)
1852 stack_verbose_block_exit(sd, superblockend);
1855 /* propagate to the next block */
1858 if (!stack_reach_next_block(sd))
1865 /* stack_change_to_tempvar *****************************************************
1867 Change the given stackslot to a TEMPVAR. This includes creating a new
1868 temporary variable and changing the dst.varindex of the creator of the
1869 stacklot to the new variable index. If this stackslot has been passed
1870 through ICMDs between the point of its creation and the current point,
1871 then the variable index is also changed in these ICMDs.
1874 sd...........stack analysis data
1875 sp...........stackslot to change
1876 ilimit.......instruction up to which to look for ICMDs passing-through
1877 the stackslot (exclusive). This may point exactly after the
1878 last instruction, in which case the search is done to the
1881 *******************************************************************************/
1883 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1884 instruction *ilimit)
1892 oldindex = sp->varnum;
1894 /* create a new temporary variable */
1896 GET_NEW_VAR(*sd, newindex, sp->type);
1898 sd->var[newindex].flags = sp->flags;
1900 /* change the stackslot */
1902 sp->varnum = newindex;
1903 sp->varkind = TEMPVAR;
1905 /* change the dst.varindex of the stackslot's creator */
1908 sp->creator->dst.varindex = newindex;
1910 /* handle ICMDs this stackslot passed through, if any */
1912 if (sp->flags & PASSTHROUGH) {
1913 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1915 /* assert that the limit points to an ICMD, or after the last one */
1917 assert(ilimit >= sd->bptr->iinstr);
1918 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1920 /* find the stackdepth under sp plus one */
1921 /* Note: This number is usually known when this function is called, */
1922 /* but calculating it here is less error-prone and should not be */
1923 /* a performance problem. */
1925 for (depth = 0; sp != NULL; sp = sp->prev)
1928 /* iterate over all instructions in the range and replace */
1930 for (; iptr < ilimit; ++iptr) {
1931 switch (iptr->opc) {
1932 case ICMD_INVOKESTATIC:
1933 case ICMD_INVOKESPECIAL:
1934 case ICMD_INVOKEVIRTUAL:
1935 case ICMD_INVOKEINTERFACE:
1937 i = iptr->s1.argcount - depth;
1938 if (iptr->sx.s23.s2.args[i] == oldindex) {
1939 iptr->sx.s23.s2.args[i] = newindex;
1942 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1943 /* stackslot, it must be added in this switch! */
1950 /* stack_init_javalocals *******************************************************
1952 Initialize the mapping from Java locals to cacao variables at method entry.
1955 sd...........stack analysis data
1957 *******************************************************************************/
1959 static void stack_init_javalocals(stackdata_t *sd)
1968 jl = DMNEW(s4, sd->maxlocals);
1969 jd->basicblocks[0].javalocals = jl;
1971 for (i=0; i<sd->maxlocals; ++i)
1974 md = jd->m->parseddesc;
1976 for (i=0; i<md->paramcount; ++i) {
1977 type = md->paramtypes[i].type;
1978 jl[j] = jd->local_map[5*j + type];
1980 if (IS_2_WORD_TYPE(type))
1986 /* stack_analyse ***************************************************************
1988 Analyse_stack uses the intermediate code created by parse.c to
1989 build a model of the JVM operand stack for the current method.
1991 The following checks are performed:
1992 - check for operand stack underflow (before each instruction)
1993 - check for operand stack overflow (after[1] each instruction)
1994 - check for matching stack depth at merging points
1995 - check for matching basic types[2] at merging points
1996 - check basic types for instruction input (except for BUILTIN*
1997 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1999 [1]) Checking this after the instruction should be ok. parse.c
2000 counts the number of required stack slots in such a way that it is
2001 only vital that we don't exceed `maxstack` at basic block
2004 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2005 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2006 types are not discerned.
2008 *******************************************************************************/
2010 bool stack_analyse(jitdata *jd)
2012 methodinfo *m; /* method being analyzed */
2016 stackptr curstack; /* current stack top */
2018 int opcode; /* opcode of current instruction */
2021 int type; /* operand type */
2022 int len; /* # of instructions after the current one */
2023 bool superblockend; /* if true, no fallthrough to next block */
2024 bool deadcode; /* true if no live code has been reached */
2025 instruction *iptr; /* the current instruction */
2027 basicblock *original;
2028 exception_entry *ex;
2030 stackptr *last_store_boundary;
2031 stackptr coalescing_boundary;
2033 stackptr src1, src2, src3, src4, dst1, dst2;
2035 branch_target_t *table;
2036 lookup_target_t *lookup;
2037 #if defined(ENABLE_VERIFIER)
2038 int expectedtype; /* used by CHECK_BASIC_TYPE */
2040 builtintable_entry *bte;
2042 constant_FMIref *fmiref;
2043 #if defined(ENABLE_STATISTICS)
2044 int iteration_count; /* number of iterations of analysis */
2046 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2048 #if defined(STACK_VERBOSE)
2049 show_method(jd, SHOW_PARSE);
2052 /* get required compiler data - initialization */
2057 /* initialize the stackdata_t struct */
2061 sd.varcount = jd->varcount;
2062 sd.vartop = jd->vartop;
2063 sd.localcount = jd->localcount;
2065 sd.varsallocated = sd.varcount;
2066 sd.maxlocals = m->maxlocals;
2067 sd.javalocals = DMNEW(s4, sd.maxlocals);
2068 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2070 /* prepare the variable for exception handler stacks */
2071 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2073 sd.exstack.type = TYPE_ADR;
2074 sd.exstack.prev = NULL;
2075 sd.exstack.varnum = sd.localcount;
2076 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2078 #if defined(ENABLE_STATISTICS)
2079 iteration_count = 0;
2082 /* find the last real basic block */
2084 sd.last_real_block = NULL;
2085 tbptr = jd->basicblocks;
2086 while (tbptr->next) {
2087 sd.last_real_block = tbptr;
2088 tbptr = tbptr->next;
2090 assert(sd.last_real_block);
2092 /* find the last exception handler */
2094 if (jd->exceptiontablelength)
2095 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2097 sd.extableend = NULL;
2099 /* init jd->interface_map */
2101 jd->maxinterfaces = m->maxstack;
2102 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2103 for (i = 0; i < m->maxstack * 5; i++)
2104 jd->interface_map[i].flags = UNUSED;
2106 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2108 /* initialize flags and invars (none) of first block */
2110 jd->basicblocks[0].flags = BBREACHED;
2111 jd->basicblocks[0].invars = NULL;
2112 jd->basicblocks[0].indepth = 0;
2113 jd->basicblocks[0].inlocals =
2114 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2115 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2116 jd->localcount + VERIFIER_EXTRA_LOCALS);
2118 /* initialize java local mapping of first block */
2120 stack_init_javalocals(&sd);
2122 /* stack analysis loop (until fixpoint reached) **************************/
2125 #if defined(ENABLE_STATISTICS)
2129 /* initialize loop over basic blocks */
2131 sd.bptr = jd->basicblocks;
2132 superblockend = true;
2138 /* iterate over basic blocks *****************************************/
2140 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2142 if (sd.bptr->flags == BBDELETED) {
2143 /* This block has been deleted - do nothing. */
2148 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2149 /* re-analyse a block because its input changed */
2153 if (!stack_reanalyse_block(&sd))
2156 superblockend = true; /* XXX */
2160 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2161 /* This block has not been reached so far, and we
2162 don't fall into it, so we'll have to iterate
2169 if (sd.bptr->flags > BBREACHED) {
2170 /* This block is already finished. */
2172 superblockend = true;
2176 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2177 /* This block is a clone and the original has not been
2178 analysed, yet. Analyse it on the next
2182 /* XXX superblockend? */
2186 /* This block has to be analysed now. */
2190 /* XXX The rest of this block is still indented one level too */
2191 /* much in order to avoid a giant diff by changing that. */
2193 /* We know that sd.bptr->flags == BBREACHED. */
2194 /* This block has been reached before. */
2196 assert(sd.bptr->flags == BBREACHED);
2197 stackdepth = sd.bptr->indepth;
2199 /* find exception handlers for this block */
2201 /* determine the active exception handlers for this block */
2202 /* XXX could use a faster algorithm with sorted lists or */
2205 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2208 ex = jd->exceptiontable;
2209 for (; ex != NULL; ex = ex->down) {
2210 if ((ex->start <= original) && (ex->end > original)) {
2211 sd.handlers[len++] = ex;
2214 sd.handlers[len] = NULL;
2217 /* reanalyse cloned block */
2219 if (sd.bptr->original) {
2220 if (!stack_reanalyse_block(&sd))
2225 /* reset the new pointer for allocating stackslots */
2229 /* create the instack of this block */
2231 curstack = stack_create_instack(&sd);
2233 /* initialize locals at the start of this block */
2235 if (sd.bptr->inlocals)
2236 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2238 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2240 /* set up local variables for analyzing this block */
2242 superblockend = false;
2243 len = sd.bptr->icount;
2244 iptr = sd.bptr->iinstr;
2246 /* mark the block as analysed */
2248 sd.bptr->flags = BBFINISHED;
2250 /* reset variables for dependency checking */
2252 coalescing_boundary = sd.new;
2253 for( i = 0; i < m->maxlocals; i++)
2254 last_store_boundary[i] = sd.new;
2256 /* remember the start of this block's variables */
2258 sd.bptr->varstart = sd.vartop;
2260 #if defined(STACK_VERBOSE)
2261 stack_verbose_block_enter(&sd, false);
2264 /* reach exception handlers for this block */
2266 if (!stack_reach_handlers(&sd))
2269 /* iterate over ICMDs ****************************************/
2271 while (--len >= 0) {
2273 #if defined(STACK_VERBOSE)
2274 stack_verbose_show_state(&sd, iptr, curstack);
2277 /* fetch the current opcode */
2281 /* automatically replace some ICMDs with builtins */
2283 bte = builtintable_get_automatic(opcode);
2285 if ((bte != NULL) && (bte->opcode == opcode)) {
2286 iptr->opc = ICMD_BUILTIN;
2287 iptr->flags.bits &= INS_FLAG_ID_MASK;
2288 iptr->sx.s23.s3.bte = bte;
2289 /* iptr->line is already set */
2290 jd->isleafmethod = false;
2294 /* main opcode switch *************************************/
2306 case ICMD_CHECKNULL:
2307 coalescing_boundary = sd.new;
2308 COUNT(count_check_null);
2311 iptr->dst.varindex = iptr->s1.varindex;
2315 varindex = iptr->s1.varindex =
2316 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2318 #if defined(ENABLE_VERIFIER)
2319 if (sd.var[varindex].type != TYPE_RET) {
2320 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2327 iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
2328 superblockend = true;
2332 COUNT(count_pcmd_return);
2335 superblockend = true;
2336 sd.jd->returncount++;
2337 sd.jd->returnblock = sd.bptr;
2341 /* pop 0 push 1 const */
2343 /************************** ICONST OPTIMIZATIONS **************************/
2346 COUNT(count_pcmd_load);
2350 switch (iptr[1].opc) {
2352 iptr->opc = ICMD_IADDCONST;
2356 iptr[1].opc = ICMD_NOP;
2357 OP1_1(TYPE_INT, TYPE_INT);
2358 COUNT(count_pcmd_op);
2362 iptr->opc = ICMD_ISUBCONST;
2363 goto icmd_iconst_tail;
2364 #if SUPPORT_CONST_MUL
2366 iptr->opc = ICMD_IMULCONST;
2367 goto icmd_iconst_tail;
2368 #else /* SUPPORT_CONST_MUL */
2370 if (iptr->sx.val.i == 0x00000002)
2372 else if (iptr->sx.val.i == 0x00000004)
2374 else if (iptr->sx.val.i == 0x00000008)
2376 else if (iptr->sx.val.i == 0x00000010)
2378 else if (iptr->sx.val.i == 0x00000020)
2380 else if (iptr->sx.val.i == 0x00000040)
2382 else if (iptr->sx.val.i == 0x00000080)
2384 else if (iptr->sx.val.i == 0x00000100)
2386 else if (iptr->sx.val.i == 0x00000200)
2388 else if (iptr->sx.val.i == 0x00000400)
2389 iptr->sx.val.i = 10;
2390 else if (iptr->sx.val.i == 0x00000800)
2391 iptr->sx.val.i = 11;
2392 else if (iptr->sx.val.i == 0x00001000)
2393 iptr->sx.val.i = 12;
2394 else if (iptr->sx.val.i == 0x00002000)
2395 iptr->sx.val.i = 13;
2396 else if (iptr->sx.val.i == 0x00004000)
2397 iptr->sx.val.i = 14;
2398 else if (iptr->sx.val.i == 0x00008000)
2399 iptr->sx.val.i = 15;
2400 else if (iptr->sx.val.i == 0x00010000)
2401 iptr->sx.val.i = 16;
2402 else if (iptr->sx.val.i == 0x00020000)
2403 iptr->sx.val.i = 17;
2404 else if (iptr->sx.val.i == 0x00040000)
2405 iptr->sx.val.i = 18;
2406 else if (iptr->sx.val.i == 0x00080000)
2407 iptr->sx.val.i = 19;
2408 else if (iptr->sx.val.i == 0x00100000)
2409 iptr->sx.val.i = 20;
2410 else if (iptr->sx.val.i == 0x00200000)
2411 iptr->sx.val.i = 21;
2412 else if (iptr->sx.val.i == 0x00400000)
2413 iptr->sx.val.i = 22;
2414 else if (iptr->sx.val.i == 0x00800000)
2415 iptr->sx.val.i = 23;
2416 else if (iptr->sx.val.i == 0x01000000)
2417 iptr->sx.val.i = 24;
2418 else if (iptr->sx.val.i == 0x02000000)
2419 iptr->sx.val.i = 25;
2420 else if (iptr->sx.val.i == 0x04000000)
2421 iptr->sx.val.i = 26;
2422 else if (iptr->sx.val.i == 0x08000000)
2423 iptr->sx.val.i = 27;
2424 else if (iptr->sx.val.i == 0x10000000)
2425 iptr->sx.val.i = 28;
2426 else if (iptr->sx.val.i == 0x20000000)
2427 iptr->sx.val.i = 29;
2428 else if (iptr->sx.val.i == 0x40000000)
2429 iptr->sx.val.i = 30;
2430 else if (iptr->sx.val.i == 0x80000000)
2431 iptr->sx.val.i = 31;
2435 iptr->opc = ICMD_IMULPOW2;
2436 goto icmd_iconst_tail;
2437 #endif /* SUPPORT_CONST_MUL */
2439 if (iptr->sx.val.i == 0x00000002)
2441 else if (iptr->sx.val.i == 0x00000004)
2443 else if (iptr->sx.val.i == 0x00000008)
2445 else if (iptr->sx.val.i == 0x00000010)
2447 else if (iptr->sx.val.i == 0x00000020)
2449 else if (iptr->sx.val.i == 0x00000040)
2451 else if (iptr->sx.val.i == 0x00000080)
2453 else if (iptr->sx.val.i == 0x00000100)
2455 else if (iptr->sx.val.i == 0x00000200)
2457 else if (iptr->sx.val.i == 0x00000400)
2458 iptr->sx.val.i = 10;
2459 else if (iptr->sx.val.i == 0x00000800)
2460 iptr->sx.val.i = 11;
2461 else if (iptr->sx.val.i == 0x00001000)
2462 iptr->sx.val.i = 12;
2463 else if (iptr->sx.val.i == 0x00002000)
2464 iptr->sx.val.i = 13;
2465 else if (iptr->sx.val.i == 0x00004000)
2466 iptr->sx.val.i = 14;
2467 else if (iptr->sx.val.i == 0x00008000)
2468 iptr->sx.val.i = 15;
2469 else if (iptr->sx.val.i == 0x00010000)
2470 iptr->sx.val.i = 16;
2471 else if (iptr->sx.val.i == 0x00020000)
2472 iptr->sx.val.i = 17;
2473 else if (iptr->sx.val.i == 0x00040000)
2474 iptr->sx.val.i = 18;
2475 else if (iptr->sx.val.i == 0x00080000)
2476 iptr->sx.val.i = 19;
2477 else if (iptr->sx.val.i == 0x00100000)
2478 iptr->sx.val.i = 20;
2479 else if (iptr->sx.val.i == 0x00200000)
2480 iptr->sx.val.i = 21;
2481 else if (iptr->sx.val.i == 0x00400000)
2482 iptr->sx.val.i = 22;
2483 else if (iptr->sx.val.i == 0x00800000)
2484 iptr->sx.val.i = 23;
2485 else if (iptr->sx.val.i == 0x01000000)
2486 iptr->sx.val.i = 24;
2487 else if (iptr->sx.val.i == 0x02000000)
2488 iptr->sx.val.i = 25;
2489 else if (iptr->sx.val.i == 0x04000000)
2490 iptr->sx.val.i = 26;
2491 else if (iptr->sx.val.i == 0x08000000)
2492 iptr->sx.val.i = 27;
2493 else if (iptr->sx.val.i == 0x10000000)
2494 iptr->sx.val.i = 28;
2495 else if (iptr->sx.val.i == 0x20000000)
2496 iptr->sx.val.i = 29;
2497 else if (iptr->sx.val.i == 0x40000000)
2498 iptr->sx.val.i = 30;
2499 else if (iptr->sx.val.i == 0x80000000)
2500 iptr->sx.val.i = 31;
2504 iptr->opc = ICMD_IDIVPOW2;
2505 goto icmd_iconst_tail;
2508 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2509 if ((iptr->sx.val.i == 0x00000002) ||
2510 (iptr->sx.val.i == 0x00000004) ||
2511 (iptr->sx.val.i == 0x00000008) ||
2512 (iptr->sx.val.i == 0x00000010) ||
2513 (iptr->sx.val.i == 0x00000020) ||
2514 (iptr->sx.val.i == 0x00000040) ||
2515 (iptr->sx.val.i == 0x00000080) ||
2516 (iptr->sx.val.i == 0x00000100) ||
2517 (iptr->sx.val.i == 0x00000200) ||
2518 (iptr->sx.val.i == 0x00000400) ||
2519 (iptr->sx.val.i == 0x00000800) ||
2520 (iptr->sx.val.i == 0x00001000) ||
2521 (iptr->sx.val.i == 0x00002000) ||
2522 (iptr->sx.val.i == 0x00004000) ||
2523 (iptr->sx.val.i == 0x00008000) ||
2524 (iptr->sx.val.i == 0x00010000) ||
2525 (iptr->sx.val.i == 0x00020000) ||
2526 (iptr->sx.val.i == 0x00040000) ||
2527 (iptr->sx.val.i == 0x00080000) ||
2528 (iptr->sx.val.i == 0x00100000) ||
2529 (iptr->sx.val.i == 0x00200000) ||
2530 (iptr->sx.val.i == 0x00400000) ||
2531 (iptr->sx.val.i == 0x00800000) ||
2532 (iptr->sx.val.i == 0x01000000) ||
2533 (iptr->sx.val.i == 0x02000000) ||
2534 (iptr->sx.val.i == 0x04000000) ||
2535 (iptr->sx.val.i == 0x08000000) ||
2536 (iptr->sx.val.i == 0x10000000) ||
2537 (iptr->sx.val.i == 0x20000000) ||
2538 (iptr->sx.val.i == 0x40000000) ||
2539 (iptr->sx.val.i == 0x80000000))
2541 iptr->opc = ICMD_IREMPOW2;
2542 iptr->sx.val.i -= 1;
2543 goto icmd_iconst_tail;
2546 #if SUPPORT_CONST_LOGICAL
2548 iptr->opc = ICMD_IANDCONST;
2549 goto icmd_iconst_tail;
2552 iptr->opc = ICMD_IORCONST;
2553 goto icmd_iconst_tail;
2556 iptr->opc = ICMD_IXORCONST;
2557 goto icmd_iconst_tail;
2559 #endif /* SUPPORT_CONST_LOGICAL */
2561 iptr->opc = ICMD_ISHLCONST;
2562 goto icmd_iconst_tail;
2565 iptr->opc = ICMD_ISHRCONST;
2566 goto icmd_iconst_tail;
2569 iptr->opc = ICMD_IUSHRCONST;
2570 goto icmd_iconst_tail;
2571 #if SUPPORT_LONG_SHIFT
2573 iptr->opc = ICMD_LSHLCONST;
2574 goto icmd_lconst_tail;
2577 iptr->opc = ICMD_LSHRCONST;
2578 goto icmd_lconst_tail;
2581 iptr->opc = ICMD_LUSHRCONST;
2582 goto icmd_lconst_tail;
2583 #endif /* SUPPORT_LONG_SHIFT */
2584 case ICMD_IF_ICMPEQ:
2585 iptr[1].opc = ICMD_IFEQ;
2589 /* set the constant for the following icmd */
2590 iptr[1].sx.val.i = iptr->sx.val.i;
2592 /* this instruction becomes a nop */
2593 iptr->opc = ICMD_NOP;
2596 case ICMD_IF_ICMPLT:
2597 iptr[1].opc = ICMD_IFLT;
2598 goto icmd_if_icmp_tail;
2600 case ICMD_IF_ICMPLE:
2601 iptr[1].opc = ICMD_IFLE;
2602 goto icmd_if_icmp_tail;
2604 case ICMD_IF_ICMPNE:
2605 iptr[1].opc = ICMD_IFNE;
2606 goto icmd_if_icmp_tail;
2608 case ICMD_IF_ICMPGT:
2609 iptr[1].opc = ICMD_IFGT;
2610 goto icmd_if_icmp_tail;
2612 case ICMD_IF_ICMPGE:
2613 iptr[1].opc = ICMD_IFGE;
2614 goto icmd_if_icmp_tail;
2616 #if SUPPORT_CONST_STORE
2621 # if SUPPORT_CONST_STORE_ZERO_ONLY
2622 if (iptr->sx.val.i != 0)
2625 switch (iptr[1].opc) {
2627 iptr->opc = ICMD_IASTORECONST;
2628 iptr->flags.bits |= INS_FLAG_CHECK;
2631 iptr->opc = ICMD_BASTORECONST;
2632 iptr->flags.bits |= INS_FLAG_CHECK;
2635 iptr->opc = ICMD_CASTORECONST;
2636 iptr->flags.bits |= INS_FLAG_CHECK;
2639 iptr->opc = ICMD_SASTORECONST;
2640 iptr->flags.bits |= INS_FLAG_CHECK;
2644 iptr[1].opc = ICMD_NOP;
2646 /* copy the constant to s3 */
2647 /* XXX constval -> astoreconstval? */
2648 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2649 OP2_0(TYPE_ADR, TYPE_INT);
2650 COUNT(count_pcmd_op);
2653 case ICMD_PUTSTATIC:
2655 # if SUPPORT_CONST_STORE_ZERO_ONLY
2656 if (iptr->sx.val.i != 0)
2659 /* XXX check field type? */
2661 /* copy the constant to s2 */
2662 /* XXX constval -> fieldconstval? */
2663 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2666 /* set the field reference (s3) */
2667 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2668 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2669 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2670 fmiref = iptr->sx.s23.s3.uf->fieldref;
2673 fmiref = iptr[1].sx.s23.s3.fmiref;
2674 iptr->sx.s23.s3.fmiref = fmiref;
2677 #if defined(ENABLE_VERIFIER)
2678 expectedtype = fmiref->parseddesc.fd->type;
2679 switch (iptr[0].opc) {
2681 if (expectedtype != TYPE_INT)
2682 goto throw_stack_type_error;
2685 if (expectedtype != TYPE_LNG)
2686 goto throw_stack_type_error;
2689 if (expectedtype != TYPE_ADR)
2690 goto throw_stack_type_error;
2695 #endif /* defined(ENABLE_VERIFIER) */
2697 switch (iptr[1].opc) {
2698 case ICMD_PUTSTATIC:
2699 iptr->opc = ICMD_PUTSTATICCONST;
2703 iptr->opc = ICMD_PUTFIELDCONST;
2708 iptr[1].opc = ICMD_NOP;
2709 COUNT(count_pcmd_op);
2711 #endif /* SUPPORT_CONST_STORE */
2717 /* if we get here, the ICONST has been optimized */
2721 /* normal case of an unoptimized ICONST */
2725 /************************** LCONST OPTIMIZATIONS **************************/
2728 COUNT(count_pcmd_load);
2732 /* switch depending on the following instruction */
2734 switch (iptr[1].opc) {
2735 #if SUPPORT_LONG_ADD
2737 iptr->opc = ICMD_LADDCONST;
2741 /* instruction of type LONG -> LONG */
2742 iptr[1].opc = ICMD_NOP;
2743 OP1_1(TYPE_LNG, TYPE_LNG);
2744 COUNT(count_pcmd_op);
2748 iptr->opc = ICMD_LSUBCONST;
2749 goto icmd_lconst_tail;
2751 #endif /* SUPPORT_LONG_ADD */
2752 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2754 iptr->opc = ICMD_LMULCONST;
2755 goto icmd_lconst_tail;
2756 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2757 # if SUPPORT_LONG_SHIFT
2759 if (iptr->sx.val.l == 0x00000002)
2761 else if (iptr->sx.val.l == 0x00000004)
2763 else if (iptr->sx.val.l == 0x00000008)
2765 else if (iptr->sx.val.l == 0x00000010)
2767 else if (iptr->sx.val.l == 0x00000020)
2769 else if (iptr->sx.val.l == 0x00000040)
2771 else if (iptr->sx.val.l == 0x00000080)
2773 else if (iptr->sx.val.l == 0x00000100)
2775 else if (iptr->sx.val.l == 0x00000200)
2777 else if (iptr->sx.val.l == 0x00000400)
2778 iptr->sx.val.i = 10;
2779 else if (iptr->sx.val.l == 0x00000800)
2780 iptr->sx.val.i = 11;
2781 else if (iptr->sx.val.l == 0x00001000)
2782 iptr->sx.val.i = 12;
2783 else if (iptr->sx.val.l == 0x00002000)
2784 iptr->sx.val.i = 13;
2785 else if (iptr->sx.val.l == 0x00004000)
2786 iptr->sx.val.i = 14;
2787 else if (iptr->sx.val.l == 0x00008000)
2788 iptr->sx.val.i = 15;
2789 else if (iptr->sx.val.l == 0x00010000)
2790 iptr->sx.val.i = 16;
2791 else if (iptr->sx.val.l == 0x00020000)
2792 iptr->sx.val.i = 17;
2793 else if (iptr->sx.val.l == 0x00040000)
2794 iptr->sx.val.i = 18;
2795 else if (iptr->sx.val.l == 0x00080000)
2796 iptr->sx.val.i = 19;
2797 else if (iptr->sx.val.l == 0x00100000)
2798 iptr->sx.val.i = 20;
2799 else if (iptr->sx.val.l == 0x00200000)
2800 iptr->sx.val.i = 21;
2801 else if (iptr->sx.val.l == 0x00400000)
2802 iptr->sx.val.i = 22;
2803 else if (iptr->sx.val.l == 0x00800000)
2804 iptr->sx.val.i = 23;
2805 else if (iptr->sx.val.l == 0x01000000)
2806 iptr->sx.val.i = 24;
2807 else if (iptr->sx.val.l == 0x02000000)
2808 iptr->sx.val.i = 25;
2809 else if (iptr->sx.val.l == 0x04000000)
2810 iptr->sx.val.i = 26;
2811 else if (iptr->sx.val.l == 0x08000000)
2812 iptr->sx.val.i = 27;
2813 else if (iptr->sx.val.l == 0x10000000)
2814 iptr->sx.val.i = 28;
2815 else if (iptr->sx.val.l == 0x20000000)
2816 iptr->sx.val.i = 29;
2817 else if (iptr->sx.val.l == 0x40000000)
2818 iptr->sx.val.i = 30;
2819 else if (iptr->sx.val.l == 0x80000000)
2820 iptr->sx.val.i = 31;
2824 iptr->opc = ICMD_LMULPOW2;
2825 goto icmd_lconst_tail;
2826 # endif /* SUPPORT_LONG_SHIFT */
2827 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2828 #if SUPPORT_LONG_DIV_POW2
2830 if (iptr->sx.val.l == 0x00000002)
2832 else if (iptr->sx.val.l == 0x00000004)
2834 else if (iptr->sx.val.l == 0x00000008)
2836 else if (iptr->sx.val.l == 0x00000010)
2838 else if (iptr->sx.val.l == 0x00000020)
2840 else if (iptr->sx.val.l == 0x00000040)
2842 else if (iptr->sx.val.l == 0x00000080)
2844 else if (iptr->sx.val.l == 0x00000100)
2846 else if (iptr->sx.val.l == 0x00000200)
2848 else if (iptr->sx.val.l == 0x00000400)
2849 iptr->sx.val.i = 10;
2850 else if (iptr->sx.val.l == 0x00000800)
2851 iptr->sx.val.i = 11;
2852 else if (iptr->sx.val.l == 0x00001000)
2853 iptr->sx.val.i = 12;
2854 else if (iptr->sx.val.l == 0x00002000)
2855 iptr->sx.val.i = 13;
2856 else if (iptr->sx.val.l == 0x00004000)
2857 iptr->sx.val.i = 14;
2858 else if (iptr->sx.val.l == 0x00008000)
2859 iptr->sx.val.i = 15;
2860 else if (iptr->sx.val.l == 0x00010000)
2861 iptr->sx.val.i = 16;
2862 else if (iptr->sx.val.l == 0x00020000)
2863 iptr->sx.val.i = 17;
2864 else if (iptr->sx.val.l == 0x00040000)
2865 iptr->sx.val.i = 18;
2866 else if (iptr->sx.val.l == 0x00080000)
2867 iptr->sx.val.i = 19;
2868 else if (iptr->sx.val.l == 0x00100000)
2869 iptr->sx.val.i = 20;
2870 else if (iptr->sx.val.l == 0x00200000)
2871 iptr->sx.val.i = 21;
2872 else if (iptr->sx.val.l == 0x00400000)
2873 iptr->sx.val.i = 22;
2874 else if (iptr->sx.val.l == 0x00800000)
2875 iptr->sx.val.i = 23;
2876 else if (iptr->sx.val.l == 0x01000000)
2877 iptr->sx.val.i = 24;
2878 else if (iptr->sx.val.l == 0x02000000)
2879 iptr->sx.val.i = 25;
2880 else if (iptr->sx.val.l == 0x04000000)
2881 iptr->sx.val.i = 26;
2882 else if (iptr->sx.val.l == 0x08000000)
2883 iptr->sx.val.i = 27;
2884 else if (iptr->sx.val.l == 0x10000000)
2885 iptr->sx.val.i = 28;
2886 else if (iptr->sx.val.l == 0x20000000)
2887 iptr->sx.val.i = 29;
2888 else if (iptr->sx.val.l == 0x40000000)
2889 iptr->sx.val.i = 30;
2890 else if (iptr->sx.val.l == 0x80000000)
2891 iptr->sx.val.i = 31;
2895 iptr->opc = ICMD_LDIVPOW2;
2896 goto icmd_lconst_tail;
2897 #endif /* SUPPORT_LONG_DIV_POW2 */
2899 #if SUPPORT_LONG_REM_POW2
2901 if ((iptr->sx.val.l == 0x00000002) ||
2902 (iptr->sx.val.l == 0x00000004) ||
2903 (iptr->sx.val.l == 0x00000008) ||
2904 (iptr->sx.val.l == 0x00000010) ||
2905 (iptr->sx.val.l == 0x00000020) ||
2906 (iptr->sx.val.l == 0x00000040) ||
2907 (iptr->sx.val.l == 0x00000080) ||
2908 (iptr->sx.val.l == 0x00000100) ||
2909 (iptr->sx.val.l == 0x00000200) ||
2910 (iptr->sx.val.l == 0x00000400) ||
2911 (iptr->sx.val.l == 0x00000800) ||
2912 (iptr->sx.val.l == 0x00001000) ||
2913 (iptr->sx.val.l == 0x00002000) ||
2914 (iptr->sx.val.l == 0x00004000) ||
2915 (iptr->sx.val.l == 0x00008000) ||
2916 (iptr->sx.val.l == 0x00010000) ||
2917 (iptr->sx.val.l == 0x00020000) ||
2918 (iptr->sx.val.l == 0x00040000) ||
2919 (iptr->sx.val.l == 0x00080000) ||
2920 (iptr->sx.val.l == 0x00100000) ||
2921 (iptr->sx.val.l == 0x00200000) ||
2922 (iptr->sx.val.l == 0x00400000) ||
2923 (iptr->sx.val.l == 0x00800000) ||
2924 (iptr->sx.val.l == 0x01000000) ||
2925 (iptr->sx.val.l == 0x02000000) ||
2926 (iptr->sx.val.l == 0x04000000) ||
2927 (iptr->sx.val.l == 0x08000000) ||
2928 (iptr->sx.val.l == 0x10000000) ||
2929 (iptr->sx.val.l == 0x20000000) ||
2930 (iptr->sx.val.l == 0x40000000) ||
2931 (iptr->sx.val.l == 0x80000000))
2933 iptr->opc = ICMD_LREMPOW2;
2934 iptr->sx.val.l -= 1;
2935 goto icmd_lconst_tail;
2938 #endif /* SUPPORT_LONG_REM_POW2 */
2940 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2943 iptr->opc = ICMD_LANDCONST;
2944 goto icmd_lconst_tail;
2947 iptr->opc = ICMD_LORCONST;
2948 goto icmd_lconst_tail;
2951 iptr->opc = ICMD_LXORCONST;
2952 goto icmd_lconst_tail;
2953 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2955 #if SUPPORT_LONG_CMP_CONST
2957 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2960 /* switch on the instruction after LCONST - LCMP */
2962 switch (iptr[2].opc) {
2964 iptr->opc = ICMD_IF_LEQ;
2967 icmd_lconst_lcmp_tail:
2968 /* convert LCONST, LCMP, IFXX to IF_LXX */
2969 iptr->dst.block = iptr[2].dst.block;
2970 iptr[1].opc = ICMD_NOP;
2971 iptr[2].opc = ICMD_NOP;
2973 OP1_BRANCH(TYPE_LNG);
2975 COUNT(count_pcmd_bra);
2976 COUNT(count_pcmd_op);
2980 iptr->opc = ICMD_IF_LNE;
2981 goto icmd_lconst_lcmp_tail;
2984 iptr->opc = ICMD_IF_LLT;
2985 goto icmd_lconst_lcmp_tail;
2988 iptr->opc = ICMD_IF_LGT;
2989 goto icmd_lconst_lcmp_tail;
2992 iptr->opc = ICMD_IF_LLE;
2993 goto icmd_lconst_lcmp_tail;
2996 iptr->opc = ICMD_IF_LGE;
2997 goto icmd_lconst_lcmp_tail;
3001 } /* end switch on opcode after LCONST - LCMP */
3003 #endif /* SUPPORT_LONG_CMP_CONST */
3005 #if SUPPORT_CONST_STORE
3007 # if SUPPORT_CONST_STORE_ZERO_ONLY
3008 if (iptr->sx.val.l != 0)
3011 #if SIZEOF_VOID_P == 4
3012 /* the constant must fit into a ptrint */
3013 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3016 /* move the constant to s3 */
3017 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3019 iptr->opc = ICMD_LASTORECONST;
3020 iptr->flags.bits |= INS_FLAG_CHECK;
3021 OP2_0(TYPE_ADR, TYPE_INT);
3023 iptr[1].opc = ICMD_NOP;
3024 COUNT(count_pcmd_op);
3027 case ICMD_PUTSTATIC:
3029 # if SUPPORT_CONST_STORE_ZERO_ONLY
3030 if (iptr->sx.val.l != 0)
3033 #if SIZEOF_VOID_P == 4
3034 /* the constant must fit into a ptrint */
3035 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3038 /* XXX check field type? */
3040 /* copy the constant to s2 */
3041 /* XXX constval -> fieldconstval? */
3042 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3046 #endif /* SUPPORT_CONST_STORE */
3050 } /* end switch opcode after LCONST */
3052 /* if we get here, the LCONST has been optimized */
3056 /* the normal case of an unoptimized LCONST */
3060 /************************ END OF LCONST OPTIMIZATIONS *********************/
3063 COUNT(count_pcmd_load);
3068 COUNT(count_pcmd_load);
3072 /************************** ACONST OPTIMIZATIONS **************************/
3075 coalescing_boundary = sd.new;
3076 COUNT(count_pcmd_load);
3077 #if SUPPORT_CONST_STORE
3078 /* We can only optimize if the ACONST is resolved
3079 * and there is an instruction after it. */
3081 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3084 switch (iptr[1].opc) {
3086 /* We can only optimize for NULL values
3087 * here because otherwise a checkcast is
3089 if (iptr->sx.val.anyptr != NULL)
3092 /* copy the constant (NULL) to s3 */
3093 iptr->sx.s23.s3.constval = 0;
3094 iptr->opc = ICMD_AASTORECONST;
3095 iptr->flags.bits |= INS_FLAG_CHECK;
3096 OP2_0(TYPE_ADR, TYPE_INT);
3098 iptr[1].opc = ICMD_NOP;
3099 COUNT(count_pcmd_op);
3102 case ICMD_PUTSTATIC:
3104 # if SUPPORT_CONST_STORE_ZERO_ONLY
3105 if (iptr->sx.val.anyptr != NULL)
3108 /* XXX check field type? */
3109 /* copy the constant to s2 */
3110 /* XXX constval -> fieldconstval? */
3111 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3119 /* if we get here the ACONST has been optimized */
3123 #endif /* SUPPORT_CONST_STORE */
3128 /* pop 0 push 1 load */
3135 COUNT(count_load_instruction);
3136 type = opcode - ICMD_ILOAD;
3138 varindex = iptr->s1.varindex =
3139 jd->local_map[iptr->s1.varindex * 5 + type];
3141 #if defined(ENABLE_VERIFIER)
3142 if (sd.var[varindex].type == TYPE_RET) {
3143 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3147 LOAD(type, varindex);
3156 coalescing_boundary = sd.new;
3157 iptr->flags.bits |= INS_FLAG_CHECK;
3158 COUNT(count_check_null);
3159 COUNT(count_check_bound);
3160 COUNT(count_pcmd_mem);
3161 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3168 coalescing_boundary = sd.new;
3169 iptr->flags.bits |= INS_FLAG_CHECK;
3170 COUNT(count_check_null);
3171 COUNT(count_check_bound);
3172 COUNT(count_pcmd_mem);
3173 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3176 /* pop 0 push 0 iinc */
3179 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3180 last_store_boundary[iptr->s1.varindex] = sd.new;
3183 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3188 if ((copy->varkind == LOCALVAR) &&
3189 (copy->varnum == iptr->s1.varindex))
3191 assert(IS_LOCALVAR(copy));
3198 iptr->dst.varindex = iptr->s1.varindex;
3201 /* pop 1 push 0 store */
3210 type = opcode - ICMD_ISTORE;
3211 javaindex = iptr->dst.varindex;
3212 varindex = iptr->dst.varindex =
3213 jd->local_map[javaindex * 5 + type];
3215 COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
3217 iptr->sx.s23.s3.javaindex = javaindex;
3219 if (curstack->type == TYPE_RET) {
3220 iptr->flags.bits |= INS_FLAG_RETADDR;
3221 iptr->sx.s23.s2.retaddrnr =
3222 JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
3223 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3226 sd.javalocals[javaindex] = varindex;
3228 /* invalidate the following javalocal for 2-word types */
3230 if (IS_2_WORD_TYPE(type)) {
3231 sd.javalocals[javaindex+1] = UNUSED;
3232 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3235 /* invalidate 2-word types if second half was overwritten */
3237 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
3238 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3239 sd.javalocals[javaindex-1] = UNUSED;
3240 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3244 #if defined(ENABLE_STATISTICS)
3247 i = sd.new - curstack;
3249 count_store_length[20]++;
3251 count_store_length[i]++;
3254 count_store_depth[10]++;
3256 count_store_depth[i]++;
3260 /* check for conflicts as described in Figure 5.2 */
3262 copy = curstack->prev;
3265 if ((copy->varkind == LOCALVAR) &&
3266 (copy->varnum == varindex))
3268 copy->varkind = TEMPVAR;
3269 assert(IS_LOCALVAR(copy));
3276 /* if the variable is already coalesced, don't bother */
3278 /* We do not need to check against INOUT, as invars */
3279 /* are always before the coalescing boundary. */
3281 if (curstack->varkind == LOCALVAR)
3284 /* there is no STORE Lj while curstack is live */
3286 if (curstack < last_store_boundary[javaindex])
3287 goto assume_conflict;
3289 /* curstack must be after the coalescing boundary */
3291 if (curstack < coalescing_boundary)
3292 goto assume_conflict;
3294 /* there is no DEF LOCALVAR(varindex) while curstack is live */
3296 copy = sd.new; /* most recent stackslot created + 1 */
3297 while (--copy > curstack) {
3298 if (copy->varkind == LOCALVAR && copy->varnum == varindex)
3299 goto assume_conflict;
3302 /* coalesce the temporary variable with Lj */
3303 assert((curstack->varkind == TEMPVAR)
3304 || (curstack->varkind == UNDEFVAR));
3305 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3306 assert(!IS_INOUT(curstack));
3307 assert(!IS_PREALLOC(curstack));
3309 assert(curstack->creator);
3310 assert(curstack->creator->dst.varindex == curstack->varnum);
3311 assert(!(curstack->flags & PASSTHROUGH));
3312 RELEASE_INDEX(sd, curstack);
3313 curstack->varkind = LOCALVAR;
3314 curstack->varnum = varindex;
3315 curstack->creator->dst.varindex = varindex;
3318 /* revert the coalescing, if it has been done earlier */
3320 if ((curstack->varkind == LOCALVAR)
3321 && (curstack->varnum == varindex))
3323 assert(IS_LOCALVAR(curstack));
3324 SET_TEMPVAR(curstack);
3327 /* remember the stack boundary at this store */
3329 last_store_boundary[javaindex] = sd.new;
3331 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3332 STORE(TYPE_RET, varindex);
3334 STORE(opcode - ICMD_ISTORE, varindex);
3340 coalescing_boundary = sd.new;
3341 iptr->flags.bits |= INS_FLAG_CHECK;
3342 COUNT(count_check_null);
3343 COUNT(count_check_bound);
3344 COUNT(count_pcmd_mem);
3346 bte = builtintable_get_internal(BUILTIN_FAST_canstore);
3349 if (md->memuse > rd->memuse)
3350 rd->memuse = md->memuse;
3351 if (md->argintreguse > rd->argintreguse)
3352 rd->argintreguse = md->argintreguse;
3353 /* XXX non-leaf method? */
3355 /* make all stack variables saved */
3359 sd.var[copy->varnum].flags |= SAVEDVAR;
3360 /* in case copy->varnum is/will be a LOCALVAR */
3361 /* once and set back to a non LOCALVAR */
3362 /* the correct SAVEDVAR flag has to be */
3363 /* remembered in copy->flags, too */
3364 copy->flags |= SAVEDVAR;
3368 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3375 coalescing_boundary = sd.new;
3376 iptr->flags.bits |= INS_FLAG_CHECK;
3377 COUNT(count_check_null);
3378 COUNT(count_check_bound);
3379 COUNT(count_pcmd_mem);
3380 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3387 coalescing_boundary = sd.new;
3388 iptr->flags.bits |= INS_FLAG_CHECK;
3389 COUNT(count_check_null);
3390 COUNT(count_check_bound);
3391 COUNT(count_pcmd_mem);
3392 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3398 #ifdef ENABLE_VERIFIER
3401 if (IS_2_WORD_TYPE(curstack->type))
3402 goto throw_stack_category_error;
3413 coalescing_boundary = sd.new;
3414 /* Assert here that no LOCAL or INOUTS get */
3415 /* preallocated, since tha macros are not */
3416 /* available in md-abi.c! */
3417 if (IS_TEMPVAR(curstack))
3418 md_return_alloc(jd, curstack);
3419 COUNT(count_pcmd_return);
3420 OP1_0(opcode - ICMD_IRETURN);
3421 superblockend = true;
3422 sd.jd->returncount++;
3423 sd.jd->returnblock = sd.bptr;
3427 coalescing_boundary = sd.new;
3428 COUNT(count_check_null);
3430 curstack = NULL; stackdepth = 0;
3431 superblockend = true;
3434 case ICMD_PUTSTATIC:
3435 coalescing_boundary = sd.new;
3436 COUNT(count_pcmd_mem);
3437 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3438 OP1_0(fmiref->parseddesc.fd->type);
3441 /* pop 1 push 0 branch */
3444 case ICMD_IFNONNULL:
3445 COUNT(count_pcmd_bra);
3446 OP1_BRANCH(TYPE_ADR);
3456 COUNT(count_pcmd_bra);
3457 /* iptr->sx.val.i is set implicitly in parse by
3458 clearing the memory or from IF_ICMPxx
3461 OP1_BRANCH(TYPE_INT);
3462 /* iptr->sx.val.i = 0; */
3466 /* pop 0 push 0 branch */
3469 COUNT(count_pcmd_bra);
3472 superblockend = true;
3475 /* pop 1 push 0 table branch */
3477 case ICMD_TABLESWITCH:
3478 COUNT(count_pcmd_table);
3479 OP1_BRANCH(TYPE_INT);
3481 table = iptr->dst.table;
3482 BRANCH_TARGET(*table, tbptr);
3485 i = iptr->sx.s23.s3.tablehigh
3486 - iptr->sx.s23.s2.tablelow + 1;
3489 BRANCH_TARGET(*table, tbptr);
3492 superblockend = true;
3495 /* pop 1 push 0 table branch */
3497 case ICMD_LOOKUPSWITCH:
3498 COUNT(count_pcmd_table);
3499 OP1_BRANCH(TYPE_INT);
3501 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3503 lookup = iptr->dst.lookup;
3505 i = iptr->sx.s23.s2.lookupcount;
3508 BRANCH_TARGET(lookup->target, tbptr);
3511 superblockend = true;
3514 case ICMD_MONITORENTER:
3515 case ICMD_MONITOREXIT:
3516 coalescing_boundary = sd.new;
3517 COUNT(count_check_null);
3521 /* pop 2 push 0 branch */
3523 case ICMD_IF_ICMPEQ:
3524 case ICMD_IF_ICMPNE:
3525 case ICMD_IF_ICMPLT:
3526 case ICMD_IF_ICMPGE:
3527 case ICMD_IF_ICMPGT:
3528 case ICMD_IF_ICMPLE:
3529 COUNT(count_pcmd_bra);
3530 OP2_BRANCH(TYPE_INT, TYPE_INT);
3534 case ICMD_IF_ACMPEQ:
3535 case ICMD_IF_ACMPNE:
3536 COUNT(count_pcmd_bra);
3537 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3544 coalescing_boundary = sd.new;
3545 COUNT(count_check_null);
3546 COUNT(count_pcmd_mem);
3547 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3548 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3553 if (!IS_2_WORD_TYPE(curstack->type)) {
3555 #ifdef ENABLE_VERIFIER
3558 if (IS_2_WORD_TYPE(curstack->prev->type))
3559 goto throw_stack_category_error;
3562 OP2_0_ANY_ANY; /* pop two slots */
3565 iptr->opc = ICMD_POP;
3566 OP1_0_ANY; /* pop one (two-word) slot */
3570 /* pop 0 push 1 dup */
3573 #ifdef ENABLE_VERIFIER
3576 if (IS_2_WORD_TYPE(curstack->type))
3577 goto throw_stack_category_error;
3580 COUNT(count_dup_instruction);
3586 coalescing_boundary = sd.new - 1;
3591 if (IS_2_WORD_TYPE(curstack->type)) {
3593 iptr->opc = ICMD_DUP;
3598 /* ..., ????, cat1 */
3599 #ifdef ENABLE_VERIFIER
3601 if (IS_2_WORD_TYPE(curstack->prev->type))
3602 goto throw_stack_category_error;
3605 src1 = curstack->prev;
3608 COPY_UP(src1); iptr++; len--;
3611 coalescing_boundary = sd.new;
3615 /* pop 2 push 3 dup */
3618 #ifdef ENABLE_VERIFIER
3621 if (IS_2_WORD_TYPE(curstack->type) ||
3622 IS_2_WORD_TYPE(curstack->prev->type))
3623 goto throw_stack_category_error;
3628 src1 = curstack->prev;
3633 /* move non-temporary sources out of the way */
3634 if (!IS_TEMPVAR(src2)) {
3635 MOVE_TO_TEMP(src2); iptr++; len--;
3638 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3640 MOVE_UP(src1); iptr++; len--;
3641 MOVE_UP(src2); iptr++; len--;
3643 COPY_DOWN(curstack, dst1);
3645 coalescing_boundary = sd.new;
3650 if (IS_2_WORD_TYPE(curstack->type)) {
3651 /* ..., ????, cat2 */
3652 #ifdef ENABLE_VERIFIER
3654 if (IS_2_WORD_TYPE(curstack->prev->type))
3655 goto throw_stack_category_error;
3658 iptr->opc = ICMD_DUP_X1;
3662 /* ..., ????, cat1 */
3663 #ifdef ENABLE_VERIFIER
3666 if (IS_2_WORD_TYPE(curstack->prev->type)
3667 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3668 goto throw_stack_category_error;
3673 src1 = curstack->prev->prev;
3674 src2 = curstack->prev;
3676 POPANY; POPANY; POPANY;
3679 /* move non-temporary sources out of the way */
3680 if (!IS_TEMPVAR(src2)) {
3681 MOVE_TO_TEMP(src2); iptr++; len--;
3683 if (!IS_TEMPVAR(src3)) {
3684 MOVE_TO_TEMP(src3); iptr++; len--;
3687 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3688 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3690 MOVE_UP(src1); iptr++; len--;
3691 MOVE_UP(src2); iptr++; len--;
3692 MOVE_UP(src3); iptr++; len--;
3694 COPY_DOWN(curstack, dst2); iptr++; len--;
3695 COPY_DOWN(curstack->prev, dst1);
3697 coalescing_boundary = sd.new;
3701 /* pop 3 push 4 dup */
3705 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3706 /* ..., cat2, ???? */
3707 #ifdef ENABLE_VERIFIER
3709 if (IS_2_WORD_TYPE(curstack->type))
3710 goto throw_stack_category_error;
3713 iptr->opc = ICMD_DUP_X1;
3717 /* ..., cat1, ???? */
3718 #ifdef ENABLE_VERIFIER
3721 if (IS_2_WORD_TYPE(curstack->type)
3722 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3723 goto throw_stack_category_error;
3727 src1 = curstack->prev->prev;
3728 src2 = curstack->prev;
3730 POPANY; POPANY; POPANY;
3733 /* move non-temporary sources out of the way */
3734 if (!IS_TEMPVAR(src2)) {
3735 MOVE_TO_TEMP(src2); iptr++; len--;
3737 if (!IS_TEMPVAR(src3)) {
3738 MOVE_TO_TEMP(src3); iptr++; len--;
3741 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3743 MOVE_UP(src1); iptr++; len--;
3744 MOVE_UP(src2); iptr++; len--;
3745 MOVE_UP(src3); iptr++; len--;
3747 COPY_DOWN(curstack, dst1);
3749 coalescing_boundary = sd.new;
3755 if (IS_2_WORD_TYPE(curstack->type)) {
3756 /* ..., ????, cat2 */
3757 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3758 /* ..., cat2, cat2 */
3759 iptr->opc = ICMD_DUP_X1;
3763 /* ..., cat1, cat2 */
3764 #ifdef ENABLE_VERIFIER
3767 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3768 goto throw_stack_category_error;
3771 iptr->opc = ICMD_DUP_X2;
3777 /* ..., ????, ????, cat1 */
3779 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3780 /* ..., cat2, ????, cat1 */
3781 #ifdef ENABLE_VERIFIER
3783 if (IS_2_WORD_TYPE(curstack->prev->type))
3784 goto throw_stack_category_error;
3787 iptr->opc = ICMD_DUP2_X1;
3791 /* ..., cat1, ????, cat1 */
3792 #ifdef ENABLE_VERIFIER
3795 if (IS_2_WORD_TYPE(curstack->prev->type)
3796 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3797 goto throw_stack_category_error;
3801 src1 = curstack->prev->prev->prev;
3802 src2 = curstack->prev->prev;
3803 src3 = curstack->prev;
3805 POPANY; POPANY; POPANY; POPANY;
3808 /* move non-temporary sources out of the way */
3809 if (!IS_TEMPVAR(src2)) {
3810 MOVE_TO_TEMP(src2); iptr++; len--;
3812 if (!IS_TEMPVAR(src3)) {
3813 MOVE_TO_TEMP(src3); iptr++; len--;
3815 if (!IS_TEMPVAR(src4)) {
3816 MOVE_TO_TEMP(src4); iptr++; len--;
3819 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3820 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3822 MOVE_UP(src1); iptr++; len--;
3823 MOVE_UP(src2); iptr++; len--;
3824 MOVE_UP(src3); iptr++; len--;
3825 MOVE_UP(src4); iptr++; len--;
3827 COPY_DOWN(curstack, dst2); iptr++; len--;
3828 COPY_DOWN(curstack->prev, dst1);
3830 coalescing_boundary = sd.new;
3834 /* pop 2 push 2 swap */
3837 #ifdef ENABLE_VERIFIER
3840 if (IS_2_WORD_TYPE(curstack->type)
3841 || IS_2_WORD_TYPE(curstack->prev->type))
3842 goto throw_stack_category_error;
3846 src1 = curstack->prev;
3851 /* move non-temporary sources out of the way */
3852 if (!IS_TEMPVAR(src1)) {
3853 MOVE_TO_TEMP(src1); iptr++; len--;
3856 MOVE_UP(src2); iptr++; len--;
3859 coalescing_boundary = sd.new;
3866 coalescing_boundary = sd.new;
3867 #if !SUPPORT_DIVISION
3868 bte = iptr->sx.s23.s3.bte;
3871 if (md->memuse > rd->memuse)
3872 rd->memuse = md->memuse;
3873 if (md->argintreguse > rd->argintreguse)
3874 rd->argintreguse = md->argintreguse;
3876 /* make all stack variables saved */
3880 sd.var[copy->varnum].flags |= SAVEDVAR;
3881 copy->flags |= SAVEDVAR;
3886 #endif /* !SUPPORT_DIVISION */
3897 COUNT(count_pcmd_op);
3898 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3903 coalescing_boundary = sd.new;
3904 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3905 bte = iptr->sx.s23.s3.bte;
3908 if (md->memuse > rd->memuse)
3909 rd->memuse = md->memuse;
3910 if (md->argintreguse > rd->argintreguse)
3911 rd->argintreguse = md->argintreguse;
3912 /* XXX non-leaf method? */
3914 /* make all stack variables saved */
3918 sd.var[copy->varnum].flags |= SAVEDVAR;
3919 copy->flags |= SAVEDVAR;
3924 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3929 #if SUPPORT_LONG_LOGICAL
3933 #endif /* SUPPORT_LONG_LOGICAL */
3934 COUNT(count_pcmd_op);
3935 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3941 COUNT(count_pcmd_op);
3942 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3950 COUNT(count_pcmd_op);
3951 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3959 COUNT(count_pcmd_op);
3960 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3964 COUNT(count_pcmd_op);
3965 #if SUPPORT_LONG_CMP_CONST
3966 if ((len == 0) || (iptr[1].sx.val.i != 0))
3969 switch (iptr[1].opc) {
3971 iptr->opc = ICMD_IF_LCMPEQ;
3973 iptr->dst.block = iptr[1].dst.block;
3974 iptr[1].opc = ICMD_NOP;
3976 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3979 COUNT(count_pcmd_bra);
3982 iptr->opc = ICMD_IF_LCMPNE;
3983 goto icmd_lcmp_if_tail;
3985 iptr->opc = ICMD_IF_LCMPLT;
3986 goto icmd_lcmp_if_tail;
3988 iptr->opc = ICMD_IF_LCMPGT;
3989 goto icmd_lcmp_if_tail;
3991 iptr->opc = ICMD_IF_LCMPLE;
3992 goto icmd_lcmp_if_tail;
3994 iptr->opc = ICMD_IF_LCMPGE;
3995 goto icmd_lcmp_if_tail;
4001 #endif /* SUPPORT_LONG_CMP_CONST */
4002 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4007 COUNT(count_pcmd_op);
4008 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4013 COUNT(count_pcmd_op);
4014 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4022 case ICMD_INT2SHORT:
4023 COUNT(count_pcmd_op);
4024 OP1_1(TYPE_INT, TYPE_INT);
4027 COUNT(count_pcmd_op);
4028 OP1_1(TYPE_LNG, TYPE_LNG);
4031 COUNT(count_pcmd_op);
4032 OP1_1(TYPE_FLT, TYPE_FLT);
4035 COUNT(count_pcmd_op);
4036 OP1_1(TYPE_DBL, TYPE_DBL);
4040 COUNT(count_pcmd_op);
4041 OP1_1(TYPE_INT, TYPE_LNG);
4044 COUNT(count_pcmd_op);
4045 OP1_1(TYPE_INT, TYPE_FLT);
4048 COUNT(count_pcmd_op);
4049 OP1_1(TYPE_INT, TYPE_DBL);
4052 COUNT(count_pcmd_op);
4053 OP1_1(TYPE_LNG, TYPE_INT);
4056 COUNT(count_pcmd_op);
4057 OP1_1(TYPE_LNG, TYPE_FLT);
4060 COUNT(count_pcmd_op);
4061 OP1_1(TYPE_LNG, TYPE_DBL);
4064 COUNT(count_pcmd_op);
4065 OP1_1(TYPE_FLT, TYPE_INT);
4068 COUNT(count_pcmd_op);
4069 OP1_1(TYPE_FLT, TYPE_LNG);
4072 COUNT(count_pcmd_op);
4073 OP1_1(TYPE_FLT, TYPE_DBL);
4076 COUNT(count_pcmd_op);
4077 OP1_1(TYPE_DBL, TYPE_INT);
4080 COUNT(count_pcmd_op);
4081 OP1_1(TYPE_DBL, TYPE_LNG);
4084 COUNT(count_pcmd_op);
4085 OP1_1(TYPE_DBL, TYPE_FLT);
4088 case ICMD_CHECKCAST:
4089 coalescing_boundary = sd.new;
4090 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4091 /* array type cast-check */
4093 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4096 if (md->memuse > rd->memuse)
4097 rd->memuse = md->memuse;
4098 if (md->argintreguse > rd->argintreguse)
4099 rd->argintreguse = md->argintreguse;
4101 /* make all stack variables saved */
4105 sd.var[copy->varnum].flags |= SAVEDVAR;
4106 copy->flags |= SAVEDVAR;
4110 OP1_1(TYPE_ADR, TYPE_ADR);
4113 case ICMD_INSTANCEOF:
4114 case ICMD_ARRAYLENGTH:
4115 coalescing_boundary = sd.new;
4116 OP1_1(TYPE_ADR, TYPE_INT);
4120 case ICMD_ANEWARRAY:
4121 coalescing_boundary = sd.new;
4122 OP1_1(TYPE_INT, TYPE_ADR);
4126 coalescing_boundary = sd.new;
4127 COUNT(count_check_null);
4128 COUNT(count_pcmd_mem);
4129 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4130 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4135 case ICMD_GETSTATIC:
4136 coalescing_boundary = sd.new;
4137 COUNT(count_pcmd_mem);
4138 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4139 OP0_1(fmiref->parseddesc.fd->type);
4143 coalescing_boundary = sd.new;
4150 tbptr = iptr->sx.s23.s3.jsrtarget.block;
4151 tbptr->type = BBTYPE_SBR;
4153 assert(sd.bptr->next); /* XXX exception */
4154 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4155 #if defined(ENABLE_VERIFIER)
4156 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4159 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4163 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4165 /* We need to check for overflow right here because
4166 * the pushed value is poped afterwards */
4169 superblockend = true;
4170 /* XXX should not be marked as interface, as it does not need to be */
4171 /* allocated. Same for the invar of the target. */
4174 /* pop many push any */
4178 bte = iptr->sx.s23.s3.bte;
4182 case ICMD_INVOKESTATIC:
4183 case ICMD_INVOKESPECIAL:
4184 case ICMD_INVOKEVIRTUAL:
4185 case ICMD_INVOKEINTERFACE:
4186 COUNT(count_pcmd_met);
4188 /* Check for functions to replace with builtin
4191 if (builtintable_replace_function(iptr))
4194 INSTRUCTION_GET_METHODDESC(iptr, md);
4195 /* XXX resurrect this COUNT? */
4196 /* if (lm->flags & ACC_STATIC) */
4197 /* {COUNT(count_check_null);} */
4201 coalescing_boundary = sd.new;
4205 if (md->memuse > rd->memuse)
4206 rd->memuse = md->memuse;
4207 if (md->argintreguse > rd->argintreguse)
4208 rd->argintreguse = md->argintreguse;
4209 if (md->argfltreguse > rd->argfltreguse)
4210 rd->argfltreguse = md->argfltreguse;
4214 iptr->s1.argcount = stackdepth;
4215 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4218 for (i-- ; i >= 0; i--) {
4219 iptr->sx.s23.s2.args[i] = copy->varnum;
4221 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4222 /* -> won't help anyway */
4223 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4225 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4226 /* If we pass float arguments in integer argument registers, we
4227 * are not allowed to precolor them here. Floats have to be moved
4228 * to this regs explicitly in codegen().
4229 * Only arguments that are passed by stack anyway can be precolored
4230 * (michi 2005/07/24) */
4231 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4232 (!IS_FLT_DBL_TYPE(copy->type)
4233 || md->params[i].inmemory)) {
4235 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4240 if (md->params[i].inmemory) {
4241 sd.var[copy->varnum].vv.regoff =
4242 md->params[i].regoff;
4243 sd.var[copy->varnum].flags |=
4247 if (IS_FLT_DBL_TYPE(copy->type)) {
4248 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4249 assert(0); /* XXX is this assert ok? */
4251 sd.var[copy->varnum].vv.regoff =
4252 md->params[i].regoff;
4253 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4256 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4257 if (IS_2_WORD_TYPE(copy->type))
4258 sd.var[copy->varnum].vv.regoff =
4259 PACK_REGS(GET_LOW_REG(md->params[i].regoff),
4260 GET_HIGH_REG(md->params[i].regoff));
4263 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4264 sd.var[copy->varnum].vv.regoff =
4265 md->params[i].regoff;
4273 /* deal with live-through stack slots "under" the */
4279 iptr->sx.s23.s2.args[i++] = copy->varnum;
4280 sd.var[copy->varnum].flags |= SAVEDVAR;
4281 copy->flags |= SAVEDVAR | PASSTHROUGH;
4285 /* pop the arguments */
4294 /* push the return value */
4296 if (md->returntype.type != TYPE_VOID) {
4297 GET_NEW_VAR(sd, new_index, md->returntype.type);
4298 DST(md->returntype.type, new_index);
4303 case ICMD_MULTIANEWARRAY:
4304 coalescing_boundary = sd.new;
4305 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4306 rd->argintreguse = MIN(3, INT_ARG_CNT);
4308 i = iptr->s1.argcount;
4312 iptr->sx.s23.s2.args = DMNEW(s4, i);
4314 #if defined(SPECIALMEMUSE)
4315 # if defined(__DARWIN__)
4316 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4317 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4319 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4320 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4323 # if defined(__I386__)
4324 if (rd->memuse < i + 3)
4325 rd->memuse = i + 3; /* n integer args spilled on stack */
4326 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4327 if (rd->memuse < i + 2)
4328 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4331 rd->memuse = i; /* n integer args spilled on stack */
4332 # endif /* defined(__I386__) */
4336 /* check INT type here? Currently typecheck does this. */
4337 iptr->sx.s23.s2.args[i] = copy->varnum;
4338 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4339 && (!IS_INOUT(copy))
4340 && (!IS_LOCALVAR(copy)) ) {
4341 copy->varkind = ARGVAR;
4342 sd.var[copy->varnum].flags |=
4343 INMEMORY & PREALLOC;
4344 #if defined(SPECIALMEMUSE)
4345 # if defined(__DARWIN__)
4346 sd.var[copy->varnum].vv.regoff = i +
4347 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4349 sd.var[copy->varnum].vv.regoff = i +
4350 LA_SIZE_IN_POINTERS + 3;
4353 # if defined(__I386__)
4354 sd.var[copy->varnum].vv.regoff = i + 3;
4355 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4356 sd.var[copy->varnum].vv.regoff = i + 2;
4358 sd.var[copy->varnum].vv.regoff = i;
4359 # endif /* defined(__I386__) */
4360 #endif /* defined(SPECIALMEMUSE) */
4365 sd.var[copy->varnum].flags |= SAVEDVAR;
4366 copy->flags |= SAVEDVAR;
4370 i = iptr->s1.argcount;
4375 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4376 DST(TYPE_ADR, new_index);
4381 exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
4388 } /* while instructions */
4390 /* show state after last instruction */
4392 #if defined(STACK_VERBOSE)
4393 stack_verbose_show_state(&sd, NULL, curstack);
4396 /* stack slots at basic block end become interfaces */
4398 sd.bptr->outdepth = stackdepth;
4399 sd.bptr->outvars = DMNEW(s4, stackdepth);
4402 for (copy = curstack; copy; i--, copy = copy->prev) {
4405 /* with the new vars rd->interfaces will be removed */
4406 /* and all in and outvars have to be STACKVARS! */
4407 /* in the moment i.e. SWAP with in and out vars can */
4408 /* create an unresolvable conflict */
4413 v = sd.var + copy->varnum;
4416 /* do not allocate variables for returnAddresses */
4418 if (type != TYPE_RET) {
4419 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4420 /* no interface var until now for this depth and */
4422 jd->interface_map[i*5 + type].flags = v->flags;
4425 jd->interface_map[i*5 + type].flags |= v->flags;
4429 sd.bptr->outvars[i] = copy->varnum;
4432 /* check if interface slots at basic block begin must be saved */
4434 for (i=0; i<sd.bptr->indepth; ++i) {
4435 varinfo *v = sd.var + sd.bptr->invars[i];
4439 if (type != TYPE_RET) {
4440 if (jd->interface_map[i*5 + type].flags == UNUSED) {
4441 /* no interface var until now for this depth and */
4443 jd->interface_map[i*5 + type].flags = v->flags;
4446 jd->interface_map[i*5 + type].flags |= v->flags;
4451 /* store the number of this block's variables */
4453 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4455 #if defined(STACK_VERBOSE)
4456 stack_verbose_block_exit(&sd, superblockend);
4459 /* reach the following block, if any */
4462 if (!stack_reach_next_block(&sd))
4467 } while (sd.repeat && !deadcode);
4469 /* reset locals of TYPE_RET|VOID to TYPE_ADR */
4471 /* A local variable may be used as both a returnAddress and a reference */
4472 /* type variable, as we do not split variables between these types when */
4473 /* renaming locals. While returnAddresses have been eliminated now, we */
4474 /* must assume that the variable is still used as TYPE_ADR. */
4475 /* The only way that a local can be TYPE_VOID at this point, is that it */
4476 /* was a TYPE_RET variable for which incompatible returnAddresses were */
4477 /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET */
4479 /* XXX: It would be nice to remove otherwise unused returnAddress */
4480 /* variables from the local variable array, so they are not */
4481 /* allocated by simplereg. (For LSRA this is not needed). */
4483 for (i=0; i<sd.localcount; ++i) {
4484 if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
4485 sd.var[i].type = TYPE_ADR;
4488 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4490 for (i=sd.localcount; i<sd.vartop; ++i) {
4491 if (sd.var[i].type == TYPE_RET)
4492 sd.var[i].flags |= PREALLOC;
4495 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4497 ex = jd->exceptiontable;
4498 for (; ex != NULL; ex = ex->down) {
4499 if (ex->start == ex->end) {
4500 assert(ex->end->next);
4501 ex->end = ex->end->next;
4505 /* store number of created variables */
4507 jd->vartop = sd.vartop;
4509 /* gather statistics *****************************************************/
4511 #if defined(ENABLE_STATISTICS)
4513 if (jd->basicblockcount > count_max_basic_blocks)
4514 count_max_basic_blocks = jd->basicblockcount;
4515 count_basic_blocks += jd->basicblockcount;
4516 if (jd->instructioncount > count_max_javainstr)
4517 count_max_javainstr = jd->instructioncount;
4518 count_javainstr += jd->instructioncount;
4519 if (jd->stackcount > count_upper_bound_new_stack)
4520 count_upper_bound_new_stack = jd->stackcount;
4521 if ((sd.new - jd->stack) > count_max_new_stack)
4522 count_max_new_stack = (sd.new - jd->stack);
4524 sd.bptr = jd->basicblocks;
4525 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4526 if (sd.bptr->flags > BBREACHED) {
4527 if (sd.bptr->indepth >= 10)
4528 count_block_stack[10]++;
4530 count_block_stack[sd.bptr->indepth]++;
4531 len = sd.bptr->icount;
4533 count_block_size_distribution[len]++;
4535 count_block_size_distribution[10]++;
4537 count_block_size_distribution[11]++;
4539 count_block_size_distribution[12]++;
4541 count_block_size_distribution[13]++;
4543 count_block_size_distribution[14]++;
4545 count_block_size_distribution[15]++;
4547 count_block_size_distribution[16]++;
4549 count_block_size_distribution[17]++;
4553 if (iteration_count == 1)
4554 count_analyse_iterations[0]++;
4555 else if (iteration_count == 2)
4556 count_analyse_iterations[1]++;
4557 else if (iteration_count == 3)
4558 count_analyse_iterations[2]++;
4559 else if (iteration_count == 4)
4560 count_analyse_iterations[3]++;
4562 count_analyse_iterations[4]++;
4564 if (jd->basicblockcount <= 5)
4565 count_method_bb_distribution[0]++;
4566 else if (jd->basicblockcount <= 10)
4567 count_method_bb_distribution[1]++;
4568 else if (jd->basicblockcount <= 15)
4569 count_method_bb_distribution[2]++;
4570 else if (jd->basicblockcount <= 20)
4571 count_method_bb_distribution[3]++;
4572 else if (jd->basicblockcount <= 30)
4573 count_method_bb_distribution[4]++;
4574 else if (jd->basicblockcount <= 40)
4575 count_method_bb_distribution[5]++;
4576 else if (jd->basicblockcount <= 50)
4577 count_method_bb_distribution[6]++;
4578 else if (jd->basicblockcount <= 75)
4579 count_method_bb_distribution[7]++;
4581 count_method_bb_distribution[8]++;
4583 #endif /* defined(ENABLE_STATISTICS) */
4585 /* everything's ok *******************************************************/
4589 /* goto labels for throwing verifier exceptions **************************/
4591 #if defined(ENABLE_VERIFIER)
4593 throw_stack_underflow:
4594 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4597 throw_stack_overflow:
4598 exceptions_throw_verifyerror(m, "Stack size too large");
4601 throw_stack_type_error:
4602 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4605 throw_stack_category_error:
4606 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4613 /* stack_javalocals_store ******************************************************
4615 Model the effect of a ?STORE instruction upon the given javalocals array.
4618 iptr.............the ?STORE instruction
4619 javalocals.......the javalocals array to modify
4621 *******************************************************************************/
4623 void stack_javalocals_store(instruction *iptr, s4 *javalocals)
4625 s4 varindex; /* index into the jd->var array */
4626 s4 javaindex; /* java local index */
4628 varindex = iptr->dst.varindex;
4629 javaindex = iptr->sx.s23.s3.javaindex;
4631 if (javaindex != UNUSED) {
4632 assert(javaindex >= 0);
4633 if (iptr->flags.bits & INS_FLAG_RETADDR)
4634 javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
4636 javalocals[javaindex] = varindex;
4638 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
4639 javalocals[javaindex-1] = UNUSED;
4641 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
4642 javalocals[javaindex+1] = UNUSED;
4647 /* functions for verbose stack analysis output ********************************/
4649 #if defined(STACK_VERBOSE)
4650 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4652 printf("%c", show_jit_type_letters[v->type]);
4653 if (v->type == TYPE_RET) {
4654 printf("{L%03d}", v->vv.retaddr->nr);
4655 #if defined(ENABLE_VERIFIER)
4656 printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
4662 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4664 assert(index >= 0 && index < sd->vartop);
4665 stack_verbose_show_varinfo(sd, sd->var + index);
4669 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4673 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4675 for (i=0; i<bptr->indepth; ++i) {
4678 stack_verbose_show_variable(sd, bptr->invars[i]);
4683 printf("] javalocals ");
4684 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4685 printf(" inlocals [");
4686 if (bptr->inlocals) {
4687 for (i=0; i<sd->localcount; ++i) {
4690 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4695 printf("] out:%d [", bptr->outdepth);
4696 if (bptr->outvars) {
4697 for (i=0; i<bptr->outdepth; ++i) {
4700 stack_verbose_show_variable(sd, bptr->outvars[i]);
4708 printf(" (clone of L%03d)", bptr->original->nr);
4710 basicblock *b = bptr->copied_to;
4712 printf(" (copied to ");
4713 for (; b; b = b->copied_to)
4714 printf("L%03d ", b->nr);
4721 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4725 printf("======================================== STACK %sANALYSE BLOCK ",
4726 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4727 stack_verbose_show_block(sd, sd->bptr);
4730 if (sd->handlers[0]) {
4731 printf("HANDLERS: ");
4732 for (i=0; sd->handlers[i]; ++i) {
4733 printf("L%03d ", sd->handlers[i]->handler->nr);
4741 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4743 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4744 stack_verbose_show_block(sd, sd->bptr);
4748 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
4756 printf(" javalocals ");
4757 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4760 for(i = 0, sp = curstack; sp; sp = sp->prev)
4764 stack = MNEW(stackptr, depth);
4765 for(sp = curstack; sp; sp = sp->prev)
4768 for(i=0; i<depth; ++i) {
4772 v = &(sd->var[sp->varnum]);
4774 if (v->flags & INOUT)
4776 if (v->flags & PREALLOC)
4778 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4779 if (v->type == TYPE_RET) {
4780 printf("(L%03d)", v->vv.retaddr->nr);
4785 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4792 * These are local overrides for various environment variables in Emacs.
4793 * Please do not remove this and leave it at the end of the file, where
4794 * Emacs will automagically detect them.
4795 * ---------------------------------------------------------------------
4798 * indent-tabs-mode: t
4802 * vim:noexpandtab:sw=4:ts=4: