X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fparse.h;h=55917d6a27db984ffbef144c7c108d196ad0699d;hb=777a728b1d476cd762c1e8943f9c6412b027b43d;hp=d73328ed49a0577300001c956551168cf0d04479;hpb=08e992142b328df654d3650492164595a378cdc0;p=cacao.git diff --git a/src/vm/jit/parse.h b/src/vm/jit/parse.h index d73328ed4..55917d6a2 100644 --- a/src/vm/jit/parse.h +++ b/src/vm/jit/parse.h @@ -1,9 +1,9 @@ -/* jit/parse.h - parser header +/* src/vm/jit/parse.h - parser header - Copyright (C) 1996-2005 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 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 This file is part of CACAO. @@ -19,14 +19,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at + Contact: cacao@cacaojvm.org - Author: Christian Thalinger - - $Id: parse.h 2262 2005-04-11 09:55:44Z twisti $ + Author: Christian Thalinger + Edwin Steiner */ @@ -34,178 +33,250 @@ #ifndef _PARSE_H #define _PARSE_H +#include "config.h" +#include "vm/types.h" + #include "vm/global.h" -#include "vm/jit/codegen.inc.h" -#include "vm/jit/inline/inline.h" +#include "vm/jit/codegen-common.h" -/* intermediate code generating macros */ +/* macros for verifier checks during parsing **********************************/ -#define PINC iptr++;ipc++ +#if defined(ENABLE_VERIFIER) -#define LOADCONST_I(v) \ - iptr->opc = ICMD_ICONST; \ - /*iptr->op1=0;*/ \ - iptr->val.i = (v); \ - iptr->line = currentline; \ - iptr->method = inline_env->method; \ - PINC +/* We have to check local variables indices here because they are */ +/* used in stack.c to index the locals array. */ -#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;/*iptr->op1=0*/;iptr->val.l=(v);iptr->line=currentline;iptr->method=inline_env->method;PINC -#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;/*iptr->op1=0*/;iptr->val.f=(v);iptr->line=currentline;iptr->method=inline_env->method;PINC -#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;/*iptr->op1=0*/;iptr->val.d=(v);iptr->line=currentline;iptr->method=inline_env->method;PINC -#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;/*iptr->op1=0*/;iptr->val.a=(v);iptr->line=currentline;iptr->method=inline_env->method;PINC +#define INDEX_ONEWORD(num) \ + do { \ + if (((num) < 0) || ((num) >= m->maxlocals)) \ + goto throw_illegal_local_variable_number; \ + } while (0) -/* 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) \ - iptr->opc = ICMD_ACONST; \ - iptr->op1 = 1; \ - iptr->val.a = (v); \ - iptr->line = currentline; \ - iptr->method = inline_env->method; \ - PINC +#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(pd, i) \ + do { \ + (pd)->basicblockstart[(i)] = 1; \ + } while (0) + +#define INSTRUCTIONS_CHECK(i) \ + if ((ircount + (i)) > pd.instructionslength) \ + iptr = parse_realloc_instructions(&pd, ircount, (i)) + + +/* intermediate code generating macros ****************************************/ + +/* These macros ALWAYS set the following fields of *iptr to valid values: */ +/* iptr->opc */ +/* iptr->flags */ +/* iptr->line */ -#define OP(o) iptr->opc=(o);/*iptr->op1=0*/;/*iptr->val.l=0*/;iptr->line=currentline;iptr->method=inline_env->method;PINC -#define OP1(o,o1) iptr->opc=(o);iptr->op1=(o1);/*iptr->val.l=(0)*/;iptr->line=currentline;iptr->method=inline_env->method;PINC -#define OP2I(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);iptr->line=currentline;iptr->method=inline_env->method;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 OP2A_NOINC(o,o1,v,l) \ - iptr->opc = (o); \ - iptr->op1 = (o1); \ - iptr->val.a = (v); \ - iptr->line = (l); \ - iptr->method = inline_env->method +/* The _PREPARE macros omit the PINC, so you can set additional fields */ +/* afterwards. */ -#define OP2A(o,o1,v,l) \ - OP2A_NOINC(o,o1,v,l); \ +#define PINC \ + iptr++; ircount++ + +#define OP_PREPARE_FLAGS(o, f) \ + iptr->opc = (o); \ + iptr->line = currentline; \ + iptr->flags.bits |= (f) | (ircount << INS_FLAG_ID_SHIFT); + +#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 OP2AT(o,o1,v,t,l) \ - OP2A_NOINC(o,o1,v,l); \ - iptr->target = (t); \ +#define OP_CHECK_EXCEPTION(o) \ + OP_PREPARE_FLAGS(o, INS_FLAG_CHECK); \ PINC -#define BUILTIN1(v,t,l) \ - inline_env->method->isleafmethod = false; \ - iptr->opc = ICMD_BUILTIN1; \ - iptr->op1 = (t); \ - iptr->val.fp = (v); \ - iptr->line = (l); \ - iptr->method = inline_env->method; \ +#define OP_LOADCONST_I(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \ + iptr->sx.val.i = (v); \ PINC -#define BUILTIN2(v,t,l) \ - inline_env->method->isleafmethod = false; \ - iptr->opc = ICMD_BUILTIN2; \ - iptr->op1 = (t);\ - iptr->val.fp = (v); \ - iptr->line = (l); \ - iptr->method = inline_env->method; \ +#define OP_LOADCONST_L(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \ + iptr->sx.val.l = (v); \ PINC -#define BUILTIN3(v,t,l) \ - inline_env->method->isleafmethod = false; \ - iptr->opc = ICMD_BUILTIN3; \ - iptr->op1 = (t);\ - iptr->val.fp = (v); \ - iptr->line = (l); \ - iptr->method = inline_env->method; \ +#define OP_LOADCONST_F(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_FCONST); \ + iptr->sx.val.f = (v); \ PINC +#define OP_LOADCONST_D(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_DCONST); \ + iptr->sx.val.d = (v); \ + PINC -/* We have to check local variables indices here because they are - * used in stack.c to index the locals array. */ +#define OP_LOADCONST_NULL() \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.anyptr = NULL; \ + PINC -#define INDEX_ONEWORD(num) \ - do { \ - if ((num) < 0 || (num) >= inline_env->cumlocals) { \ - *exceptionptr = \ - new_verifyerror(inline_env->method, "Illegal local variable number"); \ - return NULL; \ - } \ - } while (0) +#define OP_LOADCONST_STRING(v) \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.stringconst = (v); \ + PINC -#define INDEX_TWOWORD(num) \ - do { \ - if ((num) < 0 || ((num) + 1) >= inline_env->cumlocals) { \ - *exceptionptr = \ - new_verifyerror(inline_env->method, "Illegal local variable number"); \ - return NULL; \ - } \ - } while (0) +#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 OP1LOAD(o,o1) \ - do {if (o == ICMD_LLOAD || o == ICMD_DLOAD) \ - INDEX_TWOWORD(o1); \ - else \ - INDEX_ONEWORD(o1); \ - OP1(o,o1);} while(0) +#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 OP1STORE(o,o1) \ - do {if (o == ICMD_LSTORE || o == ICMD_DSTORE) \ - INDEX_TWOWORD(o1); \ - else \ - INDEX_ONEWORD(o1); \ - OP1(o,o1);} while(0) +#define OP_INSINDEX(o, iindex) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->dst.insindex = (iindex); \ + PINC -/* block generating and checking macros */ +# define OP_LOCALINDEX(o,index) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->s1.varindex = (index); \ + PINC -#define block_insert(i) \ - do { \ - if (!(m->basicblockindex[(i)] & 1)) { \ - b_count++; \ - m->basicblockindex[(i)] |= 1; \ - } \ +# define OP_LOCALINDEX_I(o,index,v) \ + OP_PREPARE_ZEROFLAGS(o); \ + iptr->s1.varindex = (index); \ + iptr->sx.val.i = (v); \ + PINC + +# define LOCALTYPE_USED(index,type) \ + do { \ + local_map[(index) * 5 + (type)] = 1; \ } while (0) +#define OP_LOAD_ONEWORD(o,index,type) \ + do { \ + INDEX_ONEWORD(index); \ + OP_LOCALINDEX(o,index); \ + LOCALTYPE_USED(index,type); \ + } while (0) -/* FIXME really use cumjcodelength for the bound_checkers ? */ +#define OP_LOAD_TWOWORD(o,index,type) \ + do { \ + INDEX_TWOWORD(index); \ + OP_LOCALINDEX(o,index); \ + LOCALTYPE_USED(index,type); \ + } while (0) -#define bound_check(i) \ - do { \ - if (i < 0 || i >= inline_env->cumjcodelength) { \ - printf("bound_check i=%i >= %i=cum\n",i,inline_env->cumjcodelength); \ - fflush(stdout); \ - /* if (i < 0 || i >= m->jcodelength) { */ \ - *exceptionptr = \ - new_verifyerror(inline_env->method, "Illegal target of jump or branch"); \ - return NULL; \ - } \ +# 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) -/* bound_check1 is used for the inclusive ends of exception handler ranges */ -#define bound_check1(i) \ - do { \ - if (i < 0 || i > inline_env->cumjcodelength) { \ -/* if (i < 0 || i > m->jcodelength) { */ \ - *exceptionptr = \ - new_verifyerror(inline_env->method, "Illegal target of jump or branch"); \ - return NULL; \ - } \ +# 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) \ + code_unflag_leafmethod(code); \ + OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -/* macros for byte code fetching *********************************************** +#define OP_BUILTIN_NO_EXCEPTION(bte) \ + code_unflag_leafmethod(code); \ + OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC - fetch a byte code of given size from position p in code array jcode +#define OP_BUILTIN_ARITHMETIC(opcode, bte) \ + code_unflag_leafmethod(code); \ + OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -*******************************************************************************/ +/* 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); -#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])) -/* function prototypes */ +/* function prototypes ********************************************************/ -void compiler_addinitclass(classinfo *c); -methodinfo *parse(methodinfo *m, codegendata *cd, t_inlining_globals *inline_env); +bool parse(jitdata *jd); #endif /* _PARSE_H */ @@ -221,6 +292,6 @@ methodinfo *parse(methodinfo *m, codegendata *cd, t_inlining_globals *inline_env * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */ -