X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fparse.h;h=c7d561dbb8ebfafcd6dd7633d46d46918ca5317a;hb=ff4083aaec535fb7a937e3221a42782959586644;hp=cbdd63a324178a3445c5fe44055f52a2d1cd1476;hpb=3ae649d7d8c0f0c0301b33e9bbbc76361c7e4af5;p=cacao.git diff --git a/src/vm/jit/parse.h b/src/vm/jit/parse.h index cbdd63a32..c7d561dbb 100644 --- a/src/vm/jit/parse.h +++ b/src/vm/jit/parse.h @@ -24,11 +24,10 @@ Contact: cacao@cacaojvm.org - Author: Christian Thalinger + Author: Christian Thalinger + Edwin Steiner - Changes: - - $Id: parse.h 4734 2006-04-05 09:57:55Z edwin $ + $Id: parse.h 5959 2006-11-12 13:31:14Z edwin $ */ @@ -43,182 +42,243 @@ #include "vm/jit/codegen-common.h" +/* macros for verifier checks during parsing **********************************/ + +#if defined(ENABLE_VERIFIER) + +/* We have to check local variables indices here because they are */ +/* used in stack.c to index the locals array. */ + +#define INDEX_ONEWORD(num) \ + do { \ + if (((num) < 0) || ((num) >= m->maxlocals)) \ + goto throw_illegal_local_variable_number; \ + } while (0) + +#define INDEX_TWOWORD(num) \ + do { \ + if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \ + goto throw_illegal_local_variable_number; \ + } while (0) + +/* CHECK_BYTECODE_INDEX(i) checks whether i is a valid bytecode index. */ +/* The end of the bytecode (i == m->jcodelength) is considered valid. */ + +#define CHECK_BYTECODE_INDEX(i) \ + do { \ + if (((i) < 0) || ((i) >= m->jcodelength)) \ + goto throw_invalid_bytecode_index; \ + } while (0) + +/* CHECK_BYTECODE_INDEX_EXCLUSIVE is used for the exclusive ends */ +/* of exception handler ranges. */ +#define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \ + do { \ + if ((i) < 0 || (i) > m->jcodelength) \ + goto throw_invalid_bytecode_index; \ + } while (0) + +#else /* !defined(ENABLE_VERIFIER) */ + +#define INDEX_ONEWORD(num) +#define INDEX_TWOWORD(num) +#define CHECK_BYTECODE_INDEX(i) +#define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) + +#endif /* defined(ENABLE_VERIFIER) */ + + +/* basic block generating macro ***********************************************/ + +#define MARK_BASICBLOCK(i) \ + do { \ + if (!(jd->basicblockindex[(i)] & 1)) { \ + b_count++; \ + jd->basicblockindex[(i)] |= 1; \ + } \ + } while (0) + +#define INSTRUCTIONS_CHECK(i) \ + if ((ipc + (i)) > pd.instructionslength) \ + iptr = parse_realloc_instructions(&pd, ipc, (i)) + + /* intermediate code generating macros ****************************************/ -#define PINC iptr++;ipc++ +/* These macros ALWAYS set the following fields of *iptr to valid values: */ +/* iptr->opc */ +/* iptr->flags */ +/* iptr->line */ -#define LOADCONST_I(v) \ - iptr->opc = ICMD_ICONST; \ - iptr->val.i = (v); \ - iptr->line = currentline; \ - PINC +/* These macros do NOT touch the following fields of *iptr, unless a value is */ +/* given for them: */ +/* iptr->s1 */ +/* iptr->sx */ +/* iptr->dst */ -#define LOADCONST_L(v) \ - iptr->opc = ICMD_LCONST; \ - iptr->val.l = (v); \ - iptr->line = currentline; \ - PINC +/* The _PREPARE macros omit the PINC, so you can set additional fields */ +/* afterwards. */ -#define LOADCONST_F(v) \ - iptr->opc = ICMD_FCONST; \ - iptr->val.f = (v); \ - iptr->line = currentline; \ - PINC +#define PINC \ + iptr++; ipc++ -#define LOADCONST_D(v) \ - iptr->opc = ICMD_DCONST; \ - iptr->val.d = (v); \ - iptr->line = currentline; \ - PINC +#define OP_PREPARE_FLAGS(o, f) \ + iptr->opc = (o); \ + iptr->line = currentline; \ + iptr->flags.bits = (f) | (ipc << INS_FLAG_ID_SHIFT); -#define LOADCONST_A(v) \ - iptr->opc = ICMD_ACONST; \ - iptr->val.a = (v); \ - iptr->line = currentline; \ +#define OP_PREPARE_ZEROFLAGS(o) \ + OP_PREPARE_FLAGS(o, 0) + +#define OP_PREPARE(o) \ + OP_PREPARE_ZEROFLAGS(o) + +#define OP(o) \ + OP_PREPARE_ZEROFLAGS(o); \ PINC -#define LOADCONST_A_CLASS(v,t) \ - iptr->opc = ICMD_ACONST; \ - iptr->val.a = (v); \ - iptr->target = (t); \ - iptr->line = currentline; \ +#define OP_LOADCONST_I(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \ + iptr->sx.val.i = (v); \ PINC -/* ACONST instructions generated as arguments for builtin functions - * have op1 set to non-zero. This is used for stack overflow checking - * in stack.c. */ -#define LOADCONST_A_BUILTIN(v,t) \ - iptr->opc = ICMD_ACONST; \ - iptr->op1 = 1; \ - iptr->val.a = (v); \ - iptr->target = (t); \ - iptr->line = currentline; \ +#define OP_LOADCONST_L(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \ + iptr->sx.val.l = (v); \ PINC -#define OP(o) \ - iptr->opc = (o); \ - iptr->line = currentline; \ +#define OP_LOADCONST_F(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_FCONST); \ + iptr->sx.val.f = (v); \ PINC -#define OP1(o,o1) \ - iptr->opc = (o); \ - iptr->op1 = (o1); \ - iptr->line = currentline; \ +#define OP_LOADCONST_D(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_DCONST); \ + iptr->sx.val.d = (v); \ PINC -#define OP2I(o,o1,v) \ - iptr->opc = (o); \ - iptr->op1 = (o1); \ - iptr->val.i = (v); \ - iptr->line = currentline; \ +#define OP_LOADCONST_NULL() \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.anyptr = NULL; \ PINC -#define OP2A_NOINC(o,o1,v,l) \ - iptr->opc = (o); \ - iptr->op1 = (o1); \ - iptr->val.a = (v); \ - iptr->line = (l); +#define OP_LOADCONST_STRING(v) \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.stringconst = (v); \ + PINC -#define OP2A(o,o1,v,l) \ - OP2A_NOINC(o,o1,v,l); \ +#define OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS(cl, cr, extraflags) \ + OP_PREPARE(ICMD_ACONST); \ + if (cl) { \ + iptr->sx.val.c.cls = (cl); \ + iptr->flags.bits |= INS_FLAG_CLASS | (extraflags); \ + } \ + else { \ + iptr->sx.val.c.ref = (cr); \ + iptr->flags.bits |= INS_FLAG_CLASS | INS_FLAG_UNRESOLVED \ + | (extraflags); \ + } \ PINC -#define OP2AT(o,o1,v,t,l) \ - OP2A_NOINC(o,o1,v,l); \ - iptr->target = (t); \ +#define OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr) \ + OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), INS_FLAG_CHECK) + +#define OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr) \ + OP_LOADCONST_CLASSINFO_OR_CLASSREF_FLAGS((c), (cr), 0) + +#define OP_S3_CLASSINFO_OR_CLASSREF(o, c, cr, extraflags) \ + OP_PREPARE(o); \ + if (c) { \ + iptr->sx.s23.s3.c.cls= (c); \ + iptr->flags.bits |= (extraflags); \ + } \ + else { \ + iptr->sx.s23.s3.c.ref= (cr); \ + iptr->flags.bits |= INS_FLAG_UNRESOLVED | (extraflags); \ + } \ PINC -#define BUILTIN(v,o1,t,l) \ - m->isleafmethod = false; \ - iptr->opc = ICMD_BUILTIN; \ - iptr->op1 = (o1); \ - iptr->val.a = (v); \ - iptr->target = (t); \ - iptr->line = (l); \ +#define OP_INSINDEX(o, iindex) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->dst.insindex = (iindex); \ PINC +# define OP_LOCALINDEX(o,index) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->s1.varindex = (index); \ + PINC -/* We have to check local variables indices here because they are - * used in stack.c to index the locals array. */ +# define OP_LOCALINDEX_I(o,index,v) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->s1.varindex = (index); \ + iptr->sx.val.i = (v); \ + PINC -#define INDEX_ONEWORD(num) \ - do { \ - if (((num) < 0) || ((num) >= m->maxlocals)) \ - goto throw_illegal_local_variable_number; \ +# define LOCALTYPE_USED(index,type) \ + do { \ + local_map[(index) * 5 + (type)] = 1; \ } while (0) -#define INDEX_TWOWORD(num) \ - do { \ - if (((num) < 0) || (((num) + 1) >= m->maxlocals)) \ - goto throw_illegal_local_variable_number; \ +#define OP_LOAD_ONEWORD(o,index,type) \ + do { \ + INDEX_ONEWORD(index); \ + OP_LOCALINDEX(o,index); \ + LOCALTYPE_USED(index,type); \ } while (0) -#define OP1LOAD(o,o1) \ - do { \ - if (((o) == ICMD_LLOAD) || ((o) == ICMD_DLOAD)) \ - INDEX_TWOWORD(o1); \ - else \ - INDEX_ONEWORD(o1); \ - OP1(o,o1); \ +#define OP_LOAD_TWOWORD(o,index,type) \ + do { \ + INDEX_TWOWORD(index); \ + OP_LOCALINDEX(o,index); \ + LOCALTYPE_USED(index,type); \ } while (0) -#define OP1STORE(o,o1) \ - do { \ - if (((o) == ICMD_LSTORE) || ((o) == ICMD_DSTORE)) \ - INDEX_TWOWORD(o1); \ - else \ - INDEX_ONEWORD(o1); \ - OP1(o,o1); \ +# define OP_STORE_ONEWORD(o,index,type) \ + do { \ + INDEX_ONEWORD(index); \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->dst.varindex = (index); \ + LOCALTYPE_USED(index,type); \ + PINC; \ } while (0) -/* block generating and checking macros */ - -#define block_insert(i) \ - do { \ - if (!(m->basicblockindex[(i)] & 1)) { \ - b_count++; \ - m->basicblockindex[(i)] |= 1; \ - } \ +# define OP_STORE_TWOWORD(o,index,type) \ + do { \ + INDEX_TWOWORD(index); \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->dst.varindex = (index); \ + LOCALTYPE_USED(index,type); \ + PINC; \ } while (0) +#define OP_BUILTIN_CHECK_EXCEPTION(bte) \ + jd->isleafmethod = false; \ + OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -#if defined(ENABLE_VERIFIER) - -#define CHECK_BYTECODE_INDEX(i) \ - do { \ - if (((i) < 0) || ((i) >= m->jcodelength)) \ - goto throw_invalid_bytecode_index; \ - } while (0) - -/* CHECK_BYTECODE_INDEX_EXCLUSIVE is used for the exclusive ends */ -/* of exception handler ranges */ -#define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) \ - do { \ - if ((i) < 0 || (i) > m->jcodelength) \ - goto throw_invalid_bytecode_index; \ - } while (0) - -#else /* !ENABLE_VERIFIER */ - -#define CHECK_BYTECODE_INDEX(i) -#define CHECK_BYTECODE_INDEX_EXCLUSIVE(i) +#define OP_BUILTIN_NO_EXCEPTION(bte) \ + jd->isleafmethod = false; \ + OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -#endif +#define OP_BUILTIN_ARITHMETIC(opcode, bte) \ + jd->isleafmethod = false; \ + OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -/* macros for byte code fetching *********************************************** +/* CAUTION: You must set iptr->flags yourself when using this! */ +#define OP_FMIREF_PREPARE(o, fmiref) \ + OP_PREPARE(o); \ + iptr->sx.s23.s3.fmiref = (fmiref); - fetch a byte code of given size from position p in code array jcode -*******************************************************************************/ +/* external macros ************************************************************/ -#define code_get_u1(p,m) m->jcode[p] -#define code_get_s1(p,m) ((s1)m->jcode[p]) -#define code_get_u2(p,m) ((((u2)m->jcode[p]) << 8) + m->jcode[p + 1]) -#define code_get_s2(p,m) ((s2)((((u2)m->jcode[p]) << 8) + m->jcode[p + 1])) -#define code_get_u4(p,m) ((((u4)m->jcode[p]) << 24) + (((u4)m->jcode[p + 1]) << 16) \ - +(((u4)m->jcode[p + 2]) << 8) + m->jcode[p + 3]) -#define code_get_s4(p,m) ((s4)((((u4)m->jcode[p]) << 24) + (((u4)m->jcode[p + 1]) << 16) \ - +(((u4)m->jcode[p + 2]) << 8) + m->jcode[p + 3])) +#define BLOCK_OF(index) \ + (jd->basicblocks + jd->basicblockindex[index]) /* function prototypes ********************************************************/ @@ -242,4 +302,3 @@ bool parse(jitdata *jd); * vim:noexpandtab:sw=4:ts=4: */ -