Authors: Andreas Krall
Reinhard Grafl
+ Christian Thalinger
+ Edwin Steiner
- Changes: Christian Thalinger
- Edwin Steiner
-
- $Id: jit.h 5715 2006-10-07 12:54:14Z edwin $
+ $Id: jit.h 6211 2006-12-16 22:53:24Z edwin $
*/
typedef struct branchref branchref;
typedef struct instruction instruction;
typedef struct insinfo_inline insinfo_inline;
+typedef struct exception_entry exception_entry;
#include "config.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/reg.h"
#include "vm/jit/stacktrace.h"
+#include "vm/jit/replace.h"
#if defined(ENABLE_INLINING)
# include "vm/jit/inline/inline.h"
/* jitdata ********************************************************************/
struct jitdata {
- methodinfo *m; /* methodinfo of the method compiled */
+ methodinfo *m; /* methodinfo of the method compiled */
codeinfo *code;
codegendata *cd;
registerdata *rd;
loopdata *ld;
#endif
#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
- lsradata *ls;
+ lsradata *ls;
#endif
- u4 flags; /* contains JIT compiler flags */
- bool isleafmethod; /* does method call subroutines */
+ u4 flags; /* contains JIT compiler flags */
+ bool isleafmethod; /* true, if no subroutines are called */
instruction *instructions; /* ICMDs, valid between parse and stack */
basicblock *basicblocks; /* start of basic block list */
s4 basicblockcount; /* number of basic blocks */
s4 stackcount; /* number of stackelements to allocate */
/* (passed from parse to stack) */
- s4 c_block_nr; /* counter for basic block number */
- varinfo *var; /* array of variables */
- s4 vartop; /* next free index in var array */
+ varinfo *var; /* array of variables */
+ s4 vartop; /* next free index in var array */
- s4 varcount; /* number of variables in var array */
- s4 localcount; /* number of locals at start of var ar. */
- s4 *local_map; /* internal structure to rename(de-coallesc) locals */
- /* and keep the coalescing info for simplereg. */
+ s4 varcount; /* number of variables in var array */
+ s4 localcount; /* number of locals at start of var ar. */
+ s4 *local_map; /* internal structure to rename(de-coallesc) */
+ /* locals and keep the coalescing info for simplereg. */
/* local_map[local_index * 5 + local_type] = */
/* new_index in rd->var or UNUSED */
- interface_info *interface_map;
+ s4 maxlocals; /* max. number of javalocals */
+
+ interface_info *interface_map; /* interface variables (for simplereg) */
+ s4 maxinterfaces; /* max. number of interface variables */
+
+ s4 exceptiontablelength; /* exceptiontable length */
+ exception_entry *exceptiontable; /* the exceptiontable */
+
+ basicblock *returnblock; /* block containing the *RETURN */
+ /* (only use if returncount==1) */
+ s4 returncount; /* number of return instructions */
+ bool branchtoentry; /* true if first block is a target */
+ bool branchtoend; /* true if end dummy is a target */
};
+
#define UNUSED -1
#define JITDATA_FLAG_PARSE 0x00000001
#define JITDATA_FLAG_IFCONV 0x00000008
#define JITDATA_FLAG_REORDER 0x00000010
+#define JITDATA_FLAG_INLINE 0x00000020
+
+#define JITDATA_FLAG_COUNTDOWN 0x00000100
#define JITDATA_FLAG_SHOWINTERMEDIATE 0x20000000
#define JITDATA_FLAG_SHOWDISASSEMBLE 0x40000000
#define JITDATA_HAS_FLAG_REORDER(jd) \
((jd)->flags & JITDATA_FLAG_REORDER)
+#define JITDATA_HAS_FLAG_INLINE(jd) \
+ ((jd)->flags & JITDATA_FLAG_INLINE)
+
+#define JITDATA_HAS_FLAG_COUNTDOWN(jd) \
+ ((jd)->flags & JITDATA_FLAG_COUNTDOWN)
+
#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
#define VAR(i) (jd->var + (i))
+/* exception_entry ************************************************************/
+
+struct exception_entry {
+ basicblock *start;
+ basicblock *end;
+ basicblock *handler;
+ classref_or_classinfo catchtype; /* catchtype of exc. (NULL == catchall) */
+ exception_entry *next; /* next in list of exceptions when */
+ /* loops are copied */
+ exception_entry *down; /* next exception_entry */
+};
+
+
/* stack element structure ****************************************************/
/* flags */
stackptr prev; /* pointer to next element towards bottom */
instruction *creator; /* instruction that created this element */
s4 type; /* slot type of stack element */
-#ifdef ENABLE_VERIFIER
- typeinfo typeinfo; /* info on reference types */
-#endif
s4 flags; /* flags (SAVED, INMEMORY) */
s4 varkind; /* kind of variable or register */
s4 varnum; /* number of variable */
- s4 regoff; /* register number or memory offset */
};
typedef union {
s4 varindex;
- s4 *args;
+ s4 *args;
classref_or_classinfo c;
unresolved_class *uc;
ptrint constval; /* for PUT*CONST */
s4 tablelow; /* for TABLESWITCH */
u4 lookupcount; /* for LOOKUPSWITCH */
+ s4 retaddrnr; /* for ASTORE */
} s2_operand_t;
/*** s3 operand ***/
s4 tablehigh; /* for TABLESWITCH */
branch_target_t lookupdefault; /* for LOOKUPSWITCH */
branch_target_t jsrtarget; /* for JSR */
+ s4 javaindex; /* for *STORE */
struct builtintable_entry *bte;
} s3_operand_t;
/*** flags (32 bits) ***/
#define INS_FLAG_UNRESOLVED 0x01 /* contains unresolved field/meth/class*/
-#define INS_FLAG_CLASS 0x02 /* for ACONST with class */
+#define INS_FLAG_CLASS 0x02 /* for ACONST, PUT*CONST with class */
#define INS_FLAG_ARRAY 0x04 /* for CHECKCAST/INSTANCEOF with array */
#define INS_FLAG_CHECK 0x08 /* for *ALOAD|*ASTORE: check index */
/* for BUILTIN: check exception */
+#define INS_FLAG_KILL_PREV 0x02 /* for *STORE, invalidate prev local */
+#define INS_FLAG_KILL_NEXT 0x04 /* for *STORE, invalidate next local */
+#define INS_FLAG_RETADDR 0x08 /* for ASTORE: op is a returnAddress */
+
+#define INS_FLAG_ID_SHIFT 4
+#define INS_FLAG_ID_MASK (~0 << INS_FLAG_ID_SHIFT)
typedef union {
u4 bits;
- struct { /* fields: */
-
- union {
- u1 type; /* TYPE_* constant for fields */
- u1 argcount; /* XXX does u1 suffice? */
- /* for MULTIANEWARRAY and */
- /* INVOKE* */
- } f; /* XXX these could be made smaller */
- /* only MULTIANEWARRAY needs the argcount */
-
- bool predicated:1;
- int condition :3;
- bool unresolved:1; /* field/method is unresolved */
- bool nocheck :1; /* don't check array access */
- bool branch :1; /* branch to dst.target */
-
- int tmpreg1 :5;
- int tmpreg2 :5;
- int tmpreg3 :5;
-
- int unused :2;
-
- } fields;
} flags_operand_t;
/*** instruction ***/
/* for ICMD_INLINE_START and ICMD_INLINE_END */
struct insinfo_inline {
- methodinfo *method; /* the inlined method starting/ending here */
- methodinfo *outer; /* the outer method suspended/resumed here */
- s4 startmpc; /* machine code offset of start of inlining */
- s4 synclocal; /* local index used for synchronization */
- bool synchronize; /* true if synchronization is needed */
+ /* fields copied from the inlining tree ----------------------------------*/
+ insinfo_inline *parent; /* insinfo of the surrounding inlining, if any*/
+ methodinfo *method; /* the inlined method starting/ending here */
+ methodinfo *outer; /* the outer method suspended/resumed here */
+ s4 synclocal; /* local index used for synchronization */
+ bool synchronize; /* true if synchronization is needed */
+ s4 throughcount; /* total # of pass-through variables */
+ s4 paramcount; /* number of parameters of original call */
+ s4 stackvarscount; /* source stackdepth at INLINE_START */
+ s4 *stackvars; /* stack vars at INLINE_START */
+
+ /* fields set by inlining ------------------------------------------------*/
+ s4 *javalocals_start; /* javalocals at start of inlined body */
+ s4 *javalocals_end; /* javalocals after inlined body */
+
+ /* fields set by replacement point creation ------------------------------*/
+ rplpoint *rp; /* replacement point at INLINE_START */
+
+ /* fields set by the codegen ---------------------------------------------*/
+ s4 startmpc; /* machine code offset of start of inlining */
};
+
/* basicblock *****************************************************************/
-
+
/* flags */
#define BBDELETED -2
instruction *iinstr; /* pointer to intermediate code instructions */
varinfo *inlocals; /* copy of locals on block entry */
+ s4 *javalocals; /* map from java locals to cacao variables */
s4 *invars; /* array of in-variables at begin of block */
s4 *outvars; /* array of out-variables at end of block */
s4 indepth; /* stack depth at begin of basic block */
basicblock *original; /* block of which this block is a clone */
/* NULL for the original block itself */
methodinfo *method; /* method this block belongs to */
+ insinfo_inline *inlineinfo; /* inlineinfo for the start of this block */
s4 mpc; /* machine code pc at start of block */
};
bptr->flags = -1; \
bptr->type = BBTYPE_STD; \
bptr->method = (m); \
- bptr->nr = (m)->c_block_nr++; \
} while (0)
};
-/********** op1 values for ACONST instructions ********************************/
+/* data-flow constants for the ICMD table ************************************/
+
+#define DF_0_TO_0 0
+#define DF_1_TO_0 1
+#define DF_2_TO_0 2
+#define DF_3_TO_0 3
+
+#define DF_DST_BASE 4 /* from this value on, iptr->dst is a variable */
+
+#define DF_0_TO_1 (DF_DST_BASE + 0)
+#define DF_1_TO_1 (DF_DST_BASE + 1)
+#define DF_2_TO_1 (DF_DST_BASE + 2)
+#define DF_3_TO_1 (DF_DST_BASE + 3)
+#define DF_N_TO_1 (DF_DST_BASE + 4)
+
+#define DF_INVOKE (DF_DST_BASE + 5)
+#define DF_BUILTIN (DF_DST_BASE + 6)
+
+#define DF_COPY (DF_DST_BASE + 7)
+#define DF_MOVE (DF_DST_BASE + 8)
+
+#define DF_DUP -1
+#define DF_DUP_X1 -1
+#define DF_DUP_X2 -1
+#define DF_DUP2 -1
+#define DF_DUP2_X1 -1
+#define DF_DUP2_X2 -1
+#define DF_SWAP -1
+
+/* special data-flow recognized by verify/generate.pl: */
+#define DF_LOAD DF_COPY
+#define DF_STORE DF_MOVE
+#define DF_IINC DF_1_TO_1
+#define DF_POP DF_1_TO_0
+#define DF_POP2 DF_2_TO_0
+
+
+/* control-flow constants for the ICMD table *********************************/
+
+#define CF_NORMAL 0
+#define CF_IF 1
+
+#define CF_END_BASE 2 /* from here on, they mark the end of a superblock */
+
+#define CF_END (CF_END_BASE + 0)
+#define CF_GOTO (CF_END_BASE + 1)
+#define CF_TABLE (CF_END_BASE + 2)
+#define CF_LOOKUP (CF_END_BASE + 3)
+#define CF_JSR (CF_END_BASE + 4)
+#define CF_RET (CF_END_BASE + 5)
+
+
+/* flag constants for the ICMD table *****************************************/
+
+#define ICMDTABLE_PEI 0x0001 /* ICMD may throw an exception */
+#define ICMDTABLE_CALLS 0x0002 /* needs registers to be saved, may call */
+
+
+/* ICMD table entry **********************************************************/
+
+typedef struct icmdtable_entry_t icmdtable_entry_t;
+
+struct icmdtable_entry_t {
+#if !defined(NDEBUG)
+ char *name; /* name, without ICMD_ prefix */
+#endif
+ s4 dataflow; /* a DF_ constant, see above */
+ s4 controlflow; /* a CF_ constant, see above */
+ s4 flags; /* a combination of ICMDTABLE_ flags */
+};
+
+
+/* the ICMD table ************************************************************/
-#define ACONST_LOAD 0 /* ACONST_NULL or LDC instruction */
-#define ACONST_BUILTIN 1 /* constant argument for a builtin function call */
+extern icmdtable_entry_t icmd_table[256];
/********** JavaVM operation codes (sorted) and instruction lengths ***********/
-extern char *icmd_names[256];
extern char *opcode_names[256];
extern int jcommandsize[256];
+extern int stackreq[256];
#define JAVA_NOP 0
#define ICMD_NOP 0
#define ICMD_ICONST 3 /* val.i = constant */
#define JAVA_ICONST_1 4
-#define ICMD_CHECKNULL_POP 4
#define JAVA_ICONST_2 5
#define ICMD_IDIVPOW2 5 /* val.i = constant */
#define ICMD_INLINE_START 251 /* instruction before inlined method */
#define ICMD_INLINE_END 252 /* instruction after inlined method */
-#define ICMD_INLINE_GOTO 253 /* jump to caller of inlined method */
+#define ICMD_INLINE_BODY 253 /* start of inlined body */
#define ICMD_BUILTIN 255 /* internal opcode */
-/******************* description of JavaVM instructions ***********************/
-
-
-
/***************************** register types *********************************/
#define REG_RES 0 /* reserved register for OS or code generator */
#define PARAMMODE_STUFFED 1
-/***************************** register info block ****************************/
-
-extern int stackreq[256];
-/* extern int op_needs_saved[256]; */
-/* extern int op_is_pei[256]; */
-#define NEEDS_SAVED 0
-#define PEI 1
-#define OP_DATA_SIZE 2
-extern int op_data[256][OP_DATA_SIZE];
-/* [0..255][NEEDS_SAVED] ... if ICMD needs a SAVEDVAR */
-/* [0..255][PEI] ... if ICMD could throw an exception */
-
/* function prototypes ********************************************************/
/* compiler initialisation */
/* compiler finalisation */
void jit_close(void);
+/* create a new jitdata */
+jitdata *jit_jitdata_new(methodinfo *m);
+
/* compile a method with jit compiler */
u1 *jit_compile(methodinfo *m);
u1 *jit_recompile(methodinfo *m);
+void jit_invalidate_code(methodinfo *m);
+codeinfo *jit_get_current_code(methodinfo *m);
+void jit_request_optimization(methodinfo *m);
+
/* patch the method entrypoint */
u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
s4 jit_complement_condition(s4 opcode);
+void jit_renumber_basicblocks(jitdata *jd);
+#if !defined(NDEBUG)
+void jit_check_basicblock_numbers(jitdata *jd);
+#endif
+
/* machine dependent functions */
#if defined(ENABLE_JIT)
void md_init(void);