/* src/vm/jit/stack.c - stack analysis
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
struct stackdata_t {
basicblock *bptr; /* the current basic block being analysed */
- stackptr new; /* next free stackelement */
+ stackelement_t *new; /* next free stackelement */
s4 vartop; /* next free variable index */
s4 localcount; /* number of locals (at the start of var) */
s4 varcount; /* maximum number of variables expected */
bool repeat; /* if true, iterate the analysis again */
exception_entry **handlers; /* exception handlers for the current block */
exception_entry *extableend; /* points to the last exception entry */
- stackelement exstack; /* instack for exception handlers */
+ stackelement_t exstack; /* instack for exception handlers */
};
/* forward declarations *******************************************************/
static void stack_create_invars(stackdata_t *sd, basicblock *b,
- stackptr curstack, int stackdepth);
+ stackelement_t * curstack, int stackdepth);
static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
#if defined(STACK_VERBOSE)
static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
- stackptr curstack);
+ stackelement_t * curstack);
#endif
*******************************************************************************/
static void stack_create_invars(stackdata_t *sd, basicblock *b,
- stackptr curstack, int stackdepth)
+ stackelement_t * curstack, int stackdepth)
{
- stackptr sp;
+ stackelement_t * sp;
int i;
int index;
varinfo *dv;
*******************************************************************************/
static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
- stackptr curstack, int stackdepth)
+ stackelement_t * curstack, int stackdepth)
{
int i;
- stackptr sp;
+ stackelement_t * sp;
basicblock *orig;
bool separable;
varinfo *sv;
*******************************************************************************/
-static stackptr stack_create_instack(stackdata_t *sd)
+static stackelement_t * stack_create_instack(stackdata_t *sd)
{
- stackptr sp;
+ stackelement_t * sp;
int depth;
int index;
*******************************************************************************/
-static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
+static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackelement_t * curstack, int stackdepth)
{
assert(b != NULL);
assert(iptr->opc == ICMD_NOP);
iptr->opc = ICMD_GOTO;
iptr->dst.block = tbptr;
+#if defined(STACK_VERBOSE)
+ if (iptr->line == 0) printf("goto with line 0 in L%03d\n", sd->bptr->nr);
+#endif
if (tbptr->flags < BBFINISHED)
sd->repeat = true; /* XXX check if we really need to repeat */
case ICMD_IF_LCMPGT:
case ICMD_IF_LCMPLE:
- case ICMD_IF_FCMPEQ:
- case ICMD_IF_FCMPNE:
-
- case ICMD_IF_FCMPL_LT:
- case ICMD_IF_FCMPL_GE:
- case ICMD_IF_FCMPL_GT:
- case ICMD_IF_FCMPL_LE:
-
- case ICMD_IF_FCMPG_LT:
- case ICMD_IF_FCMPG_GE:
- case ICMD_IF_FCMPG_GT:
- case ICMD_IF_FCMPG_LE:
-
- case ICMD_IF_DCMPEQ:
- case ICMD_IF_DCMPNE:
-
- case ICMD_IF_DCMPL_LT:
- case ICMD_IF_DCMPL_GE:
- case ICMD_IF_DCMPL_GT:
- case ICMD_IF_DCMPL_LE:
-
- case ICMD_IF_DCMPG_LT:
- case ICMD_IF_DCMPG_GE:
- case ICMD_IF_DCMPG_GT:
- case ICMD_IF_DCMPG_LE:
-
case ICMD_IF_ACMPEQ:
case ICMD_IF_ACMPNE:
RELOCATE(iptr->sx.s23.s2.varindex);
*******************************************************************************/
-static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
+static void stack_change_to_tempvar(stackdata_t *sd, stackelement_t * sp,
instruction *ilimit)
{
s4 newindex;
bool stack_analyse(jitdata *jd)
{
methodinfo *m; /* method being analyzed */
+ codeinfo *code;
registerdata *rd;
stackdata_t sd;
int stackdepth;
- stackptr curstack; /* current stack top */
- stackptr copy;
+ stackelement_t *curstack; /* current stack top */
+ stackelement_t *copy;
int opcode; /* opcode of current instruction */
int i, varindex;
int javaindex;
basicblock *original;
exception_entry *ex;
- stackptr *last_store_boundary;
- stackptr coalescing_boundary;
+ stackelement_t **last_store_boundary;
+ stackelement_t *coalescing_boundary;
- stackptr src1, src2, src3, src4, dst1, dst2;
+ stackelement_t *src1, *src2, *src3, *src4, *dst1, *dst2;
branch_target_t *table;
lookup_target_t *lookup;
/* get required compiler data - initialization */
m = jd->m;
+ code = jd->code;
rd = jd->rd;
/* initialize the stackdata_t struct */
for (i = 0; i < m->maxstack * 5; i++)
jd->interface_map[i].flags = UNUSED;
- last_store_boundary = DMNEW(stackptr, m->maxlocals);
+ last_store_boundary = DMNEW(stackelement_t *, m->maxlocals);
/* initialize flags and invars (none) of first block */
iptr->flags.bits &= INS_FLAG_ID_MASK;
iptr->sx.s23.s3.bte = bte;
/* iptr->line is already set */
- jd->isleafmethod = false;
+ code_unflag_leafmethod(code);
goto icmd_BUILTIN;
}
case ICMD_IINC:
STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
- last_store_boundary[iptr->s1.varindex] = sd.new;
+ javaindex = iptr->s1.varindex;
+ last_store_boundary[javaindex] = sd.new;
iptr->s1.varindex =
- jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
+ jd->local_map[javaindex * 5 + TYPE_INT];
copy = curstack;
i = stackdepth - 1;
while (copy) {
if ((copy->varkind == LOCALVAR) &&
- (copy->varnum == iptr->s1.varindex))
+ (jd->reverselocalmap[copy->varnum] == javaindex))
{
assert(IS_LOCALVAR(copy));
SET_TEMPVAR(copy);
i = stackdepth - 2;
while (copy) {
if ((copy->varkind == LOCALVAR) &&
- (copy->varnum == varindex))
+ (jd->reverselocalmap[copy->varnum] == javaindex))
{
- copy->varkind = TEMPVAR;
assert(IS_LOCALVAR(copy));
SET_TEMPVAR(copy);
}
copy = sd.new; /* most recent stackslot created + 1 */
while (--copy > curstack) {
- if (copy->varkind == LOCALVAR && copy->varnum == varindex)
+ if (copy->varkind == LOCALVAR && jd->reverselocalmap[copy->varnum] == javaindex)
goto assume_conflict;
}
/* revert the coalescing, if it has been done earlier */
assume_conflict:
if ((curstack->varkind == LOCALVAR)
- && (curstack->varnum == varindex))
+ && (jd->reverselocalmap[curstack->varnum] == javaindex))
{
assert(IS_LOCALVAR(curstack));
SET_TEMPVAR(curstack);
COUNT(count_check_bound);
COUNT(count_pcmd_mem);
- bte = builtintable_get_internal(BUILTIN_canstore);
+ bte = builtintable_get_internal(BUILTIN_FAST_canstore);
md = bte->md;
if (md->memuse > rd->memuse)
OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
break;
- /* XXX why is this deactivated? */
-#if 0
- case ICMD_FCMPL:
- COUNT(count_pcmd_op);
- if ((len == 0) || (iptr[1].sx.val.i != 0))
- goto normal_FCMPL;
-
- switch (iptr[1].opc) {
- case ICMD_IFEQ:
- iptr->opc = ICMD_IF_FCMPEQ;
- icmd_if_fcmpl_tail:
- iptr->dst.block = iptr[1].dst.block;
- iptr[1].opc = ICMD_NOP;
-
- OP2_BRANCH(TYPE_FLT, TYPE_FLT);
- BRANCH(tbptr);
-
- COUNT(count_pcmd_bra);
- break;
- case ICMD_IFNE:
- iptr->opc = ICMD_IF_FCMPNE;
- goto icmd_if_fcmpl_tail;
- case ICMD_IFLT:
- iptr->opc = ICMD_IF_FCMPL_LT;
- goto icmd_if_fcmpl_tail;
- case ICMD_IFGT:
- iptr->opc = ICMD_IF_FCMPL_GT;
- goto icmd_if_fcmpl_tail;
- case ICMD_IFLE:
- iptr->opc = ICMD_IF_FCMPL_LE;
- goto icmd_if_fcmpl_tail;
- case ICMD_IFGE:
- iptr->opc = ICMD_IF_FCMPL_GE;
- goto icmd_if_fcmpl_tail;
- default:
- goto normal_FCMPL;
- }
- break;
-
-normal_FCMPL:
- OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
- break;
-
- case ICMD_FCMPG:
- COUNT(count_pcmd_op);
- if ((len == 0) || (iptr[1].sx.val.i != 0))
- goto normal_FCMPG;
-
- switch (iptr[1].opc) {
- case ICMD_IFEQ:
- iptr->opc = ICMD_IF_FCMPEQ;
- icmd_if_fcmpg_tail:
- iptr->dst.block = iptr[1].dst.block;
- iptr[1].opc = ICMD_NOP;
-
- OP2_BRANCH(TYPE_FLT, TYPE_FLT);
- BRANCH(tbptr);
-
- COUNT(count_pcmd_bra);
- break;
- case ICMD_IFNE:
- iptr->opc = ICMD_IF_FCMPNE;
- goto icmd_if_fcmpg_tail;
- case ICMD_IFLT:
- iptr->opc = ICMD_IF_FCMPG_LT;
- goto icmd_if_fcmpg_tail;
- case ICMD_IFGT:
- iptr->opc = ICMD_IF_FCMPG_GT;
- goto icmd_if_fcmpg_tail;
- case ICMD_IFLE:
- iptr->opc = ICMD_IF_FCMPG_LE;
- goto icmd_if_fcmpg_tail;
- case ICMD_IFGE:
- iptr->opc = ICMD_IF_FCMPG_GE;
- goto icmd_if_fcmpg_tail;
- default:
- goto normal_FCMPG;
- }
- break;
-
-normal_FCMPG:
- OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
- break;
-
- case ICMD_DCMPL:
- COUNT(count_pcmd_op);
- if ((len == 0) || (iptr[1].sx.val.i != 0))
- goto normal_DCMPL;
-
- switch (iptr[1].opc) {
- case ICMD_IFEQ:
- iptr->opc = ICMD_IF_DCMPEQ;
- icmd_if_dcmpl_tail:
- iptr->dst.block = iptr[1].dst.block;
- iptr[1].opc = ICMD_NOP;
-
- OP2_BRANCH(TYPE_DBL, TYPE_DBL);
- BRANCH(tbptr);
-
- COUNT(count_pcmd_bra);
- break;
- case ICMD_IFNE:
- iptr->opc = ICMD_IF_DCMPNE;
- goto icmd_if_dcmpl_tail;
- case ICMD_IFLT:
- iptr->opc = ICMD_IF_DCMPL_LT;
- goto icmd_if_dcmpl_tail;
- case ICMD_IFGT:
- iptr->opc = ICMD_IF_DCMPL_GT;
- goto icmd_if_dcmpl_tail;
- case ICMD_IFLE:
- iptr->opc = ICMD_IF_DCMPL_LE;
- goto icmd_if_dcmpl_tail;
- case ICMD_IFGE:
- iptr->opc = ICMD_IF_DCMPL_GE;
- goto icmd_if_dcmpl_tail;
- default:
- goto normal_DCMPL;
- }
- break;
-
-normal_DCMPL:
- OPTT2_1(TYPE_DBL, TYPE_INT);
- break;
-
- case ICMD_DCMPG:
- COUNT(count_pcmd_op);
- if ((len == 0) || (iptr[1].sx.val.i != 0))
- goto normal_DCMPG;
-
- switch (iptr[1].opc) {
- case ICMD_IFEQ:
- iptr->opc = ICMD_IF_DCMPEQ;
- icmd_if_dcmpg_tail:
- iptr->dst.block = iptr[1].dst.block;
- iptr[1].opc = ICMD_NOP;
-
- OP2_BRANCH(TYPE_DBL, TYPE_DBL);
- BRANCH(tbptr);
-
- COUNT(count_pcmd_bra);
- break;
- case ICMD_IFNE:
- iptr->opc = ICMD_IF_DCMPNE;
- goto icmd_if_dcmpg_tail;
- case ICMD_IFLT:
- iptr->opc = ICMD_IF_DCMPG_LT;
- goto icmd_if_dcmpg_tail;
- case ICMD_IFGT:
- iptr->opc = ICMD_IF_DCMPG_GT;
- goto icmd_if_dcmpg_tail;
- case ICMD_IFLE:
- iptr->opc = ICMD_IF_DCMPG_LE;
- goto icmd_if_dcmpg_tail;
- case ICMD_IFGE:
- iptr->opc = ICMD_IF_DCMPG_GE;
- goto icmd_if_dcmpg_tail;
- default:
- goto normal_DCMPG;
- }
- break;
-
-normal_DCMPG:
- OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
- break;
-#else
case ICMD_FCMPL:
case ICMD_FCMPG:
COUNT(count_pcmd_op);
COUNT(count_pcmd_op);
OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
break;
-#endif
/* pop 1 push 1 */
printf("\n");
}
-static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackelement_t *curstack)
{
- stackptr sp;
+ stackelement_t *sp;
s4 i;
s4 depth;
varinfo *v;
- stackptr *stack;
+ stackelement_t **stack;
printf(" javalocals ");
show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
i++;
depth = i;
- stack = MNEW(stackptr, depth);
+ stack = MNEW(stackelement_t *, depth);
for(sp = curstack; sp; sp = sp->prev)
stack[--i] = sp;