X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fparse.h;h=c7d561dbb8ebfafcd6dd7633d46d46918ca5317a;hb=ff4083aaec535fb7a937e3221a42782959586644;hp=ce8f1ea565af94898888ab562a5fdb219a9ae224;hpb=617846d9677bfa97c6dbcebb059266d016c5811c;p=cacao.git diff --git a/src/vm/jit/parse.h b/src/vm/jit/parse.h index ce8f1ea56..c7d561dbb 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, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, - M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, - P. Tomsich, J. Wenninger + 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,15 @@ 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 + Author: Christian Thalinger + Edwin Steiner - $Id: parse.h 1082 2004-05-26 15:04:54Z jowenn $ + $Id: parse.h 5959 2006-11-12 13:31:14Z edwin $ */ @@ -34,124 +35,255 @@ #ifndef _PARSE_H #define _PARSE_H -#include "global.h" +#include "config.h" +#include "vm/types.h" +#include "vm/global.h" +#include "vm/jit/codegen-common.h" -/* intermediate code generating macros */ -#define PINC iptr++;ipc++ -#define LOADCONST_I(v) iptr->opc=ICMD_ICONST;/*iptr->op1=0*/;iptr->val.i=(v);iptr->line=currentline;iptr->method=method;PINC -#define LOADCONST_L(v) iptr->opc=ICMD_LCONST;/*iptr->op1=0*/;iptr->val.l=(v);iptr->line=currentline;iptr->method=method;PINC -#define LOADCONST_F(v) iptr->opc=ICMD_FCONST;/*iptr->op1=0*/;iptr->val.f=(v);iptr->line=currentline;iptr->method=method;PINC -#define LOADCONST_D(v) iptr->opc=ICMD_DCONST;/*iptr->op1=0*/;iptr->val.d=(v);iptr->line=currentline;iptr->method=method;PINC -#define LOADCONST_A(v) iptr->opc=ICMD_ACONST;/*iptr->op1=0*/;iptr->val.a=(v);iptr->line=currentline;iptr->method=method;PINC +/* macros for verifier checks during parsing **********************************/ -/* 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=method;PINC +#if defined(ENABLE_VERIFIER) -#define OP(o) iptr->opc=(o);/*iptr->op1=0*/;/*iptr->val.l=0*/;iptr->line=currentline;iptr->method=method;PINC -#define OP1(o,o1) iptr->opc=(o);iptr->op1=(o1);/*iptr->val.l=(0)*/;iptr->line=currentline;iptr->method=method;PINC -#define OP2I(o,o1,v) iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);iptr->line=currentline;iptr->method=method;PINC +/* We have to check local variables indices here because they are */ +/* used in stack.c to index the locals array. */ -#define OP2A(o,o1,v,l) \ - iptr->opc = (o); \ - iptr->op1 = (o1); \ - iptr->val.a = (v); \ - iptr->line = l; \ - iptr->method = method; \ - PINC - -#define BUILTIN1(v,t,l) isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\ - iptr->val.a=(v);iptr->line=l;iptr->method=method;PINC -#define BUILTIN2(v,t,l) isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\ - iptr->val.a=(v);iptr->line=l;iptr->method=method;PINC -#define BUILTIN3(v,t,l) isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\ - iptr->val.a=(v);iptr->line=l;iptr->method=method;PINC - -/* 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)>=maxlocals) \ - panic("Invalid local variable index"); } while (0) -#define INDEX_TWOWORD(num) \ - do { if((num)<0 || ((num)+1)>=maxlocals) \ - panic("Invalid local variable index"); } while (0) - -#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 OP1STORE(o,o1) \ - do {if (o == ICMD_LSTORE || o == ICMD_DSTORE) \ - INDEX_TWOWORD(o1); \ - else \ - INDEX_ONEWORD(o1); \ - OP1(o,o1);} while(0) - -/* block generating and checking macros */ - -#define block_insert(i) \ +#define INDEX_ONEWORD(num) \ do { \ - if (!(block_index[(i)] & 1)) { \ - b_count++; \ - block_index[(i)] |= 1; \ - } \ + 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) -/* FIXME really use cumjcodelength for the bound_checkers ? */ +/* CHECK_BYTECODE_INDEX(i) checks whether i is a valid bytecode index. */ +/* The end of the bytecode (i == m->jcodelength) is considered valid. */ -#define bound_check(i) \ +#define CHECK_BYTECODE_INDEX(i) \ do { \ - if (i < 0 || i >= cumjcodelength) { \ - panic("branch target out of code-boundary"); \ - } \ + if (((i) < 0) || ((i) >= m->jcodelength)) \ + goto throw_invalid_bytecode_index; \ } while (0) -/* bound_check1 is used for the inclusive ends of exception handler ranges */ -#define bound_check1(i) \ +/* 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 > cumjcodelength) { \ - panic("branch target out of code-boundary"); \ - } \ + 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 ****************************************/ + +/* These macros ALWAYS set the following fields of *iptr to valid values: */ +/* iptr->opc */ +/* iptr->flags */ +/* iptr->line */ + +/* These macros do NOT touch the following fields of *iptr, unless a value is */ +/* given for them: */ +/* iptr->s1 */ +/* iptr->sx */ +/* iptr->dst */ + +/* The _PREPARE macros omit the PINC, so you can set additional fields */ +/* afterwards. */ + +#define PINC \ + iptr++; ipc++ + +#define OP_PREPARE_FLAGS(o, f) \ + iptr->opc = (o); \ + iptr->line = currentline; \ + iptr->flags.bits = (f) | (ipc << 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 OP_LOADCONST_I(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_ICONST); \ + iptr->sx.val.i = (v); \ + PINC + +#define OP_LOADCONST_L(v) \ + OP_PREPARE_ZEROFLAGS(ICMD_LCONST); \ + iptr->sx.val.l = (v); \ + PINC + +#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 + +#define OP_LOADCONST_NULL() \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.anyptr = NULL; \ + PINC + +#define OP_LOADCONST_STRING(v) \ + OP_PREPARE_FLAGS(ICMD_ACONST, INS_FLAG_CHECK); \ + iptr->sx.val.stringconst = (v); \ + PINC + +#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 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 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 + +# 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) -/* macros for byte code fetching *********************************************** +#define OP_LOAD_TWOWORD(o,index,type) \ + do { \ + INDEX_TWOWORD(index); \ + OP_LOCALINDEX(o,index); \ + LOCALTYPE_USED(index,type); \ + } while (0) - fetch a byte code of given size from position p in code array jcode +# 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) -*******************************************************************************/ +# 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 code_get_u1(p) jcode[p] -#define code_get_s1(p) ((s1)jcode[p]) -#define code_get_u2(p) ((((u2)jcode[p]) << 8) + jcode[p + 1]) -#define code_get_s2(p) ((s2)((((u2)jcode[p]) << 8) + jcode[p + 1])) -#define code_get_u4(p) ((((u4)jcode[p]) << 24) + (((u4)jcode[p + 1]) << 16) \ - +(((u4)jcode[p + 2]) << 8) + jcode[p + 3]) -#define code_get_s4(p) ((s4)((((u4)jcode[p]) << 24) + (((u4)jcode[p + 1]) << 16) \ - +(((u4)jcode[p + 2]) << 8) + jcode[p + 3])) +#define OP_BUILTIN_CHECK_EXCEPTION(bte) \ + jd->isleafmethod = false; \ + OP_PREPARE_FLAGS(ICMD_BUILTIN, INS_FLAG_CHECK); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC +#define OP_BUILTIN_NO_EXCEPTION(bte) \ + jd->isleafmethod = false; \ + OP_PREPARE_ZEROFLAGS(ICMD_BUILTIN); \ + iptr->sx.s23.s3.bte = (bte); \ + PINC -extern classinfo *rt_class; -extern methodinfo *rt_method; -extern utf *rt_descriptor; -extern int rt_jcodelength; -extern u1 *rt_jcode; +#define OP_BUILTIN_ARITHMETIC(opcode, bte) \ + jd->isleafmethod = false; \ + 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); + + +/* external macros ************************************************************/ +#define BLOCK_OF(index) \ + (jd->basicblocks + jd->basicblockindex[index]) -/* function prototypes */ -void compiler_addinitclass(classinfo *c); -classSetNode * descriptor2typesL(methodinfo *m); -void descriptor2types(methodinfo *m); -void parse(); + +/* function prototypes ********************************************************/ + +bool parse(jitdata *jd); #endif /* _PARSE_H */ @@ -167,6 +299,6 @@ void parse(); * c-basic-offset: 4 * tab-width: 4 * End: + * vim:noexpandtab:sw=4:ts=4: */ -