Changes: Christian Thalinger
Edwin Steiner
- $Id: jit.h 5024 2006-06-10 14:53:54Z edwin $
+ $Id: jit.h 5404 2006-09-07 13:29:05Z christian $
*/
#ifndef _JIT_H
#define _JIT_H
+#define NEW_VAR
+
/* forward typedefs ***********************************************************/
typedef struct jitdata jitdata;
typedef struct basicblock basicblock;
typedef struct branchref branchref;
typedef struct instruction instruction;
-typedef struct new_instruction new_instruction;
typedef struct insinfo_inline insinfo_inline;
#if defined(ENABLE_LOOP)
# include "vm/jit/loop/loop.h"
#endif
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+#endif
+#if defined(ENABLE_LSRA)
+# include "vm/jit/allocator/lsra.h"
+#endif
#include "vm/jit/verify/typeinfo.h"
-
/* common jit/codegen macros **************************************************/
#if defined(ENABLE_STATISTICS)
/* jitdata ********************************************************************/
-#define JITDATA_FLAG_IFCONV 0x00000001
-
struct jitdata {
- methodinfo *m; /* methodinfo of the method compiled */
- codeinfo *code;
- codegendata *cd;
- registerdata *rd;
+ methodinfo *m; /* methodinfo of the method compiled */
+ codeinfo *code;
+ codegendata *cd;
+ registerdata *rd;
#if defined(ENABLE_LOOP)
- loopdata *ld;
+ loopdata *ld;
+#endif
+#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
+ lsradata *ls;
#endif
- u4 flags; /* contains JIT compiler flags */
- new_instruction *new_instructions;
+ u4 flags; /* contains JIT compiler flags */
+ bool isleafmethod; /* does method call subroutines */
+
+ instruction *new_instructions;
basicblock *new_basicblocks;
s4 *new_basicblockindex;
stackelement *new_stack;
s4 new_basicblockcount;
s4 new_stackcount;
s4 new_c_debug_nr;
+
+#if defined(NEW_VAR)
+ varinfo *var;
+ s4 vartop;
+
+ s4 varcount;
+ s4 localcount;
+ 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 LOCAL_UNUSED */
+ s4 *interface_map; /* like local_map for interfaces */
+#endif
};
+#define UNUSED -1
-/************************** stack element structure ***************************/
+#define JITDATA_FLAG_PARSE 0x00000001
+#define JITDATA_FLAG_VERIFY 0x00000002
-/* slot types */
+#define JITDATA_FLAG_INSTRUMENT 0x00000004
-/* Unified these with longer names. Maybe someday use only
- * one set of names? -Edwin
- */
-/*#define TYPE_INT 0*/ /* the stack slot types must numbered in the */
-#define TYPE_LNG TYPE_LONG /*1*/ /* same order as the ICMD_Ixxx to ICMD_Axxx */
-#define TYPE_FLT TYPE_FLOAT /*2*/ /* instructions (LOAD and STORE) */
-#define TYPE_DBL TYPE_DOUBLE /*3*/ /* integer, long, float, double, address */
-#define TYPE_ADR TYPE_ADDRESS /*4*/
+#define JITDATA_FLAG_IFCONV 0x00000008
+#define JITDATA_FLAG_REORDER 0x00000010
+
+#define JITDATA_FLAG_SHOWINTERMEDIATE 0x20000000
+#define JITDATA_FLAG_SHOWDISASSEMBLE 0x40000000
+#define JITDATA_FLAG_VERBOSECALL 0x80000000
-#define IS_INT_LNG_TYPE(a) (!((a) & TYPE_FLT))
-#define IS_FLT_DBL_TYPE(a) ((a) & TYPE_FLT)
-#define IS_2_WORD_TYPE(a) ((a) & TYPE_LNG)
-#define IS_INT_TYPE(a) ((a) == TYPE_INT)
-#define IS_LNG_TYPE(a) ((a) == TYPE_LNG)
-#define IS_ADR_TYPE(a) ((a) == TYPE_ADR)
+#define JITDATA_HAS_FLAG_PARSE(jd) \
+ ((jd)->flags & JITDATA_FLAG_PARSE)
+#define JITDATA_HAS_FLAG_VERIFY(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERIFY)
+
+#define JITDATA_HAS_FLAG_INSTRUMENT(jd) \
+ ((jd)->flags & JITDATA_FLAG_INSTRUMENT)
+
+#define JITDATA_HAS_FLAG_IFCONV(jd) \
+ ((jd)->flags & JITDATA_FLAG_IFCONV)
+
+#define JITDATA_HAS_FLAG_REORDER(jd) \
+ ((jd)->flags & JITDATA_FLAG_REORDER)
+
+#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
+
+#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWDISASSEMBLE)
+
+#define JITDATA_HAS_FLAG_VERBOSECALL(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
+
+
+/* stack element structure ****************************************************/
/* flags */
/* using the same register/memory location */
#define STKEEP 32 /* to prevent reg_mark_copy to free this */
/* stackslot */
+#define PREALLOC 64 /* preallocated var like for ARGVARS. Used */
+ /* with the new var system */
+#define OUTVAR 128 /* STACKVR flag for new var system */
+
+#define IS_SAVEDVAR(x) ((x) & SAVEDVAR)
+#define IS_INMEMORY(x) ((x) & INMEMORY)
+
/* variable kinds */
/*** s1 operand ***/
typedef union {
+#if defined(NEW_VAR)
+ s4 varindex;
+#else
stackptr var;
s4 localindex;
+#endif
s4 argcount;
} s1_operand_t;
/*** s2 operand ***/
typedef union {
+#if defined(NEW_VAR)
+ s4 varindex;
+ s4 *args;
+#else
stackptr var;
stackptr *args;
+#endif
classref_or_classinfo c;
unresolved_class *uc;
ptrint constval; /* for PUT*CONST */
/*** s3 operand ***/
typedef union {
+#if defined(NEW_VAR)
+ s4 varindex;
+#else
stackptr var;
+#endif
ptrint constval;
classref_or_classinfo c;
constant_FMIref *fmiref;
/*** dst operand ***/
typedef union {
+#if defined(NEW_VAR)
+ s4 varindex;
+#else
stackptr var;
s4 localindex;
+#endif
basicblock *block; /* valid after stack analysis */
branch_target_t *table; /* for TABLESWITCH */
lookup_target_t *lookup; /* for LOOKUPSWITCH */
s4 insindex; /* used between parse and stack */
+#if defined(NEW_VAR)
+ s4 *dupslots; /* for SWAP, DUP* except DUP */
+#else
stackptr *dupslots; /* for SWAP, DUP* except DUP */
+#endif
} dst_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_ARRAY 0x04 /* for CHECKCAST/INSTANCEOF with array */
-#define INS_FLAG_NOCHECK 0x08
+#define INS_FLAG_CHECK 0x08 /* for *ALOAD|*ASTORE: check index */
+ /* for BUILTIN: check exception */
typedef union {
u4 bits;
/*** instruction ***/
-/* The new instruction format for the intermediate representation: */
+/* The instruction format for the intermediate representation: */
-struct new_instruction {
+struct instruction {
u2 opc; /* opcode */
u2 line; /* line number */
#if SIZEOF_VOID_P == 8
#endif
};
-/* XXX This instruction format will become obsolete. */
-
-struct instruction {
- stackptr dst; /* stack index of destination operand stack */
- u2 opc; /* opcode of intermediate code command */
- s4 op1; /* first operand, usually variable number */
- imm_union val; /* immediate constant */
- void *target; /* used for targets of branches and jumps */
- /* and as address for list of targets for */
- /* statements */
- u2 line; /* line number in source file */
-};
#define INSTRUCTION_IS_RESOLVED(iptr) \
- (!((ptrint)(iptr)->target & 0x01)) /* XXX target used temporarily as flag */
+ (!((iptr)->flags.bits & INS_FLAG_UNRESOLVED))
#define INSTRUCTION_IS_UNRESOLVED(iptr) \
- ((ptrint)(iptr)->target & 0x01) /* XXX target used temporarily as flag */
+ ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
-#define NEW_INSTRUCTION_GET_FIELDREF(iptr,fref) \
+#define INSTRUCTION_MUST_CHECK(iptr) \
+ ((iptr)->flags.bits & INS_FLAG_CHECK)
+
+#define INSTRUCTION_GET_FIELDREF(iptr,fref) \
do { \
if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
fref = iptr->sx.s23.s3.uf->fieldref; \
fref = iptr->sx.s23.s3.fmiref; \
} while (0)
-#define INSTRUCTION_GET_FIELDREF(iptr,fref) \
- do { \
- if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
- fref = ((unresolved_field *) (iptr)->val.a)->fieldref; \
- else \
- fref = ((constant_FMIref *)(iptr)->val.a); \
- } while (0)
-
-#define NEW_INSTRUCTION_GET_METHODREF(iptr,mref) \
+#define INSTRUCTION_GET_METHODREF(iptr,mref) \
do { \
if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
mref = iptr->sx.s23.s3.um->methodref; \
mref = iptr->sx.s23.s3.fmiref; \
} while (0)
-#define INSTRUCTION_GET_METHODREF(iptr,mref) \
- do { \
- if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
- mref = ((unresolved_method *) (iptr)->val.a)->methodref; \
- else \
- mref = ((constant_FMIref *)(iptr)->val.a); \
- } while (0)
-
-#define INSTRUCTION_GET_FIELDDESC(iptr,fd) \
- do { \
- if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
- fd = ((unresolved_field *)(iptr)->val.a)->fieldref->parseddesc.fd; \
- else \
- fd = ((constant_FMIref *)(iptr)->val.a)->parseddesc.fd; \
- } while (0)
-
-#define NEW_INSTRUCTION_GET_METHODDESC(iptr, md) \
+#define INSTRUCTION_GET_METHODDESC(iptr, md) \
do { \
if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
md = iptr->sx.s23.s3.um->methodref->parseddesc.md; \
md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
} while (0)
-#define INSTRUCTION_GET_METHODDESC(iptr,md) \
- do { \
- if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
- md = ((unresolved_method *) (iptr)->val.a)->methodref->parseddesc.md; \
- else \
- md = ((constant_FMIref *)(iptr)->val.a)->parseddesc.md; \
- } while (0)
-
-#define INSTRUCTION_UNRESOLVED_METHOD(iptr) \
- ((unresolved_method *) (iptr)->val.a)
-
-#define INSTRUCTION_UNRESOLVED_FIELD(iptr) \
- ((unresolved_field *) (iptr)->val.a)
-
-#define INSTRUCTION_RESOLVED_FMIREF(iptr) \
- ((constant_FMIref *)(iptr)->val.a)
-
-#define INSTRUCTION_RESOLVED_FIELDINFO(iptr) \
- (INSTRUCTION_RESOLVED_FMIREF(iptr)->p.field)
-
-#define INSTRUCTION_RESOLVED_METHODINFO(iptr) \
- (INSTRUCTION_RESOLVED_FMIREF(iptr)->p.method)
-
-#define INSTRUCTION_PUTCONST_TYPE(iptr) \
- ((iptr)[0].op1)
-
-#define INSTRUCTION_PUTCONST_VALUE_ADR(iptr) \
- ((iptr)[0].val.a)
-
-#define INSTRUCTION_PUTCONST_FIELDINFO(iptr) \
- ((fieldinfo *)((iptr)[1].val.a))
-
-#define INSTRUCTION_PUTCONST_FIELDINFO_PTR(iptr) \
- ((fieldinfo **) &((iptr)[1].val.a))
-
-#define INSTRUCTION_PUTCONST_FIELDREF(iptr) \
- ((unresolved_field *)((iptr)[1].target))
-
-/* for ICMD_ACONST */
-
-#define ICMD_ACONST_IS_CLASS(iptr) \
- ((ptrint)(iptr)->target & 0x02) /* XXX target used temporarily as flag */
-
-#define ICMD_ACONST_CLASSREF_OR_CLASSINFO(iptr) \
-(CLASSREF_OR_CLASSINFO((iptr)->val.a))
-
-#define ICMD_ACONST_RESOLVED_CLASSINFO(iptr) \
- ((classinfo *) (iptr)->val.a)
-
-#define ICMD_ACONST_UNRESOLVED_CLASSREF(iptr) \
- ((constant_classref *) (iptr)->val.a)
-
/* additional info structs for special instructions ***************************/
/* the others by using bitfields. */
struct basicblock {
- s4 debug_nr; /* basic block number */
- s4 flags; /* used during stack analysis, init with -1 */
- s4 bitflags; /* OR of BBFLAG_... constants, init with 0 */
- s4 type; /* basic block type (std, xhandler, subroutine*/
- instruction *iinstr; /* pointer to intermediate code instructions */
- s4 icount; /* number of intermediate code instructions */
- s4 mpc; /* machine code pc at start of block */
- stackptr instack; /* stack at begin of basic block */
- stackptr outstack; /* stack at end of basic block */
- s4 indepth; /* stack depth at begin of basic block */
- s4 outdepth; /* stack depth end of basic block */
- s4 pre_count; /* count of predecessor basic blocks */
- branchref *branchrefs; /* list of branches to be patched */
-
- basicblock *next; /* used to build a BB list (instead of array) */
- s4 lflags; /* used during loop copying, init with 0 */
- basicblock *copied_to; /* points to the copy of this basic block */
+ s4 nr; /* basic block number */
+ s4 flags; /* used during stack analysis, init with -1 */
+ s4 bitflags; /* OR of BBFLAG_... constants, init with 0 */
+ s4 type; /* basic block type (std, xhandler, subroutine*/
+ instruction *iinstr; /* pointer to intermediate code instructions */
+ s4 icount; /* number of intermediate code instructions */
+ s4 mpc; /* machine code pc at start of block */
+ stackptr instack; /* stack at begin of basic block */
+ stackptr outstack; /* stack at end of basic block */
+#if defined(NEW_VAR)
+ s4 *invars; /* array of in-variables at begin of block */
+ s4 *outvars; /* array of out-variables at end of block */
+#else
+ stackptr *invars; /* array of in-variables at begin of block */
+ stackptr *outvars; /* array of out-variables at end of block */
+#endif
+ s4 indepth; /* stack depth at begin of basic block */
+ s4 outdepth; /* stack depth end of basic block */
+
+ s4 predecessorcount;
+ s4 successorcount;
+ basicblock **predecessors; /* array of predecessor basic blocks */
+ basicblock **successors; /* array of successor basic blocks */
+
+ branchref *branchrefs; /* list of branches to be patched */
+
+ basicblock *next; /* used to build a BB list (instead of array) */
+ s4 lflags; /* used during loop copying, init with 0 */
+ basicblock *copied_to; /* points to the copy of this basic block */
/* when loop nodes are copied */
- stackptr stack; /* start of stack array for this block */
+ stackptr stack; /* start of stack array for this block */
/* (see doc/stack.txt) */
- methodinfo *method; /* method this block belongs to */
+ methodinfo *method; /* method this block belongs to */
};
-/* macro for initializing newly allocated basicblock:s */
-
-#define BASICBLOCK_INIT(bptr,m) \
- do { \
- bptr->mpc = -1; \
- bptr->flags = -1; \
- bptr->bitflags = 0; \
- bptr->lflags = 0; \
- bptr->type = BBTYPE_STD; \
- bptr->branchrefs = NULL; \
- bptr->pre_count = 0; \
- bptr->method = (m); \
- bptr->debug_nr = (m)->c_debug_nr++; \
- } while (0)
+
+/* Macro for initializing newly allocated basic block's. It does not
+ need to zero fields, as we zero out the whole basic block array. */
+
+#define BASICBLOCK_INIT(bptr,m) \
+ do { \
+ bptr->mpc = -1; \
+ bptr->flags = -1; \
+ bptr->type = BBTYPE_STD; \
+ bptr->method = (m); \
+ bptr->nr = (m)->c_debug_nr++; \
+ } while (0)
/* branchref *****************************************************************/
#define JAVA_FCONST_1 12
#define JAVA_FCONST_2 13
-#define ICMD_ELSE_ICONST 13
#define JAVA_DCONST_0 14
#define ICMD_DCONST 14 /* val.d = constant */
#define JAVA_DCONST_1 15
-#define ICMD_IFEQ_ICONST 15
#define JAVA_BIPUSH 16
-#define ICMD_IFNE_ICONST 16
#define JAVA_SIPUSH 17
-#define ICMD_IFLT_ICONST 17
#define JAVA_LDC1 18
-#define ICMD_IFGE_ICONST 18
#define JAVA_LDC2 19
-#define ICMD_IFGT_ICONST 19
#define JAVA_LDC2W 20
-#define ICMD_IFLE_ICONST 20
/* order of LOAD instructions must be */
/* equal to order of TYPE_* defines */
#define ICMD_BUILTIN 255 /* internal opcode */
-/* define some ICMD masks *****************************************************/
-
-#define ICMD_OPCODE_MASK 0x00ff /* mask to get the opcode */
-#define ICMD_CONDITION_MASK 0xff00 /* mask to get the condition */
-
/******************* description of JavaVM instructions ***********************/
/***************************** 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 ********************************************************/
/* compile a method with jit compiler */
u1 *jit_compile(methodinfo *m);
+u1 *jit_recompile(methodinfo *m);
/* patch the method entrypoint */
u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
+s4 jit_complement_condition(s4 opcode);
+
/* machine dependent functions */
#if defined(ENABLE_JIT)
void md_init(void);