Christian Thalinger
Christian Ullrich
- $Id: stack.c 5079 2006-07-06 11:36:01Z twisti $
+ $Id: stack.c 5251 2006-08-18 13:01:00Z twisti $
*/
#include "vm/resolve.h"
#include "vm/statistics.h"
#include "vm/stringlocal.h"
+#include "vm/jit/cfg.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/abi.h"
#include "vm/jit/show.h"
#define DUP_SLOT(sp) \
do { \
- if ((sp)->varkind == STACKVAR) \
+ if ((sp)->varkind != TEMPVAR) \
NEWSTACK((sp)->type, TEMPVAR, stackdepth); \
else \
NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
bptr->type = BBTYPE_EXH;
bptr->instack = new;
bptr->indepth = 1;
- bptr->pre_count = 10000;
+ bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
STACKRESET;
NEWXSTACK;
}
- /* count predecessors of each block **************************************/
+ /* count predecessors of each block ***************************************/
#if CONDITIONAL_LOADCONST
/* XXX move this to a separate function */
case ICMD_IF_ACMPEQ:
case ICMD_IF_ACMPNE:
/* XXX add missing conditional branches */
- bptr[1].pre_count++;
+ bptr[1].predecessorcount++;
/* FALLTHROUGH */
/* unconditional branch */
case ICMD_GOTO:
- BLOCK_OF(iptr->dst.insindex)->pre_count++;
+ BLOCK_OF(iptr->dst.insindex)->predecessorcount++;
break;
/* switches */
case ICMD_TABLESWITCH:
table = iptr->dst.table;
- BLOCK_OF((table++)->insindex)->pre_count++;
+ BLOCK_OF((table++)->insindex)->predecessorcount++;
i = iptr->sx.s23.s3.tablehigh
- iptr->sx.s23.s2.tablelow + 1;
while (--i >= 0) {
- BLOCK_OF((table++)->insindex)->pre_count++;
+ BLOCK_OF((table++)->insindex)->predecessorcount++;
}
break;
case ICMD_LOOKUPSWITCH:
lookup = iptr->dst.lookup;
- BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->pre_count++;
+ BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->predecessorcount++;
i = iptr->sx.s23.s2.lookupcount;
while (--i >= 0) {
- BLOCK_OF((lookup++)->target.insindex)->pre_count++;
+ BLOCK_OF((lookup++)->target.insindex)->predecessorcount++;
}
break;
/* default - fall into next block */
default:
- bptr[1].pre_count++;
+ bptr[1].predecessorcount++;
break;
} /* end switch */
} /* end basic block loop */
while (--b_count >= 0) {
#if defined(STACK_VERBOSE)
- printf("ANALYZING BLOCK L%03d\n", bptr->debug_nr);
+ printf("ANALYZING BLOCK L%03d\n", bptr->nr);
#endif
if (bptr->flags == BBDELETED) {
iptr->flags.bits = INS_FLAG_NOCHECK;
iptr->sx.s23.s3.bte = bte;
/* iptr->line is already set */
- code->isleafmethod = false;
+ jd->isleafmethod = false;
goto icmd_BUILTIN;
}
);
CLR_DST; /* XXX live through? */
break;
- case ICMD_IFEQ_ICONST:
- case ICMD_IFNE_ICONST:
- case ICMD_IFLT_ICONST:
- case ICMD_IFGE_ICONST:
- case ICMD_IFGT_ICONST:
- case ICMD_IFLE_ICONST:
- case ICMD_ELSE_ICONST:
- USE_S1(TYPE_INT);
- CLR_SX;
- CLR_DST; /* XXX live through? */
- break;
-
case ICMD_RET:
USE_S1_LOCAL(TYPE_ADR);
CLR_SX;
putconst_tail:
/* set the field reference (s3) */
- if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED)
- iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
- else
+ if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
+ iptr->flags.bits |= INS_FLAG_UNRESOLVED;
+ }
+ else {
+ iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
+ }
switch (iptr[1].opc) {
case ICMD_PUTSTATIC:
iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
iptr->dst.dupslots[0] = curstack->prev;
iptr->dst.dupslots[1] = curstack;
- curstack = curstack->prev->prev;
+ POPANY; POPANY;
DUP_SLOT(iptr->dst.dupslots[1]);
iptr->dst.dupslots[2+0] = curstack;
iptr->dst.dupslots[0] = curstack->prev->prev;
iptr->dst.dupslots[1] = curstack->prev;
iptr->dst.dupslots[2] = curstack;
- curstack = curstack->prev->prev->prev;
+ POPANY; POPANY; POPANY;
DUP_SLOT(iptr->dst.dupslots[1]);
iptr->dst.dupslots[3+0] = curstack;
iptr->dst.dupslots[0] = curstack->prev->prev;
iptr->dst.dupslots[1] = curstack->prev;
iptr->dst.dupslots[2] = curstack;
- curstack = curstack->prev->prev->prev;
+ POPANY; POPANY; POPANY;
DUP_SLOT(iptr->dst.dupslots[2]);
iptr->dst.dupslots[3+0] = curstack;
iptr->dst.dupslots[1] = curstack->prev->prev;
iptr->dst.dupslots[2] = curstack->prev;
iptr->dst.dupslots[3] = curstack;
- curstack = curstack->prev->prev->prev->prev;
+ POPANY; POPANY; POPANY; POPANY;
DUP_SLOT(iptr->dst.dupslots[2]);
iptr->dst.dupslots[4+0] = curstack;
iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
iptr->dst.dupslots[0] = curstack->prev;
iptr->dst.dupslots[1] = curstack;
- curstack = curstack->prev->prev;
+ POPANY; POPANY;
DUP_SLOT(iptr->dst.dupslots[1]);
iptr->dst.dupslots[2+0] = curstack;
REQUIRE(i);
/* XXX optimize for <= 2 args */
- iptr->s1.argcount = i;
- iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+ /* XXX not for ICMD_BUILTIN */
+ iptr->s1.argcount = stackdepth;
+ iptr->sx.s23.s2.args = DMNEW(stackptr, stackdepth);
copy = curstack;
for (i-- ; i >= 0; i--) {
copy = copy->prev;
}
+ /* deal with live-through stack slots "under" the arguments */
+ /* XXX not for ICMD_BUILTIN */
+
+ i = md->paramcount;
+
while (copy) {
+ iptr->sx.s23.s2.args[i++] = copy;
copy->flags |= SAVEDVAR;
copy = copy->prev;
}
+ /* pop the arguments */
+
i = md->paramcount;
stackdepth -= i;
POPANY;
}
+ /* push the return value */
+
if (md->returntype.type != TYPE_VOID) {
NEW_DST(md->returntype.type, stackdepth);
stackdepth++;
#if defined(SPECIALMEMUSE)
# if defined(__DARWIN__)
- if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
- rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
+ if (rd->memuse < (i + INT_ARG_CNT + LA_SIZE_IN_POINTERS))
+ rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
# else
- if (rd->memuse < (i + LA_WORD_SIZE + 3))
- rd->memuse = i + LA_WORD_SIZE + 3;
+ if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
+ rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
# endif
#else
# if defined(__I386__)
copy->flags |= INMEMORY;
#if defined(SPECIALMEMUSE)
# if defined(__DARWIN__)
- copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
+ copy->regoff = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
# else
- copy->regoff = i + LA_WORD_SIZE + 3;
+ copy->regoff = i + LA_SIZE_IN_POINTERS + 3;
# endif
#else
# if defined(__I386__)
#if defined(ENABLE_VERIFIER)
throw_stack_underflow:
- *exceptionptr =
- new_verifyerror(m, "Unable to pop operand off an empty stack");
+ exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
return false;
throw_stack_overflow:
- *exceptionptr = new_verifyerror(m, "Stack size too large");
+ exceptions_throw_verifyerror(m, "Stack size too large");
return false;
throw_stack_depth_error:
- *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
+ exceptions_throw_verifyerror(m,"Stack depth mismatch");
return false;
throw_stack_type_error:
return false;
throw_stack_category_error:
- *exceptionptr =
- new_verifyerror(m, "Attempt to split long or double on the stack");
+ exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
return false;
#endif
cd = jd->cd;
rd = jd->rd;
-#if defined(ENABLE_LSRA)
- m->maxlifetimes = 0;
-#endif
-
last_store = DMNEW(s4 , cd->maxlocals * 5);
new = m->stack;
bptr->type = BBTYPE_EXH;
bptr->instack = new;
bptr->indepth = 1;
- bptr->pre_count = 10000;
+ bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
STACKRESET;
NEWXSTACK;
}
-#if CONDITIONAL_LOADCONST
- b_count = m->basicblockcount;
- bptr = m->basicblocks;
- while (--b_count >= 0) {
- if (bptr->icount != 0) {
- iptr = bptr->iinstr + bptr->icount - 1;
- switch (iptr->opc) {
- case ICMD_RET:
- case ICMD_RETURN:
- case ICMD_IRETURN:
- case ICMD_LRETURN:
- case ICMD_FRETURN:
- case ICMD_DRETURN:
- case ICMD_ARETURN:
- case ICMD_ATHROW:
- break;
-
- case ICMD_IFEQ:
- case ICMD_IFNE:
- case ICMD_IFLT:
- case ICMD_IFGE:
- case ICMD_IFGT:
- case ICMD_IFLE:
-
- case ICMD_IFNULL:
- case ICMD_IFNONNULL:
-
- case ICMD_IF_ICMPEQ:
- case ICMD_IF_ICMPNE:
- case ICMD_IF_ICMPLT:
- case ICMD_IF_ICMPGE:
- case ICMD_IF_ICMPGT:
- case ICMD_IF_ICMPLE:
-
- case ICMD_IF_ACMPEQ:
- case ICMD_IF_ACMPNE:
- bptr[1].pre_count++;
- case ICMD_GOTO:
- m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
- break;
-
- case ICMD_TABLESWITCH:
- s4ptr = iptr->val.a;
- m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
- i = *s4ptr++; /* low */
- i = *s4ptr++ - i + 1; /* high */
- while (--i >= 0) {
- m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
- }
- break;
-
- case ICMD_LOOKUPSWITCH:
- s4ptr = iptr->val.a;
- m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
- i = *s4ptr++; /* count */
- while (--i >= 0) {
- m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
- s4ptr += 2;
- }
- break;
- default:
- bptr[1].pre_count++;
- break;
- }
- }
- bptr++;
- }
-#endif /* CONDITIONAL_LOADCONST */
-
-
do {
loops++;
b_count = m->basicblockcount;
while (--len >= 0) {
opcode = iptr->opc;
+ /* check if ICMD opcode could throw an exception */
+ /* and if so remember the instruction index in last_pei */
+
+ if (op_data[opcode][PEI])
+ last_pei = bptr->icount - len - 1;
+
#if defined(USEBUILTINTABLE)
# if defined(ENABLE_INTRP)
if (!opt_intrp) {
# endif
+ /* check for opcodes to replace */
+
bte = builtintable_get_automatic(opcode);
if (bte && bte->opcode == opcode) {
iptr->opc = ICMD_BUILTIN;
iptr->op1 = false; /* don't check for exception */
iptr->val.a = bte;
- code->isleafmethod = false;
+ jd->isleafmethod = false;
goto builtin;
}
# if defined(ENABLE_INTRP)
# endif
#endif /* defined(USEBUILTINTABLE) */
+ /* Check for functions to replace with builtin
+ functions. */
+
+ if (builtintable_replace_function(iptr))
+ goto builtin;
+
/* this is the main switch */
switch (opcode) {
case ICMD_CHECKNULL:
COUNT(count_check_null);
case ICMD_NOP:
-
- case ICMD_IFEQ_ICONST:
- case ICMD_IFNE_ICONST:
- case ICMD_IFLT_ICONST:
- case ICMD_IFGE_ICONST:
- case ICMD_IFGT_ICONST:
- case ICMD_IFLE_ICONST:
- case ICMD_ELSE_ICONST:
SETDST;
break;
case ICMD_IFGT:
case ICMD_IFLE:
COUNT(count_pcmd_bra);
-#if CONDITIONAL_LOADCONST && 0
-# if defined(ENABLE_INTRP)
- if (!opt_intrp) {
-# endif
- tbptr = m->basicblocks + b_index;
-
- if ((b_count >= 3) &&
- ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
- (tbptr[1].pre_count == 1) &&
- (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
- (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
- ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
- (tbptr[2].pre_count == 1) &&
- (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
- (tbptr[2].icount==1)) {
- /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
- OP1_1(TYPE_INT, TYPE_INT);
- switch (iptr[0].opc) {
- case ICMD_IFEQ:
- iptr[0].opc = ICMD_IFNE_ICONST;
- break;
- case ICMD_IFNE:
- iptr[0].opc = ICMD_IFEQ_ICONST;
- break;
- case ICMD_IFLT:
- iptr[0].opc = ICMD_IFGE_ICONST;
- break;
- case ICMD_IFGE:
- iptr[0].opc = ICMD_IFLT_ICONST;
- break;
- case ICMD_IFGT:
- iptr[0].opc = ICMD_IFLE_ICONST;
- break;
- case ICMD_IFLE:
- iptr[0].opc = ICMD_IFGT_ICONST;
- break;
- }
-#if 1
- iptr[0].val.i = iptr[1].val.i;
- iptr[1].opc = ICMD_ELSE_ICONST;
- iptr[1].val.i = iptr[3].val.i;
- iptr[2].opc = ICMD_NOP;
- iptr[3].opc = ICMD_NOP;
-#else
- /* HACK: save compare value in iptr[1].op1 */
- iptr[1].op1 = iptr[0].val.i;
- iptr[0].val.i = tbptr[1].iinstr[0].val.i;
- iptr[1].opc = ICMD_ELSE_ICONST;
- iptr[1].val.i = tbptr[2].iinstr[0].val.i;
- tbptr[1].iinstr[0].opc = ICMD_NOP;
- tbptr[1].iinstr[1].opc = ICMD_NOP;
- tbptr[2].iinstr[0].opc = ICMD_NOP;
-#endif
- tbptr[1].flags = BBDELETED;
- tbptr[2].flags = BBDELETED;
- tbptr[1].icount = 0;
- tbptr[2].icount = 0;
- if (tbptr[3].pre_count == 2) {
- len += tbptr[3].icount + 3;
- bptr->icount += tbptr[3].icount + 3;
- tbptr[3].flags = BBDELETED;
- tbptr[3].icount = 0;
- b_index++;
- }
- else {
- bptr->icount++;
- len ++;
- }
- b_index += 2;
- break;
- }
-# if defined(ENABLE_INTRP)
- }
-# endif
-
-#endif /* CONDITIONAL_LOADCONST */
/* iptr->val.i is set implicitly in parse by
clearing the memory or from IF_ICMPxx
/* pop many push any */
case ICMD_BUILTIN:
-#if defined(USEBUILTINTABLE)
builtin:
-#endif
bte = (builtintable_entry *) iptr->val.a;
md = bte->md;
goto _callhandling;
_callhandling:
- last_pei = bptr->icount - len - 1;
+/* last_pei = bptr->icount - len - 1; */
i = md->paramcount;
REQUIRE(i);
#if defined(SPECIALMEMUSE)
# if defined(__DARWIN__)
- if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
- rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
+ if (rd->memuse < (i + INT_ARG_CNT + LA_SIZE_IN_POINTERS))
+ rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
# else
- if (rd->memuse < (i + LA_WORD_SIZE + 3))
- rd->memuse = i + LA_WORD_SIZE + 3;
+ if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
+ rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
# endif
#else
# if defined(__I386__)
copy->flags |= INMEMORY;
#if defined(SPECIALMEMUSE)
# if defined(__DARWIN__)
- copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
+ copy->regoff = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
# else
- copy->regoff = i + LA_WORD_SIZE + 3;
+ copy->regoff = i + LA_SIZE_IN_POINTERS + 3;
# endif
#else
# if defined(__I386__)
#if defined(ENABLE_VERIFIER)
throw_stack_underflow:
- *exceptionptr =
- new_verifyerror(m, "Unable to pop operand off an empty stack");
+ exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
return false;
throw_stack_overflow:
- *exceptionptr = new_verifyerror(m, "Stack size too large");
+ exceptions_throw_verifyerror(m, "Stack size too large");
return false;
throw_stack_depth_error:
- *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
+ exceptions_throw_verifyerror(m, "Stack depth mismatch");
return false;
throw_stack_type_error:
return false;
throw_stack_category_error:
- *exceptionptr =
- new_verifyerror(m, "Attempt to split long or double on the stack");
+ exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
return false;
#endif