Authors: Christian Thalinger
Changes: Christian Ullrich
-
- $Id: stack.h 5404 2006-09-07 13:29:05Z christian $
+ Edwin Steiner
*/
/* macros used internally by analyse_stack ************************************/
-/* convenient abbreviations */
-#define CURKIND curstack->varkind
-#define CURTYPE curstack->type
-
-
-/*--------------------------------------------------*/
-/* STACK DEPTH CHECKING */
-/*--------------------------------------------------*/
-
-#if defined(ENABLE_VERIFIER)
-#define CHECK_STACK_DEPTH(depthA,depthB) \
- do { \
- if ((depthA) != (depthB)) \
- goto throw_stack_depth_error; \
- } while (0)
-#else /* !ENABLE_VERIFIER */
-#define CHECK_STACK_DEPTH(depthA,depthB)
-#endif /* ENABLE_VERIFIER */
-
-
/*--------------------------------------------------*/
/* BASIC TYPE CHECKING */
/*--------------------------------------------------*/
/* XXX would be nice if we did not have to pass the expected type */
#if defined(ENABLE_VERIFIER)
-#define CHECK_BASIC_TYPE(expected,actual) \
- do { \
- if ((actual) != (expected)) { \
- expectedtype = (expected); \
- goto throw_stack_type_error; \
- } \
- } while (0)
+#define CHECK_BASIC_TYPE(expected,actual) \
+ do { \
+ if ((actual) != (expected)) { \
+ expectedtype = (expected); \
+ goto throw_stack_type_error; \
+ } \
+ } while (0)
#else /* !ENABLE_VERIFIER */
#define CHECK_BASIC_TYPE(expected,actual)
#endif /* ENABLE_VERIFIER */
/* underflow checks */
#if defined(ENABLE_VERIFIER)
-#define REQUIRE(num) \
- do { \
- if (stackdepth < (num)) \
- goto throw_stack_underflow; \
- } while (0)
+#define REQUIRE(num) \
+ do { \
+ if (stackdepth < (num)) \
+ goto throw_stack_underflow; \
+ } while (0)
#else /* !ENABLE_VERIFIER */
#define REQUIRE(num)
#endif /* ENABLE_VERIFIER */
-#define REQUIRE_1 REQUIRE(1)
-#define REQUIRE_2 REQUIRE(2)
-#define REQUIRE_3 REQUIRE(3)
-#define REQUIRE_4 REQUIRE(4)
-
/* overflow check */
/* We allow ACONST instructions inserted as arguments to builtin
/* XXX we should find a way to remove the opc/op1 check */
#if defined(ENABLE_VERIFIER)
-#define CHECKOVERFLOW \
- do { \
- if (stackdepth > m->maxstack) \
- if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr)) \
- goto throw_stack_overflow; \
- } while(0)
+#define CHECKOVERFLOW \
+ do { \
+ if (stackdepth > m->maxstack) \
+ if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr))\
+ goto throw_stack_overflow; \
+ } while(0)
#else /* !ENABLE_VERIFIER */
#define CHECKOVERFLOW
#endif /* ENABLE_VERIFIER */
/* ALLOCATING STACK SLOTS */
/*--------------------------------------------------*/
-#define NEWSTACK(s,v,n) \
- do { \
- new->prev = curstack; \
- new->type = (s); \
- new->flags = 0; \
- new->varkind = (v); \
- new->varnum = (n); \
- curstack = new; \
- jd->var[(n)].type = (s); \
- jd->var[(n)].flags = 0; \
- new++; \
+#define NEWSTACK(s,v,n) \
+ do { \
+ sd.new->prev = curstack; \
+ sd.new->type = (s); \
+ sd.new->flags = 0; \
+ sd.new->varkind = (v); \
+ sd.new->varnum = (n); \
+ curstack = sd.new; \
+ sd.var[(n)].type = (s); \
+ sd.var[(n)].flags = 0; \
+ sd.new++; \
} while (0)
/* Initialize regoff, so -sia can show regnames even before reg.inc */
#define NEWSTACKn(s,n) NEWSTACK(s,UNDEFVAR,n)
#define NEWSTACK0(s) NEWSTACK(s,UNDEFVAR,0)
-/* allocate the input stack for an exception handler */
-#define NEWXSTACK {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
-
-/*--------------------------------------------------*/
-/* STACK MANIPULATION */
-/*--------------------------------------------------*/
-
-/* resetting to an empty operand stack */
-
-#define STACKRESET \
- do { \
- curstack = 0; \
- stackdepth = 0; \
- } while (0)
-
-
-/* set the output stack of the current instruction */
-
-#define SETDST iptr->dst = curstack;
-
-
-/* The following macros do NOT check stackdepth, set stackdepth or iptr->dst */
-
-#define POP(s) \
- do { \
- CHECK_BASIC_TYPE((s),curstack->type); \
- if (curstack->varkind == UNDEFVAR) \
- curstack->varkind = TEMPVAR; \
- curstack = curstack->prev; \
- } while (0)
-
-#define POPANY \
- do { \
- if (curstack->varkind == UNDEFVAR) \
- curstack->varkind = TEMPVAR; \
- curstack = curstack->prev; \
- } while (0)
-
-/* Do not copy Interface Stackslots over DUPx, Swaps! */
-#define COPY(s,d) \
- do { \
- (d)->flags = 0; \
- (d)->type = (s)->type; \
- if ( (s)->varkind != STACKVAR) { \
- (d)->varkind = (s)->varkind; \
- (d)->varnum = (s)->varnum; \
- } else { \
- (d)->varkind = TEMPVAR; \
- (d)->varnum = 0; \
- } \
- } while (0)
-
-
-/*--------------------------------------------------*/
-/* MACROS FOR HANDLING BASIC BLOCKS */
-/*--------------------------------------------------*/
-
-/* COPYCURSTACK makes a copy of the current operand stack (curstack)
- * and returns it in the variable copy.
- *
- * This macro is used to propagate the operand stack from one basic
- * block to another. The destination block receives the copy as its
- * input stack.
- */
-#if defined(NEW_VAR)
-# define COPYCURSTACK(copy) {\
- stackptr s;\
- if(curstack){\
- s=curstack;\
- new+=stackdepth;\
- copy=new;\
- while(s){\
- copy--; \
- copy->prev=copy-1;\
- copy->type=s->type;\
- copy->flags=0;\
- copy->varkind=STACKVAR;\
- copy->varnum=s->varnum;\
- SET_OUTVAR(s); \
- s=s->prev;\
- }\
- copy->prev=NULL;\
- copy=new-1;\
- }\
- else\
- copy=NULL;\
-}
-#else
-# define COPYCURSTACK(copy) {\
- int d;\
- stackptr s;\
- if(curstack){\
- s=curstack;\
- new+=stackdepth;\
- d=stackdepth;\
- copy=new;\
- while(s){\
- copy--;d--;\
- copy->prev=copy-1;\
- copy->type=s->type;\
- copy->flags=0;\
- copy->varkind=STACKVAR;\
- copy->varnum=d;\
- s=s->prev;\
- }\
- copy->prev=NULL;\
- copy=new-1;\
- }\
- else\
- copy=NULL;\
-}
-#endif
-
-/* MARKREACHED marks the destination block <b> as reached. If this
- * block has been reached before we check if stack depth and types
- * match. Otherwise the destination block receives a copy of the
- * current stack as its input stack.
- *
- * b...destination block
- * c...current stack
- */
-
-/* XXX this macro is much too big! */
-
-#define MARKREACHED(b,c) \
- do { \
- if ((b) <= (bptr)) \
- (b)->bitflags |= BBFLAG_REPLACEMENT; \
- if ((b)->flags < BBREACHED) { \
- int locali; \
- COPYCURSTACK((c)); \
- (b)->flags = BBREACHED; \
- (b)->instack = (c); \
- (b)->indepth = stackdepth; \
- (b)->invars = DMNEW(s4, stackdepth); \
- for (locali = stackdepth; locali--; (c) = (c)->prev) { \
- (b)->invars[locali] = (c)->varnum; \
- SET_OUTVAR((c)); \
- } \
- } else { \
- stackptr s = curstack; \
- stackptr t = (b)->instack; \
- CHECK_STACK_DEPTH((b)->indepth, stackdepth); \
- while (s) { \
- CHECK_BASIC_TYPE(s->type,t->type); \
- s = s->prev; \
- t = t->prev; \
- } \
- } \
- } while (0)
-
-
-/* external macros ************************************************************/
-
-#define BLOCK_OF(index) \
- (jd->new_basicblocks + jd->new_basicblockindex[index])
-
/* function prototypes ********************************************************/
bool stack_init(void);
-bool new_stack_analyse(jitdata *jd);
+bool stack_analyse(jitdata *jd);
+
+void stack_javalocals_store(instruction *iptr, s4 *javalocals);
#endif /* _STACK_H */