-/* jit/jit.h - code generation header
+/* src/vm/jit/jit.h - code generation 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.
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
Authors: Andreas Krall
Reinhard Grafl
Changes: Christian Thalinger
+ Edwin Steiner
- $Id: jit.h 1082 2004-05-26 15:04:54Z jowenn $
+ $Id: jit.h 5238 2006-08-16 11:18:05Z christian $
*/
#ifndef _JIT_H
#define _JIT_H
-#include "toolbox/chain.h"
-#include "global.h"
-#include "builtin.h"
-#include "typeinfo.h"
-
-/**************************** resolve typedef-cycles **************************/
+/* forward typedefs ***********************************************************/
+typedef struct jitdata jitdata;
typedef struct stackelement stackelement;
typedef stackelement *stackptr;
typedef struct basicblock basicblock;
-typedef struct instruction instruction;
-typedef struct subroutineinfo subroutineinfo;
-typedef struct varinfo varinfo;
typedef struct branchref branchref;
-typedef struct jumpref jumpref;
-typedef struct dataref dataref;
-typedef varinfo *varinfoptr;
-typedef struct linenumberref linenumberref;
+typedef struct instruction instruction;
+typedef struct new_instruction new_instruction;
+typedef struct insinfo_inline insinfo_inline;
-/************************** stack element structure ***************************/
+#include "config.h"
+#include "vm/types.h"
-/* slot types */
+#include "toolbox/chain.h"
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
+#include "vm/statistics.h"
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/stacktrace.h"
+
+#if defined(ENABLE_INLINING)
+# include "vm/jit/inline/inline.h"
+#endif
-/* 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*/
+#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)
+# define COUNT(x) (x)++
+# define COUNT_SPILLS count_spills++
+#else
+# define COUNT(x) /* nothing */
+# define COUNT_SPILLS /* nothing */
+#endif
+
+
+/* jitdata ********************************************************************/
+
+struct jitdata {
+ methodinfo *m; /* methodinfo of the method compiled */
+ codeinfo *code;
+ codegendata *cd;
+ registerdata *rd;
+#if defined(ENABLE_LOOP)
+ loopdata *ld;
+#endif
+#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
+ lsradata *ls;
+#endif
+ u4 flags; /* contains JIT compiler flags */
+ bool isleafmethod; /* does method call subroutines */
+
+ new_instruction *new_instructions;
+ basicblock *new_basicblocks;
+ s4 *new_basicblockindex;
+ stackelement *new_stack;
+ s4 new_instructioncount;
+ s4 new_basicblockcount;
+ s4 new_stackcount;
+ s4 new_c_debug_nr;
+ registerdata *new_rd;
+};
-#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 JITDATA_FLAG_PARSE 0x00000001
+#define JITDATA_FLAG_VERIFY 0x00000002
+
+#define JITDATA_FLAG_INSTRUMENT 0x00000004
+
+#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 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 */
#define SAVEDVAR 1 /* variable has to survive method invocations */
#define INMEMORY 2 /* variable stored in memory */
#define SAVEDTMP 4 /* temporary variable using a saved register */
+#define TMPARG 8 /* temporary variable using a arg register */
+#define STCOPY 16 /* there is another stackslot alive "below" */
+ /* using the same register/memory location */
+#define STKEEP 32 /* to prevent reg_mark_copy to free this */
+ /* stackslot */
/* variable kinds */
struct stackelement {
stackptr prev; /* pointer to next element towards bottom */
- int type; /* slot type of stack element */
-#ifdef CACAO_TYPECHECK
+ s4 type; /* slot type of stack element */
+#ifdef ENABLE_VERIFIER
typeinfo typeinfo; /* info on reference types */
#endif
- int flags; /* flags (SAVED, INMEMORY) */
- int varkind; /* kind of variable or register */
- int varnum; /* number of variable */
- int regoff; /* register number or memory offset */
+ s4 flags; /* flags (SAVED, INMEMORY) */
+ s4 varkind; /* kind of variable or register */
+ s4 varnum; /* number of variable */
+ s4 regoff; /* register number or memory offset */
};
/**************************** instruction structure ***************************/
+/* branch_target_t: used in TABLESWITCH tables */
+
+typedef union {
+ s4 insindex; /* used between parse and stack */
+ basicblock *block; /* used from stack analysis onwards */
+} branch_target_t;
+
+/* lookup_target_t: used in LOOKUPSWITCH tables */
+
+typedef struct {
+ s4 value; /* case value */
+ branch_target_t target; /* branch target, see above */
+} lookup_target_t;
+
+/*** s1 operand ***/
+
+typedef union {
+ stackptr var;
+ s4 localindex;
+ s4 argcount;
+} s1_operand_t;
+
+/*** s2 operand ***/
+
+typedef union {
+ stackptr var;
+ stackptr *args;
+ classref_or_classinfo c;
+ unresolved_class *uc;
+ ptrint constval; /* for PUT*CONST */
+ s4 tablelow; /* for TABLESWITCH */
+ u4 lookupcount; /* for LOOKUPSWITCH */
+} s2_operand_t;
+
+/*** s3 operand ***/
+
+typedef union {
+ stackptr var;
+ ptrint constval;
+ classref_or_classinfo c;
+ constant_FMIref *fmiref;
+ unresolved_method *um;
+ unresolved_field *uf;
+ insinfo_inline *inlineinfo; /* for INLINE_START/END */
+ s4 tablehigh; /* for TABLESWITCH */
+ branch_target_t lookupdefault; /* for LOOKUPSWITCH */
+ branch_target_t jsrtarget; /* for JSR */
+ struct builtintable_entry *bte;
+} s3_operand_t;
+
+/*** val operand ***/
+
+typedef union {
+ s4 i;
+ s8 l;
+ float f;
+ double d;
+ void *anyptr;
+ java_objectheader *stringconst; /* for ACONST with string */
+ classref_or_classinfo c; /* for ACONST with class */
+} val_operand_t;
+
+/*** dst operand ***/
+
+typedef union {
+ stackptr var;
+ s4 localindex;
+ 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 */
+ stackptr *dupslots; /* for SWAP, DUP* except DUP */
+} 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
+
+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 ***/
+
+/* The new instruction format for the intermediate representation: */
+
+struct new_instruction {
+ u2 opc; /* opcode */
+ u2 line; /* line number */
+#if SIZEOF_VOID_P == 8
+ flags_operand_t flags; /* 4 bytes */
+#endif
+ s1_operand_t s1; /* pointer-size */
+ union {
+ struct {
+ s2_operand_t s2; /* pointer-size */
+ s3_operand_t s3; /* pointer-size */
+ } s23; /* XOR */
+ val_operand_t val; /* long-size */
+ } sx;
+ dst_operand_t dst; /* pointer-size */
+#if SIZEOF_VOID_P == 4
+ flags_operand_t flags; /* 4 bytes */
+#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 */
- methodinfo *method; /*needed for inlining. can't be done on basic block level, since an inlined
- function doesn't start necessarily start a new block*/
+ 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 */
+
+#define INSTRUCTION_IS_UNRESOLVED(iptr) \
+ ((ptrint)(iptr)->target & 0x01) /* XXX target used temporarily as flag */
+
+#define NEW_INSTRUCTION_IS_RESOLVED(iptr) \
+ (!((iptr)->flags.bits & INS_FLAG_UNRESOLVED))
+
+#define NEW_INSTRUCTION_IS_UNRESOLVED(iptr) \
+ ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
+
+#define NEW_INSTRUCTION_MUST_CHECK(iptr) \
+ (!((iptr)->flags.bits & INS_FLAG_NOCHECK))
+
+#define NEW_INSTRUCTION_GET_FIELDREF(iptr,fref) \
+ do { \
+ if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
+ fref = iptr->sx.s23.s3.uf->fieldref; \
+ else \
+ fref = iptr->sx.s23.s3.fmiref; \
+ } while (0)
-/**************************** basic block structure ***************************/
-
-/* flags */
+#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 BBDELETED -2
-#define BBUNDEF -1
-#define BBREACHED 0
-#define BBFINISHED 1
-#define BBTYPECHECK_UNDEF 2
-#define BBTYPECHECK_REACHED 3
+#define NEW_INSTRUCTION_GET_METHODREF(iptr,mref) \
+ do { \
+ if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
+ mref = iptr->sx.s23.s3.um->methodref; \
+ else \
+ mref = iptr->sx.s23.s3.fmiref; \
+ } while (0)
-#define BBTYPE_STD 0 /* standard basic block type */
-#define BBTYPE_EXH 1 /* exception handler basic block type */
-#define BBTYPE_SBR 2 /* subroutine basic block type */
-
-struct basicblock {
- int flags; /* used during stack analysis, init with -1 */
- int type; /* basic block type (std, xhandler, subroutine*/
- instruction *iinstr; /* pointer to intermediate code instructions */
- int icount; /* number of intermediate code instructions */
- int mpc; /* machine code pc at start of block */
- stackptr instack; /* stack at begin of basic block */
- stackptr outstack; /* stack at end of basic block */
- int indepth; /* stack depth at begin of basic block */
- int outdepth; /* stack depth end of basic block */
- int 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) */
- int lflags; /* used during loop copying, init with 0 */
- basicblock *copied_to; /* points to the copy of this basic block */
- /* when loop nodes are copied */
- int debug_nr;
-};
+#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)
-/************************* pseudo variable structure **************************/
+#define NEW_INSTRUCTION_GET_METHODDESC(iptr, md) \
+ do { \
+ if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
+ md = iptr->sx.s23.s3.um->methodref->parseddesc.md; \
+ else \
+ md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
+ } while (0)
-struct varinfo {
- int type; /* basic type of variable */
- int flags; /* flags (SAVED, INMEMORY) */
- int regoff; /* register number or memory offset */
-};
+#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)
-typedef varinfo varinfo5[5];
+#define INSTRUCTION_UNRESOLVED_CLASS(iptr) \
+ ((unresolved_class *) (iptr)->val.a)
+#define INSTRUCTION_UNRESOLVED_METHOD(iptr) \
+ ((unresolved_method *) (iptr)->val.a)
-/***************** forward references in branch instructions ******************/
+#define INSTRUCTION_UNRESOLVED_FIELD(iptr) \
+ ((unresolved_field *) (iptr)->val.a)
-struct branchref {
- s4 branchpos; /* patching position in code segment */
- s4 reg; /* used for ArrayIndexOutOfBounds index reg */
- branchref *next; /* next element in branchref list */
-};
+#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)
-/******************** forward references in tables ***************************/
+#define INSTRUCTION_PUTCONST_FIELDINFO(iptr) \
+ ((fieldinfo *)((iptr)[1].val.a))
-struct jumpref {
- s4 tablepos; /* patching position in data segment */
- basicblock *target; /* target basic block */
- jumpref *next; /* next element in jumpref list */
+#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 ***************************/
+
+/* 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 */
};
-struct linenumberref {
- s4 tablepos; /* patching position in data segment */
- int targetmpc; /* machine code program counter of first instruction for given line*/
- u2 linenumber; /* line number, used for inserting into the table and for validty checking*/
- linenumberref *next; /* next element in linenumberref list */
+/* basicblock *****************************************************************/
+
+/* flags */
+
+#define BBDELETED -2
+#define BBUNDEF -1
+#define BBREACHED 0
+#define BBFINISHED 1
+
+#define BBTYPECHECK_UNDEF 2
+#define BBTYPECHECK_REACHED 3
+
+#define BBTYPE_STD 0 /* standard basic block type */
+#define BBTYPE_EXH 1 /* exception handler basic block type */
+#define BBTYPE_SBR 2 /* subroutine basic block type */
+
+#define BBFLAG_REPLACEMENT 0x01 /* put a replacement point at the start */
+
+/* XXX basicblock wastes quite a lot of memory by having four flag fields */
+/* (flags, bitflags, type and lflags). Probably the last three could be */
+/* combined without loss of efficiency. The first one could be combined with */
+/* the others by using bitfields. */
+
+struct basicblock {
+ 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 */
+ 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 */
+ /* (see doc/stack.txt) */
+ methodinfo *method; /* method this block belongs to */
};
-struct dataref {
- u1 *pos; /* patching position in generated code */
- dataref *next; /* next element in dataref list */
+/* 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 *****************************************************************/
+
+struct branchref {
+ s4 branchpos; /* patching position in code segment */
+ branchref *next; /* next element in branchref list */
};
#define ACONST_LOAD 0 /* ACONST_NULL or LDC instruction */
#define ACONST_BUILTIN 1 /* constant argument for a builtin function call */
+
/********** JavaVM operation codes (sorted) and instruction lengths ***********/
extern char *icmd_names[256];
#define ICMD_ACONST 1 /* val.a = constant */
#define JAVA_ICONST_M1 2
-#define ICMD_NULLCHECKPOP 2
+#define ICMD_CHECKNULL 2
#define JAVA_ICONST_0 3
#define ICMD_ICONST 3 /* val.i = constant */
#define JAVA_ICONST_1 4
-#define ICMD_IREM0X10001 4
+#define ICMD_CHECKNULL_POP 4
#define JAVA_ICONST_2 5
#define ICMD_IDIVPOW2 5 /* val.i = constant */
#define JAVA_ICONST_4 7
#define JAVA_ICONST_5 8
-#define ICMD_LREM0X10001 8
#define JAVA_LCONST_0 9
#define ICMD_LCONST 9 /* val.l = constant */
#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_XXX defines */
+ /* equal to order of TYPE_* defines */
#define JAVA_ILOAD 21
#define ICMD_ILOAD 21 /* op1 = local variable */
#define ICMD_SALOAD 53
/* order of STORE instructions must be*/
- /* equal to order of TYPE_XXX defines */
+ /* equal to order of TYPE_* defines */
#define JAVA_ISTORE 54
#define ICMD_ISTORE 54 /* op1 = local variable */
#define JAVA_INVOKEINTERFACE 185
#define ICMD_INVOKEINTERFACE 185 /* val.a = method info pointer */
-#define ICMD_CHECKASIZE 186 /* */
+/* UNDEF186 */
#define JAVA_NEW 187
#define ICMD_NEW 187 /* op1 = 1, val.a = class pointer */
#define JAVA_BREAKPOINT 202
-#define ICMD_CHECKOOM 203 /* check for out of memory error */
+/* UNDEF203 */
-#define ICMD_BUILTIN3 253 /* internal opcode */
-#define ICMD_BUILTIN2 254 /* internal opcode */
-#define ICMD_BUILTIN1 255 /* internal opcode */
-#define ICMD_READONLY_ARG 1024 /* used for inlining, opcodes 1024-1028 are used */
-#define ICMD_CLEAR_ARGREN 1029 /* indicates the start of a new inlined method argument renaming must be reset */
+#define ICMD_IASTORECONST 204
+#define ICMD_LASTORECONST 205
+#define ICMD_FASTORECONST 206
+#define ICMD_DASTORECONST 207
+#define ICMD_AASTORECONST 208
+#define ICMD_BASTORECONST 209
+#define ICMD_CASTORECONST 210
+#define ICMD_SASTORECONST 211
+#define ICMD_PUTSTATICCONST 212
+#define ICMD_PUTFIELDCONST 213
-/******************* description of JavaVM instructions ***********************/
+#define ICMD_IMULPOW2 214
+#define ICMD_LMULPOW2 215
+
+#define ICMD_IF_FCMPEQ 216
+#define ICMD_IF_FCMPNE 217
+
+#define ICMD_IF_FCMPL_LT 218
+#define ICMD_IF_FCMPL_GE 219
+#define ICMD_IF_FCMPL_GT 220
+#define ICMD_IF_FCMPL_LE 221
+
+#define ICMD_IF_FCMPG_LT 222
+#define ICMD_IF_FCMPG_GE 223
+#define ICMD_IF_FCMPG_GT 224
+#define ICMD_IF_FCMPG_LE 225
+
+#define ICMD_IF_DCMPEQ 226
+#define ICMD_IF_DCMPNE 227
-#if defined(USEBUILTINTABLE)
+#define ICMD_IF_DCMPL_LT 228
+#define ICMD_IF_DCMPL_GE 229
+#define ICMD_IF_DCMPL_GT 230
+#define ICMD_IF_DCMPL_LE 231
-builtin_descriptor *find_builtin(int opcode);
+#define ICMD_IF_DCMPG_LT 232
+#define ICMD_IF_DCMPG_GE 233
+#define ICMD_IF_DCMPG_GT 234
+#define ICMD_IF_DCMPG_LE 235
+
+#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_BUILTIN 255 /* internal opcode */
+
+
+/******************* description of JavaVM instructions ***********************/
-#endif /* USEBUILTINTABLE */
/***************************** register types *********************************/
/***************************** register info block ****************************/
-extern int nregdescint[]; /* description of integer registers */
-extern int nregdescfloat[]; /* description of floating point registers */
-
-extern int nreg_parammode;
-
-
-/* compiler switches (set by main function) ***********************************/
-
-extern int count_jit_calls;
-extern int count_methods;
-extern int count_spills;
-extern int count_pcmd_activ;
-extern int count_pcmd_drop;
-extern int count_pcmd_zero;
-extern int count_pcmd_const_store;
-extern int count_pcmd_const_alu;
-extern int count_pcmd_const_bra;
-extern int count_pcmd_load;
-extern int count_pcmd_move;
-extern int count_load_instruction;
-extern int count_pcmd_store;
-extern int count_pcmd_store_comb;
-extern int count_dup_instruction;
-extern int count_pcmd_op;
-extern int count_pcmd_mem;
-extern int count_pcmd_met;
-extern int count_pcmd_bra;
-extern int count_pcmd_table;
-extern int count_pcmd_return;
-extern int count_pcmd_returnx;
-extern int count_check_null;
-extern int count_check_bound;
-extern int count_max_basic_blocks;
-extern int count_basic_blocks;
-extern int count_max_javainstr;
-extern int count_javainstr;
-extern int count_javacodesize;
-extern int count_javaexcsize;
-extern int count_calls;
-extern int count_tryblocks;
-extern int count_code_len;
-extern int count_data_len;
-extern int count_cstub_len;
-extern int count_nstub_len;
-extern int count_max_new_stack;
-extern int count_upper_bound_new_stack;
-extern int *count_block_stack;
-extern int *count_analyse_iterations;
-extern int *count_method_bb_distribution;
-extern int *count_block_size_distribution;
-extern int *count_store_length;
-extern int *count_store_depth;
-
-
-/* global compiler variables */
-
-extern classinfo *class; /* class the compiled method belongs to */
-extern methodinfo *method; /* pointer to method info of compiled method */
-extern utf *descriptor; /* type descriptor of compiled method */
-extern int mparamcount; /* number of parameters (incl. this) */
-extern u1 *mparamtypes; /* types of all parameters (TYPE_INT, ...) */
-
-extern int maxstack; /* maximal JavaVM stack size */
-extern int maxlocals; /* maximal number of local JavaVM variables */
-extern int jcodelength; /* length of JavaVM-codes */
-extern u1 *jcode; /* pointer to start of JavaVM-code */
-extern lineinfo *jlinenumbers; /* line information array */
-extern u2 jlinenumbercount; /* number of entries in the linenumber array */
-extern int exceptiontablelength;/* length of exception table */
-extern xtable *extable; /* pointer to start of exception table */
-extern exceptiontable *raw_extable;
-
-extern int block_count; /* number of basic blocks */
-extern basicblock *block; /* points to basic block array */
-extern int *block_index; /* a table which contains for every byte of */
- /* JavaVM code a basic block index if at this */
- /* byte there is the start of a basic block */
-
-extern int instr_count; /* number of JavaVM instructions */
-extern instruction *instr; /* points to intermediate code instructions */
-
-extern int stack_count; /* number of stack elements */
-extern stackelement *stack; /* points to intermediate code instructions */
-
-extern bool isleafmethod; /* true if a method doesn't call subroutines */
-
-extern basicblock *last_block; /* points to the end of the BB list */
-
-extern bool regs_ok; /* true if registers have been allocated */
-
-
-/* list of all classes used by the compiled method which have to be */
-/* initialised (if not already done) before execution of this method */
-extern chain *uninitializedclasses;
-
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 ********************************************************/
-#if defined(__I386__)
-extern bool method_uses_ecx;
-extern bool method_uses_edx;
-#endif
-
+/* compiler initialisation */
+void jit_init(void);
-/* function prototypes */
+/* compiler finalisation */
+void jit_close(void);
-methodptr jit_compile (methodinfo *m); /* compile a method with jit compiler */
+/* compile a method with jit compiler */
+u1 *jit_compile(methodinfo *m);
+u1 *jit_recompile(methodinfo *m);
-void jit_init(); /* compiler initialisation */
-void jit_close(); /* compiler finalisation */
+/* patch the method entrypoint */
+u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
-u1 *createcompilerstub(methodinfo *m);
-u1 *createnativestub(functionptr f, methodinfo *m);
+s4 jit_complement_condition(s4 opcode);
-void removecompilerstub(u1 *stub);
-void removenativestub(u1 *stub);
+/* machine dependent functions */
+#if defined(ENABLE_JIT)
+void md_init(void);
-void typecheck();
+u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr);
-/* debug helpers (in stack.c) */
+void md_cacheflush(u1 *addr, s4 nbytes);
+void md_icacheflush(u1 *addr, s4 nbytes);
+void md_dcacheflush(u1 *addr, s4 nbytes);
+#endif
-void icmd_print_stack(stackptr s);
-char *icmd_builtin_name(functionptr bptr);
-void show_icmd_block(basicblock *bptr);
-void show_icmd(instruction *iptr,bool deadcode);
-void show_icmd_method();
+#if defined(ENABLE_INTRP)
+void intrp_md_init(void);
+#endif
#endif /* _JIT_H */
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/